Pages: [1]   Go Down
Author Topic: Arduino weatherstation - Freezing/hang/stackoverflow!  (Read 862 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 0
Posts: 145
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I bought the weatherstation kit a while ago... I got the DHT temp/humidity sensor installed and it seems to be reading and displaying temperature fine (though it seems to overshooting by a few degrees). I ordered a few relays and have one installed to switch on with pin13 (no blinking) just to hear the click.

As a newbie I have a few questions... but the most important one that I would like answered before I pursue anything else is that it keeps freezing. I am using a 12 volt 2A adaptor to power it (high I know), but it freezes when connected through serial/usb as well. I have no idea why this is.. all I can think is it must be running out of memory somehow (Stack overflow?)

It only freezes while the "light" is being displayed.. not humidity, and I don't have the photoresistor installed... could this be the problem??

The code I just copied from the hobbyist website, I undid some of the comments to get it to actually display something but apart from that I haven't changed a thing. I've also noticed it will stop displaying serial too.

http://weather--station.googlecode.com/svn-history/r3/trunk/WeatherStation.pde

The other questions include wiring in series/parallel. I am simply using one "strip" on the breadboard for + and another strip for ground. I am just plugging things directly into these strips (with the exception of the LCD pins which have a resistor crossing the breadboard seperator) so I guess that means everything is in series with the LCD as well... could this explain why it is freezing?!

How can I view/display the memory remaining? I guess theres no way for the code to detect hangs ie the halting problem either... so all I can think off is to get it to periodically restart/dump/garbage collect unused memory. I have no idea how to solve this problem or where to start. I have some basic understanding of the C syntax but I have no idea about the arduino library functions etc where do I start?? Help!
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 176
Posts: 12283
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I bought the weatherstation kit a while ago...

Quote
About 122,000 results

I suggest narrowing that list.
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 145
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry I know there will be alot of weatherstation posts.. but I find it hard to locate/understand the specific problem with my setup, especially regarding overflow seems to be too advanced for me especially since I am still learning what each bit of code does currently. I would just like some advice specific to my code such as - does what im doing currently even use near enough memory to cause an overflow? Is it an error in the code or more likely my wiring?
Logged

Tucson, AZ
Offline Offline
Sr. Member
****
Karma: 4
Posts: 272
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Giving us a link to the specific weatherstation that you bought would be a good start.
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 145
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The controller is a Arduino Duemilanove. This is the tutorial I've been using: http://www.hobbyist.co.nz/?q=node/19
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 145
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is the actual code I am using at the moment. I have some questions regarding it. Firstly why does the LCD display random characters when I uncomment the   //Serial.begin(9600); ? Can it not output both at the same time?

I deleted everything to do with the light sensor incase that was using up memory (but deleting #define LIGHT_SENSOR_PIN 1 seems to cause issues), but still the freezing problem, sometimes straight away sometimes after a while.

I also tried to replace the light sensor output
Code:
         lcd.print("Light =         ");
          lcd.setCursor(8, 1);
          lcd.print( light_intensity, DEC);

with

Code:
lcd.setCursor(8, 1);
lcd.print(millis()/1000);

Thinking that instead of flipping to the light intensity it would instead display the startup time but no luck.. I don't understand why making these minor changes to the code should break it.. please explain why.

Code:

//#define dht_PIN 0      //no ; here. deprecate ADC0...
  //even though we are using it as a digital pin.
  //Other parts of code restrict us to using
  //ADC0-5, aka D14-19
#define dht_dpin 14 //no ; here. Set equal to channel sensor is on,
     //where if dht_dpin is 14, sensor is on digital line 14, aka analog 0

#define LIGHT_SENSOR_PIN 1
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(0, 1, 2, 3, 4, 5);

byte bGlobalErr;//for passing error code back from complex functions.
byte dht_dat[4];//Array to hold the bytes sent from sensor.
int light_intensity = 0;
unsigned int flip = 0;

void setup(){
  //Blink LED to detect hangs
  pinMode(13, OUTPUT);
   // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  lcd.print("hello, world!");
  InitDHT();//Do what's necessary to prepare for reading DHT
  //Serial.begin(9600);
  delay(300);//Let system settle
  //Serial.println("Humidity and temperature\n\n");
  delay(700);//Wait rest of 1000ms recommended delay before
  //accessing sensor
}//end "setup()"

void loop(){
    // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  //lcd.print("100");
  lcd.print(millis()/1000);
  if ( flip & 1 )
  {
    digitalWrite(13, HIGH);  
  } else {
    //digitalWrite(13, LOW);
  }
  
flip++;
  
  light_intensity=analogRead(LIGHT_SENSOR_PIN);
  
  ReadDHT();//This is the "heart" of the program.
      //Fills global array dht_dpin[], and bGlobalErr, which
      //will hold zero if ReadDHT went okay.
      //Must call InitDHT once (in "setup()" is usual) before
      //calling ReadDHT.
  //Following: Display what was seen...
  switch (bGlobalErr){
     case 0:
        lcd.setCursor(0, 0);
Serial.print("Humdity = ");
        lcd.print("Temp =       ");
        lcd.setCursor(7, 0);
        lcd.print( dht_dat[2], DEC);

//Serial.print(dht_dat[0], DEC);
//Serial.print(".");
//Serial.print(dht_dat[1], DEC);
//Serial.print("%  ");
        lcd.setCursor(0, 1);
        //Every 7 out of 15 times we show humidity, rest temp
        if ((flip % 15) > 7 )
        {
          lcd.print("humidity = ");
          lcd.setCursor(11, 1);
          lcd.print( dht_dat[0], DEC);
        } else {
          lcd.print("Light =         ");
          lcd.setCursor(8, 1);
          lcd.print( light_intensity, DEC);
        }
//Serial.print("temperature = ");
//Serial.print(dht_dat[2], DEC);
//Serial.print(".");
//Serial.print(dht_dat[3], DEC);
//Serial.println("C  ");
        break;
     case 1:
        //Serial.println("Error 1: DHT start condition 1 not met.");
        break;
     case 2:
        //Serial.println("Error 2: DHT start condition 2 not met.");
        break;
     case 3:
        //Serial.println("Error 3: DHT checksum error.");
        break;
     default:
        //Serial.println("Error: Unrecognized code encountered.");
        break;
     }//end "switch"
  delay(800);//Don't try to access too frequently... in theory
                   //should be once per two seconds, fastest,
                   //but seems to work after 0.8 second.
                  
}// end loop()

/*Below here: Only "black box" elements which can just be plugged unchanged
  unchanged into programs. Provide InitDHT() and ReadDHT(), and a function
  one of them uses.*/

void InitDHT(){
   //DDRC |= _BV(dht_PIN);//set data pin... for now... as output
              //DDRC is data direction register for pins A0-5 are on
//PORTC |= _BV(dht_PIN);//Set line high
              //PORTC relates to the pins A0-5 are on.
        //Alternative code...
//        if (dht_dpin-14 != dht_PIN){Serial.println("ERROR- dht_dpin must be 14 more than dht_PIN");};//end InitDHT
        pinMode(dht_dpin,OUTPUT);// replaces DDRC... as long as dht_dpin=14->19
        digitalWrite(dht_dpin,HIGH);//Replaces PORTC |= if dht_pin=14->19
}//end InitDHT

void ReadDHT(){
/*Uses global variables dht_dat[0-4], and bGlobalErr to pass
  "answer" back. bGlobalErr=0 if read went okay.
  Depends on global dht_PIN for where to look for sensor.*/
bGlobalErr=0;
byte dht_in;
byte i;
  // Send "start read and report" command to sensor....
  // First: pull-down i/o pin for 18ms
digitalWrite(dht_dpin,LOW);//Was: PORTC &= ~_BV(dht_PIN);
delay(18);
delay(5);//TKB, frm Quine at Arduino forum
/*aosong.com datasheet for DHT22 says pin should be low at least
  500us. I infer it can be low longer without any]
  penalty apart from making "read sensor" process take
  longer. */
//Next line: Brings line high again,
//   second step in giving "start read..." command
digitalWrite(dht_dpin,HIGH);//Was: PORTC |= _BV(dht_PIN);
delayMicroseconds(40);//DHT22 datasheet says host should
   //keep line high 20-40us, then watch for sensor taking line
   //low. That low should last 80us. Acknowledges "start read
   //and report" command.

//Next: Change Arduino pin to an input, to
//watch for the 80us low explained a moment ago.
pinMode(dht_dpin,INPUT);//Was: DDRC &= ~_BV(dht_PIN);
delayMicroseconds(40);

dht_in=digitalRead(dht_dpin);//Was: dht_in = PINC & _BV(dht_PIN);

if(dht_in){
   bGlobalErr=1;//Was: Serial.println("dht11 start condition 1 not met");
   return;
   }//end "if..."
delayMicroseconds(80);

dht_in=digitalRead(dht_dpin);//Was: dht_in = PINC & _BV(dht_PIN);

if(!dht_in){
   bGlobalErr=2;//Was: Serial.println("dht11 start condition 2 not met");
   return;
   }//end "if..."

/*After 80us low, the line should be taken high for 80us by the
  sensor. The low following that high is the start of the first
  bit of the forty to come. The routine "read_dht_dat()"
  expects to be called with the system already into this low.*/
delayMicroseconds(80);
//now ready for data reception... pick up the 5 bytes coming from
//   the sensor
for (i=0; i<5; i++)
   dht_dat[i] = read_dht_dat();

//Next: restore pin to output duties
pinMode(dht_dpin,OUTPUT);//Was: DDRC |= _BV(dht_PIN);
//N.B.: Using DDRC put restrictions on value of dht_pin

//Next: Make data line high again, as output from Arduino
digitalWrite(dht_dpin,HIGH);//Was: PORTC |= _BV(dht_PIN);
//N.B.: Using PORTC put restrictions on value of dht_pin

//Next see if data received consistent with checksum received
byte dht_check_sum =
       dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3];
/*Condition in following "if" says "if fifth byte from sensor
       not the same as the sum of the first four..."*/
if(dht_dat[4]!= dht_check_sum)
   {bGlobalErr=3;}//Was: Serial.println("DHT11 checksum error");
};//end ReadDHT()

byte read_dht_dat(){
//Collect 8 bits from datastream, return them interpreted
//as a byte. I.e. if 0000.0101 is sent, return decimal 5.

//Code expects the system to have recently entered the
//dataline low condition at the start of every data bit's
//transmission BEFORE this function is called.

  byte i = 0;
  byte result=0;
  for(i=0; i< 8; i++){
      //We enter this during the first start bit (low for 50uS) of the byte
      //Next: wait until pin goes high
      while(digitalRead(dht_dpin)==LOW);//Was: while(!(PINC & _BV(dht_PIN)));
            //signalling end of start of bit's transmission.

      //Dataline will now stay high for 27 or 70 uS, depending on
            //whether a 0 or a 1 is being sent, respectively.
      delayMicroseconds(30);//AFTER pin is high, wait further period, to be
        //into the part of the timing diagram where a 0 or a 1 denotes
        //the datum being send. The "further period" was 30uS in the software
        //that this has been created from. I believe that a higher number
        //(45?) would be more appropriate.

      //Next: Wait while pin still high
      if (digitalRead(dht_dpin)==HIGH)//Was: if(PINC & _BV(dht_PIN))
    result |=(1<<(7-i));// "add" (not just addition) the 1
                      //to the growing byte
    //Next wait until pin goes low again, which signals the START
    //of the NEXT bit's transmission.
    while (digitalRead(dht_dpin)==HIGH);//Was: while((PINC & _BV(dht_PIN)));
    }//end of "for.."
  return result;
}//end of "read_dht_dat()"
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is the actual code I am using at the moment. I have some questions regarding it. Firstly why does the LCD display random characters when I uncomment the   //Serial.begin(9600); ? Can it not output both at the same time?

You are using pins 0 and 1 (amongst others) to connect the LCD. Pins 0 and 1 are the serial receive and transmit pins. That's why you see random characters when you print to serial. To avoid this, either use different pins to connect the LCD (leaving 0 and 1 free), or shuffle the LCD pins around so that the LCD Enable pin is not connected to Arduino pin 0 or 1.

You can reduce the RAM usage by using F-strings in your Serial.print and lcd.print calls, for example use Serial.print(F("Hello world")) instead of Serial.print("Hello world").
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Offline Offline
Full Member
***
Karma: 0
Posts: 145
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for that I will redirect the pins. Where is this RAM stored? In the EEPROM?
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

RAM stands for random access memory and is a separate area from the flash memory (used to store the program) and the EEPROM. It is used to hold the stack and the variables you declare in your program. It is a very limited resource, just 2K bytes on the Arduino Uno.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Offline Offline
Full Member
***
Karma: 0
Posts: 145
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Someone please help... All I tried to do was comment out everything to do with the light sensor because its not connected, thinking that might solve the freezing problem.


So now I just have this in the loop:
Code:
ReadDHT()

lcd.setCursor(0, 0);

lcd.print("temp =       ");
lcd.setCursor(7, 0);
lcd.print( dht_dat[2], DEC);

lcd.setCursor(0, 1);

lcd.print("humidity = ");
lcd.setCursor(11, 1);
lcd.print( dht_dat[0], DEC);

and these have been deleted:

Code:
#define LIGHT_SENSOR_PIN 1

and

light_intensity=analogRead(LIGHT_SENSOR_PIN);

But now it doesn't get past the "Hello, world!". I dont see why this would cause that effect at all..
« Last Edit: March 05, 2013, 04:48:35 pm by syphex » Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 145
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok so im going back to even more basics.

Now I only have this code, just displaying "Hello, world!" and the time in seconds beneath it:

Code:
int ledPin = 13;                 // LED connected to digital pin 13
#define dht_PIN 0      //no ; here. deprecate ADC0...
  //even though we are using it as a digital pin.
  //Other parts of code restrict us to using
  //ADC0-5, aka D14-19
#define dht_dpin 14 //no ; here. Set equal to channel sensor is on,
     //where if dht_dpin is 14, sensor is on digital line 14, aka analog 0

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(0, 1, 2, 3, 4, 5);

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  lcd.begin(16, 2);
  lcd.print("hello, world!");
  delay(300);//Let system settle
}

void loop()
{/*
  digitalWrite(ledPin, HIGH);   // sets the LED on
  delay(1000);                  // waits for a second
  digitalWrite(ledPin, LOW);    // sets the LED off
  delay(1000);                  // waits for a second
  */
 
      // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  //print the number of seconds since reset:
  //lcd.print("100");
  lcd.print(millis()/1000);
}

Now I want to introduce the sensor... The LCD is still connected to 0, 1, 2, 3, 4, 5 but it hasent freezed yet so I'm guessing it was a problem with the code not the pins. The DHT11 sensor is still connected as before to analog 0.. but the rest of the code I had before seems really messy with all the silly error handlers. IDK what to do from here...
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 145
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is ridiculous.. every time I delete everything to do with the "light sensor" the thing refuses to flip, even though none of the other code uses anything to do with it and I replace  lcd.print( light_intensity, DEC); with lcd.print(millis()/1000);. This is getting REALLY frustrating and I have no idea why, this should be SIMPLE code. Cant the italians make anything that actually works? Someone actually HELP me before I take to this italian shit with a hammer.

I cant figure out if its the DHT, or trying to use a non existant light sensor that causes it to freeze/stop flipping even though its blinking. I swear to christ if I see that LED stop blinking one more time...
Logged

UK
Offline Offline
Shannon Member
****
Karma: 184
Posts: 11173
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


every time I delete everything to do with the "light sensor" the thing refuses to flip

I have no idea what that means. If you're still having trouble with the sketch then post the whole sketch, tell us what it's supposed to do and what it actually does. Preferably, before posting, delete any code that was commented out so we have less to read through. If it uses any external hardware then tell us what the hardware is (ideally with links to data sheet) and how it's connected.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Rome, Italy
Offline Offline
Sr. Member
****
Karma: 20
Posts: 442
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Cant the italians make anything that actually works? Someone actually HELP me before I take to this italian shit with a hammer.

Being Italian myself (not particularly proud of it, just happened), I feel like recommending the hammer as the most satisfying choice. Otherwise calm down, understand that in this forum you'll find people like me that cannot understand what's written in your code when you only give a description of your changes, post the version that "refuses to flip" and we'll see. I won't elaborate on the coding skills you've demonstrated so far.
« Last Edit: March 05, 2013, 07:14:27 pm by spatula » Logged

Pages: [1]   Go Up
Jump to: