Out of memory just printing a struct...

Status
Not open for further replies.

braddo

Member
I'm developing a little struct to hold some data for my sprinkler controller, which uses the T3.1 and Wiznet 820io (great stuff!).

But, just a setup() which sets the values and a loop which prints them out kicks out of memory errors after less than a minute of running.

It's probably something simple, but I can't see what the issue might be - any ideas?

Code:
#include <Flash.h>

enum {front=8,back=9};

struct zone_t {
  byte pPin;
  byte pState;
  byte pDuration;
  unsigned long pOnAtMillis;
  byte pEnabled;
  struct slot_t {
    byte iHour;
    byte iMin;
    byte iDuration;
    byte dayOfWeek[7];
  } slot[2];
} zone[2];


void setup(){
  Serial.begin(9600);
  for (int i=0;i<2;i++){
        zone[i].pPin = i+100;
        zone[i].pState = i+110;
        zone[i].pDuration = i+120;
        zone[i].pOnAtMillis = i+130;
        zone[i].pEnabled = i+140;
     for (int j=0;j<2;j++){       
        zone[i].slot[j].iHour = j+200;
        zone[i].slot[j].iMin = j+210;
        zone[i].slot[j].iDuration = j+220;
       for (int k=0;k<7;k++){       
        zone[i].slot[j].dayOfWeek[k] = k+300;
      };
    };
  };
};

void loop(){
  for (int i=0;i<2;i++){
        Serial << "pPin: " << zone[i].pPin << " pState: " << zone[i].pState
                  << " pDuration: " << zone[i].pDuration << " pOnAtMillis: " << zone[i].pOnAtMillis << " pEnabled: " << zone[i].pEnabled << "\n";
      for (int j=0;j<2;j++){  
        Serial << "\tiHour: " << zone[i].slot[j].iHour << " iMin: " << zone[i].slot[j].iMin
                    << " iDuration: " << zone[i].slot[j].iDuration << "\n";
      for (int k=0;k<7;k++){
         Serial << "\t\tDayOfWeek" << zone[i].slot[j].dayOfWeek[k] << "\t";
      };
      Serial << "\n";
    };
  Serial << "\n";  
  };
Serial << "\n";
};
 
Last edited:
Please re-post with code tags done correctly so the indentation is preserved.
I didn't pore over the code but two things pop out
structure type definition within structure type definition ... I avoid that, esp. where you define an instance of the struct inside another.
My habit is to define each structure independently, not nested definitions. Define slot_t first, then use its type inside the definition of zone_t.
What you have may work, but it may be unorthodox.

the use of IO streaming as in Serial << is not normally done on simple microprocessors. I never use it and to do so, I think there's some includes and class instances to do.
I tend to use sprintf() then Serial.print() or Serial.printf()
 
Hey Paul, thanks for the question - the Flash.h is from here:

https://github.com/mikalhart/Flash/releases

I did originally have a compile problem with this library but did solve it as per a previous post on this forum and in the issues for that library on github.

I"m using this library because TinyWebServer https://github.com/ovidiucp/TinyWebServer uses it extensively. Primarily it is used for memory saving through the F() macro, which I think you have posted is unnecessary with teensy, but since it's througout TinyWebServer I decided to keep it in. Otherwise testing of the webserver itself seems to work.
 
stevech, sorry for the markdown typo, fixed.

I did look around for a while before selecting this nested struct/struct/array. I've seen it done both ways and, as far as I know, there's nothing wrong with this configuration. I find it to be both easier to read and more succinct. I *think* that the streaming (<<) notation is part of the Flash.h library which Paul already asked about. I also find that notation extremely convenient, but it's a good thing to test independently and see if it's what's causing the OOM condition. If it is though, I'm wondering if it might not be a teensy issue specifically, as this Flash.h library is quite widely used and classic.
 
Hey Paul, thanks for the question - the Flash.h is from here:

https://github.com/mikalhart/Flash/releases

I did originally have a compile problem with this library but did solve it as per a previous post on this forum and in the issues for that library on github.

Perhaps I didn't ask my question clearly.

I want you to provide a link or post a copy of the EXACT code you're actually using (not merely a link to a version that doens't work with Teensy3 and an unspecified change that fixes the issue). We're now 6 replies into this thread and I *still* can't compile your code with precisely the same stuff you used.

How do you expect me to resolve this problem for you, if you don't give me the exact code to reproduce it here?
 
Initializing and Printing Struct to Serial Monitor causes OOM

Here's a new version with the Flash.h reference and use stripped out. Basically I just write the struct and print it out over and over using standard Serial.print() and println() commands. I tried 9600 baud and 115200 baud and both fail when you have the serial monitor open after less than a minute. If you don't open the Serial Monitor, no failure appears to occur. Below is the initial error screen. The arduino ide becomes unresponsive and has to be killed multiple times with task manager (on Windows) so can't get it all very easily.

TeensyOOMwStruct.PNG

I am using Arduino 1.0.5-r2, which is the current stable release.

Here's the cleaner but still failing code:

Code:
struct zone_t {
  int pPin;
  int pState;
  int pDuration;
  unsigned long pOnAtMillis;
  int pEnabled;
  struct slot_t {
    int iHour;
    int iMin;
    int iDuration;
    int dayOfWeek[7];
  } slot[2];
} zone[2];

void setup(){
  Serial.begin(115200);
  for (int i=0;i<2;i++){
        zone[i].pPin = i+100;
        zone[i].pState = i+110;
        zone[i].pDuration = i+120;
        zone[i].pOnAtMillis = i+130;
        zone[i].pEnabled = i+140;
     for (int j=0;j<2;j++){       
        zone[i].slot[j].iHour = j+200;
        zone[i].slot[j].iMin = j+210;
        zone[i].slot[j].iDuration = j+220;
       for (int k=0;k<7;k++){       
        zone[i].slot[j].dayOfWeek[k] = k+300;
      };
    };
  };
};

void loop(){
  for (int i=0;i<2;i++){
        Serial.print("pPin: ");
        Serial.print(zone[i].pPin);
        Serial.print(" pState: ");
        Serial.print(zone[i].pState);
        Serial.print(" pDuration: ");
        Serial.print(zone[i].pDuration);
        Serial.print(" pOnAtMillis: ");
        Serial.print(zone[i].pOnAtMillis);
        Serial.print(" pEnabled: ");
        Serial.println(zone[i].pEnabled);
        for (int j=0;j<2;j++){
          Serial.print("\tiHour: ");
          Serial.print(zone[i].slot[j].iHour);
          Serial.print(" iMin: ");
          Serial.print(zone[i].slot[j].iMin);
          Serial.print(" iDuration: ");
          Serial.println(zone[i].slot[j].iDuration);
          Serial.print("\t\tDayOfWeek: ");
          for (int k=0;k<7;k++){
            Serial.print(zone[i].slot[j].dayOfWeek[k]);
            Serial.print(" ");
          };
          Serial.println(" ");
        };
        Serial.println(" "); 
  };
  Serial.println(" ");
};
 
Oh, now I see.

I misunderstood your original messages, which seemed to suggest you were running out of memory on the Teensy.

But instead this is a memory leak in Arduino's serial monitor.....
 
I ran the code from post #8 above on a Teensy 3.1.
It runs OK. Lots of display output on the terminal but it does loop as it should.

So the original code with IO streaming cout << may be the culprit. I don't suggest using that in microprocessors - kind of heavy code loading. I think too that you need to #include the streaming .h to use cout <<

The Arduino serial monitor/JRE is known to have bugs when it is overwhelmed with data at high baud rates. A condition to be avoided.
I added this to the bottom of loop()
Serial.println(millis()); delay(500);
to slow it down a bit. And display a unique number per pass else the screen just redisplays the same thing each iteration of loop()
 
No, well I didn't know which sort of OOM I was getting. Sounds like you're confident its Arduino serial monitor so I guess the fix should be "don't do that!" Wrt overloaded serial output. Thanks!

To previous poster, I'm curious why you're not getting a crash for the cleaner code. Are you running Mac or Linux version?

I'll make another post on the Flash library and my fix In case that's interesting for others.
 
No, well I didn't know which sort of OOM
To previous poster, I'm curious why you're not getting a crash for the cleaner code. Are you running Mac or Linux version?
If that's me, I ran under Windows 7 64 bit.
When Arduino's Serial Monitor crashes or deadlocks, due to overload, the force-kill says it was within the JRE code.
 
Use a different terminal/serial-monitor; under windows I sort of like realterm, for Linux I sort of like gtkterm but I am fairly lazy and didn't look that hard for alternatives.

When my verbose messaging sunk the serial monitor built into arduino one day I made a mental note not to use it for anything that sends (even relatively) continuous data; to test something that only replies to messages I happily enough (coz convenient really) press [CTRL]+[SHIFT]+[M] in the arduino interface and just use theirs.
 
Thanks, yes. Sorry I was posting from mobile in the airport. I'm using Win7 64 too, not sure why it crashes reliably for me but doesn't matter if it's just the Arduino serial monitor code itself.

If that's me, I ran under Windows 7 64 bit.
When Arduino's Serial Monitor crashes or deadlocks, due to overload, the force-kill says it was within the JRE code.
 
Download and install Atmel Studio 6.2. Then download and install VisualMicro. Throw away the Arduino IDE and hey presto proper gui with a proper Serial monitor. That you don't have to close everytime you upload a new sketch.:p
 
I've been using free Atmel Studio 6 and the free (donations welcome) Visual micro plug-in. Teensy 3 and 2 are supported.
(edit Boards.txt to add Teensy 3)
Open multiple Serial Monitors if you have 2+ AVRs or Teensys connected.
Each serial monitor is in a window that you can dock/pane wherever you wish in the IDE's window - so it tracks along with the GUI window.
They auto-reconnect after a download. They don't close during a download.

And of course, editing one or more code files is a thousand time better than with the Arduino IDE.

Eclipse is another alternative IDE - but almost impossible to figure out how to get it running for Teensy. I've used it for other projects in Python. It's OK but kinda slow and far less beneficial to productivity.
 
Status
Not open for further replies.
Back
Top