Forum: Mikrocontroller und Digitale Elektronik ESP32: Konstante Abtastrate / Timing des ADC


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Christian B. (bastlerbire)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen!

ich habe einige allgemeine Fragen bezüglich des ADC des ESP32, bzw. zur 
korrekten Umsetzung des Timings für drei analoge Eingangskanäle mit dem 
ESP32. Ich würde mit Euch gerne einmal darüber diskutieren.

Folgende Applikation: Prinzipiell möchte ich "nur" drei Eingangskanäle 
zeitgleich abtasten. An diesen drei Kanälen hängt jeweils ein 
Stromsensor 
https://www.watterott.com/de/Wechselstrom-Messwandler-30A-max mit einem 
Ausgang von 0-1 Volt. Diese Signale sollen mit dem ADC des ESP erfasst 
werden.

Da ich mit dem o.g. Sensor den Strom erfassen möchte, um diesen zur 
Zustandsüberwachung einzusetzen, würde ich gerne äquidistant abgetastete 
Sensorwerte erhalten. Mit einem Arduino habe ich schon einmal 
hinbekommen, dass ich eine konstante Samplerate des ADC erhalten kann. 
Leider weiß ich nicht, wie ich das auf den ESP32 übertragen kann und 
auch die Dokumentation zum ESP32 sind für mich als Fachfremder zu 
dürftig um darauf aufzubauen. Vielleicht frägt nun jemand: Ja, warum 
nimmt er den ESP dann...Gute Frage: Der Grund ist, dass hier die direkte 
Verbindung dreier Analogsignale zum Internet möglich ist und der Bauraum 
eine Rolle spielt...

