gwdeveloper 275 Posted August 6, 2011 Share Posted August 6, 2011 I'm pretty sure this is a simple question but I'm reading past the answers. Basically, I am trying to transmit four floating point numbers via SimpliciTI's SMPL_Send. The data struct look likes: struct sensors_struct { float thermistor; float relativeHumidity; float gyroRoll; float gyroPitch; }sensor_data[16]; struct sensors_struct sensor; It's transmitted with: SMPL_Send(linkIDTemp, (uint8_t *)&sensor, sizeof( struct sensors_struct )); Receive command: SMPL_Receive(linkIDTemp, (uint8_t*)&smpl_buffer, &len) So, I guess my question is what is the best method to return the received data into the struct? AFAIK, it's 16 bytes total due to the 4 float variables. Is there a way to simply cast the buffer into the struct? I referenced some of the help found here http://e2e.ti.com/support/low_power_rf/f/156/p/98693/345255.aspx Quote Link to post Share on other sites
oPossum 1,083 Posted August 6, 2011 Share Posted August 6, 2011 struct sensors_struct foo; // Received data will be copied to foo SMPL_Receive(linkIDTemp, (uint8_t*)&smpl_buffer, &len); if(len == sizeof(foo)) { memcpy(&foo, &smpl_buffer, len); } else { // rx data is the wrong size } Quote Link to post Share on other sites
gordon 229 Posted August 6, 2011 Share Posted August 6, 2011 struct sensors_struct { float thermistor; float relativeHumidity; float gyroRoll; float gyroPitch; }sensor_data[16]; struct sensors_struct sensor; Are you aware that this creates a 16-strong array of sensors_struct items (so taking up 16 * 4 * sizeof(float) bytes in RAM) named sensor_data as well? From your post I gather you don't want this. Drop the "sensor_data[16]" part if all you want is one single sensor variable (I think this is what you want). Quote Link to post Share on other sites
gwdeveloper 275 Posted August 6, 2011 Author Share Posted August 6, 2011 @oPossum, I attemped to create my receive callback isr as: static uint8_t sRxCallback(linkID_t linkIDTemp) { SMPL_Receive(linkIDTemp, (uint8_t*)&smpl_buffer, &len); if(len == sizeof(sensor)) { P1OUT |= BIT1; memcpy(&sensor, &smpl_buffer, len); } else { P1OUT |= BIT0; } return 0; } It still hangs up. I'm almost now wondering if the data is being transferred. The devices connect but stopped tx/rx after I changed my sensor data to a structure. @Gordon No, I had no idea it did this. I'm trying to make my code a bit more efficient so I'm teaching myself to use structures to do so. Splitting each float into 4 bytes and combining into a message was taking quite a bit of time and space. I would like to transmit all 4 floats of sensor data in one message. From my understanding, a SimpliciTI message can be 52 bytes (or actually 64 bytes = 52bytes + simpliciti_headers). I was attempting to TX all 4 float variables by sending the struct and thought it would be well under the max size. By adding sensor_data[16] to the end of the struct locks the space in RAM whether it is used or not, correct? Quote Link to post Share on other sites
gordon 229 Posted August 6, 2011 Share Posted August 6, 2011 Grouping the four floats into a struct and transmitting that in one go is OK. The following (with some pseudocode sprinkled in, since i do not know SimpliciTI) struct sensors_struct { float thermistor; float relativeHumidity; float gyroRoll; float gyroPitch; }; sensors_struct sensor; sensor.thermistor = ReadThermistor(); sensor.relativeHumidity = ReadHumidity(); sensor.gyroRoll = ReadRoll(); sensor.gyroPitch = ReadPitch(); Transmit(&sensor, sizeof(sensor)); will do just that. By adding sensor_data[16] to the end of the struct locks the space in RAM whether it is used or not, correct? Yes. It is basically a shorthand for struct sensors_struct { float thermistor; float relativeHumidity; float gyroRoll; float gyroPitch; }; struct sensors_struct sensor_data[16]; gwdeveloper 1 Quote Link to post Share on other sites
gordon 229 Posted August 6, 2011 Share Posted August 6, 2011 @oPossum, I attemped to create my receive callback isr as: static uint8_t sRxCallback(linkID_t linkIDTemp) { SMPL_Receive(linkIDTemp, (uint8_t*)&smpl_buffer, &len); When oPossum speaks usually the best course of action is to sit back and listen for something might as well stick, so I'm feeling the tiniest bit uncomfortable here, but anyway. That uint8_t looks suspicious. Some random web page I found says "@param msg - pointer to where received message should be copied" for the second argument to SMPL_Receive(). Depending on your particular MCU (whether or not it is CPUX that is), a pointer will be either uint16_t or uint32_t. Truncating it to uint8_t will highly likely cause memory corruption on the spot. Quote Link to post Share on other sites
oPossum 1,083 Posted August 6, 2011 Share Posted August 6, 2011 All pointers are the same size sizeof(char *) == sizeof(int *) == sizeof(double *) == sizeof(void *) So casting from a pointer to one type to a pointer to another type is not a problem. Quote Link to post Share on other sites
gordon 229 Posted August 6, 2011 Share Posted August 6, 2011 And I stand corrected. Again. Quote Link to post Share on other sites
gwdeveloper 275 Posted August 6, 2011 Author Share Posted August 6, 2011 Well, I'm pretty sure it's transmitting. The struct values are being properly loaded when checking with the CCS debugger. For now, the 4 floats are loaded after sampling each channel 8 times and averaged; I'm using the DTC set to take 32 sequential samples so it's faster. Simply: // initial ADCdata[] position for thermistor = 3; ADCdata[i] is pointer to DTC ram location sensor.thermistor = 0; for (i=3; i < 32; i+=4) { sensor.thermistor += ADCdata[i]; } sensor.thermistor /= 8; Transmission command is: SMPL_Send(linkIDTemp, (uint8_t *)&sensor, sizeof( struct sensors_struct )); Once the message is transmitted, the transmitter thinks it's still connected appears to be functioning fine; wakes up every 1s to collect data, calculate and transmit -all verified in the debugger. On the receiver, the connection leds toggle properly and then waits for a message. Is "sizeof( struct sensors_struct )" a proper way to get the size of the struct? Transmitting ints is easy, the msg would be created by: msg[0] = tempReading&0xFF; msg[1] = (tempReading>>8)&0xFF; And sent by: SMPL_Send(linkIDTemp, msg, sizeof(msg)); Hopefully this week's bathroom renovation project stays on budget and I can order a https://estore.ti.com/Search.aspx?detail=1&k=CC2511EMK to use as a packet sniffer. Quote Link to post Share on other sites
gwdeveloper 275 Posted August 17, 2011 Author Share Posted August 17, 2011 Thanks for all the help. Now that I have the struct declared and used properly and my MAX_APP_PAYLOAD is now set to 16 bytes (not 10!) the data is transmitting with no issues. Working but not completed pieces of transmitter: typedef struct sensors_struct { float thermistor; float relativeHumidity; float gyroRoll; float gyroPitch; }my_sensors; my_sensors sensor; //struct sensors_struct sensor; sensor.thermistor = 1.0; sensor.relativeHumidity = 2.0; sensor.gyroRoll = 380.0; sensor.gyroPitch = 381.0; SMPL_Send(linkIDTemp, (uint8_t *)&sensor, sizeof( my_sensors )); And receiver: typedef struct sensors_struct { float thermistor; float relativeHumidity; float gyroRoll; float gyroPitch; }my_sensors; struct sensors_struct sensor; uint8_t smpl_buffer[MAX_APP_PAYLOAD]; SMPL_Init(sRxCallback); static uint8_t sRxCallback(linkID_t linkIDTemp) { SMPL_Receive(linkIDTemp, (uint8_t*)&smpl_buffer, &len); if(len == sizeof(my_sensors)) { P1OUT |= BIT1; memcpy(&sensor, smpl_buffer, len); } else { P1OUT |= BIT0; } // replace with_ return message; return 0; } zeke 1 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.