GPS and DHT22 help needed

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
Jeffka02
 
Posts: 4
Joined: Tue Jun 10, 2014 1:17 am

GPS and DHT22 help needed

Post by Jeffka02 »

Hello,

As part of an undergraduate geography project, I am attempting to combine the Ultimate GPS logging shield with the DHT22 Temperature/RH sensor. I have the hardware all set and working and most of the software, but for the life of me I cannot understand how to write the temperature and RH values to the end (or at all) with the GPS coordinates. What I ultimately need is a "NMEA sentence, temperature reading, relative humidity reading" all on one line and comma separated for further processing in ArcGIS and R.

Any help as to where I am going wrong would be greatly appreciated. I have posted the sketch as I have cobbled it together below (sensor data coming in on pin 2).

Thank you,

Jeffrey Ashby
IUPUI Geography Department Senior

-- Begin sketch --

Code: Select all

#include <SPI.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <SD.h>
#include <avr/sleep.h>

#include "DHT.h"

// Ladyada's logger modified by Bill Greiman to use the SdFat library
//
// This code shows how to listen to the GPS module in an interrupt
// which allows the program to have more 'freedom' - just parse
// when a new NMEA sentence is available! Then access data when
// desired.
//
// Tested and works great with the Adafruit Ultimate GPS Shield
// using MTK33x9 chipset
//    ------> http://www.adafruit.com/products/
// Pick one up today at the Adafruit electronics shop 
// and help support open source hardware & software! -ada

SoftwareSerial mySerial(8, 7);
Adafruit_GPS GPS(&mySerial);

// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO  false
/* set to true to only log to SD when GPS has a fix, for debugging, keep it false */
#define LOG_FIXONLY true 

// Set the pins used
#define chipSelect 10
#define ledPin 13
#define DHTPIN 2     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
#define data
DHT dht(DHTPIN, DHTTYPE);

File logfile;

// read a Hex value and return the decimal equivalent
uint8_t parseHex(char c) {
  if (c < '0')
    return 0;
  if (c <= '9')
    return c - '0';
  if (c < 'A')
    return 0;
  if (c <= 'F')
    return (c - 'A')+10;
}

// blink out an error code
void error(uint8_t errno) {
/*
  if (SD.errorCode()) {
    putstring("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  */
  while(1) {
    uint8_t i;
    for (i=0; i<errno; i++) {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
      delay(100);
    }
    for (i=errno; i<10; i++) {
      delay(200);
    }
  }
}

void setup() {
  // for Leonardos, if you want to debug SD issues, uncomment this line
  // to see serial output
  //while (!Serial);
  
  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
  // also spit it out
  Serial.begin(115200);
  Serial.println("\r\nUltimate GPSlogger Shield");
  pinMode(ledPin, OUTPUT);

  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
//  if (!SD.begin(chipSelect, 11, 12, 13)) {
    if (!SD.begin(chipSelect)) {      // if you're using an UNO, you can use this line instead
    Serial.println("Card init. failed!");
    error(2);
  }
  char filename[15];
  strcpy(filename, "GPSLOG00.TXT");
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = '0' + i/10;
    filename[7] = '0' + i%10;
    // create if does not exist, do not open existing, write, sync after write
    if (! SD.exists(filename)) {
      break;
    }
  }

  logfile = SD.open(filename, FILE_WRITE);
  if( ! logfile ) {
    Serial.print("Couldnt create "); Serial.println(filename);
    error(3);
  }
  Serial.print("Writing to "); Serial.println(filename);
  
  // connect to the GPS at the desired rate
  GPS.begin(9600);

  // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  // uncomment this line to turn on only the "minimum recommended" data
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // For logging data, we don't suggest using anything but either RMC only or RMC+GGA
  // to keep the log files at a reasonable size
  // Set the update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 or 5 Hz update rate

  // Turn off updates on antenna status, if the firmware permits it
  GPS.sendCommand(PGCMD_NOANTENNA);
  
  Serial.println("Ready!");

  dht.begin();
}

void loop() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();  

  char c = GPS.read();
  if (GPSECHO)
     if (c)   Serial.print(c);

  // if a sentence is received, we can check the checksum, parse it...
  if (GPS.newNMEAreceived()) {
    // a tricky thing here is if we print the NMEA sentence, or data
    // we end up not listening and catching other sentences! 
    // so be very wary if using OUTPUT_ALLDATA and trying to print out data
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
        
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
    
    // Sentence parsed! 
    Serial.println("OK");
    if (LOG_FIXONLY && !GPS.fix) {
        Serial.print("No Fix");
        return;
    }

    // Rad. lets log it!
    Serial.println("Log");
    
    char *stringptr = GPS.lastNMEA();
    uint8_t stringsize = strlen(stringptr);
    if (stringsize != logfile.write((uint8_t *)stringptr, stringsize))    //write the string to the SD file
      error(4);
    if (strstr(stringptr, "RMC"))   logfile.flush();
    Serial.println();
  }
}


/* End code */
Last edited by adafruit_support_rick on Tue Jun 10, 2014 9:07 am, edited 1 time in total.
Reason: please use Code tags when posting code (</> button)

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: GPS and DHT22 help needed

Post by adafruit_support_rick »

Is the problem that you want to strip off the checksum (i.e., "*nn") from the end of the NMEA sentence, and don't know how to do that?
Or is the problem that the NMEA sentence ends with a <CR><LF>?

Jeffka02
 
Posts: 4
Joined: Tue Jun 10, 2014 1:17 am

Re: GPS and DHT22 help needed

Post by Jeffka02 »

I am ok with NMEA string as it is. My problem is I cannot figure out how to append the DHT22 data to the end of string when I go to write to the SD card. All of the changes I have made cause the sketch to write nothing to the SD card. So I assume it has to do with the logfile.write command.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: GPS and DHT22 help needed

Post by adafruit_support_rick »

I think the dht reads are interfering with the GPS reads by delaying the loop. I borrowed the interrupt-based GPS reading from the parsing sketch. I also added the logfile prints to output your t and h:

Code: Select all

#include <SPI.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <SD.h>
#include <avr/sleep.h>

#include "DHT.h"

// Ladyada's logger modified by Bill Greiman to use the SdFat library
//
// This code shows how to listen to the GPS module in an interrupt
// which allows the program to have more 'freedom' - just parse
// when a new NMEA sentence is available! Then access data when
// desired.
//
// Tested and works great with the Adafruit Ultimate GPS Shield
// using MTK33x9 chipset
//    ------> http://www.adafruit.com/products/
// Pick one up today at the Adafruit electronics shop 
// and help support open source hardware & software! -ada

SoftwareSerial mySerial(8, 7);
Adafruit_GPS GPS(&mySerial);

// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO  false
/* set to true to only log to SD when GPS has a fix, for debugging, keep it false */
#define LOG_FIXONLY true 

// this keeps track of whether we're using the interrupt
// off by default!
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy

// Set the pins used
#define chipSelect 10
#define ledPin 13
#define DHTPIN 2     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
#define data
DHT dht(DHTPIN, DHTTYPE);

File logfile;

// read a Hex value and return the decimal equivalent
uint8_t parseHex(char c) {
  if (c < '0')
    return 0;
  if (c <= '9')
    return c - '0';
  if (c < 'A')
    return 0;
  if (c <= 'F')
    return (c - 'A')+10;
}

// blink out an error code
void error(uint8_t errno) {
/*
  if (SD.errorCode()) {
    putstring("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  */
  while(1) {
    uint8_t i;
    for (i=0; i<errno; i++) {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
      delay(100);
    }
    for (i=errno; i<10; i++) {
      delay(200);
    }
  }
}

void setup() {
  // for Leonardos, if you want to debug SD issues, uncomment this line
  // to see serial output
  //while (!Serial);
  
  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
  // also spit it out
  Serial.begin(115200);
  Serial.println("\r\nUltimate GPSlogger Shield");
  pinMode(ledPin, OUTPUT);

  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
//  if (!SD.begin(chipSelect, 11, 12, 13)) {
    if (!SD.begin(chipSelect)) {      // if you're using an UNO, you can use this line instead
    Serial.println("Card init. failed!");
    error(2);
  }
  char filename[15];
  strcpy(filename, "GPSLOG00.TXT");
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = '0' + i/10;
    filename[7] = '0' + i%10;
    // create if does not exist, do not open existing, write, sync after write
    if (! SD.exists(filename)) {
      break;
    }
  }

  logfile = SD.open(filename, FILE_WRITE);
  if( ! logfile ) {
    Serial.print("Couldnt create "); Serial.println(filename);
    error(3);
  }
  Serial.print("Writing to "); Serial.println(filename);
  
  // connect to the GPS at the desired rate
  GPS.begin(9600);

  // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  // uncomment this line to turn on only the "minimum recommended" data
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // For logging data, we don't suggest using anything but either RMC only or RMC+GGA
  // to keep the log files at a reasonable size
  // Set the update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 or 5 Hz update rate

  // Turn off updates on antenna status, if the firmware permits it
  GPS.sendCommand(PGCMD_NOANTENNA);
  

  // the nice thing about this code is you can have a timer0 interrupt go off
  // every 1 millisecond, and read data from the GPS for you. that makes the
  // loop code a heck of a lot easier!
  useInterrupt(true);
  Serial.println("Ready!");

  dht.begin();
}

void loop() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();  

  // if a sentence is received, we can check the checksum, parse it...
  if (GPS.newNMEAreceived()) {
    // a tricky thing here is if we print the NMEA sentence, or data
    // we end up not listening and catching other sentences! 
    // so be very wary if using OUTPUT_ALLDATA and trying to print out data
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
        
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
    
    // Sentence parsed! 
    Serial.println("OK");
    if (LOG_FIXONLY && !GPS.fix) {
        Serial.print("No Fix");
        return;
    }

    // Rad. lets log it!
    Serial.println("Log");
    
    char *stringptr = GPS.lastNMEA();
    uint8_t stringsize = strlen(stringptr) - 1; //subtract 2 to eliminate <cr>
    if (stringsize != logfile.write((uint8_t *)stringptr, stringsize))    //write the string to the SD file
      error(4);
    logfile.print(","); logfile.print(h,2);logfile.print(","); logfile.println(t,2); //append temp and humidity
    if (strstr(stringptr, "RMC"))   logfile.flush();
    Serial.println();
  }
}



// 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)
  #ifdef UDR0
    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. 
  #else
    Serial.write(c);
  #endif
#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;
  }
}

/* End code */

Jeffka02
 
Posts: 4
Joined: Tue Jun 10, 2014 1:17 am

Re: GPS and DHT22 help needed

Post by Jeffka02 »

This is a wonderful thing! Thank you so much. I will upload and test it out as soon as I get off work today! Thank you so much for your help with this!

Jeffka02
 
Posts: 4
Joined: Tue Jun 10, 2014 1:17 am

Re: GPS and DHT22 help needed

Post by Jeffka02 »

It works!!!

Thank you so much!

Tell your boss I approve your raise ;)

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: GPS and DHT22 help needed

Post by adafruit_support_rick »

Terrific!
Looking forward to that raise, too! ;)

User avatar
dhdpic
 
Posts: 11
Joined: Sun Jan 12, 2014 2:32 pm

Re: GPS and DHT22 help needed

Post by dhdpic »

Hello All,

Hoping to revive this thread.

I am having problems reading from the DHT22 (AM2302) sensor while using the Ultimate GPS Logger shield. I can read fine from the DHT22 in a sketch without the shield, and I can read from the DHT22 and successfully write the data to the SD card on the shield without reading any GPS data, but as soon as I try to read the DHT22 and read GPS data it seems to freeze the program completely and doesn't complete loop() iterations. (only the first set of Serial.println() statements get through before stopping, although GPSECHO statements still go though to serial monitor).

I've used the code you posted in this thread with no luck; I've used my own code with no luck; I'm sure the wiring is correct as the sensor works OK in other sketches; I'm sure the memory card is OK as I can write either GPS data or DHT22 data to it; I've also previously written data from light sensors and microphones to the SD card with GPS data without issue; SO I AM STUMPED! I guess it is a timing thing as you suggested in the post before, but I have no idea how to remedy this.

Any suggestions or solutions are greatly appreciated!

Thank you,

David

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: GPS and DHT22 help needed

Post by adafruit_support_rick »

Are you sure it doesn't work with the code I posted?

It sounds as if you are running out of SRAM. This is the classic symptom - everything works separately, but the Arduino freezes when you put everything together.
Please see this tutorial: https://learn.adafruit.com/memories-of-an-arduino

The code I posted should work on a Uno without modification. I'm surprised you're having trouble with it, unless you made some modifications to it...

User avatar
dhdpic
 
Posts: 11
Joined: Sun Jan 12, 2014 2:32 pm

Re: GPS and DHT22 help needed

Post by dhdpic »

Thank you for your reply Rick. And yes I was surprised and gutted when the code didn't work! I tried your code completely unmodified and it didn't work. Just tried it again with no joy.

The console says it takes up 25,690 bytes (of a 32,256 byte maximum). I will read through the tutorial on memory, and will test on another Uno incase it is something up with this one specifically.

If it still doesn't work perhaps I'll post some photos or a video.

Thanks again,

David

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: GPS and DHT22 help needed

Post by adafruit_support_mike »

dhdpic wrote:The console says it takes up 25,690 bytes (of a 32,256 byte maximum).
That's Flash memory, where the program is stored.

The Uno only has 2k of SRAM, which holds variables while the program is running. You may be running out of that if you have, for instance, long strings sitting around in memory waiting to be printed.

User avatar
dhdpic
 
Posts: 11
Joined: Sun Jan 12, 2014 2:32 pm

Re: GPS and DHT22 help needed

Post by dhdpic »

OK looks like I got it working! Tried three different Uno boards and all ran into the same freezing issue. I read some of the memory optimisation advice for SRAM and reduced all the string serial outputs for example "\r\nUltimate GPSlogger Shield" to "\r\nGPShield" and it works. Going to continue testing and hopefully it will be able to run a few hours at a time without crashing and I can reintegrate the other sensors.

Thank you for your help.

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: GPS and DHT22 help needed

Post by adafruit_support_mike »

You can also wrap your non-changing strings in the F() macro, which stores them in program memory rather than RAM.

Static strings consume a lot space and don't need to be in data memory. Moving them to program memory is an easy way to reclaim RAM.

User avatar
dhdpic
 
Posts: 11
Joined: Sun Jan 12, 2014 2:32 pm

Re: GPS and DHT22 help needed

Post by dhdpic »

OK thanks, I will probably give that a go too.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”