Pages: [1]   Go Down
Author Topic: Strange Struct issue  (Read 812 times)
0 Members and 1 Guest are viewing this topic.
New Hampshire
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
  Serial.begin(9600);
 
  // Wait till user enters a key
  Serial.println("");
  Serial.println("Type a key to start");
  do {
    digitalWrite(PIN_LED, HIGH);
    delay(250);
    digitalWrite(PIN_LED, LOW);
    delay(250);
  } while (!Serial.available());
  Serial.println("Starting");
 
  // Fails
#if TEST == 1
  strcat(thing[0].b_eee, "aaa");
#endif

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

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

 
} // end Setup



//********************************************************************
//
// Main loop
//
//********************************************************************
void loop() {

  delay(500);
  Serial.println("loop");
 
} // end loop
Logged

Skye Sweeney

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 27425
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Did you intend to
Serial.read()

the data after seeing something was there, or just notice that something was there with
Serial.available());
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.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
God Member
*****
Karma: 32
Posts: 507
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged


UK, Southwest
Offline Offline
Full Member
***
Karma: 5
Posts: 138
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

New Hampshire
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Skye Sweeney

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 653
Posts: 50881
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Logged

Pages: [1]   Go Up
Jump to: