PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Sensor Wert mehrfach abfragen, erst dann...



xxrider
20.06.2017, 13:24
Hallo,
ich bin ein Neuling in Sachen Arduino und habe eine Frage:
Wie kann ich einen Spannungswert mehrfach abfragen (z. B. innherhalb von 10 Sekunden) und erst, wenn der Wert jedesmal innerhalb dieses 10-Sekundenintervalles einen definierten Schwellenwert unterschreitet eine Aktion durchführen?
Es geht um einen Akku, der wenn er entladen ist, abgeschalten werden soll, aber nicht wenn der Schwellwert nur kurzzeitig unterschritten wird.
Danke!

Ceos
20.06.2017, 13:51
dafür gibt es statistische und arithmetische mittel, weist du denn wie du deinen wert überhaupt bekommst? oder brauchst du da auch schon hilfe für?
das kam aus deiner frage jetzt nicht unbedingt so klar heraus :)

HaWe
20.06.2017, 17:32
Hallo,
ich bin ein Neuling in Sachen Arduino und habe eine Frage:
Wie kann ich einen Spannungswert mehrfach abfragen (z. B. innherhalb von 10 Sekunden) und erst, wenn der Wert jedesmal innerhalb dieses 10-Sekundenintervalles einen definierten Schwellenwert unterschreitet eine Aktion durchführen?
Es geht um einen Akku, der wenn er entladen ist, abgeschalten werden soll, aber nicht wenn der Schwellwert nur kurzzeitig unterschritten wird.
Danke!

wie Ceos schon schrieb, arithmetische Mittel gehen und finde ich auch ausreichend.

Direkt am Analogpin misst du einen Rohwert zwischen 0...1024, das ist dein Messbereich (Achtung! darf direkt am Arduino Pin hächstens 5V sein, bei manchen Arduinos sogar nur 3.3V!);

Du musst ihn dann in float umwandeln und nimmst einfach das Mittel zwischen dem bisherigen Durchschnittswert und deinem aktuellen:

float Durchschnitt;

Durchschnitt = (Durchschnitt + (float)analogRead(MessPin) ) /2;

kurze kleine Ausreißer werden nicht viel ausmachen, mit der Zeit wird dann bei dauerhaft niedrigem Messwert auch deine Schwelle unterschritten.
Ansonsten ist bei häufigen starken Ausreißern ein anderes Verfahren nötig (z.B. Median) - das ist aber deutlich komplizierter.
Das ganze packst du in deine Arduino-Funktion loop().

Zwischen die einzelnen Messungen kommen dann am einfachsten delay(ms-Anzahl), bei 10 s also delay(10000);
es reicht aus zum testen, auch dafür gibt es elegantere Methoden.

Für absolute Anfänger empfehle ich allerdings: mach erst mal ein Arduino Tutorial!

xxrider
20.06.2017, 17:59
Ich habe mich wohl mißverständlich ausgedrückt:
Ich will keinen Mittelwert.
Ich will sagen wir mal 5 Werte abfragen innerhalb eines Zeitraumes von 10 Sekunden.
Wenn ALLE Werte UNTERHALB eines Schwellenwertes sind, dann soll eine Aktion erfolgen.
Wenn nicht, dann soll wieder von vorne abgefragt werden (5x).

Den Wert mit Spannungsteiler und Analogeingang zu ermitteln ist kein Problem.
Nur die Logik und Syntax für diese Aufgabe, da fehlt mir etwas das Verständnis...

HaWe
20.06.2017, 18:18
Ich habe mich wohl mißverständlich ausgedrückt:
Ich will keinen Mittelwert.
Ich will sagen wir mal 5 Werte abfragen innerhalb eines Zeitraumes von 10 Sekunden.
Wenn ALLE Werte UNTERHALB eines Schwellenwertes sind, dann soll eine Aktion erfolgen.
Wenn nicht, dann soll wieder von vorne abgefragt werden (5x).

Den Wert mit Spannungsteiler und Analogeingang zu ermitteln ist kein Problem.
Nur die Logik und Syntax für diese Aufgabe, da fehlt mir etwas das Verständnis...

ok, aber auch nicht so schwer...:


void loop() {
volatile static int counter=0;

int wert = analogRead(messPin);
if (wert<Schwelle) counter++;
else
counter=0;

if(counter>=5) {
bingo();
}
delay(2000);
}


so als erste Idee... 8)

xxrider
20.06.2017, 20:13
danke das muss ich mir näher zu gemüte führen.

Muss ich da unbedingt so seltsam definieren:
volatile static int counter=0;

oder geht nicht auch einfach mit
int...?

HaWe
20.06.2017, 20:54
danke das muss ich mir näher zu gemüte führen.

Muss ich da unbedingt so seltsam definieren:
volatile static int counter=0;

oder geht nicht auch einfach mit
int...?

kurze Antwort: probier's aus!
lange Antwort:
ich bin bei Arduino mit seinen verschiedenen Compiler-settings für verschiedene Zielplattformen (AVR, SAM, SAMD, ESP8266) vorsichtig geworden.
Die loop() Funktion ist mir da besonders suspekt.
volatile: man weiß nie, was der Code-optimizer rausschmeißt, für welche Zielplattform auch immer, wenn mit den Werten nicht groß was passiert. Ich ging hier im Testcode auf Nummer Sicher, damit es bei dir auch wirklich sicher funktioniert, darauf verzichten kann man nach Test immer noch, aber dieser Punkt ist wschl am unkritischsten.
static: es ist eine lokale Funktion mit einer lokalen Variablen, die innerhalb der Funktion in verschiedenen Durchläufen hochgezählt oder wieder resettet wird. Gerade mit solchen Werten habe ich bereits schlechte Erfahrungen in loop() gemacht, wenn sie nicht als static deklariert waren, insb. Arduino Due (SAM) mit Scheduler und ESP8266.

Aber wie gesagt, muss vlt alles nicht unbedingt sein, probier's einfach aus.

xxrider
20.06.2017, 20:55
Das dumme ist - ausprobieren geht grad nicht weil ich mein Board durch Falschpolung heute geschrottet hab! Ein Neues ist aber unterwegs...

Noch eine Frage:
die Zuweisung von 0 an den counter
(volatile static int counter=0)

befindet sich doch innerhalb der schleife. Also dürfte der Wert doch niemals >1 werden weil er bei jedem Durchgang wieder auf 0 gesetzt wird,
oder seh ich da was falsch???

HaWe
20.06.2017, 20:58
nein, eben nicht, weil er static ist und in loop nur beim ersten Durchlauf zu Beginn initialisiert wird.
Ist auch so eine auf den ersten Blick seltsame und nicht ganz transparente loop-Eigenheit, eben Arduinoisch, nicht echt C++, auch deshalb gehe ich hier immer auf Nummer Sicher.
Wie es in C++ umgeformt hieße, führt hier aber jetzt zu weit.