Hallo zusammen,
nach einer Dekade Pause widme ich mich einem neuen Arduino Projekt. Leider komme ich an einer Stelle nicht weiter und brauche eure Unterstützung.
Beim Auslesen der Analogwerte des GY-61 über einen ADS1115 am ESP8266-12F treten immer wieder schwankende Werte auf. Ich habe den Sensor kalibriert und mir eine kleine Tabelle dazu angelegt, da die Werteverhältnisse des Sensors nicht linear sind. Mit der multiMap() Finktion bekomme ich die Werte prima ins Raster. Es fällt allerdings auf, dass sich die ausgelesenen Messwerte nach jedem Neustart des ESP verändern.
Nach etwas Recherche soll das an schwankenden Spannungen liegen. Ich betreibe die Schaltung daher nun hinter einem 3,3V Festspannungsregler LF33CV und einem 100uF Kondensator.
Bei den Arduino Onboard ADC lässt sich der Referenzwert der Spannung nach entsprechender Verdrahtung einbeziehen. Wenn ich es richtig verstanden habe, benötigt man das beim ADS1115 nicht, da ein interner Komperator das selber macht.
Da ich nur die X-Achse benötige, und auch nur 0°-90° habe ich den GY-61 nur mit X an den A2 des ADS115 angeschlossen. Ein 10kOhm Widerstand in Pull-down zieht den Eingang dann auf GND.
Habt ihr einen Tipp für mich, wie ich die Messwerte so stabil bekomme, dass die Winkelanzeige auch Grad-genau funktioniert?
Vielen Dank!
Anbei ein paar Code Schnipsel:
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <Adafruit_ADS1X15.h>
#include "MultiMap.h"
Adafruit_ADS1115 ads; /* Use this for the 16-bit version */
// Variable declaration ADC for ADS1115
uint16_t adc0, adc1, adc2, adc3, adc4;
float volts0, volts1, volts2, volts3;
//Variable declaration Y average
const int yAvgNo = 20;
int yAvg[yAvgNo];
int yAvgSum;
float yAngle;
// Variable Declaration transmission cycle sent to LOXONE
unsigned long previousMillis = 0;
const long sendInterval = 500;
void setup() {
// Serial Output
Serial.begin(115200);
Serial.println("Booting");
// Define GPIO
pinMode(LED_BUILTIN, OUTPUT);
// Send UDP Ready
sendUDP("UDP Ready", 1);
// The ADC input range (or gain) can be changed via the following
// functions, but be careful never to exceed VDD +0.3V max, or to
// exceed the upper and lower limits if you adjust the input range!
// Setting these values incorrectly may destroy your ADC!
// ADS1015 ADS1115
// ------- -------
// ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default)
ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV (perfect for 3.3V)
// ads.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV
// ads.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV
// ads.setGain(GAIN_EIGHT); // 8x gain +/- 0.512V 1 bit = 0.25mV 0.015625mV
// ads.setGain(GAIN_SIXTEEN); // 16x gain +/- 0.256V 1 bit = 0.125mV 0.0078125mV
ads.begin();
}
void loop() {
ArduinoOTA.handle();
readADS1115();
yAngleCalc();
// Read ADC with interval
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= sendInterval) {
sendUDP("Photo.Top: ", volts0);
sendUDP("Photo.Bottom: ", volts1);
sendUDP("Gyro.Y.Analog: ", adc2);
sendUDP("Gyro.Y.Volt: ", volts2);
sendUDP("Gyro.Y.Angle: ", yAngle);
previousMillis = currentMillis;
}
digitalWrite(LED_BUILTIN, millis() % 2000 > 900 ? LOW : HIGH);
}
// Function to read ADC Data from ADS 1115 in 16bit
void readADS1115(){
adc0 = ads.readADC_SingleEnded(0);
volts0 = ads.computeVolts(adc0);
adc1 = ads.readADC_SingleEnded(1);
volts1 = ads.computeVolts(adc1);
adc2 = ads.readADC_SingleEnded(2);
volts2 = ads.computeVolts(adc2);
adc3 = ads.readADC_SingleEnded(3);
volts3 = ads.computeVolts(adc3);
}
//Function to calculate Y Angle by using average of yAvg(20)
void yAngleCalc(){
for (int i = yAvgNo-1; i>0; i--){
yAvg[i] = yAvg[i - 1];
yAvgSum+=yAvg[i];
}
yAvg[0] = ads.readADC_SingleEnded(2);
yAvgSum+=yAvg[0];
yAvgSum = yAvgSum / yAvgNo;
int inputArray[] = {2632, 2647, 2670, 2715, 2784, 2866, 2957, 3061, 3170, 3277};
int outputArray[] = {90, 80, 70, 60, 50, 40, 30, 20, 10, 0};
yAngle = multiMap(yAvgSum, inputArray, outputArray, 10);
Serial.print("Y average Sum: ");
Serial.print(yAvgSum);
Serial.print(" Winkel: ");
Serial.println(yAngle);
}
// Hypofunction to send UDP packets
void sendUDP(String text, float value){
Udp.beginPacket(RecipientIP, RecipientUdpPort);
Udp.print(text);
Udp.print(value);
Udp.endPacket();
delay(2);
}