Adafruit Ultimate GPS, Sparkfun ePaper Display, and Xbee Wifi on an Arduino... Conflicts and Chaos ensues...

by darkwolfe5 on Thu May 02, 2013 6:41 pm

Hi there, I'm posting this on both Adafruit and Sparkfun forums since I have products from both sites, and I'm in a time crunch for my Senior Design Project.

Here's the problem, I have the Adafruit Ultimate GPS, Spartfun ePaper display, and an xbee wi-fi chip all connected to an Arduino.

I have successfully gotten the GPS and xbee working together quite nicely using the SoftwareSerial library with no display.

I have successfully gotten the xbee and the display working together quite happily together as well.

The problem is when I try to get all THREE working at the same time. After much painstaking tedious attempts at going through (and compiling and testing) the code by slowly adding one line at a time, I think I've tracked the problem down to the ePaper::writeTop() and ePaper::writeBottom() functions. Right now those seem to be the ones that cause catastrophic failure.

By that I mean that I load the program, and even if I have a Serial.println() immediately after beginning the hardware and software serials, I see NOTHING on the serial monitor. When I comment out the sinlge epaper.writeTop("HelloThere"); <leaving the epaper.writeDisplay();> the program goes through the setup() and starts chugging away at the loop with no problems.

I'm at my wits end. Does anyone have ANY idea what's causing the problem?

I'm just trying to set some messages on the display to give useful feedback while it's running on a battery (and therefor not connected to a hardware serial line)

Code included:
Code: Select all
#include <avr\pgmspace.h>
#include <avr/eeprom.h>

//Begin Adafruit_GPS Stuff
    #include <Adafruit_GPS.h>
    #include <SoftwareSerial.h>
   
    SoftwareSerial mySerial(A4,A5);
    Adafruit_GPS GPS(&mySerial);
   
    #define GPSECHO true
   
    boolean usingInterrupt = true;
    void useInterrupt(boolean);
    uint32_t timer = millis();
//End Adafruit_GPS Stuff

//E-PAPER setup
   #include <ePaper.h>  // This file includes defines for each displayable character
   
   const int EIOpin = 2;     // Input/output pin for chip selection
   const int XCKpin = 3;     // Clock input pin for taking display data
   const int LATCHpin = 4;   // Latch pulse input pin for display data
   const int SLEEPBpin = 5;  // Sleep Pin for the display
   const int DI0pin = 6;     // Input pin for display data

   //setup display with pin definitions
   ePaper epaper = ePaper(EIOpin, XCKpin, LATCHpin, SLEEPBpin, DI0pin);
//end E-PAPER  */

//XBEE Wi-Fi set-up and global variables
   #include <XbeeWifi.h>

   // These are the pins that we are using to connect to the Xbee 
   #define XBEE_RESET 7
   #define XBEE_DOUT 8
   #define XBEE_ATN 9
   #define XBEE_SELECT SS

   // These are the network configuration parameters we're going to use
   #define CONFIG_ENCMODE XBEE_SEC_ENCTYPE_WPA2     // Network type is WPA2 encrypted
   #define CONFIG_SSID "Gum-DropB(EARS)"                   // SSID
   #define CONFIG_KEY "Candycane"                  // Password
   #define TxIP {192,168,0,101}
   #define Gateway "192.168.0.1"
   #define MyIP "192.168.0.222"

   // Create an xbee object to handle things for us
   XbeeWifi xbee;
//end XBEE


// Allow us to embed some PROGMEM strings inline so we don't run out of memory
   class __FlashStringHelper;
   #define F(str) reinterpret_cast<__FlashStringHelper *>(PSTR(str))

void setup(){
  // Serial at 57600
  Serial.begin(57600);
  GPS.begin(9600);
[b]//epaper.writeTop("Start Boot");   //   <--This line of code when un commented kills all functionality on the 'duino[/b]
epaper.writeDisplay();
  useInterrupt(false);
  pinMode(A0, INPUT);
  unsigned long age = 0;
  Serial.println("Booting Start:");
 
// Initialize the xbee
  bool result = xbee.init(XBEE_SELECT, XBEE_ATN, XBEE_RESET, XBEE_DOUT);
  if(!result){Serial.println("Failed @ 0");}
  if (result) {
    // Initialization okay so far, send setup parameters - if anything fails, result goes false
    result &= xbee.at_cmd_byte(XBEE_AT_NET_TYPE, XBEE_NET_TYPE_IBSS_INFRASTRUCTURE);
  if(!result){Serial.println("Failed @ 1");}
    result &= xbee.at_cmd_str(XBEE_AT_NET_SSID, CONFIG_SSID);
  if(!result){Serial.println("Failed @ 2");}
    result &= xbee.at_cmd_byte(XBEE_AT_NET_ADDRMODE, XBEE_NET_ADDRMODE_STATIC);
  if(!result){Serial.println("Failed @ 3");}
    result &= xbee.at_cmd_str(XBEE_AT_ADDR_IPADDR, MyIP);
  if(!result){Serial.println("Failed @ 4");}
    result &= xbee.at_cmd_str(XBEE_AT_ADDR_GATEWAY, Gateway);
  if(!result){Serial.println("Failed @ 5");}
    result &= xbee.at_cmd_byte(XBEE_AT_SEC_ENCTYPE, CONFIG_ENCMODE);
  if(!result){Serial.println("Failed @ 6");}
    if (CONFIG_ENCMODE != XBEE_SEC_ENCTYPE_NONE) {
      result &= xbee.at_cmd_str(XBEE_AT_SEC_KEY, CONFIG_KEY);
  if(!result){Serial.println("Failed @ 7");}
    }
  }
  if (!result) {
    // Something failed
    Serial.println(F("XBee Init Failed"));
 //   epaper.writeTop("XB Failed ");
    epaper.writeDisplay();
    while (true) { /* Loop forever - game over */}
  } else {   
    Serial.println("XB Success");
 //   epaper.writeTop("XB Init   ");
    epaper.writeDisplay();
  } 
//end XBEE init

}//end setup

