Printf() issue across two wixels (Send>Receive)

I have a small project I’m working on for my house. I have two wixels right now setup as transmitter and receiver. The TX module has a thermistor and some fancy math on it to send it to the receiver. I plan on adding more functionality in the future but I thought I’d start small for now. I also have the TX module dump its data to the COM port just for display purposes at this point. The issue is, the data that’s being output from the TX modules printf() statements are different from the RX modules. I’ve tried different formats %u %d %ld, etc and various integer types, nothing seems to work. Any help would be appreciated. I’m hoping its something I’m just overlooking.

-Dan

–Code for RX module

uint8 XDATA * rxData; // Check if there is a radio packet to report and space in the // USB TX buffers to report it. if ((rxData = radioQueueRxCurrentPacket()) && usbComTxAvailable() >= 64) { printf("%u\r\n",rxData[1]); printf("%f\r\n",rxData[2]); printf("%u\r\n",rxData[3]); printf("\r\n\r\n"); radioQueueRxDoneWithPacket(); }

–Code for TX Module

int32 CODE param_input_mode = 0;
int32 CODE param_send_delay = 2000;
int32 lastTx;
uint16 cTime;
uint16 rawADC;
float Temp;

int32 CODE param_input_mode = 0;
int32 CODE param_send_delay = 2000;
int32 lastTx;
uint16 cTime;
uint16 rawADC;
float Temp;


void grabTemp()
{

	// Assuming a 10k Thermistor.  Calculation is actually: Resistance = (4096/ADC)
	//Resistance = ((20470000/RawADC) - 10000);


	/******************************************************************/
	/* Utilizes the Steinhart-Hart Thermistor Equation:				  */
	/* Temperature in Kelvin = 1 / {A + B[ln(R)] + C[ln(R)]^3}		  */
	/* where A = 0.001129148, B = 0.000234125 and C = 8.76741E-08	  */
	/******************************************************************/

	rawADC = adcRead(0); //Grab ADC Reading
	Temp = logf(((20470000/rawADC) - 10000));
	//Temp = 1 / (0.003354016 + (0.000256985 * Temp) + (0.000002620131 * Temp * Temp * Temp));
	Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
	Temp = Temp - 273.15;  // Convert Kelvin to Celsius
	Temp = (Temp * 9.0)/ 5.0 + 32.0; // Convert to Fahrenheit
	cTime = getMs();

	if ((getMs() - lastTx) >= param_send_delay)
	{
		lastTx = getMs();
		printf("RawADC = %u\r\n",rawADC);
		printf("Temperature = %f\r\n",Temp);
		printf("CTime = %d\r\n",cTime/1000);
		printf("\r\n\r\n");

	}


}


void txData()
{
	static uint16 lastTx = 0;
	uint8 XDATA * packet;

	if ((uint16)(getMs() - lastTx) >= param_send_delay && (packet = radioQueueTxCurrentPacket()))
		{
			lastTx = getMs();
			//Length
			packet[0] = 2;   // must not exceed RADIO_QUEUE_PAYLOAD_SIZE
			//Data
			packet[1] = rawADC;
			packet[2] = Temp;
			packet[3] = cTime;
			//Send
			radioQueueTxSendPacket();
		}
}


That certainly won't work, the data byte isn't floating point. The format specifier has to be compatible with the declared data type.

That certainly won’t work, the data byte isn’t floating point. The format specifier has to be compatible with the declared data type.

So are you saying that the variable “Temp” declared as Float on the TX module isn’t passed through to the RX module as a float? I did notice that if I change the function type to %d I get my temperature, just not in float form, it displays it as a whole number. This doesn’t explain the other two data bytes though?

int32 CODE param_input_mode = 0; int32 CODE param_send_delay = 2000; int32 lastTx; uint16 cTime; uint16 rawADC; float Temp;

Hello, Dan.

The problem originates in these lines of your TX code:

packet[1] = rawADC; packet[2] = Temp; packet[3] = cTime;

The variable packet is a "uint8 ", so packet[1] is a uint8, and it can only hold numbers between 0 and 255. When you assign a float or a uint16 to uint8 like you are doing, you will silently lose some data. For example, your TX module displayed RawADC as 1004, but the byte it transmitted over the radio was 1004 % 256 = 1004 - 3256 = 236.

I would recommend making a struct to hold those three numbers and then using memcpy to copy the bytes of the struct into the packet buffer. Then on the receiving end, you can use a cast to interpret the received bytes as that struct, just like we are doing in the wireless_adc_rx app.

Also, floating point calculations are expensive to do on 8-bit microcontrollers so in general I recommend sticking with integers.

–David

I thought that had something to do with it, that makes sense then.

So I’ve setup a struct and memcpy…

typedef struct values { uint16 rawADC; float temp; int32 cTime; } values;

when I build the project I get this error…

apps/usb_temperatureTX/usb_temperatureTX.c:94: syntax error: token -> ‘values’ ; column 23
make: *** [apps/usb_temperatureTX/usb_temperatureTX.rel] Error 1

Shouldn’t you be using “sizeof(values)”?

There is conceivably also a problem with having a struct type and the variable having the same name (values).

Yes, that was a typo on my part. The length variable should read “values”.