Go Down

Topic: Redfly und Dallas OneWire TempSensor (Read 1 time) previous topic - next topic

TrunX

Hallo zusammen,
ich versuche gerade ein Projekt zu basteln, in welchem ich die Temperatur über OneWire an 2 Orten messe und über das RedFly auf eine Seite schreibe. Zumindest soll das so vereinfacht erstmal aussehen.

Ich habe in dem Projekt nen LCD-Display, RTC-Modul und eben die 2 Sensoren hintereinander.
Das läuft auch ohne Probleme "offline".
Das Testprogramm mit dem RedFlyServer bekomme ich auch zum laufen und kann die Seite im Browser öffnen.
Nun zum Problem:
Wenn ich beides zusammenbastel, dann hängt sich der Arduino auf, sobald ich den Browserzugriff starte.

Ich habe das Problem soweit eingegrenzt, dass sich der Arduino nur aufhängt, sobald ich irgendwie auf die Sensoren zugreife.
Also wenn ein Befehl wie "sensors.requestTemperatures();" auftaucht, hängt sich der Arduino beim Browserzugriff auf.

Ich vermute das Problem irgendwo in den Bibliotheken. Ist dazu vielleicht schon was bekannt?

#include <RedFly.h>
#include <RedFlyServer.h>
#include <Wire.h>              
#include <RTClib.h>
#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>

Arduino Uno R3
Dallas Sensor DS18B20

Liebe Grüße

Addi

Ist genügend RAM für dein Programm übrig?
Benutze mal diesen Code http://playground.arduino.cc/Code/AvailableMemory

Addi
/ \    _|  _| o
 /--\ (_| (_| |

uwefed

oder Versuch Dein Programm auf einem Arduino MEGA; der hat mehr RAM.

Hast Du das F()- Makro für Texte verwendet?

Grüße Uwe

skorpi08

Code: [Select]

sensors.requestTemperatures

Ist wahrscheinlich im loop drinnen,  was bedeutet dass der Arduino überfordert ist mit den Ergebnissen zu liefern.
Eine Sekunde pause wäre schon ganz gut.
Nicht Mensch, nicht Tier: Programmierer halt...

TrunX

#4
Jun 28, 2013, 11:31 pm Last Edit: Jun 28, 2013, 11:36 pm by TrunX Reason: 1
Also hat das ganze Problem nichts mit den Librarys zu tun?!
Und ich weiß leider nicht genau, was du mit F()-Makros meinst.
Ich sende mit dem RedFly bisher nichts, außer einem Text mit ,Hallo'.
Und das available Memory Programm einfach noch hinten anhängen um mir das anzuzeigen?
Wieviel Memory sollte denn übrig sein?

Ansonsten ist das requestTemperatures wirklich im Loop, allerdings läuft es ohne Probleme, bis ich das RedFly anspreche ohne Delay. Ich steh nicht auf Delays, denn dann hängt immer alles für die Zeit.
Werde das morgen aber mal ausprobieren.

Hilft es, wenn ich den ganzen Code poste?! Ist relativ lang ^^

Serenifly

Delays kann man auch ohne Blockierung machen. Schau dir das Beispiel BlinkWithoutDelay an. Kurz gesagt ließt man da die aktuelle zeit mit millis() aus und vergleicht sie mit einer alten Zeit + Delay-Zeit.

z.B.:
Code: [Select]

unsigned long _previousMillis = 0;
unsigned long _currentMillis = 0;

void loop()
{
_currentMillis = millis();

if(_currentMillis - _previousMillis > 1000)
{
_previousMillis = _currentMillis;


                //Code der jede Sekunde ausgeführt wird
        }
}

TrunX


Delays kann man auch ohne Blockierung machen. Schau dir das Beispiel BlinkWithoutDelay an.

Das stimmt, das kenne ich auch, aber dann habe ich ja, soweit ich weiß, nicht den Effekt, dass der Arduino die Zeit hat, die Ergebnisse zu liefern. Denn dann arbeitet er ja weiter.

Serenifly

Er soll ja weiter arbeiten. Nämlich mit dem Webserver. Wenn du aber ständig den Sensor abfragst (was alleine durch die OneWire Lib wahrscheinlich ein paar Millisekunden dauert) lässt du ihm keine Zeit für andere Dinge.

TrunX

#8
Jun 29, 2013, 12:42 am Last Edit: Jun 29, 2013, 12:46 am by TrunX Reason: 1

Er soll ja weiter arbeiten. Nämlich mit dem Webserver. Wenn du aber ständig den Sensor abfragst (was alleine durch die OneWire Lib wahrscheinlich ein paar Millisekunden dauert) lässt du ihm keine Zeit für andere Dinge.

Also du meinst ich soll keinen Delay einsetzen, durch den er wartet, sondern das requestTemperatures in eine Schleife (zB mit den millis) setzen, sodass er nur noch 1x pro Sekunde die Temperaturen erfragt?
Und dadurch, dass er sonst so oft abfragt und viele Daten verarbeitet, hängt er sich sonst auf?
Klingt schlüssig :D
Mach ich morgen, jetzt erstmal ins Bett! :D

TrunX

#9
Jun 29, 2013, 09:46 am Last Edit: Jun 29, 2013, 10:43 am by TrunX Reason: 1
Also das Delay(1000):
unsigned long currentMillis = millis();
 if(currentMillis - previousMillis > interval) {
   previousMillis = currentMillis;  
   sensors.requestTemperatures();
 }

bringt nicht wirklich einen Fortschritt.

Bis er sich aufhängt habe ich:
freeMemory()=1163

EDIT:
Also wenn ich das interval auf 10000 (10sek.) stelle, hängt er sich unregelmäßig beim Browserzugriff auf.
bzw. ich hab das gefühl, der schnelle zugriff (1-2x direkt nach hochfahren) klappt, danach hängt er sich auf.

jurs


Bis er sich aufhängt habe ich:
freeMemory()=1163

EDIT:
Also wenn ich das interval auf 10000 (10sek.) stelle, hängt er sich unregelmäßig beim Browserzugriff auf.
bzw. ich hab das gefühl, der schnelle zugriff (1-2x direkt nach hochfahren) klappt, danach hängt er sich auf.


Verwendest Du String-Objekte in Deinem Programm?

String-Objekte sind wegen eines Fehlers in der Speicherverwaltung erst ab der Version 1.0.5 so halbwegs problemlos verwendbar, ohne dass ein Programm sich früher oder später aufhängt, das intensiv mit String-Objekten arbeitet.

Also entweder Arduino 1.0.5 verwenden, oder auf String-Objekte im Programm komplett verzichten (was sowieso immer besser ist) und C-Strings/Char-Arrays stattdessen verwenden.

TrunX

#11
Jun 29, 2013, 02:23 pm Last Edit: Jun 29, 2013, 02:41 pm by TrunX Reason: 1
Code: [Select]
#include <RedFly.h>
#include <RedFlyServer.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <RTClib.h>
#include <SoftwareSerial.h>        //LCD
#include <MemoryFree.h>

#define RELAY 11

SoftwareSerial mySerial(3,8);    // pin 8 = TX, pin 3 = RX (unused)

#define ONE_WIRE_BUS 10          // DS18B20 an Pin 10 angeschlossen
// Pass our oneWire reference to Dallas Temperature.
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

RTC_DS1307 RTC;

int buttonPin = 12;
int warte = 0;
long previousMillis = 0; //für millis-delay
int interval = 10000;

byte ip[]      = { 192,168,178,111 }; //ip from shield (server)
byte netmask[] = { 255,255,255,0 }; //netmask

//initialize the server library with the port
//you want to use (port 80 is default for HTTP)
RedFlyServer server(80);


//debug output functions (9600 Baud, 8N2)
//Leonardo boards use USB for communication, so we dont need to disable the RedFly
void debugout(char *s)
{
#if defined(__AVR_ATmega32U4__)
 Serial.print(s);
#else
 RedFly.disable();
 Serial.print(s);
 RedFly.enable();
#endif
}

void debugoutln(char *s)
{
#if defined(__AVR_ATmega32U4__)
 Serial.println(s);
#else
 RedFly.disable();
 Serial.println(s);
 RedFly.enable();
#endif
}


void setup(){
 
 uint8_t ret;

 Serial.begin(9600); //init serial port and set baudrate
 while(!Serial); //wait for serial port to connect (needed for Leonardo only)

 //init the WiFi module on the shield
 // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
 // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
 // ret = RedFly.init() //9600 baud, HIGH_POWER
 ret = RedFly.init();
 if(ret)
 {
   debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
 }
 else
 {
   //scan for wireless networks (must be run before join command)
   RedFly.scan();

   //join network
   ret = RedFly.join(*SSID*, *PW*, INFRASTRUCTURE);
   if(ret)
   {
     debugoutln("JOIN ERR");
     for(;;); //do nothing forevermore
   }
   else
   {
     //set ip config
     ret = RedFly.begin(ip, 0, 0, netmask);
     if(ret)
     {
       debugoutln("BEGIN ERR");
       RedFly.disconnect();
       for(;;); //do nothing forevermore
     }
     else
     {
       RedFly.getlocalip(ip); //receive shield IP in case of DHCP/Auto-IP
       server.begin();
     }
   }
 }
 pinMode(RELAY, OUTPUT);
 digitalWrite(RELAY, HIGH);   // turn the relay on (HIGH is the voltage level)


 //LCD
   mySerial.begin(9600); // set up serial port for 9600 baud
   delay(500); // wait for display to boot up
   clearLCD();
   backlightOn();
 //RTC
   Wire.begin();
   RTC.begin();
   
 //Temperatur  
   sensors.begin();
   delay(1000);

 if (! RTC.isrunning()) {
   Serial.println("RTC is NOT running!");  }
   
  // following line sets the RTC to the date & time this sketch was compiled
  // RTC.adjust(DateTime(__DATE__, __TIME__));
 

}


void loop()
{
 long currentMillis = millis();
 if(currentMillis - previousMillis > interval) {
   previousMillis = currentMillis;  
   sensors.requestTemperatures();
 }
int Temp1 = sensors.getTempCByIndex(0);
int Temp2 = sensors.getTempCByIndex(1);  
 
 
 //listen for incoming clients
 if(server.available())
 {
   //a http request ends with a blank line
   boolean currentLineIsBlank = true;
   while(server.available())
   {
     char c = server.read();
     //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)
     {
       //clear input buffer
       server.flush();

       //send standard HTTP 200 header
       server.print_P(PSTR("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"));

       //send some text
       server.println_P(PSTR("Willkommen auf Steffens Terrarien-Server! <br><br>"));
       server.println_P(PSTR("<br>Temperatur oben: "));
       server.print(Temp1, DEC);
       server.println_P(PSTR("&deg;C"));
       server.println_P(PSTR("<br>Temperatur unten: "));
       server.print(Temp2, DEC);
       server.println_P(PSTR("&deg;C"));
       server.println_P(PSTR("<br><br>"));


       //show IP address of RedFly
       server.println_P(PSTR("<br><i>RedFly IP: "));
       server.print(ip[0], DEC); server.print(".");
       server.print(ip[1], DEC); server.print(".");
       server.print(ip[2], DEC); server.print(".");
       server.print(ip[3], DEC);
       server.println_P(PSTR("<br></i>"));
       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;
     }
   }

   //close connection
   server.stop();
}
 else if(!server.connected()) //listening port still open?
 {
   server.stop(); //stop and reset server
   server.begin(); //start server
 }
 
 
//starte offline Programm


DateTime now = RTC.now();

// In Line 1 wird das Datum und die Uhrzeit geschrieben
selectLineOne();
   if (now.day() < 10) {mySerial.print('0');}
   mySerial.print(now.day(), DEC);
   mySerial.print(".");
   if (now.month() < 10) {mySerial.print('0');}
   mySerial.print(now.month(), DEC);
   mySerial.print('.');
   if (now.year() < 10) {mySerial.print('0');}
   mySerial.print(now.year(), DEC);
   mySerial.print("  ");
   if (now.hour() < 10) {mySerial.print('0');}
   mySerial.print(now.hour(), DEC);
   mySerial.print(':');
   if (now.minute() < 10) {mySerial.print('0');}
   mySerial.print(now.minute(), DEC);
   mySerial.print(':');
   if (now.second() < 10) {mySerial.print('0');}
   mySerial.print(now.second(), DEC);
   
//In Line 2 wird geschrieben
selectLineTwo();
   mySerial.print("Temp. Oben:     ");
   mySerial.print(Temp1); // Warum "byIndex"? Man kann mehr, als nur einen IC auf dem gleichen bus haben. 0 bezieht sich auf den ersten IC.
   mySerial.print(char(223)); //°
   mySerial.print("C");
   
//In Line 3 wird geschrieben
selectLineThree();
   mySerial.print("Temp. Unten:    ");
   mySerial.print(Temp2); // Warum "byIndex"? Man kann mehr, als nur einen IC auf dem gleichen bus haben. 1 bezieht sich auf den zweiten IC.
   mySerial.print(char(223)); //°
   mySerial.print("C");
   
//In Line 4 wird geschrieben
selectLineFour();
 if (digitalRead(buttonPin)==HIGH){
   mySerial.print("gef");
   mySerial.print(char(245)); //ü
   mySerial.print("ttert:  ");
   if (now.day() < 10) {mySerial.print('0');}
   mySerial.print(now.day(), DEC);
   mySerial.print(".");
   if (now.month() < 10) {mySerial.print('0');}
   mySerial.print(now.month(), DEC);
   mySerial.print(".");
   if (now.year() < 10) {mySerial.print('0');}
   mySerial.print(now.year()-2000, DEC);}
 
 
// Schaltung des Relais
 int Stunde = now.hour();
 int relais = 0;
 
  if (Stunde > 9 && Stunde < 21){
   relais = 1;}
  else {relais = 0;}
 
  if (relais == 1 && Temp1 < 34 && warte == 0){             // Schalte das Relais an, wenn Temp. Oben < 34°C
   digitalWrite(RELAY, HIGH);}                             // und Zeit zwischen 10 Uhr und 20 Uhr
  else if(relais == 1){                                    // Wartet nach 34°C auf Abkühlung bis 30°C
 
  if(Temp1 >= 34) {
   digitalWrite(RELAY, LOW);
   warte = 1;  }
  else if (Temp1 <= 29) {warte = 0;}}
  else{
   digitalWrite(RELAY, LOW);
   warte = 1;}

   Serial.print("freeMemory()=");
   Serial.println(freeMemory());
   
} //void loop Ende


//SerialLCD Functions
void selectLineOne(){  //puts the cursor at line 0 char 0.
  mySerial.write(0xFE);   //command flag
  mySerial.write(128);    //position
}
void selectLineTwo(){  //puts the cursor at line 2 char 0.
  mySerial.write(0xFE);   //command flag
  mySerial.write(192);    //position
}
void selectLineThree(){  //puts the cursor at line 3 char 0.
  mySerial.write(0xFE);   //command flag
  mySerial.write(148);    //position
}
void selectLineFour(){  //puts the cursor at line 4 char 0.
  mySerial.write(0xFE);   //command flag
  mySerial.write(212);    //position
}
void clearLCD(){
  mySerial.write(0xFE);   //command flag
  mySerial.write(0x01);   //clear command.
}
void backlightOn(){  //turns on the backlight
   mySerial.write(0x7C);   //command flag for backlight stuff
   mySerial.write(157);    //light level.
}
void backlightOff(){  //turns off the backlight
   mySerial.write(0x7C);   //command flag for backlight stuff
   mySerial.write(128);     //light level for off.
}
void backlight50(){  //sets the backlight at 50% brightness
   mySerial.write(0x7C);   //command flag for backlight stuff
   mySerial.write(150);     //light level for off.
}


TrunX

#12
Jun 29, 2013, 02:24 pm Last Edit: Jun 29, 2013, 02:31 pm by TrunX Reason: 1
Das ist das komplette Programm.
Ich verwende Arduino 1.0.5.
Damit habe ich auf einem LCD: Datum/Uhrzeit (aus dem RTC-Modul), Temp1 + Temp2 (vom Dallas Sensor über OneWire) und einen Button für die letzte Fütterung
Und ein Relais, welches eine Heizlampe an und Ausschaltet.

zusätzlich jetzt halt noch das RedFly-Shield.
Vielleicht hilft der Code ja, wenn sich da jemand drantraut :smiley-roll:

zu 90% hängt er sich auf, wenn ich den Browser zugriff starte, 8% danach, und 2% geht ;)

EDIT:
pingen geht übrigens ohne Probleme

Ich habe den Code nur überflogen, aber ein Serial.print() darf man nur machen, wenn das RedFly vorher deaktiviert wird. Daher gibt es auch die debugout() Funktionen.

Der Pin 3 wird von der SoftwareSerial Lib und dem RedFly gleichzeitig belegt. Dies kann unter Umständen Probleme machen.

PS: Code bitte nicht als Zitat/Quote posten. Es gibt dafür separate [ code ] Tags.

TrunX

#14
Jun 29, 2013, 02:46 pm Last Edit: Jun 29, 2013, 03:48 pm by TrunX Reason: 1

Ich habe den Code nur überflogen, aber ein Serial.print() darf man nur machen, wenn das RedFly vorher deaktiviert wird. Daher gibt es auch die debugout() Funktionen.

Der Pin 3 wird von der SoftwareSerial Lib und dem RedFly gleichzeitig belegt. Dies kann unter Umständen Probleme machen.

PS: Code bitte nicht als Zitat/Quote posten. Es gibt dafür separate [ code ] Tags.

Hab ich als Code geschrieben, kein Problem ;)

Pin 3 wird ja nicht benutzt, soll ich den in der SoftwareSerial.h einfach ändern?

Reicht es, wenn ich vor den "Offline Teil" RedFly.disable();  und nach dem Teil  RedFly.enable();   schreibe?
Oder meinst du damit was anderes?

EDIT:
Wenn ich das mache, hängt er sich nicht mehr auf, Ping geht auch, aber kein Browserzugriff mehr.

EDIT 2:
Ich habe es wieder rausgenommen und die Temperatur zuordnung auch in die millis schleife geschrieben.
Damit scheint es erstmal zu funktionieren, wenn ich das richtig sehe.

Go Up