int Record = 0;

void loop(){

  // Just keep calling the process method on the xbee object
  xbee.process();

//Included code for Adafruit GPS example
  unsigned long age = 0;
  bool newdata = false;
  if (! usingInterrupt) {
    // read data from the GPS in the 'main loop'
    char c = GPS.read();
    // if you want to debug, this is a good time to do it!
    if (GPSECHO)
      if (c) Serial.print(c);
  }
 if(GPS.newNMEAreceived()){
    if(!GPS.parse(GPS.lastNMEA()))
      return;
//end adafruit example code
    
//wait 5 seconds
    if(millis() - timer > 5000)
    {
        timer = millis();
//Print data to Serial to computer
      Serial.print(GPS.hour, DEC); Serial.print(':');
      Serial.print(GPS.minute, DEC); Serial.print(':');
      Serial.print(GPS.seconds, DEC); Serial.print('.');
      Serial.println(GPS.milliseconds);
      Serial.print("Fix: "); Serial.println((int)GPS.fix);
      if (GPS.fix) {
        Serial.print("Location: ");
        Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
        Serial.print(", ");
        Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
       
        Serial.print("Speed (knots): "); Serial.println(GPS.speed);
        Serial.print("Altitude: "); Serial.println(GPS.altitude);
        if(Record < 512){
//record data to EEPROM
          float time = 10000 * GPS.hour + 100 * GPS.minute + GPS.seconds;
          eeprom_write_block((void*)&time, (void*)((Record*20)), sizeof(time));
          eeprom_write_block((void*)&GPS.latitude, (void*)((Record*20)-12), sizeof(GPS.latitude));
          eeprom_write_block((void*)&GPS.longitude, (void*)((Record*20)-8), sizeof(GPS.longitude));
          eeprom_write_block((void*)&GPS.altitude, (void*)((Record*20)-4), sizeof(GPS.altitude));
          Serial.print("Records Saved: ");
          Serial.println(Record + 1);
          Record++;
        }
      }
    }
  }

//external trigger (just using a pin to connect to Vcc and GND as needed to test this part)
  if(digitalRead(A0))
  {
    //Join network
    if (xbee.last_status != XBEE_MODEM_STATUS_JOINED) {
      Serial.println(F("Not yet up and running"));
 //     epaper.writeTop("Connecting");
 //     epaper.writeBottom("To Network");
      epaper.writeDisplay();
    } else {
      Serial.println(F("Transmitting now"));
 //     epaper.writeTop(" Transmit ");
 //     epaper.writeBottom("          ");
      epaper.writeDisplay();
     
      // Create an s_txoptions object to describe the port, protocol and behaviors
      s_txoptions txopts;
      txopts.dest_port=12345;
      txopts.source_port=12345;
      txopts.protocol = XBEE_NET_IPPROTO_TCP;

      // Create a binary IP address representation
      char ip[] = TxIP;

      // Transmit the frame on  network with xbee
      if (!xbee.transmit((uint8_t *)ip, &txopts, (uint8_t *)"HelloWorld!\n", 12)) {
        Serial.println(F("Transmit failed"));
 //       epaper.writeTop(" Transmit ");
 //       epaper.writeBottom("  Failed  ");
        epaper.writeDisplay();
      } else {
        Serial.println(F("Transmit OK"));   
//        epaper.writeTop(" Transmit ");
 //       epaper.writeBottom(" Success  ");
        epaper.writeDisplay();
      }
    }
  }


//****Included with the Adafruit GPS example
      // Interrupt is called once a millisecond, looks for any new GPS data, and stores it
      SIGNAL(TIMER0_COMPA_vect) {
        char c = GPS.read();
        // if you want to debug, this is a good time to do it!
      #ifdef UDR0
        if (GPSECHO)
         if (c) UDR0 = c; 
         // writing direct to UDR0 is much much faster than Serial.print
         // but only one character can be written at a time.
      #endif
      }

      void useInterrupt(boolean v) {
        if (v) {
         // Timer0 is already used for millis() - we'll just interrupt somewhere
         // in the middle and call the "Compare A" function above
         OCR0A = 0xAF;
         TIMSK0 |= _BV(OCIE0A);
         usingInterrupt = true;
        } else {
         // do not call the interrupt function COMPA anymore
         TIMSK0 &= ~_BV(OCIE0A);
         usingInterrupt = false;
        }
      }
darkwolfe5
 
Posts: 7
Joined: Sun Apr 28, 2013 1:32 pm

Re: Adafruit Ultimate GPS, Sparkfun ePaper Display, and Xbee Wifi on an Arduino... Conflicts and Chaos ensues...

by adafruit_support_rick on Thu May 02, 2013 7:06 pm

That's a tough one. Best guess is that you're running out of SRAM - probably a stack crash when you call writeTop.

An easy thing to try is to use the F() macro on all your Serial.print string constants:
Code: Select all
Serial.print(F(“Hello World”));

That tells the linker to locate the literal string in flash (PROGMEM) instead of SRAM, and print() knows enough to get it from there.
User avatar
adafruit_support_rick
 
Posts: 8575
Joined: Tue Mar 15, 2011 10:42 am
Location: Buffalo, NY

Re: Adafruit Ultimate GPS, Sparkfun ePaper Display, and Xbee Wifi on an Arduino... Conflicts and Chaos ensues...

by darkwolfe5 on Thu May 02, 2013 7:45 pm

AWESOME! That got things rolling a bit again. At least it worked for the first epaper.write command... I only got a few epaper writes before things stopped working again.

If the case is the SRAM, then I'm going to have to figure out how to do a lot of cutting...

Is there any way I can report back how full the SRAM is through the Serial?

Thanks for the tip, it's gotten something rolling again at least :)
darkwolfe5
 
Posts: 7
Joined: Sun Apr 28, 2013 1:32 pm

Re: Adafruit Ultimate GPS, Sparkfun ePaper Display, and Xbee Wifi on an Arduino... Conflicts and Chaos ensues...

by adafruit_support_rick on Thu May 02, 2013 8:11 pm

Well, at least you know what the problem is...

The SdFat library has a free_memory function in a file called freeRam.h
I attached it...

P.S. - Here's a last-gasp hole-card: The Leonardo has an extra 512bytes of SRAM. The bad news is that it may or may not be easy to get your peripheral devices working with it...
Attachments
freeRam.h
(499 Bytes) Downloaded 9 times
User avatar
adafruit_support_rick
 
Posts: 8575
Joined: Tue Mar 15, 2011 10:42 am
Location: Buffalo, NY

Re: Adafruit Ultimate GPS, Sparkfun ePaper Display, and Xbee Wifi on an Arduino... Conflicts and Chaos ensues...

by buton on Fri May 03, 2013 9:15 am

upgrade to a mega2560 and problem solve.....

is a lot of load for your current microncontroller... and also store all strings on flash. that will help a little
buton
 
Posts: 54
Joined: Fri May 11, 2012 7:06 am

Re: Adafruit Ultimate GPS, Sparkfun ePaper Display, and Xbee Wifi on an Arduino... Conflicts and Chaos ensues...

by adafruit_support_rick on Fri May 03, 2013 10:02 am

Here's a fast way to save a few bytes: Change these to #define - const int still winds up in SRAM:
Code: Select all
   #define EIOpin  2     // Input/output pin for chip selection
   #define XCKpin  3     // Clock input pin for taking display data
   #define LATCHpin  4   // Latch pulse input pin for display data
   #define SLEEPBpin  5  // Sleep Pin for the display
   #define DI0pin  6     // Input pin for display data

Also, have a look at the Sparkfun epaper driver - if it allocates some large buffers, maybe you can make them smaller.

buton wrote:upgrade to a mega2560 and problem solve.....

Awww! That's cheating! There's a lot to be learned from trying to optimize memory. Ultimately, you always run out of memory at some point (just ask my iMac - it has 16GB and it's not enough). And you just might be surprised at how much you can actually squeeze out of a Uno or a Leo.
User avatar
adafruit_support_rick
 
Posts: 8575
Joined: Tue Mar 15, 2011 10:42 am
Location: Buffalo, NY

Re: Adafruit Ultimate GPS, Sparkfun ePaper Display, and Xbee Wifi on an Arduino... Conflicts and Chaos ensues...

by darkwolfe5 on Mon May 06, 2013 2:08 pm

adafruit_support_rick wrote:Here's a fast way to save a few bytes: Change these to #define - const int still winds up in SRAM:
Code: Select all
   #define EIOpin  2     // Input/output pin for chip selection
   #define XCKpin  3     // Clock input pin for taking display data
   #define LATCHpin  4   // Latch pulse input pin for display data
   #define SLEEPBpin  5  // Sleep Pin for the display
   #define DI0pin  6     // Input pin for display data

Also, have a look at the Sparkfun epaper driver - if it allocates some large buffers, maybe you can make them smaller.

buton wrote:upgrade to a mega2560 and problem solve.....

Awww! That's cheating! There's a lot to be learned from trying to optimize memory. Ultimately, you always run out of memory at some point (just ask my iMac - it has 16GB and it's not enough). And you just might be surprised at how much you can actually squeeze out of a Uno or a Leo.
darkwolfe5
 
Posts: 7
Joined: Sun Apr 28, 2013 1:32 pm