Forum: Mikrocontroller und Digitale Elektronik Einschaltautomatik Esp8266


von Simon O. (mola-4-speed)



Lesenswert?

Hallo,

Ich versuche mir gerade für meine Werkstatt eine Einschaltautomatik für 
die Gerätesteckdosen zu basteln.

Das Ziel in Schritten:
1. Gerät an -> Stromsensor (Acs758): Erkennt den Stromfluss.
2. Schalterposition -> ESP8266 (D1 Mini #1): Liest Position 
aus(AN/AUTO/Aus)
3. Sperrschieber auf -> Servo (MG995): Dreht sich um 180 grad.
4. D1 Mini #1 Post an -> Raspi Zero(MQTT Broker)
5. D1 Mini #2 Subscribe von -> Raspi Zero(MQTT Broker)
6. D1 Mini #2 Relais An
7. Relais schaltet Staubsauger Schütz an.

Bis jetzt habe ich die Schritte einzelnen hinbekommen, jedoch bin ich 
beim Versuch mit dem ESP8266 das Analoge Signal vom ACS758 abzufragen 
und gleichzeitig die WLAN Kommunikation mit dem Broker 
aufrechtzuerhalten gescheitert. Das scheint ein typisches Problem des 
ESPs zu sein, welches mit grösseren Abfrageintervallen zu lösen sein 
soll oder mit ab/an-schalten des Wlans - Was ich aber nach zahlreichen 
Versuchen nicht geschafft habe. Daraufhin entschied ich mich den ACS758 
nicht direkt an dem AO vom ESP8266 anzuschliessen, sondern über einen 
ADC(GY-MCP3421 18-Kanal Analog-Digital-Wandler) an die SCL/SDA vom ESP 
anzuschliessen.

Hier nun meine Fragen:
1.) Kann ich den Stromsensor(Acs758) über den ADC (MCP3421) auslesen?
2.) Gibt Verbesserungsvorschläge oder Anregungen :-)?

Liebe Grüsse aus dem Süden und Danke für eure Mühe.
Simon

von my2ct (Gast)


Lesenswert?

Simon O. schrieb:
> Hier nun meine Fragen:
> 1.) Kann ich den Stromsensor(Acs758) über den ADC (MCP3421) auslesen?

Da du hier die Frage stellt, scheinst du es nicht zu können ;-)

Ein 18-Bit ADC mag etwas überzogen sein, aber warum nicht.
Und der ACD758 scheint abgekündigt zu sein, was natürlich bei einem 
Einzelprojekt kein Hindernis sein muss. Ob der allerdings für dein 
Vorhaben geeignet ist, hängt von der Sensorvariante und dem 
auszuwertenden Strom ab.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Simon O. schrieb:
> 7. Relais schaltet Staubsauger Schütz an.
Was für ein absurd hoher Aufwand.

> 1. Gerät an -> Stromsensor (Acs758): Erkennt den Stromfluss.
Nein, der "erkennt" keinen Stromfluss, sondern er wandelt einen Strom in 
eine entsprechende Spannung um.

> Daraufhin entschied ich mich den ACS758 nicht direkt an dem AO vom ESP8266
> anzuschliessen, sondern über einen ADC(GY-MCP3421 18-Kanal Analog-Digital-
> Wandler) an die SCL/SDA vom ESP anzuschliessen.
Was sollte das bringen?

> 18-Kanal Analog-Digital- Wandler
18-Kanal-Wandler bedeutet, dass du 18 Analogsignale daran anschließen 
kannst. Aber es ist zum Glück nur ein 18-Bit-Wnalder, von dem du mit 
deinem aufbau gleich mal 7-8 Bit vergessen kanst.

> jedoch bin ich beim Versuch mit dem ESP8266 das Analoge Signal vom ACS758
> abzufragen und gleichzeitig die WLAN Kommunikation mit dem Broker
> aufrechtzuerhalten gescheitert.
Funktioniert der ganze Klimbim, wenn du das für die Aufgabe völlig 
unnötige WLAN samt der ebenso unnötigen Schritte 4..6 erst mal weglässt?

