Spannung messen mit ESP32 und externe ADC´s

Die Arduino DUE, sowie die ESP32, ESP8266 und sonstige.
Antworten
Benutzeravatar
Admin
Administrator
Beiträge: 1194
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Spannung messen mit ESP32 und externe ADC´s

Beitrag von Admin »

Also das Spannung messen mit den eingebauten ADC´s des ESP32 ist in meinen Augen nicht möglich. Ausser Spannung da, ja / nein ? :(o): Ich habe da Abweichungen von fast nem halben Volt, bei einem Bereich von 0 bis 3,3 Volt. Wenn ich da noch einen 1:10 Spannungsteiler dran hänge, dass ich 0-33 Volt messen kann, bekomme ich Fehlmessungen in der Nähe von einem Volt. Das kann man in der Pfeife rauchen. Vielleicht noch mit nem Analogen Lichtsensor, wo ich zumindest sehe wenn es mehr oder weniger Licht wird. Aber auch da eigentlich nicht wirklich brauchbar, weil die Spannung ja dann auch ohne dass sich die Werte ändern das Ergebnis laufend rel. weit bewegt. Ich habe externe 16 Bit ADC - Sensoren bestellt, die sollen rechtgenau sein. Die kommen diese Tage. Es sind die 4 Kanal "ADS1115". Er ist über I2C auslesbar, und kann mit 3 Volt bis 5,5 Volt betrieben werden.
.
ADC_ADS1115_.jpg
ADC_ADS1115_.jpg (56.12 KiB) 1434 mal betrachtet
Benutzeravatar
Admin
Administrator
Beiträge: 1194
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Spannung messen mit ESP32 und externe ADC´s

Beitrag von Admin »

Man braucht zwei Lib´s dazu.
Die eine ist die Adafruit Library für den ADS1115, das ist die hier.

Und dann braucht man aber auch diese noch Das ist die BusIO die leider Extern ist, und daher extra von der Adafruit ADS1115 Lib benutzt also aufgerufen wird.

Ich habe das Programm hier schon mal für mich angepasst, um die Daten auf dem OLED Display anzuzeigen. Ist aber noch nicht komplett, da ich noch keine ADS1115 Sensoren habe. Bekomme ich erst morgen. Dieses Programm macht einen Messwerte - Vergleich zwischen ADC ESP32 Intern und ADS1115. In dem Teil hier unten wird zumindest schon mal der Spannungswert vom ADC Intern am Oled angezeigt. Achtung Maximal 3,3 Volt. Für mehr braucht man einen Spannungsteiler.

Code: Alles auswählen

/* Abfrage von analogen Werten am ESP32
   - per GPIO-Pin
   - am ADS1115 mit Weitergabe per I2C
  2021-05-28 Heiko (unsinnsbasis.de)
*/

#include <Adafruit_ADS1X15.h> // bindet Wire.h für I2C mit ein
Adafruit_ADS1115 ads;
#define ADS_I2C_ADDR 0x48

// OLED Display einrichten
#include <U8g2lib.h>  // als U8g2 im Bibliotheksverwalter zu finden
U8G2_SH1106_128X64_NONAME_F_HW_I2C oled(U8G2_R0);

const float multiplier = 0.125F; // ADS1115-Multiplikator bei einf. Verstärkung
#define A_PIN 4  // GPIO-Pin für analoge Eingabe
int A_Value;         // Messwert per GPIO
int adc0;            // Messwert an Kanal 0 des ADS1115
float A_mv, ads_mv;  // Messwert in Millivolt umgerechnet
// ----------------------------------------------------SETUP------------------------------------
void setup() {
  Serial.begin(115200);
  delay(500);
  Serial.println("Analog-Test ESP32");

  ads.begin(ADS_I2C_ADDR, &Wire);
  // Werte 1-fach verstärken (ESP32 liefert  max. 3,3V)
  ads.setGain(GAIN_ONE);

  oled.begin();
  oled.clearBuffer();              // Textspeicher löschen
  oled.setFont(u8g2_font_6x12_tr); // choose a suitable font 6x12
  //oled.setFont(u8g2_font_9x15_mf);
  oled.setCursor(12, (1 * 10));
  oled.print(F("Analog-Test ESP32"));
  oled.setCursor(28, (2 * 10));
  oled.print(F("Mit ADS1115"));
  oled.sendBuffer();
}
// ----------------------------------------------------LOOP--------------------------------------
void loop() {
  A_Value = analogRead(A_PIN);  // 0...4095
  Serial.printf("Rohwert: %d", A_Value);

  // Wert in Millivolt umrechnen
  A_mv = A_Value * 3300.0 / 4095.0;
  Serial.printf("; %4.2f mV", A_mv);
  // Messung ausgeben
  oled.setFont(u8g2_font_10x20_mf);
  oled.setCursor(10, (2 * 20));
  oled.print(A_mv);
  oled.print(F(" mV"));
  oled.sendBuffer();
  // Messung per ADS1115
  // - Kanal 0 messen (single-ended)
  // adc0 = ads.readADC_SingleEnded(0);
  // ads_mv = ads.computeVolts(adc0) * 1000;
  // oder
  // - differenzielle Messung an Kanal 0/1
  adc0 = ads.readADC_Differential_0_1();
  ads_mv = adc0 * multiplier;
  Serial.printf("; I2C: %4.2f mV\n", ads_mv);
  delay(200);
}
Benutzeravatar
Admin
Administrator
Beiträge: 1194
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Spannung messen mit ESP32 und externe ADC´s

Beitrag von Admin »

Endlich :oo:

.....habe ich meine ADS1115 Sensoren bekommen. Und natürlich gleich getestet.
Hier das Programm:

Code: Alles auswählen

/* Abfrage von analogen Werten am ESP32
   - per GPIO-Pin
   - am ADS1115 mit Weitergabe per I2C
  2021-05-28 Heiko (unsinnsbasis.de)
*/

#include <Adafruit_ADS1X15.h> // bindet Wire.h für I2C mit ein
Adafruit_ADS1115 ads;
#define ADS_I2C_ADDR 0x48

// OLED Display einrichten
#include <U8g2lib.h>  // als U8g2 im Bibliotheksverwalter zu finden
U8G2_SH1106_128X64_NONAME_F_HW_I2C oled(U8G2_R0);

const float multiplier = 0.125F; // ADS1115-Multiplikator bei einf. Verstärkung
#define A_PIN 4  // GPIO-Pin für analoge Eingabe
int A_Value;         // Messwert per GPIO
int adc0;            // Messwert an Kanal 0 des ADS1115
float A_mv, ads_mv;  // Messwert in Millivolt umgerechnet
// ----------------------------------------------------SETUP------------------------------------
void setup() {
  Serial.begin(115200);
  delay(500);
  Serial.println("Analog-Test ESP32");

  ads.begin(ADS_I2C_ADDR, &Wire);
  // Werte 1-fach verstärken (ESP32 liefert  max. 3,3V)
  ads.setGain(GAIN_ONE);

  oled.begin();
  oled.clearBuffer();              // Textspeicher löschen
  oled.setFont(u8g2_font_6x12_tr); // choose a suitable font 6x12
  //oled.setFont(u8g2_font_9x15_mf);
  oled.setCursor(12, (1 * 10));
  oled.print(F("Analog-Test ESP32"));
  oled.setCursor(28, (2 * 10));
  oled.print(F("Mit ADS1115"));
  oled.sendBuffer();
}
// ----------------------------------------------------LOOP--------------------------------------
void loop() {
  A_Value = analogRead(A_PIN);  // 0...4095
  //Serial.printf("Rohwert: %d", A_Value);

  // Wert in Volt umrechnen für ADC - ESP32
  A_mv = (A_Value * 3300.0 / 4095.0) / 1000UL;
  //Serial.printf("; %4.2f V", A_mv);
  // Messung per ADS1115
  // - Kanal 0 messen (single-ended)
  adc0 = ads.readADC_SingleEnded(0);
  ads_mv = ads.computeVolts(adc0);
  // oder
  // - differenzielle Messung an Kanal 0/1
  //adc0 = ads.readADC_Differential_0_1();
  //ads_mv = (adc0 * multiplier) / 1000;
  //Serial.printf("; I2C: %4.2f mV\n", ads_mv);

  // Messung ausgeben
  oled.setFont(u8g2_font_10x20_mf);
  oled.setCursor(20, (2 * 20));
  oled.print(A_mv);
  oled.print(F(" Volt"));
  oled.setCursor(20, (3 * 20));
  oled.print(ads_mv);
  oled.print(F(" Volt"));
  oled.sendBuffer();
  delay(1000);
}
Im Oled Display ist der obere Wert der ADC von ESP32, der parallel hängt an der Spannungsquelle vom Poti
Im Oled Display ist der untere Wert der ADS1115 Kanal 0 Wert an der selben Quelle. Dieser Wert (2,89 Volt) ist identisch mit dem Wert am Messgerät.

