Interrupts und die DHT Library

Hallo,

ich schreibe gerade an einer Kleinen Box, die einen Bewegungsmelder hat und bei Bewegung oder einem festen Interval Werte mit der DHT library ausliest und versenden soll.

Nun mein Problem. im Intervall klappt das ganz gut. Bsp alle 60 sec.

Wenn der PIR-Sensor losgeht und den PIN 2 antriggert klappt es auch mit dem Interrupt. Ich kriege bloß keine Werte von dem Sensor. Ich weiß echt nicht mehr weiter...

Mein Code :

/**************************************************
**                 SensorBox                     **
**************************************************/

#include <RCSwitch.h>
#include <DHT.h>

     
//the time when the sensor outputs a low impulse
long unsigned int lowIn;         

/**************************************************
**                 SETTINGS                      **
**************************************************/
/*
Sleep time: 1min = 60000 ... 5min = 300000 ... 10Min = 600000  
*/
long unsigned int sleep = 60000;

/***************
**     ID    **
***************/
int Id = 01;  //The ID of your Sensorbox. Between 1 - 99
/****** PIR ****/

//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;  

/****** DHT ****/
//define the Sensor
#define DHTTYPE DHT11
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

/****** DEBUG ****/
boolean Debug = true;

/****** PINS ****/
int PirPin = 2;    //the digital pin connected to the PIR sensor's output. MUST BE AN INTERRUPT PIN
int SendPin = 8; //Pin of 433 Mhz sender
int LightPin = A4; //Light Sensor
int TempPin = A5; // Temperature and hum DHT22


/***** Vars for Readings ***/
volatile int PirState = 0;
float temp = 0;
float hum = 0;
float light = 0;


/***** Initial Classes ***/
RCSwitch mySwitch = RCSwitch();
DHT dht(TempPin, DHTTYPE);

/**************************************************
**                 SETUP                         **
**************************************************/
void setup(){
  if(Debug){
    Serial.begin(9600);
  }
  mySwitch.enableTransmit(8);
  pinMode(PirPin, INPUT);
  digitalWrite(PirPin, LOW);

  //give the PIRsensor some time to calibrate
  if(Debug){
  Serial.print("calibrating sensor ");
  
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
  }else{
   delay(calibrationTime*1000); 
  }
    delay(50);
    attachInterrupt(0, IntAct, RISING);
 }

/**************************************************
**                 Main                          **
**************************************************/
void loop(){
     
     fetchData();
      
      delay (sleep); 
  }
  
  void PirAction(){
    /************* PIR ********************/
     if(digitalRead(PirPin) == HIGH){ //PIR activity
       PirState = 1;
       if(Debug){
       Serial.println("PIR = 1");
       }
     } else {   
       PirState = 0;
     } 
  }
  void readTH(){
  /************* Temp and Hum ************/
     hum = dht.readHumidity();
     temp = dht.readTemperature();
      // Check if any reads failed and exit early (to try again).
     if (isnan(hum) || isnan(temp) ) {
      Serial.println("Failed to read from DHT sensor!");
      Serial.println(dht.read());
     //return;
      }
      if(Debug){
      Serial.print("Humidity: "); 
      Serial.print(hum);
      Serial.print(" %\t");
      Serial.print("Temperature: "); 
      Serial.print(temp);
      Serial.print(" *C \n");  
      }
  }
  void readLux(){
    /************** Light Sensor *****/
      light = map(analogRead(LightPin),0,1023,100,0);
       if(Debug){
      Serial.print("Lux: "); 
      Serial.print(light);
      Serial.print(" % \n");  
      }
  }
  void fetchData(){
      PirAction();
      readTH();
      readLux();
  }
  void IntAct(){
      PirState = 1;
      readTH();
      readLux();
  }
  void sendError (){
   
  }
    void sendData (){
    //
    
  }

Der Code wird in einigen Funktionen noch entwickelt.
Die Ausgabe sieht im Interval so aus:

Humidity: 35.00 %	Temperature: 21.00 *C        Lux: 86.00 %

Im Interrupt:

Failed to read from DHT sensor!
1
Humidity: nan %	Temperature: 0.00 *C 
Lux: 74.00 %

Need Help :frowning:

Wozu den Interrupt?
Du brauchst doch nur den Kontakt des Bewegungsmelders in der
Loop abfragen und bei entsprechendem Signal den Messwert versenden.
Dazu ist kein
Ir nötig.

Und das versenden mit der Lib RcSwitch solltest du nicht machen, dazu ist die Lib "VirtualWire" vorgesehen.