von Stefan F. (Gast)


Lesenswert?

Simon O. schrieb:
> Kann ich den Stromsensor(Acs758) über den ADC (MCP3421) auslesen?

Wenn du das kannst, dann kannst du es. Du musst halt den MCP3421 
entsprechend ansteuern.

> Das scheint ein typisches Problem des ESPs zu sein, welches mit
> a) grösseren Abfrageintervallen zu lösen sein soll oder mit
> b) ab/an-schalten des Wlans
> Was ich aber nach zahlreichen Versuchen nicht geschafft habe.

Was hast du nicht hinbekommen? a oder b? Woran hat es gescheitert? Fehlt 
dir Doku? War es nicht compilierbar, hat es nicht funktioniert?

von Simon O. (mola-4-speed)


Lesenswert?

Oh jeee.. Scheint als müsse ich noch viel nachbessern... :-(

my2ct schrieb:
> Ein 18-Bit ADC mag etwas überzogen sein, aber warum nicht.
> Und der ACD758 scheint abgekündigt zu sein, was natürlich bei einem
> Einzelprojekt kein Hindernis sein muss. Ob der allerdings für dein
> Vorhaben geeignet ist, hängt von der Sensorvariante und dem
> auszuwertenden Strom ab.

Der "18-Bit ADC" war eine "See and Buy" Entscheidung. Mit ging es nur um 
einen ADC mit einem Kanal. Was würdest du als Alternative vorschlagen?
Was meinst du mit "abgekündigt"? Der Stromsensor Acs758 muss bis zu 230v 
20A erkennen. Ich wollte lieber "Gross" gehen als mit einem "kleinen" 
ACS712.

Lothar M. schrieb:
>> 7. Relais schaltet Staubsauger Schütz an.
> Was für ein absurd hoher Aufwand.

Ich habe ein Relais-Modul zum aufsetzen auf den ESP gewählt und der kann 
nur 250v 10A schalten. Grundsätzlich habe ich vor >5V mit hohen 
Leistungen mit Installationsgeräte zu steuern. So kann ich auch eine 
Absauganlage mit 400v 1000W anschliessen.

Lothar M. schrieb:
> Funktioniert der ganze Klimbim, wenn du das für die Aufgabe völlig
> unnötige WLAN samt der ebenso unnötigen Schritte 4..6 erst mal weglässt?

Ja... Der "Klimbim" funktioniert ohne Wlan. Sobald ich die Zeile: 
"WiFi.begin(WLAN, PASSWD);" auskommentiere kann ich im Seriellen Monitor 
die Resultate aus dem Acs758 ausgeben.
Um die gewünschte Folge(Staubsauger AN) aus diesen Daten dem Staubsauger 
zu schicken würde ich gerne das WLAN nützen also entsteht hier der 
Konflikt.

Stefan ⛄ F. schrieb:
> Wenn du das kannst, dann kannst du es. Du musst halt den MCP3421
> entsprechend ansteuern.

... und das wäre? Hättest du mir ein Beispiel?

Stefan ⛄ F. schrieb:
> Was hast du nicht hinbekommen? a oder b? Woran hat es gescheitert? Fehlt
> dir Doku? War es nicht compilierbar, hat es nicht funktioniert?

Ich habe beides hinbekommen, jedoch bleiben die Probleme unverändert:
- Wlan Aus -> Im Seriellen Monitor sehe ich ob Strom durch P+/P- des 
Stromsensors(Acs758) fliesst.
- Wlan An -> Im Seriellen Monitor ist nicht eindeutig zu erkennen ob 
Strom durch den Stromsensor(Acs758) fliesst. Verändere ich die 
Abfrageintervalle durch "delay()" oder "while(millis()...)" beleibt das 
Problem bestehen.
Wenn ich das Wlan ausschalte bis ein Stromfluss zu erkennen ist und in 
dem Fall die Verbindung herstellen will, bin ich unter Umständen schon 
mit meiner Arbeit fertig.

Es scheint als Arbeiteten A0 und WLan beim ESP8266 in der selben Küche 
und da hat bekanntlich nur einer das Sagen. Deswegen mein Ansatz, dem 
Analoge Konverter eine eigene Küche zu geben.

von Stefan F. (Gast)


Lesenswert?

Simon O. schrieb:
> Hättest du mir ein Beispiel?

Nein habe ich nicht. Aber im Datenblatt scheinen alle nötigen Infos über 
die I²C Kommunikation drin zu stehen. Sieht nicht komplizierter aus, als 
bei anderen ADC.

von Brain 2.0 (Gast)


Lesenswert?

Simon O. schrieb:
> Es scheint als Arbeiteten A0 und WLan beim ESP8266 in der selben Küche
> und da hat bekanntlich nur einer das Sagen. Deswegen mein Ansatz, dem
> Analoge Konverter eine eigene Küche zu geben

Das ist Quatsch. Beides kann zusammen arbeiten, wenn du es richtig 
machst.
Aber das da noch reichlich Basiswissen fehlt,  sieht man an den 
Schaltbildern.
Wie bekommst du 230V AC aus einer 9Volt Batterie ?

von Stefan F. (Gast)


Lesenswert?

Simon O. schrieb:
> Ich habe ein Relais-Modul zum aufsetzen auf den ESP
> gewählt und der kann nur 250v 10A schalten.

Meistens sind da Relais drauf, die nicht die VDE Anforderungen nach 
2500V Isolation für mobile Geräte bzw 4000V für Fest-Installierte Geräte 
erfüllen.

Hast du wenigstens bedacht dass Schütze beträchtliche Impulse beim 
Abschalten erzeugen? Du brauchst Snubber wenn die Relais länger als 3 
Monate halten sollen.

Man kann des ADC des ESP durchaus mit aktiviertem WLAN nutzen. Nur musst 
du halt zwischen den Abfragen Pausen einfügen. Permanent in 
Endlosschleife geht nicht, aber 1x alle 100ms durchaus. Wenn das bei dir 
nicht geht hast du noch irgendwo anders einen Fehler. kennst du das?: 
http://stefanfrings.de/esp8266/index.html#fallstricke

Deine beiden 10kΩ Widerstände sehe ich skeptisch, reduziere sie besser 
auf 2,2kΩ damit nicht das eigene Funksignal des ESP Störungen auslöst.

Beim Wemos D1 Mini macht es Sinn, einen 100µF Elko nachzurüsten, und 
zwar direkt an den VCC/GND Anschlüssen des ESP Moduls.

Das 3W Netzteil reicht so gerade eben aus, um das Wemos D1 Board und den 
ADC zu versorgen. Aber ich sehe da noch einen Servo Motor. Das ist zu 
viel. Bedenke dass das Wemos D1 Board bereits ein für 500mA ausgelegtes 
Netzteil braucht. Die Stromaufnahme des Servos kommt noch oben drauf. Da 
das ein besonders schneller und starker Servo ist würde ich dafür 
mindestens weitere 3A einplanen (besser nachmessen). Manche brauchen 
noch mehr.

Steckbretter und Dupont Kabel eignen sich nicht, um Servos und ESP 
Boards zu versorgen. Zu hohe Kontakt- und Leitungswiderstände.

von Prokrastinator (Gast)


Lesenswert?

Simon O. schrieb:
> Was meinst du mit "abgekündigt"?

Der Hersteller sagt das er das Teil nicht mehr produzieren wird und nur 
noch Restbestände abverkauft werden.

von Simon O. (mola-4-speed)


Lesenswert?

Stefan ⛄ F. schrieb:
Vielen lieben Dank für die Konstruktiven Hinweise. Die werde ich zeitnah 
umsetzen.

Stefan ⛄ F. schrieb:
> Man kann des ADC des ESP durchaus mit aktiviertem WLAN nutzen. Nur musst
> du halt zwischen den Abfragen Pausen einfügen. Permanent in
> Endlosschleife geht nicht, aber 1x alle 100ms durchaus. Wenn das bei dir
> nicht geht hast du noch irgendwo anders einen Fehler. kennst du das?:
> http://stefanfrings.de/esp8266/index.html#fallstricke

So sieht mein Code aus:
1
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
2
//---------------- LIBRARIES ---------------------------------------
3
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
4
5
#include <stdio.h>
6
#include <SPI.h>
7
#include <ESP8266WiFi.h>    // Enables the ESP8266 to connect to the local network (via WiFi)
8
9
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
10
//---------------- GPIO BELEGUNG, VARIABLEN & KONSTANTEN -----------
11
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
12
13
//____________________ KONSTANTEN _____________________
14
//**** NETZWERK UND SERVER ****
15
#define WLAN          "**************"
16
#define PASSWD        "**************"
17
18
//**** STROMSENSOR ****
19
#define MEASURED_VCC        4.69    // IMPORTANT: You must measure the power supply
20
#define ACS758_SENSITIVITY  40e-3   // 40mV per AMP
21
#define ACS758_NOISE        10e-3   // 10mV noise
22
#define ACS758_OFFSET_LIM   35e-3   // +/-35mV Max offset.
23
#define MAINS_VOLTS_RMS     240     // 240 or 120 Usually.
24
#define V_PER_LSB           (MEASURED_VCC/1024.0)
25
#define ACS758_NOISE_LSB    (ACS758_NOISE/V_PER_LSB) // Noise in LSBs
26
27
#define MIN_LSB             (ACS758_NOISE_LSB*1.5) // Ignore system noise
28
29
// ACS758 Starts at Vcc/2
30
static int offset = 512; // Calculated at start.
31
32
//____________________ GLOBALE VARIABLEN ____________________
33
byte Sens_Stromsensor[] = {0, 0}; // {neu,alt}    // Stromsensor
34
35
//******************************************************************
36
//----------------  SETUP ------------------------------------------
37
//******************************************************************
38
void setup()
39
  {  
40
  //__________ Serial __________
41
  Serial.begin(9600);   // Serial Monitor
42
  delay(500);           // kurze Pause um Serielle Schnittstelle zu öffenen
43
44
  //__________ WIFI __________
45
  Serial.println("------------------WIFI------------------");
46
  SetupClient();        // Setup device als Client
47
 
48
  //__________ STROMSENSOR ACS758 __________
49
  Serial.println("------------------STROMSENSOR ACS758------------------"); 
50
  offset = Get_offset();
51
  Serial.print("Offset: ");       Serial.println(offset);   Serial.println("");
52
  }
53
54
//******************************************************************
55
//---------------- LOOP --------------------------------------------
56
//******************************************************************
57
58
void loop()
59
  {
60
  static unsigned long update_zeit_war = millis();
61
  if(millis()-update_zeit_war > 100)   // 100 msec. update rate.
62
    { 
63
    update_zeit_war = millis();
64
    StromsensorAuslesen();
65
    }
66
  }
67
68
//------------------------------------------------------------------
69
//---------------- WIFI - Client (Setup) ---------------------------
70
//------------------------------------------------------------------
71
void SetupClient()
72
  {
73
  WiFi.begin(WLAN, PASSWD);             // connects to the WiFi router
74
  while(WiFi.status() != WL_CONNECTED)
75
    {
76
    Serial.print(".");
77
    delay(500);
78
    }
79
  Serial.println("Connected to wifi");   
80
  }
81
82
//------------------------------------------------------------------
83
//---------------- Stromsensor -------------------------------------
84
//------------------------------------------------------------------
85
void StromsensorAuslesen()
86
  {
87
  byte amps = 0;
88
     
89
  static unsigned long update_time_was = millis();
90
  static float nmax=0, nmin=0, rmax=0, rmin=0, y=offset, w=0.4;
91
  int a0;
92
93
  a0 = analogRead(A0);    // Don't remove offset.
94
  delay(1);               // Let analogue settle.
95
96
  // Recursive averaging.
97
  // Used to detet low level signal in noise.
98
  y = w*a0 + (1-w)*y;
99
100
  if (nmax < a0) nmax = a0;   // No averaging.
101
  if (nmin > a0) nmin = a0;   // No averaging.
102
  if (rmax < y)  rmax = y;    // Recursive averaging.
103
  if (rmin > y)  rmin = y;    // Recursive averaging.
104
105
  if(millis()-update_time_was > 1000)   // 1 sec. update rate.
106
    { 
107
    update_time_was = millis();
108
    
109
    // No averaging.
110
    int __max  = nmax;
111
    int __min  = nmin;
112
    nmax = offset;
113
    nmin = offset;
114
  
115
    // Recursive averaging.
116
    int _rmax = rmax;
117
    int _rmin = rmin;
118
    rmax = offset;
119
    rmin = offset;
120
  
121
    float navgIpeak = ((__max-__min)/2 * V_PER_LSB) / ACS758_SENSITIVITY;
122
    float navgIrms  = navgIpeak/sqrt(2);
123
    float navgPower = navgIrms * MAINS_VOLTS_RMS;
124
  
125
    // Output
126
    if(_rmax-_rmin > MIN_LSB)   // Ignore too low
127
      {  
128
      Serial.println("\n------");
129
      Serial.print(" max");           Serial.println(__max);
130
      Serial.print(" min");           Serial.println(__min);
131
      Serial.print(" Peak Current "); Serial.print(navgIpeak);
132
      Serial.print("A\n Power ");     Serial.print(navgPower);
133
      Serial.println("W");
134
      
135
      
136
      amps = navgPower;
137
      }
138
    else
139
      {
140
      Serial.println("Too low");
141
      amps = 0;
142
      }
143
    }
144
 // return amps;
145
  }
146
147
//------------------------------------------------------------------
148
//---------------- ACS758 Offset -----------------------------------
149
//------------------------------------------------------------------
150
int Get_offset()                  // Returns offset = average value.
151
  {
152
  long avg=0;
153
  for(int i=0; i<200; i++)
154
    {
155
    avg += analogRead(A0);
156
    delay(1);   // Let analogue settle.
157
    }
158
  return avg/200;
159
  }
160
161
162
//------------------------------------------------------------------
163
//----------------  ACS758 Assign_max_min --------------------------
164
//------------------------------------------------------------------
165
void Assign_max_min(float val, float *pmax, float *pmin)  // Store max min
166
  {
167
  if (*pmax < val) *pmax = val;
168
  if (*pmin > val) *pmin = val;
169
  }
170
171
//-----------------------------------------------------------------

von Stefan F. (Gast)


Lesenswert?

In Get_offset() rufst du den ADC ganze 200 mal mit nur 1ms Abstand auf. 
Ich weiß nicht wo die kritische Grenze ist aber diese Stelle würde ich 
auf jeden Fall ändern.

Zu dem frage ich mich, warum du dort aus 200 Messwerten den Mittelwert 
bildest. Welche technische Unzulänglichkeit willst du dahinter 
verbergen?

Ich würde eher einen R/C Tiefpass vor den ADC Schalten. Probleme löst 
man besser dort wo sie her kommen, nicht dort wo sie sich auswirken.

Rechne mal zusammen, wie viel Zeit deine printf() Ausgaben in der loop() 
brauchen. Ich komme grob geschätzt auf 40ms. Dazu kommt jede Menge 
Fließkomma-Arithmetik.

Der Punkt ist: Jeder einzelne Durchlauf von loop() soll maximal 20ms 
dauern. Sonst riskiert du, dass WLAN ausfällt oder der Watchdog einen 
Reset macht. Das steht in meinem "Fallstricke" Absatz und kommt 
letztendlich nicht von mir sondern von den Autoren des Arduino Cores.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.