ESP8266 D1 mini, Schlafmodus und ext. Interrupt

OP #7428031
Lesenswert?

Werte Community,

zuerst mal vorweg, das ist mein erster Beitrag hier, bzw. anders gesagt, ich bin der Neue hier. :)

Weiters möchte ich euch bitten mit mir erbarmen zu haben, denn ich weiß nicht was ich tue. hahaha Zumindest nich bei allem.

Zu meinem Problem:

Ich habe schon lange nicht mehr programmiert, deshalb hat ein Freund mir ein bisschen geholfen. Von ihm habe ich auch den ESP 8266 D1 mini bekommen und wir haben für die Programmierung VS Code mit dem Plugin PlatformIO verwendet. Ob man damit Debuggen kann weiß ich bis dato noch nicht.

Mein Projekt funktioniert soweit so gut, nur möchte ich einen kleinen Zusatz dabei haben. Ohne diesen Zusatz ist das Ganze ziemlich lästig. Ich komme aber gleich darauf zu sprechen.

Vorab möchte ich jedoch sagen, dass durch euer prüfendes Auge der bisherige Code sicherlich besser zu schreiben ist, mir ist aber das momentan egal, hauptsache das Programm tut was es soll. Bin nämlich ein bisschen im Zeitdurck und möchte einfach das es läuft.

Nun aber zu den Einzelheiten:

Ich habe einen ESP8266 D1 mini, einen Motortreiber "Motor Driver Module BTS7960", einen Motor, zwei Schalter (keine Taster, obwohl im Programm mit Taster benannt), einen LDR und ein Poti.

Der ESP ist folgendermaßen programmiert: Über den LDR und das Poti wird ein Schwellwert festgelegt welcher bei Über oder Unerschreiten den Motor eine gewisse Zeit laufen lässt. Dieser zieht eine Klappe nach oben. Da mir aufgefallen ist, dass beim Runterlaufen die Klappe schneller unten ist wurde für die Fahrt nach unten eine kürzere Zeit eingestellt. Deshalb gibt es im Programm zwei Zeiten. Der ESP geht dann in den Schlafmodus und wacht alle Minuten einmal auf, schaut nach ob die Werte des LDR noch passen oder sich verändert haben und geht wieder schlafen. Der Schalfmodus ist einfach um Strom zu sparen, da das ganze über ein Akkupack betrieben wird. Zu erwähnen ist, dass die Zeit auf Grund von Testzwecken momentan auf 5 Sekunden eingestellt ist, später aber auf eine Minute verändert werden soll.Die beiden Schalter sind dazu da, dass die Klappe manuell hoch oder runter gefahren werden kann.

Nun kommt aber das Problem!

Der Schalter wird jedoch nur dann erkannt wenn der Controler aufwacht und der Schalter gedrückt ist. Daher möchte ich, dass durch Drücken des Schalters der Controller mittels Interrupt aufgeweckt wird, je nach Schalter entweder die Klappe nach oben oder unten gefahren wird, und danach der Controller wieder schlafen geht. Der Part mit den Interrupts ist im Code noch nicht vorhanden. Ich habe zwar schon vieles probiert, aber nichts davon funktioniert wirklich.

Könnt ihr mir hier weiterhelfen wo ich ansetzen soll?

Eines sei hier noch erwähnt, beim Controller wurde zwischen Pin D0 und Pin RST eine fixe Brücke, (also mittels Draht miteinander verbunden) gelegt. Das habe ich so im in diversen Beiträgen gelesen. Dies wird zum Schlafen bzw. Aufwecken des Controllers benötigt. Für die Programmierung des Contrllers muss ich die Brücke jedoch öffnen. Ihr wisst das aber wahrscheinlich viel besser als ich.

Im Code sind noch Textausgaben die ich zu Testzwecken verwendet habe, sollen euch aber nicht weiter stören.

Ich hoffe hier die entsprechenden Antworten zu erhalten und bedanke mich vorab recht herzlich für eure Beiträge Codeergänzungen bzw. Hinweise.

LG Christian

P.S.: Hier noch der bis dato funktionierende Code:

1
#include <Arduino.h>
2
#include "user_interface.h"
3

4

5
float helligkeit = 0;
6
bool Taster1 = false;
7
bool Taster2 = false;
8

9
int helligkeitsschwelle = 950;
10
int dunkelschwelle = 970; //750
11
int currentTime = 0;
12
int LaufzeitHoch = 20;  //Laufzeit *0.01s = tatsächliche Laufzeit  //255 Runter
13
int LaufzeitRunter = 295;                                           //295 Hoch
14
int Schlafzeit = 5; //in Sekunden
15
int i = 0;
16
static int state = 0;    // 0 ist zu, 1 ist offen
17
byte statebyte;
18
byte rtcStore[1];
19

20
void setup() {
21
  // put your setup code here, to run once:
22
  Serial.begin(9600);
23
  system_rtc_mem_read(64, rtcStore, 1);
24
  state = (int)rtcStore[0];
25

26
  pinMode(D1, INPUT_PULLUP);  // AUF
27
  pinMode(D2, INPUT_PULLUP);  // ZU
28
  pinMode(D5, OUTPUT);        //Eingang 1
29
  pinMode(D6, OUTPUT);        //Eingang 2
30
  pinMode(D7, OUTPUT);        //Eingang 3
31
  pinMode(D8, OUTPUT);        //Eingang 4
32

33
  // digitalWrite(D5,LOW);
34
  // digitalWrite(D6,LOW);
35
  // digitalWrite(D7,LOW);
36
  // digitalWrite(D8,LOW);
37
  
38

39
}
40

41
void startDeepSleep(){
42
  Serial.println("Going to deep sleep...");
43
  ESP.deepSleep(Schlafzeit * 1000000);
44
  yield();
45
}
46

47
void MotorAus() {
48
  digitalWrite(D5, LOW);
49
  digitalWrite(D6, LOW);
50
  currentTime = 0;
51
}
52

53
void KlappeRunter() {
54
  if(state != 1) {
55
    Serial.print("Motor auf \n");
56
    while(currentTime < LaufzeitRunter) {
57
      digitalWrite(D5, HIGH);
58
      digitalWrite(D6, LOW);
59
      currentTime += 1;
60
      delay(10);
61
      }
62
    state = 1;
63
    rtcStore[0] = (byte)1;    //Abspeichern der Tür offen Position
64
    system_rtc_mem_write(64, rtcStore, 1);  //Schreiben in den permanenten Speicherbereich
65
    MotorAus();
66
  }
67
  
68
}
69

70
void KlappeRauf() {
71
  if(state != 0) {
72
   Serial.print("Motor zu \n");
73
    while(currentTime < LaufzeitHoch) {
74
      digitalWrite(D5, LOW);
75
      digitalWrite(D6, HIGH);
76
      currentTime += 1;
77
      delay(10);
78
      }
79
    state = 0;
80
    rtcStore[0] = (byte)0;
81
    system_rtc_mem_write(64, rtcStore, 1);
82
    MotorAus();
83
  }
84
  
85
}
86

87
void loop() {
88

89
  for(i = 0; i<5; i++) {
90
    helligkeit += analogRead(A0);
91
  }
92
  helligkeit = helligkeit/5;
93
 
94
  Taster1 = digitalRead(D1);    //Gedrückt == 0
95
  Taster2 = digitalRead(D2);
96

97

98

99
  // put your main code here, to run repeatedly:
100
  Serial.print("\n");
101
  Serial.print("\n");
102
  Serial.print(helligkeit);  //*0.003125
103
  Serial.print("\n");
104
  Serial.print("Status: ");
105
  Serial.print(state);
106
  Serial.print("\n");
107
  Serial.print(Taster1);
108
  Serial.print(" , ");
109
  Serial.print(Taster2);
110
  Serial.print("\n");
111

112

113
  if( (Taster1 && Taster2) && (round(helligkeit) < helligkeitsschwelle)) { 
114
    KlappeRunter();
115
  }
116
  else if((Taster1 && Taster2) && (round(helligkeit) > dunkelschwelle)) { 
117
    KlappeRauf();
118
  }
119
  else if(!Taster1 && Taster2) {
120
    KlappeRauf();
121
  }
122
  else if(Taster1 && !Taster2) {
123
    KlappeRunter();
124
  }
125

126
  // if(!Taster1 || (round(helligkeit) < helligkeitsschwelle)) {  //|| (helligkeit < helligkeitsschwelle)
127
  //   MotorLinks();
128
  // }
129
  // else if(!Taster2 || (round(helligkeit) > dunkelschwelle)) {  //|| (helligkeit > dunkelschwelle)
130
  //   MotorRechts();
131
  // }
132
  
133
 
134
  MotorAus();
135
  
136
  //delay(5000);
137
  startDeepSleep();
138
}
#7434304
Lesenswert?

Da hier keiner antwortet versuch ich es mal.

Interrupt-Pins

1
#define INTERRUPT_PIN_1 D1
2
#define INTERRUPT_PIN_2 D2

globale Variablen um den Zustand der Schalter zu speichern und die Interrupt-Flags zu aktivieren

1
volatile bool interruptTriggered = false;
2
volatile bool switch1Pressed = false;
3
volatile bool switch2Pressed = false;

Interrupt-Service-Routine (ISR)

1
void switchInterrupt() {
2
  switch1Pressed = digitalRead(INTERRUPT_PIN_1) == LOW;
3
  switch2Pressed = digitalRead(INTERRUPT_PIN_2) == LOW;
4
  interruptTriggered = true;
5
}

Interrupts konfigurieren

1
void setup() {
2
  // ...
3
  pinMode(INTERRUPT_PIN_1, INPUT_PULLUP);
4
  pinMode(INTERRUPT_PIN_2, INPUT_PULLUP);
5

6
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN_1), switchInterrupt, CHANGE);
7
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN_2), switchInterrupt, CHANGE);
8
}

Interrupt-Trigger lesen

1
void loop() {
2
  // ...
3

4
  if (interruptTriggered) {
5
    detachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN_1));
6
    detachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN_2));
7

8
    if (switch1Pressed && switch2Pressed) {
9
      KlappeRunter();
10
    } else if (switch1Pressed) {
11
      KlappeRauf();
12
    } else if (switch2Pressed) {
13
      KlappeRunter();
14
    }
15

16
    switch1Pressed = false;
17
    switch2Pressed = false;
18
    interruptTriggered = false;
19

20
    attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN_1), switchInterrupt, CHANGE);
21
    attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN_2), switchInterrupt, CHANGE);
22
  }
23

24
  // ...
25
}

edit: funktioniert nicht. Interrupts scheinen nicht zu laufen im sleep Modus.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren