Ethernet Shield - SD Card and Ethernet functionality

Hi… I am a complete newbie…!

I intend to do datalogging of the surface speed (m/min) and downtime of an industrial machine.

I have been able to interface a rotary encoder of type: Autotonics ENC-1-1-T-24. It generates a square waveform on two output lines with a phase difference of 90deg.

I have been able to record the data onto the SD card without difficulty.

However, while using ethernet capability and pushingbox’s GET PUSH request system, the system works 50% of the time.

When I tried to integrate the code into one, using SD card and ethernet simultaneously, the code jumps from the loop() to the setup() for perceivable reason. I know this, based on the Serial.print outputs.

There is a compilation warning: Low memory available, stability problems may occur., but I am not sure if this is the reason for the randomness.

Attachment details:
RotaryEncoder_33.ino = Code for SD card functionality alone
RotaryEncoder_eth.ino = Code for Ethernet functionality alone
RotaryEncoder_4.ino = Code for Ethernet & SD Card functionality
Serial Output - showing the Serial Monitor Output

I would really appreciate if you could please go through my code and let me know what I can do.

I read up before posting this.

  1. I tried the F() macro - didn’t make any difference at all, even after replacing all the Serial.print functions
  2. Not sure if the low memory warning is the real issue - if this can be confirmed, I will go ahead and buy a MEGA and try it out - please shed some light on this as well.

RotaryEncoder_33.ino (3.68 KB)

RotaryEncoder_4.ino (6.73 KB)

RotaryEncoder_eth.ino (5.74 KB)

Serial output.txt (1.69 KB)

If the warning is about your SRAM, you are probably running out of SRAM. The warning is from the allocation of global memory only. Any SRAM used in your functions are not included in that. In loop, you are allocating another 300 bytes for sure with postmsg, a, and b.

Thank you for your prompt reply, SurferTim...

I have replaced postmsg and b with a itself... however, it still says: Sketch uses 32,190 bytes (99%) of program storage space. Maximum is 32,256 bytes. Global variables use 1,865 bytes (91%) of dynamic memory, leaving 183 bytes for local variables. Maximum is 2,048 bytes. Low memory available, stability problems may occur.

Stability problems will occur when you use the SD card if you are that low on SRAM (dynamic memory).

If you cannot reduce the SRAM usage in your global memory, then it is time to get a Mega or a Due.

I download RotaryEncoder_4.ino, but I couldn't compile it because I don't have the RTC library. I couldn't see where it was using that much global RAM.

The RTC library is herewith attached

RTClib-master.zip (14.5 KB)

Thanks, but I have plenty of 3rd party libraries installed on my system already. If your IDE is reporting the use of that much global memory during the compile, I will presume it is correct.

Is there a way by which I can see where the majority of the SRAM is getting used?

Wherever you have .print() or .println() of a string constant, wrap the constant in the F() macro. That will keep the string constant from taking up room in SRAM.

Serial.println(F("Failed to configure ethernet using dhcp"));

I have already tried that, but it doesn't have any effect on the overall memory usage.

ashwho: Is there a way by which I can see where the majority of the SRAM is getting used?

Yes. Remove sections of the code (like the RTC library) and recompile it. You should have been doing that from the start.

I have done a few modifications and have brought down the overall global variable memory utilization.

But the code is still at 98%.

Sketch uses 31,760 bytes (98%) of program storage space. Maximum is 32,256 bytes.
Global variables use 1,551 bytes (75%) of dynamic memory, leaving 497 bytes for local variables. Maximum is 2,048 bytes.
Low memory available, stability problems may occur.

What is a safe level to operate?

Don't worry too much about the program storage space. That will not change during code execution.

The concern is the global variables. The SRAM does increase when you call library functions and allocate local function variables.

edit: To determine SRAM use during execution, this works on most AVR processors. It returns the amount of SRAM available. If you have used it all, it does not return 0. It will return an unreasonable or negative value. Call it in the functions that you have questions about the SRAM use.

int freeRam() {
  extern int __heap_start,*__brkval;
  int v;
  return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int) __brkval);  
}

Serial.print(F("SRAM remaining: "));
Serial.println(freeRam());

"Sketch uses 31,760 bytes (98%) of program storage space." I'm pretty sure you can take that right to 100%, the sketch can't change the flash once it's running).

If you need more room, I offer '1284P cards with 128K flash and 16K SRAM (twice the SRAM of a '2560), with dual hardware serial ports and 32 IO, so a nice step up from the '328. Here is a Duemilanove-style card, one of several form factors. (shown with a FT232 module that I get from Mouser.com, you can connect another USB/Serial instead if you prefer) (Uno uses a programmed '16U2 chip) http://www.crossroadsfencing.com/BobuinoRev17/ |500x209

What if unsigned int's were used in that code instead of int? Then it could support 0 to 65535, vs -32768 to +32767

Thank you, once again, SurferTim… will check it out.

@Crossroads: Since, I am a newbie, I didn;t quite understand most of what you said. But will get it touch with you for further help if changes in the coding doesn’t help.

I could convert the integers into unsigned ones, but does it serve the purpose?

Also… what is a safe limit to operate - as far as the global variables space is concerned?

@CrossRoads: If you mean freeRam, none of the processors it works with will have that much free SRAM. On an Uno, if it returns 15200 bytes available, you know that is unreasonable. Same with -31460.

I once wrote a sketch that used EEPROM for variable storage, storing bytes from Serial to display on a 8 x 32 LED display. To find out how much I could use, I just kept expanding the size of message and the amount of EEPROM used - when the sketch started acting erraticly, I back off a little.

Since you're using Libraries with undocumented requirements, you could use a similar approach. Push things until it acts oddly, then back off some.

If that doesn't meet your needs because you have to do more than the SRAM supports, move to a bigger chip with more SRAM.

Heartfelt thanks to everyone... the F() macro worked.

Another query: will F() work only on Serial.print commands or even on print commands for ethernet and SD card writing commands?

such as... client.print() or datafile.print()

Another query: will F() work only on Serial.print commands or even on print commands for ethernet and SD card writing commands?

The F() macro will keep the string literal from being copied into SRAM anywhere in the code. Whether a given function can handle string literals that are not in SRAM is the question. The only way to know for certain is to try.

EthernetClient instances and Print instances can handle the F() macro-created object.