Jetzt meine konkrete Frage: Hat hier schon jemand Erfahrung, wie ich mit 
einem ESP32 die Werte direkt vom ADC holen kann? Es existieren in der 
Dokumentation (unter 
https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-adc.c) 
Funktionen, die ich vermutlich nutzen kann/muss:
1
bool bool IRAM_ATTR __adcStart(uint8_t pin){
2
bool IRAM_ATTR __adcBusy(uint8_t pin){
3
uint16_t IRAM_ATTR __adcEnd(uint8_t pin)

Nur habe ich -offen gestanden- aber keine Ahnung, wie ich das sauber und 
korrekt in meine loop-Funktion einbauen kann. Vielleich hat mir jemand 
einen Hinweis oder das schon einmal in ähnlicher Form gemacht. Mir ist 
wichtig, dass ich verstehe, was dahintersteckt, den Rest bekomme ich 
hin, denke ich...

Ein alternativer Ansatz wäre vielleicht, dass ich einen Interrupt nutze 
um die drei Kanäle zu erfassen. Aber auch hier fehlt mir die 
Erfahrung...Wäre es z.B. möglich, in
1
IRAM_ATTR onTimer() {

einfach bei jedem Interrupt (entsprechend meiner Samplingfrequenz) einen 
Counter hochzuzählen, der dann in meiner loop()-Schleife detektiert 
wird? In dem Moment, in dem der Interrupt kommt, werden dann meine drei 
Kanäle eingelesen:
1
sampleI1 = analogRead(inPinI1);   //phase1
2
sampleI2 = analogRead(inPinI2);   //phase2
3
sampleI3 = analogRead(inPinI3);   //phase3

Wenn ich mir hier das Timing mal anschaue und die Zeiten "messe" die für 
die drei analogRead-Aufrufe benötigt werden und dann einen gewissen 
Zeitpuffer bei meiner Abtastrate einstelle, wäre das ein Ansatz? Hier 
ist sicherlich ein kleiner Fehler drin, denn zwischen den 
analogRead-Aufrufen verstreicht ja auch Zeit und ich möchte ja 
prinzipiell alle Samples zu einem Zeitpunkt...?!

Unter http://technik-fan.de/index.php/Open_Energy_Monitor_mit_dem_ESP32 
existiert ein Beispiel, exakt von meiner Applikation. Nur bin ich mir 
nicht sicher, ob das hier mit dem Timing passt, da die drei Kanäle 
"einfach" hintereinander mittels analogRead eingelesen werden. Ausserdem 
kommt mir in dem Sketch das delay(0.00002) komisch vor... Vielleicht bin 
ich aber auch falsch und kann das 1:1 übernehmen. Prinzipiell kann ich 
das ja nutzen, wenn ich hier eine saubere Lösung für die Abfrage der 3 
Kanäle über analogRead() habe. Eine Einschätzung Eurerseits wäre 
wirklich super.

Vielleicht noch einmal zusammengefasst: Ich benötige für einen ESP32 
eine Möglichkeit, um drei Kanäle zeitäquidistant abzutasten und die 
Samples jeweils zu einem Zeitpunkt zu dokumentieren.

Vielleicht hat hier jemand eine Idee, wie ich das mit dem ESP32 machen 
kann oder etwas ähnliches schon einmal gemacht.

Ich würde mich über einen Denkanstoß sehr freuen.

Vielen Dank schon einmal und viele Grüße

Christian

von c r (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich sehe dein konkretes Problem nicht... Probier's doch einfach Mal aus, 
eine Netzperiode ist eine Ewigkeit für jeden uC.
Da ist "gleichzeitig" ein dehnbarer Begriff.

von Christian B. (bastlerbire)


Bewertung
0 lesenswert
nicht lesenswert
Hallo c r,

danke für Deinen schnellen Hinweis! Ja, das werde ich tun. Die Sensoren 
sind schon da. Heute sollte der Rest der Schaltung kommen. 
Sepbstverständlich werde ich das auch einmal 1:1 ausprobieren und wenn 
es für meine Genauigkeitsanforderungen reicht, auch übernehmen.

Um Deine Frage zu beantworten: Mein konkretes Problem ist, dass ich 
gerne verstehe, wie etwas funktioniert und mir bei den bisherigen 
Ansätzen nicht klar war, wie das mit dem Timing ist - aus meiner Sicht 
muss das alles parallel laufen - prinzipiell auch die Spannungswerte 
(wenn man die Leistung berechnen will, was ich aber nicht benötige). 
Ausserdem habe ich bevor ich richtig loslege das Konzept schon gerne 
vorab festegelet - wenigstens im Groben.

Aber ich werde das in jedem Fall testen! Danke Dir!

Viele Grüße

Christian

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Christian B. schrieb:
> Folgende Applikation: Prinzipiell möchte ich "nur" drei Eingangskanäle
> zeitgleich abtasten.

Du hast EINEN ADC und DREI Eingangskanäle. Wie willst du die wirklich 
zeitgleich abtasten, wenn du nicht für jeden Kanal einen eigenen 
Sample&Hold davor setzt?

c r schrieb:
> … eine Netzperiode ist eine Ewigkeit für jeden uC.

Das setzt voraus, das keine höherfrequenten Pulslasten dran hängen bzw. 
der Stromsensor nur den niederfrequenten Signalanteil wandelt.

von Michael U. (amiga)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

beim ESP32 ist da noch vieles in Arbeit. Für ADC und I2S habe ich bei 
Espressif irgendwo inzwischen ein Beispiel gesehen, es sollen bis 
320kSample (verteilt auf die 18 möglichen Kanäle) möglich sein.
Ist für mich im Moment aber etwas zu tief in den Innereien des ESP32-IDF 
um das auf Anhieb komplett zu verstehen.
Nur als Beispiellink:
https://esp32.com/viewtopic.php?t=2346

Gruß aus Berlin
Michael

von Christian B. (bastlerbire)


Bewertung
0 lesenswert
nicht lesenswert
Hallo Wolfgang & Michael U.!

Danke für Euer Feedback - ich schau mir Deinen Link Michael nachher mal 
an. Wenn ich es auf die Schnelle richtig gesehen haben, kann man den ADC 
wohl irgendwie mit der I2S-Schnittstelle koppeln und die Ergebnisse 
(Samples) dann damit auslesen...Liege ich da richtig?

In einem weiteren Link 
(https://www.esp32.com/viewtopic.php?f=2&t=1075&sid=6852840cd3df775dfc0c6feb85bfa932&start=20) 
habe ich aber auch schon gelesen, dass man sich darauf aber auch nicht 
verlassen kann...

Was wäre, wenn mich das jetzt alles abschrecken würde?

Eine Alternative wäre es ja, die Werte mit einem stabilen ADC, z.B. auf 
einem Arduino zu erfassen und dann an einen ESP32 / 8266 zu schicken, um 
diese dann hier via Wifi wegzuschicken und zu visualisieren...Habt Ihr 
so etwas schon einmal gemacht, bzw. meint Ihr, das wäre zielführender?

Vielen Dank für Euren Einsatz und Eure Zeit

Christian

von Michael U. (amiga)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Christian B. schrieb:
> Was wäre, wenn mich das jetzt alles abschrecken würde?

einfache Antwort? Dert ESP32 ist eigentlich ein geniales und preiswertes 
Stück Silizium. Es gibt aber noch viele Baustellen im Zusammenspiel auch 
im Espressif IDF. Ich würde ihn (noch nicht?) für wirklich Wichtiges 
einsetzen wollen...

Such Dir einen oder eben 3 externe ADC, hänge die an einen ESP8266 per 
I2C oder SPI. Den ESP8266 bekommt man auch im WLAN stabil, obwohl ich 
auch da kein Freund "eierlegender Wollmilch-Säue" als Softwarebaukasten 
bin, sondern eher minimalistisch auf die konkrete Anwendung bezogen 
programmiere.
Alles aus der ArduinoIDE, ich habe zwar das Espressiv-IDF hier auf dem 
Rechner, aber keine Lust, da die Zeit in Details zu investieren.

Du kannst auch einen Arduino messen lassen, wenn Du da was hast und die 
Daten dann zum ESP schicken. Die originale AT-Software des ESP nutze ich 
slebst nicht, die ESP bekommen eigenen Software. Datenaustausch fast 
immer mit einem simplen seriellen Protokoll, I2C ist auf einem ESP8266 
als Slave wohl nicht zu empfehlen, SPI wäre kein Problem.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Cornelius (Gast)


Bewertung
0 lesenswert
nicht lesenswert
>Folgende Applikation: Prinzipiell möchte ich "nur" drei Eingangskanäle
>zeitgleich abtasten. An diesen drei Kanälen hängt jeweils ein
>Stromsensor

Wenn Du die drei analogRead hintereinanderschreibst, hast Du einen 
Zeitversatz von ca. 5us zwischen den Abtastungen.

50Hz Netzfrequenz sind 20ms. Dazwischen ist der Faktor 4000. Sollte das 
nicht für Deine Genauigkeit reichen?

von Christian B. (bastlerbire)


Bewertung
0 lesenswert
nicht lesenswert
Hallo Miachel, hallo Cornelius,

vielen Dank für Eure Antworten!

@Cornelius: ja, prinzipiell reicht das aus. Wichtiger ist -denke ich- 
dass die Zeitpunkte, zu denen ich die Werte abhole, ja auch um eine Zeit 
(< 5µs) verschoben sind. Hier würde ich bei diesem Ansatz eine Methodik 
benötigen, die quasi auf die Beendigung der ADC-Wandlung warte oder so 
Ähnlich. Wobei auch hier ein Problem vorherrscht:

Wolfgang schrieb:
> Du hast EINEN ADC und DREI Eingangskanäle. Wie willst du die wirklich
> zeitgleich abtasten, wenn du nicht für jeden Kanal einen eigenen
> Sample&Hold davor setzt?

Da muss man wohl auch noch eine Sample&Hold-Schaltung davor setzen. Hier 
muss ich aber auch noch einmal recherchieren.

@Michael:

Du hast geschrieben:
Michael U. schrieb:
> Datenaustausch fast
> immer mit einem simplen seriellen Protokoll, I2C ist auf einem ESP8266
> als Slave wohl nicht zu empfehlen, SPI wäre kein Problem.

Ich habe mich mal mit dem Thema SPI und Verbindung Arduino / ESP8266 
auseinandergesetzt. Grundsätzlich scheint das "kein Problem" zu sein. 
Was mir allerdings nicht ganz klar ist: Bei den meisten Beispiel ist der 
ESP der "Master" und der Arduino der "Slave". Müsste es nicht andersrum 
sein: Der Arduino, der schnell abtastet und nach gewissen Zeitabständen, 
z.B. wenn eine vorgegebene Zahl an Samples erreicht ist, diese zum Slave 
schickt, wo sie dann weggeschickt werden...? Hast Du so etwas schon 
einmal umgesetzt?

Euch beiden vielen Dank!

Grüße

Christian

von Michael U. (amiga)


Bewertung
0 lesenswert
nicht lesenswert
Christian B. schrieb:
> Ich habe mich mal mit dem Thema SPI und Verbindung Arduino / ESP8266
> auseinandergesetzt. Grundsätzlich scheint das "kein Problem" zu sein.
> Was mir allerdings nicht ganz klar ist: Bei den meisten Beispiel ist der
> ESP der "Master" und der Arduino der "Slave". Müsste es nicht andersrum
> sein: Der Arduino, der schnell abtastet und nach gewissen Zeitabständen,
> z.B. wenn eine vorgegebene Zahl an Samples erreicht ist, diese zum Slave
> schickt, wo sie dann weggeschickt werden...? Hast Du so etwas schon
> einmal umgesetzt?

Als Ansatz: Seriell - der Arduino schickt die Daten einfach mit 
Serial.write() o.ä. raus, wenn er welche hat. Der ESP fragt in der 
loop() mit Serial.available() ab, ob Daten da sind. Wenn ja, dann 
entweder mit Serial.readBytes(buffer, length) die erwartete Anzahl Bytes 
einlesen oder mit Serial.readBytesUntil() bis zu einem festen 
Endezeichen. Das hängt davon ab, in welchem Format Du die Daten 
rüberschickst.
Deine 3 Werte sollten ja in jedem Fall in die Buffer von Serial passen, 
Du kannst also durchaus auch 250kBaud als Baudrate setzen, der AVR kommt 
damit klar und die Übertragung ist entsprechend schnell beendet.
Der Mega328 schafft es zwar nicht, das auszureizen, der UART kann es 
aber und es gibt keine zusätzlichen Wartezeiten bis der UART das Byte 
rausgeschoben hat.
Wenn Du einen 5V Arduino nimmst, denke an die Pegel. TX vom ESP erkennt 
der AVR eigentlich immer sicher obwohl es nicht direkt in den 
Spezifikationen der Pegel ist. RX vom ESP will 3,3V-Pegel. Meine gern 
genutzte Lösung: 1k PullUp am ESP gegen die 3,3V und eine Schottkydioen 
mit Anode am ESP und Kathode am TX des AVR. Diese Lösung geht bei mir 
auch mit 8MHz und einer SD-Karte für SCK und CS stabil.

Bei SPI eben den ESP als Slave. Der Arduino schickt die Daten und der 
ESP liest sie ein. Beispiele dazu gibt es im ESP-Paket, seriell 
erfordert weniger Verbindungsaufwand.

Gruß aus Berlin
Michael

von Achim S. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Christian B. schrieb:
> Da muss man wohl auch noch eine Sample&Hold-Schaltung davor setzen. Hier
> muss ich aber auch noch einmal recherchieren.

wenn es dir wirklich auf exakt gleichzeitiges Abtasten ankommt, wäre ein 
externer Mehrkanal-ADC mit gleichzeitiger Abtastung eine Option. 
AD7606-4 käme mir spontan in den Sinn, aber sicher gibt es noch andere, 
die von Preis, Kanalzahl, Auflösung... noch besser passen.
https://www.analog.com/media/en/technical-documentation/data-sheets/AD7606_7606-6_7606-4.pdf

von Christian B. (bastlerbire)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

nachdem ich mich "schlau" gemacht habe und noch etwas recherchiert habe, 
habe ich noch eine Rückfrage, um nicht in die falsche Richtung zu 
laufen. Ich möchte nun folgendes umsetzen: Über einen Arduino möchte ich 
die drei Ströme der drei Phasen erfassen und dann über -wie Du es 
vorgeschlagen hast Michael:

Michael U. schrieb:
> Als Ansatz: Seriell - der Arduino schickt die Daten einfach mit
> Serial.write() o.ä. raus, wenn er welche hat. Der ESP fragt in der
> loop() mit Serial.available() ab, ob Daten da sind. Wenn ja, dann
> entweder mit Serial.readBytes(buffer, length) die erwartete Anzahl Bytes
> einlesen oder mit Serial.readBytesUntil() bis zu einem festen
> Endezeichen. Das hängt davon ab, in welchem Format Du die Daten
> rüberschickst.

an den ESP schicken. Die anderen Ansätze (mit externen ADC) habe ich mir 
auch angeschaut, da ich aber fachfremd bin und mich in der 
"Arduino-Welt" etwas sicherer fühle, würde ich das so (mit einem 
Arduino) machen -  auch aufgrund der vielen Dokumentation.

Jetzt sind mir aber noch einmal drei konkrete Fragen gekommen:

1. Sehe ich das richtig: Der Arduino Nano (den ich bis jetzt im Einsatz 
hatte - hatte ich bisher nicht geschrieben, sorry!) ist dafür gar nicht 
geeignet, da keine weitere serielle Schnittstelle vorhanden ist, oder?

2. Da das vermutlich richtig ist: Wäre ein Mega eine Alternative 
umschwenken, kann dieser vielleicht sogar Achim S. schrieb im Beitrag 
#5647021:
> Mehrkanal-ADC mit gleichzeitiger Abtastung
leisten?

3. Gäbe es noch eventuell eine günstigere Alternative aus dem 
"Arduino-Universum"?

Es wäre super, wenn Ihr mir noch einmal einen Tipp / Hinweis hättet, 
dann werde ich die nächsten Schritte einleiten.

Euch allen vielen Dank! Ich weiß das sehr zu schätzen! Zeit ist ein 
knappes Gut!

Viele Grüße

Christian

von Cornelius (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
>Gäbe es noch eventuell eine günstigere Alternative aus dem
>"Arduino-Universum"?

Der ESP8266 alleine ist das günstigste Planet im Arduino-Universum hat 
aber leider nur einen Mond äh ADC:
https://github.com/esp8266/Arduino

Du könntest zum Superplanet ESP32 im Arduino-Universum wechseln, der hat 
dann mehrere ADC-Kanäle:
https://github.com/espressif/arduino-esp32

Und vergiss den Gedanken, die Ströme auf die Mikrosekunde genau messen 
zu wollen. Ohne Deine geforderte Messgenauigkeit zu kennen würde ich 
sagen: Deine Messung wird auch so genau genug.

von Michael U. (amiga)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

@Cornelius (Gast): passiert mir manchmal zwar auch, aber vielleicht 
hättest Du doch den Thread ab Anfang lesen sollen?

Gruß aus Berlin
Michael

Christian B. schrieb:
> 1. Sehe ich das richtig: Der Arduino Nano (den ich bis jetzt im Einsatz
> hatte - hatte ich bisher nicht geschrieben, sorry!) ist dafür gar nicht
> geeignet, da keine weitere serielle Schnittstelle vorhanden ist, oder?

jaein... Schätze ab oder berechne, wieviele Daten Du jedesmal übertragen 
mußt und wie oft pro Sekunde das passieren soll. Die SoftSerial als 2. 
Schnittstelle ist kein Problem, wenn Du mit maximal 19200baud zum ESP 
auskommst.

Kleine Alternative zum Nano wäre auch der Arduino Micro. Da der 32U4 
selbst USB zur Verfügung stellt und darüber die Verbindung zum PC und 
zum Programmieren erfolgt, bleibt sie Hardware-Serielle frei verfügbar.

Gruß aus Berlin
Michael

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Der ATmega328PB hat zwei serielle Schnittstellen. Den kannst du auf ein 
Arduino Uno Board stecken.

Dann gibt es noch Arduino Pro Mini und Arduino Nano kompatible Board mit 
dem ATmega328PB. Zum Beispiel: 
https://www.tindie.com/products/leonerd/atmega328pb-development-board/

von Christian B. (bastlerbire)


Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen an alle!

Ihr seid wirklich klasse! Ich schaue mir die von Euch gegebenen Hinweise 
/ Vorschläge zu Alternativen und Boards an. Ich werde Euch berichten, 
wie es weitergeht!

Vielen, vielen Dank Euch und -wenn es so weit ist- schon einmal ein 
erholsames Wochenende!

Grüße

Christian

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.