Adafruit Ultimate GPS help

I carrently have a webserver setup on my arduino ethernet that displays sensor data for 4 sensors. I am trying to integrate the Adafruit Ultimate GPS board within the program and whenever I try and integrate it inside the program, my webserver no longer works nor the serial monitor. I’ve narrowed it down to one line of code that seems to freeze the arduino.

GPS.parse(GPS.lastNMEA());

I can comment that line of code out and my webserver functions normally. But whenever it is in there and I parse the info for the gps, my webserver is no longer responsive.

Below is the code of my webserver. Right now I don’t have any code that extracts the coordinates out of the parsed info, I just need it to be able to parse while working with the webserver.

#include <DHT22.h>
#include <stdio.h>
#include <math.h>
#include <Adafruit_GPS.h>
#include <SPI.h>
#include <Ethernet.h>

#if ARDUINO >= 100
 #include <SoftwareSerial.h>
#else
#endif

//Define Serial port for GPS
#if ARDUINO >= 100
  SoftwareSerial mySerial(4, 3);
#else
  NewSoftSerial mySerial(4,3);
#endif
Adafruit_GPS GPS(&mySerial);

#define GPSECHO  true
#define DHT22_PIN 5
#define RPMsensor (2)

int Direction ;
volatile unsigned long RPMTops;  // RPM tops counter in interrupt routine                             
volatile unsigned long ContactTime;  // Timer to avoid conatct bounce in interrupt routine   
float RPM;       // RPM count
float TEMP;      // Temp
float gpslat;
float gpslong;
const int analogInPin0 = A0;
const int analogInPin5 = A5; 
 

// Setup a DHT22 instance
DHT22 myDHT22(DHT22_PIN);


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0x58, 0xFD };
IPAddress ip(192,168,1, 177);
EthernetServer server(2222);

void setup() {

  Serial.begin(9600);
  GPS.begin(9600);
  delay(5000);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  pinMode(RPMsensor, INPUT); 
  attachInterrupt(0, rpm, CHANGE); 
  Serial.print("Team allStream Code");

}