Tipp:
Wenn schon eine ISR, dann halte sie schlank.
Und tue nichts in der ISR welches selber von Interrupts abhängig ist.
z.B. millis(), delay(), I2c, usw...
Möglich, dass die DHT Lib auch Interrupts braucht, und darum in der ISR versagt.

Setze einfach ein Flag in der ISR.
Mache die eigentliche Abhandlung dann in loop()

Also ganz einfach in der ISR-Routine ein (volatile) Flag setzen in der loop antestesten, bei true
zurücksetzten und in dem If das tun was du jetzt in der IR-Routine machst.
Die loop darf natürlich keine lang blockierenden Aktionen machen.

Ulli

beeblebrox:
Die loop darf natürlich keine lang blockierenden Aktionen machen.

Das ist aber bei den meisten der Grund, warum sie denken, eine ISR wäre die Lösung, anstatt die Loop blockierungsfrei und schnell zu kriegen.

beeblebrox:
Die loop darf natürlich keine lang blockierenden Aktionen machen.

Kann sie theoretisch schon. Das wird dann halt etwas später erst abgefragt. Aber anders als manuelles Pollen in loop() wird das Ereignis trotzdem registriert.

Dinge die in ISRs nicht gehen sind übrigens: delay(), Serial und wiederholte Abfragen von millis() (einmal geht, aber der Zähler wird nicht aktualisiert)

Serenifly:
Kann sie theoretisch schon. Das wird dann halt etwas später erst abgefragt. Aber anders als manuelles Pollen in loop() wird das Ereignis trotzdem registriert.

Nur SOLLTE die loop schnell genug sein, das abzuarbeiten, bevor der nächste Interrupt ausgelöst wird (klar, je nach Anwendung).

Randalf:
Need Help :frowning:

Aus mir völlig unerfindlichen Gründen verwendet Dein Programm eine Interrupt-Behandlungsroutine:

  void IntAct(){
      PirState = 1;
      readTH();
      readLux();
  }

Und innerhalb dieser Interruptbehandlung wird dann der Controller aus mir ebenso unerfindlichen Gründen für fast unendlich lange Zeit zum Abfragen von Sensorwerten blockiert.

Vielleicht solltest Du mal über das KISS-Prinzip bei der Programmierung nachdenken:

  • Keep
  • It
  • Simple and
  • Smart

Du programmierst scheinbar mehr nach dem Prinzip CHAOS, und das steht für sich selbst und ist keine Abkürzung für irgendwas.

Als erstes mal würde ich aus der Programmlogik alles raushauen, was Du an Interrupts und Interrupthandling einbaust. Interrupts sind kein Hilfsmittel für Anfänger, die ein Programm nicht frei von blockierenden Funktionsaufrufen (Stichwort "delay()") schreiben können, sondern Interrupts sind Hilfsmittel für erfahrene Programmierer, um schnelle Signale im Mikrosekunden-Zeitbereich zu verarbeiten.

Tipp: Schreibe eine Programmlogik OHNE "delay()" und OHNE Verwendung von Interrupts!

@jurs:

Newbie
Posts: 1

Jetzt hast du ihn vertrieben :frowning:
Schon 2,5 Jahre Forumsmitglied, und kriegt beim ersten Post schon so Haue :wink:
Oder gerade deswegen?

kriegt beim ersten Post schon so Haue

Sehe ich nicht so. Er bekommt ehrliche und hilfreiche Antworten.

Gerade am Anfang ist es wichtig, sich keinen Mist anzugewöhnen - da sind klare Worte durchaus angebracht.

Schließlich ist niemand hier, um seinen Teddybären wiederzufinden, sondern, um was zu lernen.

Aber vielleicht habe ich auch nur ein etwas anderes (traditionelles) Verständnis von "Haue".

Mit deutschem Gruß

Helmuth :wink:

Völlig OT, aber ich musste gerade lachen:

Der war gut :slight_smile: :slight_smile:

P.S. Wie hast du das Bild eingefügt, ohne dass man unten eine Anlage sieht?

ElEspanol:
Der war gut :slight_smile: :slight_smile:

P.S. Wie hast du das Bild eingefügt, ohne dass man unten eine Anlage sieht?

Das Bild ist nicht als Anlage hochgeladen, es ist kein Dateianhang und wird deshalb nicht als Anhang angezeigt.

Das Bild ist als Image von einer fremden Webseite eingebunden.

Fieserweise handhaben die Arduino-Webforenbetreiber es nämlich so:

