Go Down

Topic: Strange Struct issue (Read 1 time) previous topic - next topic


I have isolated a very strange behaviour down to a few lines in a simple Duemilinova program. If I try to set a structure element, the program will compile and download, but it will not run. I know something is not working because the LED never blinks as the setup program is waiting for a user to press a key.

I did some research and found the bug list and only one is similar to what I am seeing. I tried the workaround (using an intermediate pointer) but that did not work.

I hope that some of you might try out the various test cases in this code (see the TEST #define) and tell me what might be the problem. Code follows.

#define NUM_THING    16  // Number of B structures
#define NUM_A         5  // Number of A structures
#define PIN_LED 13       // PIN ID for the LED on an Arduino Duemilinova
// A structure that will be nested 
typedef struct {
  char a_aaa[15+1];
  int  a_bbb;
  int  a_ccc;
  int  a_ddd;
} A_t;
// Another structure (B) 
typedef struct {
  char          b_eee[15+1];
  A_t           b_fff[NUM_A];
} B_t;

// An instance of the top level structure (B)
B_t thing[NUM_THING];

#define TEST 5

// This gets executed before anything else
void setup() {
  int i;
  void *p;
  // Initialize the IO pins
  pinMode(PIN_LED, OUTPUT);
  // Open serial port
  // Wait till user enters a key
  Serial.println("Type a key to start");
  do {
    digitalWrite(PIN_LED, HIGH);
    digitalWrite(PIN_LED, LOW);
  } while (!Serial.available());
  // Fails
#if TEST == 1
  strcat(thing[0].b_eee, "aaa");

  // Fails
#if TEST == 2
  p = &thing[0].b_eee;
  strcat((char*)p, "aaa");
  // Works
#if TEST == 3
  p = &thing[0].b_eee;
  // Works
#if TEST == 4
  strcat((char*)p, "aaa");

  // Fails
#if TEST == 5
  thing[0].b_fff[0].a_bbb = 1;

} // end Setup

// Main loop
void loop() {

} // end loop


Did you intend to

the data after seeing something was there, or just notice that something was there with
and then leave whatever was the in the buffer?

You might want to add serial.flush() also to clear the buffer out after Serial.begin so you're in a known good state to start.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.


You might be running out of memory. Just as a test could you comment out the line B_t thing[NUM_THING]; and then get the serial monitor to print out sizeof(B_t) to see how much room each one takes, then multiply by NUM_THING for total memory usage.
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html


Its late at night, so my maths might be out.
An A seems to be 22 bytes long or so.
A B seems to be 126 bytes or so.
You are declaring 16 * 126 bytes of Bs.....

You may have no memory left. There is a limit of 1024 bytes RAM (Atmega168)  You have not said which chip you are using (ATmega328 has 2K I think.


Memory size seems to be an issue. I had not realized that you might be able to download a program that violated size requirements. My normal development environment (IAR compiler) lets you know when you screw up!

I am using an Atmel 328.

Yes, I was aware that a character was still left in the UART receive buffer. This sample was a greatly cut down version of a program I was working on that used a Sparkfun SD shield and the FAT32 library.

I cut the size of the structure array down and it now works. I guess I need to greatly rethink my software design. I guess I will only read one element at a time and store the rest in/on the SD card. I have been looking at the sketch size during the download process and was happy to see I was only 1/3 full. But that must be non volatile size and not RAM size.

Is there a way to determine RAM usage? Is there a memory map generated someplace?

Thanks for the help. I was going crazy.


Is there a memory map generated someplace?

SRAM is used for global variables, constant strings, the heap and the stack. The amount of space needed for global variables and strings is known at compile time. Heap and stack usage is run-time dependent. A memory map might show plenty of space, but the run-time usage may be very large. On the other hand, run-time usage may be minimal, while the global and string usage may use up nearly all the memory.

There is a FreeMemory() function (it's google time) that can tell you how much memory you have available at any given time. Of course, it uses some memory.
The art of getting good answers lies in asking good questions.

Go Up