Jump to content

  • Log In with Google      Sign In   
  • Create Account

Photo

Question about Structs and Pointers


  • Please log in to reply
9 replies to this topic

#1 gwdeveloper

gwdeveloper

    Level 3

  • Members
  • 580 posts


Posted 06 August 2011 - 07:26 PM

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/su...693/345255.aspx

#2 oPossum

oPossum

    Poke me with a Stick

  • Members
  • 863 posts
  • LocationMichigan, USA


Posted 06 August 2011 - 07:42 PM


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

}


Think in assembly, write in C. Sent from a bunker in an undisclosed location deep beneath a mountain.

#3 gordon

gordon

    Level 3

  • Members
  • 536 posts


Posted 06 August 2011 - 09:31 PM

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).
A mouse is a device used to point at the xterm you want to type in.

#4 gwdeveloper

gwdeveloper

    Level 3

  • Members
  • 580 posts


Posted 06 August 2011 - 09:57 PM

@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?

#5 gordon

gordon

    Level 3

  • Members
  • 536 posts


Posted 06 August 2011 - 10:35 PM

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 likes this
A mouse is a device used to point at the xterm you want to type in.

#6 gordon

gordon

    Level 3

  • Members
  • 536 posts


Posted 06 August 2011 - 10:58 PM

@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.
A mouse is a device used to point at the xterm you want to type in.

#7 oPossum

oPossum

    Poke me with a Stick

  • Members
  • 863 posts
  • LocationMichigan, USA


Posted 06 August 2011 - 11:05 PM

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.
Think in assembly, write in C. Sent from a bunker in an undisclosed location deep beneath a mountain.

#8 gordon

gordon

    Level 3

  • Members
  • 536 posts


Posted 06 August 2011 - 11:12 PM

And I stand corrected. Again. :)
A mouse is a device used to point at the xterm you want to type in.

#9 gwdeveloper

gwdeveloper

    Level 3

  • Members
  • 580 posts


Posted 06 August 2011 - 11:52 PM

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.co...l=1&k=CC2511EMK to use as a packet sniffer.

#10 gwdeveloper

gwdeveloper

    Level 3

  • Members
  • 580 posts


Posted 17 August 2011 - 12:54 AM

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 likes this




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users