SmartGong - [Teil 3] - Death-Sleep

Hallo zusammen,

in vielen Projekten wird der Deep-Sleep des Wemos D1 für einen stromsparenden Standby-Betrieb verwendet, jedoch sind die ca. 8.5 mA meiner Meinung immer noch zu viel, wenn man bedenkt, dass der Wemos D1 eigentlich nur auf seinen Einsatz wartet. In diesem Teil wollen wir daher nicht nur einen Deep-Sleep sondern einen „Death-Sleep“ erreichen.

Dafür müssen wir unsere vorhandene Hardware noch einmal erweitern und die bisherige Schaltung umbauen.

Benötigte Hardware

Für die Umsetzung benötigen wir aufbauend zu Teil 1 & Teil 2:

Anzahl Bauteil Anmerkung
1 P-LogL  MOSFET zB. BSP171P bzw. IRLIB9343PBF
1 1 MΩ Widerstand
1 1 kΩ Widerstand
1 100 Ω Widerstand
1 NPN-Transistor BC547
1 Elektrolytkondensator (3,3 uF)
1 Micro USB Adapter Board
1 LED optional
1 Mikro-Tastschalter optional

Der Aufbau 

Die Grundidee hinter dem Death-Sleep ist, dass sich der Wemos D1 Mini nach erfolgreicher Arbeit selbst die Stromversorgung kappt. Deshalb müssen wir die Schaltung so verändern, dass wir ihn auch von außen wieder reanimieren können. Der folgende Aufbau zeigt meinen Lösungsansatz:


Schaltplan und Steckbrett der SmartGong03
 

In die Versorgungsleitung integrieren wir einen P-LogL MOSFET, welcher bereits bei niedrigen Spannungsdifferenzen den notwendigen Strom durchlässt. Dessen Gate wird über den 1 MΩ Widerstand dauerhaft auf 5 V gezogen, wodurch der MOSFET sperrt. Durch Drücken des Schalters wird das Gate auf GND gezogen, dadurch schaltet der MOSFET durch und der Wemos D1 fährt hoch. Ohne den zusätzlichen Kondensator C2 würde der MOSFET nur so lange durchschalten, solange wir den Schalter drücken.

Die ca. 300 ms, welche der Wemos D1 zum Hochfahren benötigt, werden durch das RC Glied (R2 und C2) in Kombination mit der „Gate threshold voltage“, welche beim verwendeten BSP171P laut Datenblatt zwischen -2 V und -1V liegt, überbrückt.

Vereinfacht gesagt bleibt nach Betätigen des Schalters der MOSFET genau solange eingeschaltet, bis der Kondensator sich über den Widerstand R2 auf ca. 3V (=5V-2V) aufgeladen hat.

Einen praktischen online Rechner für solche Auslegungen finden Sie auf der Seite von Wenzel Schumann.

Wollen Sie Ihre Schaltung simulieren, eignet sich auch das Tool EveryCircuit.

Mit den von mir verwendeten Bauteilen ergibt sich eine Schaltzeit von ca. 3 s. Diese Zeitspanne ist mehr als ausreichend, damit der Wemos hochfährt und über den Transistor den MOSFET selbst auf GND zieht.

Analog zum Schalter reicht auch ein einziger Schaltvorgang unseres Reed Kontaktes, um den Wemos einzuschalten.

Simulation der Death-Sleepschaltung in EveryCircuit

Für die Selbsterhaltung verwenden wir den Pin D8. Dieser ist nicht nur beim Booten stabil, sondern verfügt auch noch über einen internen 10kΩ Pull-down Widerstand.

Für erste Experimente auf dem Steckbrett eignet sich auch der IRLIB9343PBF.

Der von mir verwendete MOSFET BSP171P lässt sich noch ohne Probleme von Hand auf einer normalen Lochrasterplatine mit Rastermaß: 2.54 mm verlöten.

Um den SmartGong nun weiterhin mit einem Handy Netzteil mit Strom zu versorgen, habe ich noch einen micro-USB Adapter hinzugefügt. Durch die Verbindung mit D+ und D- zum MP3 Modul wird das Gerät als SD Kartenleser per USB vom PC erkannt. Dies ermöglicht auch einen komfortablen Wechsel des Klingeltons.

Der fertig verlötete neue Prototyp ist in folgendem Bild zu sehen.


Aktueller Stand der SmartGong03

Die Spule für den Reed Kontakt habe ich zuerst um ein Stück Strohhalm gewickelt und anschließend den Reed Kontakt durch geschoben. So wird der Kontakt mit dem empfindlichen Bauteil minimiert.

Die Signalleitung für die Spule habe ich außerdem um einen Stecker und einen Schalter erweitert, so lässt sich die Klingel einfacher montieren und zwischen der bestehenden Klingel und dem SmartGong umschalten.

Die Software 

In der Software sorgen wir nur dafür, dass beim Einschalten der Pin D8 auf High schaltet und so lange wie nötig die Stromversorgung aufrecht erhält.

Das MP3 Modul verfügt über eine kleine LED, welche invertiert zum Busy-Pin anzeigt, ob gerade ein Titel abgespielt wird. Da unser Smartgong nicht länger als nötig eingeschaltet bleiben soll, holen wir uns das Signal über einen Interrupt-Pin auf den Wemos und können im Anschluss den Wemos mit Deep-Sleep schlafen legen.

Dabei fährt sich der Microcontroler bis auf das nötigste herunter und schaltet gleichzeitig das Signal am Pin D8 ab. 3 Sekunden später dreht der MOSFET unserem SmartGong den Strom ab.

Wenn man genau hinsieht, erkennt man beim Einschalten, dass die Busy-LED des MP3 Moduls einmal aufflackert, bevor es den Titel abspielt, weshalb wir im Code erst die zweite Schaltflanke abwarten.

//Benötigte Bibliotheken 
#include <SoftwareSerial.h>  //Software Serial for ESP8266 https://circuits4you.com/2016/12/14/software-serial-esp8266/   Link zur Libary https://circuits4you.com/wp-content/uploads/2016/11/SoftwareSerial.zip
#include <ESP8266WiFi.h>
#include <DFRobotDFPlayerMini.h> //https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299   Link zur Libery https://github.com/DFRobot/DFRobotDFPlayerMini/archive/1.0.3.zip
#include <Adafruit_NeoPixel.h>// https://github.com/adafruit/Adafruit_NeoPixel.git   Link zur Libary https://github.com/adafruit/Adafruit_NeoPixel/archive/master.zip 

//Benötigte Deklarationen 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(12, D2, NEO_GRB + NEO_KHZ800);//Adafruit_NeoPixel(AnzahlPixel, PINDATA, NEO_GRB + NEO_KHZ800);
SoftwareSerial SofSer(D3, D4, false, 128); //Wir deklarieren ein Objekt vom Typ "SoftwareSerial" mit dem Namen "SofSer" und setzen D3 auf RX und D4 auf TX als Ausgang für die serielle Komunikation SoftwareSerial(rxPin, txPin, inverse_logic, buffer size);
DFRobotDFPlayerMini AzMp3Player;    //Wir deklarieren ein Objekt vom Typ "DFRobotDFPlayerMini" mit dem Namen 'AzMp3Player'
int Volume = 25;                    //Variable für die Lautstärke  mit 25 als Startwert
int SE = D8;                        //Variable für die Selbsterhaltung der Stromversorgung
int interruptPin = D7;              // Variable für den Interrupt vom MP3 Modul
bool finished=0;                    // Zustandsvariable
int T=0;                            // Zustandsvariable 

void setup() {
  pinMode(SE, OUTPUT);             // Die allererste Handlung setzt den Selbsterhaltungspin als Output 
  digitalWrite(SE, HIGH);          // und anschließend auf HIGH 
  pinMode(interruptPin, INPUT_PULLUP);     // Vorbereitung der Interrupt Funktion
  attachInterrupt(digitalPinToInterrupt(interruptPin), MP3_finished, RISING );  // Wenn der interrupptPin von LOW auf HIGH wechselt soll die Funktion MP3_finised ausgeführt werden
  
  SofSer.begin(9600);                          // Einstellen der Baudrate auf 9600, welche vom MP3-Modul erwartet wird
  Volume=map(analogRead(A0), 0, 1023, 0, 30); // Liest den Wert von A0 und wandelt den Wertebereich von 0-1023 auf 0-30 um
  if (Volume > 10)                           // Wenn Lautstärke größer als 10, dann schalte die Melodie an
   { AzMp3Player.begin(SofSer);                // Starten der seriellen Komunikation zwischen dem D1 Mini und dem MP3 Modul
     AzMp3Player.volume(Volume);               // Sendet Nachricht an das MP3 Modul:  stelle Lautstärke auf 25 (0-30)
     AzMp3Player.playMp3Folder(0);             // Sendet Nachricht an das MP3 Modul:  Spielt die Dateinummer 0000.mp3
   }
  else                                      // Wenn Lautstärke kleiner als 10, dann schalte die Lichtmodi an
   { strip.begin(); 
     strip.setBrightness(250);                  //Setzt Helligkeit auf 250(0-max = 255) 
     theaterChaseRainbow(100);
     strip.show();                            // schaltet alle Pixel aus
     finished=true;                           // Bereit zum Ausschalten
   }
}

void loop() {
  if (finished == true) { ESP.deepSleep(0);} // Ist alles erledigt kann sich der ESP schlafen legen (und schaltet dabei seine Stromversorgung ab)
}

void MP3_finished(){ // Interrupt Funktion. Erst bei der zweiten Schaltflanke ist die Melodie zuende. 
  if (T == 1){finished=true;}
  T=T+1;
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j=j+8) {     // j++ cycle all 256 colors in the wheel  j=j+8  256/8=  -->32 Farben
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
      strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Mit dieser Schaltung verbraucht der SmartGong abgesehen von ein paar minimalen Kriechströmen, welche ich mit meinem Multimeter nicht mehr messen konnte, absolut keinen Strom, wenn er nicht verwendet wird.

Damit ist unsere Hardware fertig und im nächsten Teil kümmern wir uns um die Einbindung in unser Smarthome.

Viel Spaß beim Nachbauen!


1 Kommentar

Martin

Martin

Kann der Gong Aufzug mit einer Batterie betrieben werden? Z.B. mit einer 9V Blockbatterie?

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert