Hey,
ich habe mal ne Frage, warscheinlich wieder was ganz einfaches und ich hab'n Brett vorm Kopf.
Und zwar bekomme ich, wenn ich mir auf dem Seriellen Monitor den analogen Input 0 angucke bei einer bestimmten Sache ca 20x eine Zahl zwischen 600 und 800, danach ca. 20x mal eine Zahl zwischen 0 und 50. Sonst kommen immer irgendwelche zahlen. Jetzt will ich, dass wenn dieser gesagte Fall (also 20x eine Zahl zwischen 600 und 800, direkt danach eine 20x eine Zahl zwischen 0 und 50) (das Programm besteht also nur aus Serial.println(analogRead (A0)); )kommt etwas geschieht, z.B. eine LED 2x aufleuchtet.
Wenn man es mit 20x hintereinander if abfragen machen würde, würde er ja auch Lücken "mitnehmen" und das wäre glaube ich nicht so gut für ein gutes Ergebnis.
Ich hoffe, dass ihr mein Problem versteht und dass ihr mir möglichst schnell gut antwortet,
LG Finn!
Du mußt die Anzahl der aufeinanderfolgenden Messungen zählen, die über oder unter einem bestimmten Wert liegen. Etwa so:
value = analogRead(0);
if (value >= 600) highCount++;
else if (value <=50) lowCount++;
else tuWas; //andere Werte beenden eine Sequenz
Der Code für tuWas kann in einem Unterprogramm stehen, oder direkt in { ... } eingefügt werden. Er prüft, ob die Werte genügend oft hoch und niedrig waren, und blinkt dann die LED, und löscht die Zähler für die Erkennung der nächsten Sequenz.
Vermutlich muß man den Code noch verfeinern, so daß nur mehrere direkt aufeinanderfolgende hohe bzw. niedirge Werte gezählt werden, und ob dazwischen ggf. auch andere Werte vorkommen dürfen.
Vielen Dank schon mal für die schnelle Antwort.
Bei dem Code fürchte ich, dass wenn die zufälligen Werte eintrudeln, ausgelöst wird, weil diees Werte liegen auch schon sehr oft zwischen 600 und 800 und zwischen 0 und 50.
bei einer bestimmten Sache
Hardware geheim
Aufbau geheim.
So kann ich dir nicht helfen.
Meine Kristallkugel macht gerade Urlaub.
Ich weiß nur, dass meine ADCs keine zufälligen Werte liefern.
Und wenn doch, dann haben sie einen Grund dafür.
value = analogRead(0);
if ((value >= 600) highCount++;
else if (highCount<=20) highCount=0;
if (highCount>=20){
if ((value <=50) lowCount++;
else {if ((lowCount>=1) {lowCount=0;
highCount=0;}}
}
if ((value>50)&&(value<600)) {lowCount=0;
highCount=0;}
if ((highCount>=20) && (lowCount>=20) {lasse Led 2x blinken;
lowCount=0;
highCount=0;}
]
Ich habe mal Code von DrDiettrich verfeinert. Ich hoffe, ich habe keine Klammern oder Simikolons vergessen.
Edit: Code überarbeitet
Ich denke, Theseus hat das Prinzip kapiert und gut gelöst
Es ist völlig richtig, die Zähler zurückzusetzen, sobald die erwartete Sequenz irgendwie gestört wird. Ich würde aber noch prüfen, ob beim Übergang von high (>600) nach low (<50) nicht doch noch Zwischenwerte auftreten können, die nicht gleich zum Reset führen sollten.
DrDiettrich:
Ich denke, Theseus hat das Prinzip kapiert und gut gelöst
Na ja
Theseus:
Ich hoffe, ich habe keine Klammern oder Simikolons vergessen.
Hoffnungen trügen oft.
Mein Vorschlag mit Testumfeld und echtem Blinken
enum {
countBig,
countSmall,
};
byte State = countBig;
int bigCounter;
int smallCounter;
bool isBig(int val) {
return val >= 600 && val <= 800;
}
bool isSmall(int val) {
return val >= 0 && val <= 50;
}
void setup() {
Serial.begin(250000);
pinMode(LED_BUILTIN, OUTPUT);
}
uint16_t analogReadA0() {
static uint8_t seq;
static uint16_t testSeq[] = {
0, 1000, 1, 1, 1, // irgendwas davor
600, 610, 620, 630, 650, 670, 680, 700, 800, 750,
600, 610, 620, 630, 650, 670, 680, 700, 800, 750,
700, 710, // Bonus bigs
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, // Bonus smalls
345, 224, 1023, 13, // irgendwas dahinter
};
if (seq >= sizeof(testSeq) / sizeof(testSeq[0])) {
return random(0, 1023);
}
return testSeq[seq++];
}
void loop() {
static unsigned long lastHalfBlink;
static uint8_t halfBlinks;
unsigned long topLoop = millis();
int value = analogReadA0();
//int value = analogRead(A0);
switch (State) {
case countBig:
if (isBig(value)) {
bigCounter++;
} else {
if (bigCounter >= 20 && isSmall(value)) {
smallCounter = 1;
State = countSmall;
} else {
bigCounter = 0;
}
}
break;
case countSmall:
if (isSmall(value)) {
if (++smallCounter >= 20) {
Serial.print(F("Match with value "));
Serial.println(value);
lastHalfBlink = topLoop;
digitalWrite(LED_BUILTIN, HIGH);
halfBlinks = 3;
State = countBig;
bigCounter = 0;
}
} else {
bigCounter = isBig(value) ? 1 : 0;
State = countBig;
}
break;
}
if (halfBlinks && topLoop - lastHalfBlink >= 1000) {
lastHalfBlink = topLoop;
halfBlinks--;
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
}
Match with value 19
Der switch() ist für nur zwei Zustände vielleicht etwas Overkill, aber was solls.
Hallo,
das mag zwar eine schöne Spielerei zum Programmieren sein, noch spannender aber wäre bestimmt die Ursache dafür zu suchen.
Viele Grüße Manfred
Mkch:
spannender aber wäre bestimmt die Ursache dafür zu suchen.
Welche Ursache und wofür?
Das jemand anscheinend versucht ein fast digitales (<800) Signal analog (und dann falsch*) abzutasten,
sei's drum.
Ohne vernünftiges Timing des Lesens klappt das sowieso nicht zuverlässig.
*digital betrachtet wären auch die Werte über 800 HIGH