1.) Bilder von fremden Webseiten kannst Du über den Message-Editor einfach einbinden, dass sie hier angezeigt werden, als würden sie zum Forum gehören, obwohl die Bilder irgendwo ganz woanders im Internet auf ganz anderen Servern liegen.

2.) Aber Bilder des Arduino-Forums werden grundsätzlich nur zum Download angeboten.

Das Arduino-Forum ist offenbar so hoch belastet, dass die Macher Web-Traffic einsparen müssen. Daher werden hochgeladene Bilder nicht - wie es früher mal war - beim Aufrufen des Threads direkt angezeigt.

Beim Einbinden fremder Grafiken von fremden Webseiten, haben die Forenbetreiber allerdings keine Skrupel, die fremden Webserver mit zusätzlichen Traffic durch das Laden von Bildern zu belasten, wenn ein Thread hier im Forum betrachtet wird. Üblicherweise nennt sich sowas "Hot-Linking, Traffic-Stealing, oder auf Deutsch Bandbreiten-Klau". Eigentlich müßten die Forenbetreiber es mit fremden Bildern genau so machen: Also einen anklickbaren Link für das Bild generieren, und wenn man den Link anklickt, wird das Bild beispielsweise in einem neuen Fenster geöffnet. Stattdessen gibt es aber außer "Insert a link" auch "Insert an image" im Message-Editor, der es mit Bildern von fremden Webservern dann so macht wie er es macht.

Alternativ kann man auch einen freien Bildhoster benutzen, um eigenes Material hochzuladen, z.B. http://www.directupload.net/ oder Postimages — free image hosting / image upload usw.

Für die ist es explizit okay, wenn in Foren u.ä. darauf verlinkt wird.

Nebeneffekt: Das Bild landet direkt im Text - ohne die Anlage unter dem Beitag.

Aha. Also lädt man das Bild auf einen durch Werbung finanzierten Gratishoster, nimmt den deep Link zum jpg und verlinkt das direkt, damit das ganze Werbegedöns nicht aufpoppt.
Und hofft dann, dass er trotz entgangenen Einnahmen lange überlebt und die Bilder somit online bleiben. Das ist gut :smiling_imp:

Oder man speichert sie auf dem eigenen Webspace und beim nächsten Hosterwechsel sind sie weg.

Beim Einbinden fremder Grafiken von fremden Webseiten, haben die Forenbetreiber allerdings keine Skrupel, die fremden Webserver mit zusätzlichen Traffic durch das Laden von Bildern zu belasten, wenn ein Thread hier im Forum betrachtet wird. Üblicherweise nennt sich sowas "Hot-Linking, Traffic-Stealing, oder auf Deutsch Bandbreiten-Klau".

Eine merkwürdige Ansicht über html hast du da, jurs. 8)
Wer ein Bild ins öffentliche InterNetz stellt, möchte, dass web-browser es anzeigen, sonst soll er's lassen.

Um sich vor ignoranten Richtern und abmahnenden Anwälten zu schützen, ist es gelegentlich ratsam, bei einem gelinkten Bild (aber jedes Bild ist irgendwoher gelinkt) explizit dazuzuschreiben, wo es herkommt und dass es sich eventuell nicht um eine Kopie im Besitz dessen handelt, der den Text drumherum verfasst hat. Aber das sollte eigenlich egal sein, denn man kann leicht herausfinden, wo das "Kloppe" Bild herkommt. Und dass es eines der besten dort ist :wink:

Und dass der Seitenbetreiber wohl eine eigene Version des Bildes gesichert hat, bevor IKEA es eventuell in Zukunft nicht mehr selbst veröffentlicht 8)

Directupload selbst bietet nach dem Upload einen "Hotlink" zum copy&paste an, welcher werbungsfrei direkt zur Bilddatei führt.

Vermutlich begnügt man sich mit der eingeblendeten Werbung beim Upload und den Nutzern, welche keinen Adblocker verwenden.

michael_x:
Eine merkwürdige Ansicht über html hast du da, jurs. 8)
Wer ein Bild ins öffentliche InterNetz stellt, möchte, dass web-browser es anzeigen, sonst soll er's lassen.

Eine merkwürdige Ansicht über das World-Wide-Web und das in Deutschland geltende Recht hast Du da.

Selbst Wikipdedia stellt es korrekt dar, dass Hot-Linking von Media-Dateien einer fremden Seite eine "unerwünschte Nutzung" darstellen kann:

Viele Webseitenbetreiber erstellen HTML-Seiten nur aus dem Grund, um Einnahmen durch eingeblendete Werbeanzeigen zu erzielen. Durch Hot-Linking wird aber die Mediendatei aus dem Kontext herausgerissen und beim Webseitenbetreiber Traffic erzeugt, ohne dass dieser die Chance hat, Werbeanzeigen dabei einzublenden und Einnahmen aus Werbung zu erzielen.

Das kann ggf. nach deutschem Recht nicht nur eine "unerwünscht", sondern eine "illegale" Handlung darstellen.

Hot-Linking ist im Einzelfall in Deutschland bereits durch alle Instanzen bis hin zum Bundesgerichtshof durchgefochten worden. In diesem Fall ging es beispielsweise darum, dass Webseitenbetreiber Kartenausschnitte eines Kartendienstanbieters innerhalb ihrer eigenen Webseiten verlinkt hatten:

Auf der rechtlich sicheren Seite ist ein Forenbetreiber mit Hot-Linking jedenfalls nicht.
Mit folgender Ausnahme: Der Webseitenbetreiber hat das Hot-Linking seiner Mediendateien gestattet, entweder generell, oder aufgrund einer Genehmigung nach vorheriger Anfrage.

Beispielsweise erteilen Urheber (z.B. Fotografen) oft das Recht zur Veröffentlichung eines Bildes nur mit der Auflage "Veröffentlichung bei Nennung des Urhebers mit folgendem Urheberzusatz als Bildunterschrift: ...". Wie das zu behandeln ist, wenn dann beispielsweis der ursprüngliche Webseitenbetreiber den verlangten Urheberhinweis am Bild angebracht hat, dieser aber beim Anzeigen des Bildes durch Hot-Linking auf einer anderen Webseite verloren geht, ist meines Erachtens bisher nur von unteren Instanzen, nicht aber vor dem Bundesgerichtshof vor Gericht ausgefochten worden.

Den Trafficdiebstahl durch Hot-Linking in diesem Forum habe ich auch überhaupt nur deshalb angesprochen, weil der Betreiber dieses Forums mit den auf dem eigenen Server gehosteten Bilddateien anders umgeht als mit verlinkten Bildern von fremden Webservern:

a) Bilder auf dem eigenen Foren-Webserver
Es wird nur ein anklickbarer Link angezeigt. Traffic zum Laden des Bildes entsteht erst beim Anklicken.

b) Bilder auf fremden Servern, die durch Hot-Linking abgegriffen werden
Das Bild wird "inline" direkt beim Aufrufen des Forenbeitrags angezeigt und erzeugt unmittelbar einen Traffic-Load auf dem fremden Webserver.

Dazu einige Anmerkungen: Wikipedia selbst schreibt

Es gibt einige Möglichkeiten, wie ein Webserver oder eine Webanwendung Hotlinking unterbinden kann. Ein häufig gewählter Weg ist das Abfragen des HTTP-Referrers, den der Webbrowser eines Seitenbesuchers mitsendet.

Wenn ein Webmaster ein Problem mit dem zusätzlichen Traffic hat, kann er das also wirksam unterbinden.

Bei einem niedrig aufgelösten JPG sehe ich den Traffic allerding als vernachlässigbar an, wenn es nicht gerade das neueste millionenfach geklickte Viral-Bildchen wird.

Desweiteren: Ist forum.arduino.cc in Deutschland gehostet? Interessiert deutsches Recht hier überhaupt?

Viele Webseitenbetreiber erstellen HTML-Seiten nur aus dem Grund, um Einnahmen durch eingeblendete Werbeanzeigen zu erzielen.

Die Grundsatzdiskussion, ob allein durch Werbung finanzierte Webseiten überhaupt überleben sollten, möchte ich hier nur ungern anfangen.

Nur soviel: Mir würde nichts fehlen, wenn sie gänzlich verschwinden. Entweder jemand macht eine Seite als Hobby - und hat nicht die Erwartung, die Kosten zu decken. Oder, wenn wirklich relevante Traffic Kosten anfallen und die Qualität der gebotenen Inhalte stimmt, haben spendenbasierte Projekte bisher IMMER funktioniert. Prominentes Beispiel und von mir regelmäßig finanziell unterstützt, weil täglich genutzt: Radio Paradise.

Nicht nur aus dieser Überzeugung heraus benutze ich immer Adblocker. Wer seine Refinanzierung auf Werbung - der gezielten Manipulation der Gäste - aufbaut, gehört nicht unterstützt.

Das Internet der frühen 90er hat auch ohne Werbefinanzierung bestens funktioniert.

Auf der rechtlich sicheren Seite ist ein Forenbetreiber mit Hot-Linking jedenfalls nicht.

Ja, nach deutschem Recht nicht.