ESP32 mit ADS1115 Spannung V01.jpg
ESP32 mit ADS1115 Spannung V01.jpg (253.06 KiB) 1412 mal betrachtet
Benutzeravatar
Admin
Administrator
Beiträge: 1194
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Spannung messen mit ESP32 und externe ADC´s

Beitrag von Admin »

Ich habe auch die Differenzmessung ausprobiert. Alles bestens, geht wie ne Eins.
Also die Messungen mit dem ADS1115 sind super. Die Werte könnten auch vom Multimeter sein.
Für Differenzmessung wird in dem Programm, das im Beitrag vorher gezeigt ist, folgendes wie hier unten abgeändert.

Code: Alles auswählen

// - Kanal 0 messen (single-ended)
  // adc0 = ads.readADC_SingleEnded(0);
  // ads_mv = ads.computeVolts(adc0);
  // oder
  // - differenzielle Messung an Kanal 0/1
  adc0 = ads.readADC_Differential_0_1();
  ads_mv = (adc0 * multiplier);
Single Ended auskommentieren und differenzielle Messung aktivieren.
Gemessen wird dann an Kanal 0 und Kanal 1.

Franz

PS: Für die Mitleser hier.
Übrigens ist dieser Sensor selbstverständlich nicht nur für den ESP... sondern auch für andere Arduinos, wie z.B. Uno, Nano, Mega, u.s.w. Mit dem selben Programm und den selben Librarys.
Benutzeravatar
Admin
Administrator
Beiträge: 1194
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Spannung messen mit ESP32 und externe ADC´s

Beitrag von Admin »

Hier habe ich mal das Programm ein bischen geändert.
1. Die Messung über den ADC Pin.4 des ESP32 habe ich rausgeschmissen. Die war ja nur zum Vergleich um festzustellen dass das Messen darüber Schwachsinn ist.
2. Ich habe den zweiten Messkanal der 4 möglichen Kanäle des ADS1115 in Betrieb genommen und damit mal eine zweite Spannung gemessen. Geht genauso gut wie die Messung auf Kanal0.

Genauso kann man um Kanal 2 und 3 erweitern.

Hier das Programm:

Code: Alles auswählen

/* Abfrage von analogen Werten am ESP32
   - per GPIO-Pin
   - am ADS1115 mit Weitergabe per I2C
  2021-05-28 Heiko (unsinnsbasis.de)
*/

#include <Adafruit_ADS1X15.h> // bindet Wire.h für I2C mit ein
Adafruit_ADS1115 ads;
#define ADS_I2C_ADDR 0x48

// OLED Display einrichten
#include <U8g2lib.h>  // als U8g2 im Bibliotheksverwalter zu finden
U8G2_SH1106_128X64_NONAME_F_HW_I2C oled(U8G2_R0);

const float multiplier = 0.125F; // ADS1115-Multiplikator bei einf. Verstärkung
int A_Value;         // Messwert per GPIO
int adc0;            // Messwert an Kanal 0 des ADS1115
int adc1;            // Messwert an Kanal 1 des ADS1115
int adc2;            // Messwert an Kanal 2 des ADS1115
int adc3;            // Messwert an Kanal 3 des ADS1115
float A_mv, ads_mv0, ads_mv1,  ads_mv2, ads_mv3 ; // Messwert in Millivolt umgerechnet
// ----------------------------------------------------SETUP------------------------------------
void setup() {
  Serial.begin(115200);
  delay(500);
  Serial.println("Analog-Test ESP32");

  ads.begin(ADS_I2C_ADDR, &Wire);
  // Werte 1-fach verstärken (ESP32 liefert  max. 3,3V)
  ads.setGain(GAIN_ONE);

  oled.begin();
  oled.clearBuffer();              // Textspeicher löschen
  oled.setFont(u8g2_font_6x12_tr); // choose a suitable font 6x12
  //oled.setFont(u8g2_font_9x15_mf);
  oled.setCursor(12, (1 * 10));
  oled.print(F("Analog-Test ESP32"));
  oled.setCursor(28, (2 * 10));
  oled.print(F("Mit ADS1115"));
  oled.sendBuffer();
}
// ----------------------------------------------------LOOP--------------------------------------
void loop() 
{
  // Messung per ADS1115
  // - Kanal 0 messen (single-ended)
  adc0 = ads.readADC_SingleEnded(0);
  ads_mv0 = ads.computeVolts(adc0);
  // - Kanal 1 messen (single-ended)
  adc1 = ads.readADC_SingleEnded(1);
  ads_mv1 = ads.computeVolts(adc1);
  // oder
  // - differenzielle Messung an Kanal 0/1
  //adc0 = ads.readADC_Differential_0_1();
  //ads_mv = (adc0 * multiplier);
  //Serial.printf("; I2C: %4.2f mV\n", ads_mv);

  // Messung ausgeben
  oled.setFont(u8g2_font_10x20_mf);
  //ADS Kanal 0 anzeigen
  oled.setCursor(20, (2 * 20));
  oled.print(ads_mv0);
  oled.print(F(" Volt"));
  //ADS Kanal 1 anzeigen  
  oled.setCursor(20, (3 * 20));
  oled.print(ads_mv1);
  oled.print(F(" Volt"));
  oled.sendBuffer();
  delay(1000);
}
Benutzeravatar
Admin
Administrator
Beiträge: 1194
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Spannung messen mit ESP32 und externe ADC´s

Beitrag von Admin »

Ich habe jetzt den ADS1115 schon ein paar Tage so neben mir laufen, und immer wenn ich mir diese Messwerte die ich zum Testen auf 2 der 4 Kanäle eingerichtet habe, mal wieder kontrolliere, sind die wunderbar stimmig. Also man kann sich drauf verlassen, dass die zwei Stellen hinterm Komma Sinn machen.

Franz

Edit: Änderung der I2C-Adresse

Als Standardadresse ist 0x48 voreingestellt. Will man mehrere (bis zu 4) Boards an einem I2C-Bus betreiben, müssen diese unterschiedliche Adressen haben. Beim ADS1115 ist das möglich, indem man den ADDR-Pins mit einem der Anschlüsse VDD, GND, SDA oder SCL verbindet (z.B. mit einer Steckbrücke auf dem Breadboard):

GND: 0x48 (entspricht dem Standard; auch bei offener Verbindung)
VDD: 0x49
SDA: 0x4A
SCL: 0x4B

PS: Ich habe mir hier ein paar Infos geklaut, man muss sich ja nicht alles selber raussuchen, wenn das schon von einem anderen Techniker durchgearbeitet ist.
Antworten

Zurück zu „Programmierung der 32Bit Controller“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast