[gelöst] Temperaturanzeige mit Arduino Nano und Sleep-Modus

Hallo zusammen,
ich möchte mir eine Temperaturanzeige bauen. Dazu verwende ich einen Sensor DB18B20, einen Arduino Nano und eine vierstellige 7-Segment-Anzeige (siehe Schaltung).

Weil ich die Temperaturanzeige mit einem Akku betreibe und deshalb Strom sparen will, möchte ich die Temperatur nur gemessen und angezeigt bekommen, wenn ich einen Taster betätige. Dann soll der Nano aus dem „Schlaf“ geweckt werden, die Messung erfolgen und angezeigt werden und anschließend, nach loslassen des Tasters, der Nano wieder in den Schlaf wechseln.
Da ich mit dem Taster den Interrupt (Nano wecken) auslöse in dem ich Pin 2 auf LOW lege, steuer ich über Pin 3 einen Transistor an, der dann VCC an den Sonsor und die Anzeige legt. Jetzt sollte eine Temperatur angezeigt werden, denn die leuchtende LED zeigt, das am Sensor und an der Anzeige VCC anliegt.
Leider erfolgt keine Anzeige, weil das Programm nicht den Sensor liest. Die Abfrage if (sensors.getDS18Count() != 0) ist nicht erfüllt, denn in seriellen Monitor wird mir nach drücken des Tasters nur „"Interrupt" und „MESSUNG IST EIN“ ausgegeben, aber nicht "Sensor".
Ich versuche es schon stundenlang vergeblich den Fehler zu finden, ohne Erfolg.
Ich habe die 7-Segment Anzeige an einer anderen Schaltung getestet, sie funktioniert, und ich habe den Sensor ausgetauscht, auch ohne Erfolg.
Ich geh davon aus, das die Schaltung ok ist. Da ich bezüglich des programmierens noch ein ziehmlicher Anfänger bin werde ich wohl etwas im Code bei der Anpassung falsch gemacht haben.
Gruß
wAlter67

//////////////////////////////////////////////////////
// Temperaturanzeige mit 7-Segment und Schlafmodus
////////////////////////////////////////////////////

// Definitionen für Schlafmodus ////////////////////////////////
#include <avr/sleep.h>
#define INT_PIN 2
#define LED_PIN 13

// Definitionen für Temp-Messung ////////////////////////////////
#include <TM1637Display.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// Module connection pins (Digital Pins)
#define CLK A4
#define DIO A3
#define ONE_WIRE_BUS 7
const uint8_t SEG_ERR[] = {
  SEG_A | SEG_D | SEG_E | SEG_F | SEG_G, // E
  SEG_E | SEG_G,                         // r
  SEG_E | SEG_G,                         // r
  0,                                     // space
};
TM1637Display display(CLK, DIO);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
byte Messung_EIN = 3;
// Unterprogramme für Schlafmodus ////////////////////////////////
void INT_PINisr(void)
  /* ISR fuer Pin 2 */
  {
  /* detach Interrupt, damit er nur einmal auftritt */
  detachInterrupt(0);
  }

void enter_sleep(void)
  {
  digitalWrite(Messung_EIN, LOW);  // Sensor und Anzeige AUS
  attachInterrupt(0, INT_PINisr, LOW);
  /* Arduino schlafen legen */
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();
  sleep_disable(); 
  }
/////////////////////////////////////////////////////////////////
void setup()
  {
// Setupteil für Temp-Messung //////////////////////////////////
  pinMode(7, INPUT);
  pinMode(3, OUTPUT);
  digitalWrite(Messung_EIN, LOW);   // Sensor und Anzeige AUS
  display.setBrightness(0x00);
  sensors.begin();

  if (sensors.getDS18Count() == 0)
    display.setSegments(SEG_ERR);
  else
    sensors.setResolution(10);
 //////////////////////////////////////////////////////////////
  Serial.begin(9600);
  Serial.println("Starte ...");
  /* Pin 2 als Interrupt-Pin, Pullup einschalten */
  pinMode(INT_PIN, INPUT);
  digitalWrite(INT_PIN, HIGH); 
  pinMode(LED_PIN, OUTPUT);
  Serial.println("Init erfolgt ...");
  delay(100);
  }

void loop()
  {

  /* warten, bis der Interupt-Eingang wieder frei ist */
  while (digitalRead(INT_PIN) == LOW) {
     Serial.println("Interrupt");
     digitalWrite(Messung_EIN, HIGH); // Sensor und Anzeige EIN
     Serial.println("MESSUNG IST EIN");
     if (sensors.getDS18Count() != 0) {
      Serial.println("Sensor");
      sensors.requestTemperatures();
      double temp = sensors.getTempCByIndex(0);
      display.showNumberDecEx(temp * 100, 0b01000000, false);
     }
    Serial.println("*** Taste loslassen ***");  
    delay(100);
  }
  Serial.println("Gehe schlafen ...");  
  delay(100);
  /* LED umschalten und wieder schlafen */
  //digitalWrite(LED_PIN, ! digitalRead(LED_PIN));
  enter_sleep();
  Serial.println("Bin aufgewacht ...");  
  delay(100);
}

Hallo
Ein kurze Frage:
Warum schaltest du die Betriebsspannung, für den Arduino plus Sensor und Anzeige, nicht über einen Taster ein bzw aus?
Wenn ein Messwert vom Sensor DB18B20 geliefert wird dann wird dieser angezeigt.

Hallo paulpaulson,
könnte ich machen, aber dann muß ich warten und den Taster gedrückt halten, bis der Nano hochgelaufen ist.
Ich denke das Wecken aus dem sleep-Modus geht schneller.

Hallo,

Klappt es denn wenn Du den sleep mal weglässt? Es könnte sein das Du noch etwas warten musst vor der Messung. bau mal im Setup ein Delay(1000) am Ende dazu.

Heinz

wenn du eh den Nano mit einer Taste starten willst, kannst du dir doch das schlafen schicken sparen und gleich mit der Taste/Tastschalter Spannung anlegen, der Nano startet und macht seine Anzeige. Auch der Temp. Sensor und die Anzeige bekommt Spannung über diese Taste/Schalter. Dann Taste wieder loslassen oder Tastschalter erneut drücken zum Ausschalten. Das dauert ja nicht sooooo lange, bis der Nano nach dem anlegen der Spannung arbeitet. Damit verbraucht die ganze Schaltung überhaupt keine Spannung, somit dürfte der Akku für Ewigkeiten reichen, weil du nur in den paar Sekunden Spannung brauchst, in denen du die Temp. kontrollierst. Auch den ganzen Interuptzauber benötigst du dann nicht.

Franz

Hallo Rentner,

ja, ohne sleep klappt es, das hatte ich ja gestestet, als ich die Anzeige prüfen wollte, ob die vielleicht defekt ist. Ich bau jetzt mal die Wartezeit mit 1000 ein, mal sehen was wird.

Hallo Franz

du hast ja Recht, dein Vorschlag ist die absolut einfachste Lösung. Dennoch wüßte ich gern, wo der Fehler in meinem Programm liegt. Ich mach das ja alles nicht, weil ich mir kein Thermometer leisten kann, sondern weil ich kreativ sein und programmieren möchte. Wenn ich weis, warum es bei dieser Schaltung nicht funktioniert hat, lerne ich ja dazu und kann den Fehler in einem anderen Programm, dass ich nicht durch einfaches EIN-AUS-schalten ersetzen kann, vermeiden.

Gruß

Walter

Ich vermute, dein Problem liegt in der Spannungsversorgung deines Displays und Sensors.

Üblicherweise schaltet man +Spannung mit PNP-Transistoren und nicht mit NPN-Transistoren.
Außerdem fehlt der Pullup-Widerstand an der Datenleitung des Sensors.

HotSystems:
Außerdem fehlt der Pullup-Widerstand an der Datenleitung des Sensors.

Ist mir gar nicht aufgefallen. Ja, ohne den 4,7k gegen VCC geht natürlich nichts.

Franz54:
Ist mir gar nicht aufgefallen. Ja, ohne den 4,7k gegen VCC geht natürlich nichts.

Liegt wohl auch an der sehr eigenwilligen Schaltungsdarstellung.

Hallo,

der Sensor könnte auf einem der ferigen Bastelmodule aus einem Set verbaut sein, er schreibt jaauch was von einer LED am Sensor. Dann ist der Widerstand eventuell schon mit drauf. Denn messen tut sein Aufbau ja , war ja meine Frage.

Heinz

Rentner:
Hallo,

der Sensor könnte auf einem der ferigen Bastelmodule aus einem Set verbaut sein, er schreibt jaauch was von einer LED am Sensor. Dann ist der Widerstand eventuell schon mit drauf. Denn messen tut sein Aufbau ja , war ja meine Frage.

Heinz

Heinz, das mag ja sein.
Ich habe aber aktuell meinen Ratemodus abgeschaltet und nur auf Fehler in der Schaltung hingewiesen.
Mein Tipp hier, immer erst die offensichtlichen Fehler beseitigen, dann wird es einfacher.

Und so sieht keine stabil funktionierende Schaltung aus.

Edit:
Ich versteh auch aktuell nicht, warum sich der TO dazu nicht äussert, online ist er ja.

Hallo,

den 4,7 k Widerstand hab ich verbaut, aber leider vergessen auf dem Schaltplan ein zu zeichnen.
Mit der erwähnten LED ist die "Prüf-LED" gemeint, die ich angebracht habe, um zu sehen ob der Transistor durchschaltet, wenn ich den Taster betätige. Der Transistor tut also seinen Dienst richtig, da die LED leuchtet, solange ich den Taster drücke. Also bekommen der Sensor und die Anzeige Spannung.

Hallo,

wie es denn auch sei, Wenn das Ding im Prinzip misst,und das mit dem Delay auch nicht geklappt hat , dann kannst Du ja noch was einbauen was den LOOP für eine bestimmte Zeit aufrecht erhält und dann, nach mehreren Sekunden / Umläufen erst in den Sleep geht.

das ist zwar jetzt am Problem vorbei gebaut , sorg aber dafür das Du mit einem kurzen Tastendruck das Ding zum laufen bekommmts und dann selbstständig wieder ausschaltet.

Wenn der Taster in der Stromversorgung liegt must Du Ihn ja schon für eine gewisse Zeit drücken.

Heinz

wAlter67:
....
Der Transistor tut also seinen Dienst richtig, da die LED leuchtet, solange ich den Taster drücke. Also bekommen der Sensor und die Anzeige Spannung.

Mag ja sein, dass es so in deiner Schaltung durch Zufall funktioniert. Dennoch ist es der falsche Transistor.

Teste es mal mit einer anderen Betriebstemperatur oder einer anderen Spannung.
Du möchtest doch Akkubetrieb und da hast du ganz sicher keine stabilen Verhältnisse.

Wenn du es richtig machst, wird es auch stabil arbeiten.

Und wenn du es nicht glaubst, schau dir das Dtaenblatt zum Transistor an.

Natürlich werde ich deinem Hinweis folgen und einen anderen Transistor ausprobieren. Hab ja zu einem anderen Problem auch von dir die Lösung bekommen (OneWire am Attiny läuft mit 8 MHZ).
Ich melde mich dann, ob es das war.

Gruß
Walter

Ich würde wenn ich will, dass sich der Nano wieder selbst abschaltet, eine Schaltung konstruieren die alles mit einem Tastendruck mit Spannung versorgt, und dann nach der Ausgabe der Temperatur nach eine Zeit-X sich selbst, über einen Pin des Nanos, wieder die Stromversorgung killt. Ich würde einfach nicht wollen, dass ich die Batterie alle paar Tage laden muss, wenn ich es auch so machen kann, dass ich alle paar Wochen laden muss.

Ich denke zum lernen über das Thema Interupt wird es nicht soooo viel geben, weil alles schon 1000 mal im Internet vorgekaut wird. Aber klar, es mal gesehen zu haben, schadet nicht. Ich habe bisher fast alle meine Sensoren nur zum lernen, üben, Hirn frischhalten besorgt und betrieben. Einige, wenige Dinge betreibe ich wirklich.

Franz

Hallo,
ich habe die Schaltung jetzt mit einem PnP-Transistor gemacht. Sorry, wenn die Darstellung nicht eurer Norm entspricht, ich komme aus dem Stakrstrom/Hochspannungsbereich, da zeichnet man etwas anders. Werde mich künftig an die Normen der "Schwachstromer" (:-)) halten.
Das Ergebnis ist aber das Gleiche wie zuvor.
Am Code habe ich nicht weiter geändert, habe lediglich die Ansteuerung des NPN von Pin 3 aus rausgenommen.
Der PnP wird ja jetzt direkt von S1 mit GNG angesteuert.
Wenn ich den Taster betätige, schaltet der Transistor durch und versorg den Sensor und die Anzeige mit 4,56 V.
Aber es wird keine Temperatur angezeigt, weil anscheinend die Bedingung "sensors.getDS18Count() != 0" nicht erfüllt ist (Serial.Println("Sensor) wird aus der If-Abfrage nicht ausgegeben).
Ich weiß ja, dass man das anders lösen kann. Ich habe sogar zwischenzeitlich eine einfache Lösung mit einem Attiny85 / DS18B20 / 7-Segment Anzeige realisiert, aber solange ich nicht überzeugt bin, dass mein jetziger Ansatz nicht gehen kann und vor allen Dingen warum er dann nicht gehen kann, gebe ich nicht auf. Ich hoffe dabei noch immer auf eure Hilfe.

Gruß

wAlter

//////////////////////////////////////////////////////
// Temperaturanzeige mit 7-Segment und Schlafmodus
////////////////////////////////////////////////////

// Definitionen für Schlafmodus ////////////////////////////////
#include <avr/sleep.h>
#define INT_PIN 2
#define LED_PIN 13

// Definitionen für Temp-Messung ////////////////////////////////
#include <TM1637Display.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// Module connection pins (Digital Pins)
#define CLK A4
#define DIO A3
#define ONE_WIRE_BUS 7
const uint8_t SEG_ERR[] = {
  SEG_A | SEG_D | SEG_E | SEG_F | SEG_G, // E
  SEG_E | SEG_G,                         // r
  SEG_E | SEG_G,                         // r
  0,                                     // space
};
TM1637Display display(CLK, DIO);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// Unterprogramme für Schlafmodus ////////////////////////////////
void INT_PINisr(void)
  /* ISR fuer Pin 2 */
  {
  /* detach Interrupt, damit er nur einmal auftritt */
  detachInterrupt(0);
  }

void enter_sleep(void)
  {

  attachInterrupt(0, INT_PINisr, LOW);
  /* Arduino schlafen legen */
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();
  sleep_disable(); 
  }
/////////////////////////////////////////////////////////////////
void setup()
  {
// Setupteil für Temp-Messung //////////////////////////////////
  pinMode(7, INPUT);
  pinMode(3, OUTPUT);
  display.setBrightness(0x00);
  sensors.begin();

  if (sensors.getDS18Count() == 0)
    display.setSegments(SEG_ERR);
  else
    sensors.setResolution(10);
 //////////////////////////////////////////////////////////////
  Serial.begin(9600);
  Serial.println("Starte ...");
  /* Pin 2 als Interrupt-Pin, Pullup einschalten */
  pinMode(INT_PIN, INPUT);
  digitalWrite(INT_PIN, HIGH); 
  pinMode(LED_PIN, OUTPUT);
  Serial.println("Init erfolgt ...");
  delay(100);
  }

void loop()
  {

  /* warten, bis der Interupt-Eingang wieder frei ist */
  while (digitalRead(INT_PIN) == LOW) {
     Serial.println("Interrupt");
     digitalWrite(Messung_EIN, HIGH); // Sensor und Anzeige EIN
     Serial.println("MESSUNG IST EIN");
     if (sensors.getDS18Count() != 0) {
      Serial.println("Sensor");
      sensors.requestTemperatures();
      double temp = sensors.getTempCByIndex(0);
      display.showNumberDecEx(temp * 100, 0b01000000, false);
     }
    Serial.println("*** Taste loslassen ***");  
    delay(100);
  }
  Serial.println("Gehe schlafen ...");  
  delay(100);
  /* LED umschalten und wieder schlafen */
  //digitalWrite(LED_PIN, ! digitalRead(LED_PIN));
  enter_sleep();
  Serial.println("Bin aufgewacht ...");  
  delay(100);
}

wAlter67:
Aber es wird keine Temperatur angezeigt, weil anscheinend die Bedingung "sensors.getDS18Count() != 0" nicht erfüllt ist (Serial.Println("Sensor) wird aus der If-Abfrage nicht ausgegeben).

Dem DS fehlt zwischen DATA und +5V der PULLUP!
Und komm nicht auf die Idee das mit dem internen des AVR zu lösen.

Und der Transistor ist immer noch ein NPN und kein PNP.