Ethernet + Wire combined = crash!?

Hello!

I have an application where I need to use Wire(for I2C) and Ethernet client at the same time. For faulttracing I have split them in two different programs and both works individually without problems. When combining them the program crash.
If I put an if clause so that no Ethernet class functions are never executed program still crashes. If I comment the Ethernet parts out the libraries does not load and then the program works fine.
To me it seams to be a memory problem.
I shall now make a simple program that uses both libraries trying to reproduce the problem. Meanwhile has anybody run into the same problem before?

Thanks,

MrZ

Update!

char squeezeCLIBuf[1024];

This is my Ethernet receive buffer. If I lower this to 128 bytes the combined code seams stable. Program is only 11k so I can not see how it can matter.

This simplified code crash when the buffer is set to 2048.

#include <Wire.h>
#include <Client.h>
#include <Ethernet.h>
#include <Server.h>

#define I2CADDRESS 111
#define EDIPPIN      4

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};    // Ethernet MAC-Address
byte ip[] = {192, 168, 0, 99};                        // Fixed IP-Address for now
byte squeezeServer[] = {192, 168, 0, 10};             // Squeezecenterfor now
Client squeezeCLI(squeezeServer, 9090);               // SqueezeCLI port
char squeezePlayer[] = "00:04:20:17:37:27";           // SqueezePlayer MAC
char squeezeCLIBuf[2048]; // <--- 1024 or lower will work
int squeezeCLIPtr = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Starting up");
  Wire.begin();
  Ethernet.begin(mac, ip);
  squeezeCLIRegister();
  Serial.println("Ready");
}
  
void loop() {
  if (digitalRead(EDIPPIN) == LOW) {
    Serial.println("Getting I2C Data");
    getBuffer();
  }
  squeezeCLIPoll();
}

boolean getACK() {
  Wire.requestFrom(I2CADDRESS, 1);
  if(Wire.available()) {
    return (Wire.receive() == 6);
  }
  else {
    return false;
  }
}

char* getBuffer() {
  byte len = 0;
  byte c = 0;
  byte chksum = 0;
  char buf[255] = "";
  byte ptr = 0;
  char cmd[] = {18, 1, 'S', 102, 0};

  Wire.beginTransmission(I2CADDRESS);
  Wire.send(cmd);
  Wire.endTransmission();

  if (getACK()) {
    Wire.requestFrom(I2CADDRESS, 2);            // This will return two bytes DC1(17) and Len
    while (Wire.available()) {
      len = Wire.receive();
      chksum += len;
    }
    Wire.requestFrom(I2CADDRESS, len+1);      // Last byte in previous packet was Len, add one to get checksum as well
    while (Wire.available()) {
      c = Wire.receive();
      if (ptr < len) {
        chksum += c;
        buf[ptr] = c;
      }
      ptr ++;
    }
    buf[ptr] = 0;
    if (chksum != c and ptr == len+1) {
      Serial.print("************ Wrong Checksum: ");
      Serial.print(chksum, DEC);
      Serial.print("-");
      Serial.print(c, DEC);
      Serial.print("-");
      Serial.print(len, DEC);
      Serial.println(" *************");

      ptr = 0;
      while (buf[ptr] != 0) {
        byte b = buf[ptr];
        Serial.print(ptr, DEC);
        Serial.print(": ");
        Serial.print(b, DEC);
        Serial.print("-");
        Serial.println(b, HEX);
        ptr ++;
      }
      Serial.println("**************************************************");
      buf[0] = 0;
    }
  }
  return buf;
}

void squeezeCLIRegister() {
  Serial.println("Connecting SqueezeCLI");
  if (squeezeCLI.connect()) {
    Serial.println("Connected");
    squeezeCLI.println("subscribe mixer,power\n");
  }
  else {
    Serial.println("Failed to connect");
  }
}

void squeezeCLIPoll() {
  static byte decode[] = {0,0,0};
  static byte decodePtr = 0;
  if (squeezeCLI.available()) {
    decode[decodePtr] = squeezeCLI.read();
    if (decode[decodePtr] == 37 or decodePtr > 0) {
      if(decodePtr == 1 and decode[1] == 37) {
        decodePtr = 0;
      }
      else if(decodePtr == 2) {
        byte ms = decode[1] - 48;
        if (ms > 10) { ms -= 7; }
        byte ls = decode[2] - 48;
        if (ls > 10) { ls -= 7; }
        decode[0] = ms*16+ls;
        if (decode[0] == 37) { decodePtr = 1; }
        else { decodePtr = 0; }
      }
      else {
        decodePtr ++;
      }
    }
    if (decodePtr == 0) {
      if (decode[0] != 10) {
        squeezeCLIBuf[squeezeCLIPtr] = decode[0]; 
        squeezeCLIPtr ++;
      }
      else {
        squeezeCLIBuf[squeezeCLIPtr] = 0;
        if (strstr(squeezeCLIBuf, squeezePlayer) == squeezeCLIBuf) {
          Serial.println(squeezeCLIBuf);
        }
        squeezeCLIPtr = 0;
      }
    }
  }
}

MrZ

There are three kinds of memory on an Arduino: Flash - where your program code is stored SRAM - stores variables EEPROM - memory storage that retains contents without power

Your flash memory usage is 11 KB however your receive buffer goes into RAM not flash! So while you are under the Flash limit, you are exceeding the amount of SRAM. Also take note that some Arduino libraries consume SRAM for buffers (Serial takes 128 bytes, Wire takes 160 bytes).

The memory sizes for each Arduino can be found here: http://arduino.cc/en/Main/ArduinoBoardDiecimila http://arduino.cc/en/Main/ArduinoBoardDuemilanove http://arduino.cc/en/Main/ArduinoBoardMega

Thanks Waffle!

I was not aware that the RAM was only 2k. Found the MemoryFree tool and managed to program around this limitation.

MrZ