uint32_t timer = millis();
void loop() {
  
  //gps stuff
  if (timer > millis())  timer = millis();
  // approximately every 4 seconds or so, print out the current stats
  if (millis() - timer > 4000) { 
    timer = millis();
    char xv = GPS.read();
    if (GPS.newNMEAreceived()) {

      if (!GPS.parse(GPS.lastNMEA()))
        return; 
    }
  }
    
  //gather data
  int COsensor = analogRead(analogInPin5); //co sensor
  DHT22_ERROR_t errorCode;
  errorCode = myDHT22.readData(); //temp humidity
  int sensorvalueA1 = analogRead(analogInPin0); //wind direction
  
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) 
  {
    
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          client.println("<head>");
          client.println("<meta charset=utf-8>");
          client.println("<title>PSSD</title>");
          client.println("</head>");
                    // add a meta refresh tag, so the browser pulls again every 5 seconds:
          client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          // output the value of each analog input pin
           client.println("<body>");
            

            
              
            
           
            client.print(" <div class=box>");
            client.print("<h1>Temperature</h1>");
              client.print("<p>");
                client.print((( myDHT22.getTemperatureC()*9/5)+32));
                client.print("°F");
              client.print("</p>");
            client.print("</div>");
                      
       
             
           client.print(" <div class=box>");
            client.print("<h1>Humidity</h1>");
              client.print("<p>");
               client.print(myDHT22.getHumidity());
               client.print("%");
              client.print("</p>");
            client.print("</div>");
            
            client.print(" <div class=box>");
            client.print("<h1>CO Level</h1>");
              client.print("<p>");
               client.print((COsensor));
               client.print("PPM");
              client.print("</p>");
            client.print("</div>");
 
      
                     
             client.print(" <div class=wind>");
            client.print("<h1>GPS Location</h1>");
              client.print("<p>");
               client.print(gpslat);
                client.print(",");
                client.print("
");
               client.print("
");
               client.print(gpslong);
              client.print("</p>");
            client.print("</div>");
            
            
           
            
                  
            Direction = map(sensorvalueA1, 0, 1023, 0, 359); 
            Direction = Direction + 3;   // Correct for offset & 5° precision
          
          
            //RPMTops = 0;   //Set NbTops to 0 ready for calculations
          //  sei();         //Enables interrupts
            //delay (3000);  //Wait 1 seconds to average
            //  cli();         //Disable interrupts
             if ((RPMTops >= 0) and (RPMTops <= 21)) RPM = RPMTops * 1.2 *.61;
             if ((RPMTops > 21) and (RPMTops <= 45)) RPM = RPMTops * 1.15*.61;
             if ((RPMTops > 45) and (RPMTops <= 90)) RPM = RPMTops * 1.1*.61;
             if ((RPMTops > 90) and (RPMTops <= 156)) RPM = RPMTops * 1.0*.61;
             if ((RPMTops > 156) and (RPMTops <= 999)) RPM = RPMTops * 1.0*.61;
          
            // print out the value you read:
           convert:       // Convert to 360°  
           
           client.print(" <div class=wind>");
            client.print("<h1>Wind Speed</h1>");
              client.print("<p>");
               
            if (Direction < 0) {
              Direction = Direction + 360;
              goto convert;
            }
          
            if (Direction > 360) {
              Direction = Direction - 360;
              goto convert;
            }
            if (Direction == 360) Direction = 0;
            client.println();        
            client.print(Direction);
            if ((Direction)<23) {
              client.print("°N");
            } 
            if ((Direction>22) && (Direction<68)) {
              client.print("°NE");
            } 
            if ((Direction>67) && (Direction<113)) {
              client.print("°E");
            } 
            if ((Direction>112) && (Direction<158)) {
              client.print("°SE");
            } 
            if ((Direction>157) && (Direction<203)) {
              client.print("°S");
            } 
            if ((Direction>202) && (Direction<247)) {
              client.print("°SW");
            } 
            if ((Direction>246) && (Direction<292)) {
              client.print("°W");
            } 
            if ((Direction>291) && (Direction<337)) {
              client.print("°NW");
            } 
            if ((Direction>336) && (Direction<=360)) {
              client.print("°N");
            } 
          
            
            client.println();
            client.print("Speed ");
            client.print(RPM);
              // RMP=0;
                RPMTops = 0;
          
              client.print("</p>");
            client.print("</div>");
            
//style code goes here 
      
        client.println("</style>");

      client.println("</body>");


    client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(5000);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
  
  

}

void rpm ()   { 

  if ((millis() - ContactTime) > 15 ) {  // debounce of REED contact. With 15ms speed more than 150 km/h can be measured
    RPMTops++; 
    ContactTime = millis();
  }

}

I have a suspicion that the issue is a lack of SRAM. Which uP is your Arduino using?

I decided to check my suspicion by compiling your sketch in 1.0.4 ERW (one of the many enhancements tells you the estimated SRAM usage after compiling). This is what I saw when I compiled to a target of UNOr3 (ATmega328):

Binary sketch size: 21,254 bytes (of a 32,256 byte maximum)
Estimated used SRAM memory: 1,491 bytes (of a 2048 byte maximum)
Warning: Large amount of SRAM memory used. Consider using PROGMEM or F(“text”) macro to reduce ram usage

You might want to consider throwing some (most/all) of your HTML code into Flash with either PROGMEM or F(…) to leave enough overhead in your SRAM for the GPS.parse() to have working space. Using cleverness you can probably use an array of strings so each repeated HTML tag only needs to be stored once. For example, I see a lot of

and

tags, a bunch of

and

tags, etc. It might reduce the readability a bit, but you need to do something to reduce your SRAM usage.

And/or using a different Arduino (Mega or Due) with an Ethernet shield simply to get more memory.

Hello, Actually, I'm doing something very similar, in my case, the GPS failed everytime the server was running, Adafruit's people has kindly giving me some guidance, and I think the server + sensors + other stuff slow down the reading of the GPS, and the data get lost. So I'm reading the GPS just at every start up, with the server down.

Anyway, since this post was made weeks ago, I assume you already solve this. Actually I have a question.

Reading your code, I can't help but notice that you are/was using a Davis anemometer, or maybe something similar. I'm using the same code to get wind speed, but the interruption routine kills my server, so I have opted for a dedicated Arduino getting the Anemometer data, and transmit the results to a Mega via serial bus.

In your code, you have commented the lines that enable the interruption,then, the rpm routine never gets called (?), so I'm curious of how do you manage to get the wind speed. Any help would be appreciated. I think that using an UNO just for an anemometer is a waste of resources.

Thanks.