Buttons um Ordner direkt abzuspielen

Ja, auch ich konnte nicht schlafen…
Wieso möchtest du überhaupt eine flexible Toleranz? Also sicher wissen wir, dass die Umwandlung Analog->Digital Bauteilbedingt mal etwas springt, aber mit einem Schalter der auf festen Widerständen beruht, springt der doch nicht 20 oder gar 50 Analogwerte hin und her? Keine Frage, dass er sich mal uneinig ist ob er 505 oder 506 Ausgeben soll, aber eine feste Toleranz von 5 sollte bei festen Widerständen in Verbindung mit dem Einlernen drinnen sein?
Hast du die Werte an deinen Schaltern mal beobachtet?

doch tatsächlich ist zumindest annder AiO der Azsschlag bei +/-10 bis 15

Die AiO geht aber auch bis 4064 und nicht 1024 wie der Nano.

Es gibt einen Pullrequest zur Anpassung.

Gestern abend hatte ich bei 2% Toleranz gute Ergebnisse. 5% Hätten bei meiner Tastatur zu Überschneidungen geführt.
Das müsste man vueleicht auch prüfen ob es rechnerische Überschneidungen gibt.

Das Thema muss ichcaber wahrscheinlich eh ganz hinten anstellen.

runter auf den Arduino sind wir dann auch bei 2-4.
Hmm.

Da miss den oberen und unteren Grenzwert. Auf den dann noch ±2 bzw. ±8 sollte dann recht zuverlässig sein.
Hast du im EEPROM noch Platz um pro Stellung 2 Werte zu speichern?

Da ich keine Hörbücher mehr im EEPROM ablege, hab ich genug Platz.

Einzwei Dimensionales Array mit Min und Max Wert ist eine gute idee, da spar ich mir auch die Toleranzberrechnung während des Betriebs.

Hallo Marco,

anbei ein Vorschlag, um es etwas Ressourcen schonender anzugehen.

Grundsätzlich würde ich den AI mit einem PT1 Glied glätten. Das lässt sich relativ elegant rechnen.
Dieser PT1 filter läuft ständig in der Main Loop im Hintergrund und liefert kontinuierlich Werte.

Zum Anlernen deiner Stufen wählst du jede Stufe für ein paar Sekunden an und speicherst dir den gemittelten Wert vom PT1 ab. Du erhälst ein Array mit einem Wert je Stufe.
Beispiel hier vereinfacht in % Werten: Der Lernvorgang für 5 Stufen gab folgendes Array{9, 20, 35, 68, 91}

Die Schaltschwellen liegen jeweils in der Mitte:
Stufe 1: von (9-0)/2 = 4 bis 9+(20-9)/2 = 14
Stufe 2: von 14 bis 20 +(35-20)/2 = 27
Stufe 3: von 27 bis 35 + (68-35)/2 = 51
Stufe 4: von 51 bis 79
Stufe 5: von 79 bis 91 + (100-91)/2 = 95
usw.
Tipp: /2 Teilen als Shift-Operation

Wir brauchen ja keine Exaktheit mit Toleranzen, sondern es geht nur darum zu erkennen, ob es eher Stufe 2 oder 3 ist. Und wir nehmen einfach die, die halt am nächsten dran ist.

Die Werte legen wir uns als Grenzwerte ab. Die rechnen wir nur einmal. Danach sind sie fix. Du musst dir nur für n Stufen n+1 Werte merken. Keine Toleranzen in der Laufzeit berechnen usw.
GW1 = 4
GW2 = 14
GW3= 27
GW4=51
GW5 = 79
GW6 = 95

Abfrage im laufenden Betrieb ist dann:
x=PT1.Y;
If (x< GW1 | x > GW6) return 0; // Nothing in Range
If (x<GW2) return 1; // Stufe 1
if (x<GW3) return 2;
usw.
Wenn GW ein Array ist, kannst das als Schleife machen und den Index als Stufe zurück geben.

Den PT1 Filter kann man wie folgt machen. Inspiriert von: Arduino-Cascadable-Low-Pass-Filter/Lpf.cpp at master · Billwilliams1952/Arduino-Cascadable-Low-Pass-Filter · GitHub
Wobei der Code für uns übers Ziel hinaus geht. Uns interessiert eigentlich nur die Herleitung im Kommentar:

  • Return RC low-pass filter output samples, given input samples,
  • time interval dt, and time constant RC.
  • α = dt / (RC + dt) where RC = 1 / (2 * π * BW)
  • y[0] := x[0]
  • for i from 1 to n
  • y[i] = α * x[i] + (1-α) * y[i-1]
  • return y
  • Refactoring
  • for i from 1 to n
  •   y[i] = y[i-1] + α * (x[i] - y[i-1])
    
  • OR: NextValue = LastValue + alpha * (CurrentValue - LastValue)
  •    LastValue = NextValue
    

Genau genommen das: y[i] = y[i-1] + α * (x[i] - y[i-1]) wobei a nichts anderes ist als 1/A mit A = Anzahl der Abtastungen, über die du mitteln willst.

Y ist der geglättete Wert, Yalt der vom vorhergehenden Loop, A = Anzahl der Abtastungen.
Y = Yalt + (AnalogRead - Yalt) / A
Mal angenommen der Nano braucht pro Loop 1ms, und wir wollen 100ms glätten (oder über 100 Messungen), dann ist A=100. Und wenn du A als 2er Potenz nimmst, dann kann man das performant als Shift rechnen. 100 ist ca. 128 ist ShiftR 7. Denk dran, der AD-Wandler liefert nur 10. Daher lieber etwas weniger weg shiften. Shift um 5 gleicht dann schon über 32 Messungen aus. Soll ja auch nicht zu träge werden.

x=analogRead;
x-=Y
x = x >> 5
Y+=x

Guten Nacht, MfG, Nick

Das gibt es schon fertig.

Der macht es auch nach dem Verfahren,
die Schaltschellen in die Mitte zu legen.

Das ersparrt dann vermutlich auch die Glättung. Jedenfalls hat die Bib keine integriert.

Aber ich habe was von einem Kalibrierungsmodus gelesen. Könnte einen Blick wert sein.

Was mir noch zur Störanfälligkeit eingefallen ist. Du erwähntest, du nutzt den internen Pullup. Der hat glaube ich,>50kOhm. Man braucht also sehr hochohmige Widerstände, um den Spannungshub voll zu nutzen. Wenn man z. B. „nur“ 10k als Maxwert für den unteren Teil des Spannungsteilers über den Taster nimmt, kommt nur 1/6 (ca. 15%) der Spannung an. In diesen unteren 15% tummeln sich dann alle Taster. Da ist dann kaum Rauschabstand vorhanden, und es kann zu Fehlerkennungen kommen.

Nimmst du max. 100k, dann sind wir zwar schon bei 66% Spannungshub, aber eigentlich auch suboptimal.
Nimmst du max 500k sind es schon 95% Hub, aber das ganze ist so Hochohmig, dass es sehr empfindlich gegen Einkopplungen wird.

Daher denke ich wäre ein externer 1k Pullup besser. Dann erreicht man mit max 10K im Spannungteiler noch einen vernünftigen Spannungshub von. ca. 95%, und gewinnt damit ordentlich Rauschabstand, ist aber noch nicht so extrem Hochohmig, dass alles einkoppelt.

Mfg Nick

Das hier könnte auch noch interessant sein. Basiert dann eben nicht auf einer analogen Codierung, sondern binär codiert.

Danke für deine Mühe zu dem Problem!
@stephan hat mir auch schon nahe gelegt, eine richtige Lib zu verwenden.

Die Ace Button Libary schau ich mir mal an und werde sie einbauen, sobald ich mit den gröbsten noch offenen Punkten durch bin.
Aktuell läuft mein Aufbau und ich denke dem Aufbau von @papa fehlt ein externer Pull Down.
Mit dem internen Pull up konnte er gar keine Veränderung am analogen Eingang bewirken.
Mit einem Pull Down passt auch der logische Bezug, das Leerlauf = 0 ist.

Moin
Ich kann euren Ausführungen mathematisch leider nicht wirklich folgen. Aber ich habe am Wochenende ein bisschen rumprobiert und meine Schaltung geändert. Wenn ich die 5V direkt an den AI lege, komme ich auf einen Wert von 1023 - was zu erwarten war. Daher habe ich den ersten Widerstand zwischen 5V und Taster entfernt. Die Verbindung zu GND am letzten Taster habe ich ebenfalls entfernt und wenn ich AI direkt auf GND lege, bekomme ich statt 0 einen Wert schwankend zwischen 13 und 15. Ich hab dann einen Widerstand von 2,2k eingebaut und schwanke jetzt im Leerlauf zwischen 71 und 73.


Okay, ich nehme alles zurück. Wenn ich den internen Pullup abschalte, komme ich auf Werte zwischen 0 und 1022.

Mit der neuen Beschaltung der Taster bin ich zurück zur Develop Version, habe die Werte angepasst und siehe da… alle Tasten funktionieren und ich kann diese auch mehrfach drücken. Trigger Time auf 35 und es funktioniert ziemlich gut. Die Reaktionszeit ist noch nicht bei allen Tasten optimal und Tetris könnte man so nicht spielen, aber zum abspielen von MP3s reicht es allemal.

Hier noch meine Werte:

#if defined ROBOTDYN_3X4
  if (analogValue < 100 * (ANALOG_INPUT_REF_VOLTAGE / 1024.0)) {
    return  0;
  } else if (analogValue < 210 * (ANALOG_INPUT_REF_VOLTAGE / 1024.0)) {
    return  10;
  } else if (analogValue < 230 * (ANALOG_INPUT_REF_VOLTAGE / 1024.0)) {
    return  9;
  } else if (analogValue < 250 * (ANALOG_INPUT_REF_VOLTAGE / 1024.0)) {
    return  8;
  } else if (analogValue < 280 * (ANALOG_INPUT_REF_VOLTAGE / 1024.0)) {
    return  7;
  } else if (analogValue < 320 * (ANALOG_INPUT_REF_VOLTAGE / 1024.0)) {
    return  6;
  } else if (analogValue < 370 * (ANALOG_INPUT_REF_VOLTAGE / 1024.0)) {
    return  5;
  } else if (analogValue < 440 * (ANALOG_INPUT_REF_VOLTAGE / 1024.0)) {
    return  4;
  } else if (analogValue < 545 * (ANALOG_INPUT_REF_VOLTAGE / 1024.0)) {
    return  3;
  } else if (analogValue < 720 * (ANALOG_INPUT_REF_VOLTAGE / 1024.0)) {
    return  2;
  } else if (analogValue <= 1023 * (ANALOG_INPUT_REF_VOLTAGE / 1024.0)) {
    return  1;
  } else {
    return  -1;
  }
#endif

Sollte ich die Widerstände noch irgendwie anpassen, oder ist gut so? Sind jetzt wie gesagt jeweils 1k zwischen den Tastern…

1 „Gefällt mir“

Die 1k kannst du lassen.

Nutze ich bei meinem Drehschalter genauso wie du

1 „Gefällt mir“

Moin,
wie hast du denn jetzt genau deine Tasten verschaltet? Ich möchte auch zusätzliche 9 Taster in meine Box einbauen. Oder welche Anleitung ist genau dein Vorbild? Weil ich finde die Schaltungen unterscheiden sich alle und die die ich nachbebaut habe funktioniert leider nicht. Grüße

Nicolas

Die Schaltung von dem Stufenschalter…

Ich versuche es kurz zu erklären. Wenn die Taster A und B haben, dann habe ich an A1 die +5V angeschlossen. Dann zwischen A1 und A2 einen R mit 1k. Zwischen A2 und A3 ebenfalls 1k und so weiter. Beim letzten dann einfach offen lassen. B1 bis Bx sind alle verbunden und sind direkt am analogen Eingang angeschlossen. Zusätzlich wird über einen R mit 1k diese Reihe an GND angeschlossen.

Zeig Mal was Du fabriziert hast! Welche Werte kommen bei Dir raus?

Gruß
Papa

Moin, vielen dank

ich habe nun alles verkabelt und bekomme auch gute Werte wenn ich auf die Taster betätige.
jedoch fällt nach dem Drücken der Wert ab und schwankt sehr stark.

Hier der Leerlauf:

19:10:23.771 -> 422
19:10:24.283 -> 420
19:10:24.785 -> 416
19:10:25.298 -> 411
19:10:25.811 -> 407
19:10:26.275 -> 403
19:10:26.785 -> 398
19:10:27.297 -> 393
19:10:27.809 -> 388
19:10:28.274 -> 383
19:10:28.787 -> 377
19:10:29.303 -> 372
19:10:29.767 -> 366

meine Werte beim Drücken sind diese sind auch stabil schwanken nur ± 1:

19:11:55.312 -> 1023    1
19:11:57.305 -> 909     2 
19:11:57.818 -> 795     3
19:12:00.332 -> 456     4
19:12:01.308 -> 569     5
19:12:02.800 -> 681     6
19:12:04.807 -> 342     7
19:12:05.825 -> 228     8
19:12:08.336 -> 113     9

Außerdem fällt der wert sehr langsam ab nach dem Drücken

19:14:38.861 -> 1023
19:14:39.372 -> 1023
19:14:39.882 -> 1023
19:14:40.393 -> 670
19:14:40.862 -> 677
19:14:41.376 -> 669
19:14:41.891 -> 661
19:14:42.356 -> 657
19:14:42.869 -> 652
19:14:43.382 -> 607
19:14:43.848 -> 616
19:14:44.361 -> 619
19:14:44.875 -> 618
19:14:45.384 -> 613
19:14:45.892 -> 615
19:14:46.357 -> 612
19:14:46.871 -> 603
19:14:47.384 -> 599
19:14:47.894 -> 592
19:14:48.359 -> 583
19:14:48.869 -> 570
19:14:49.383 -> 557
19:14:49.896 -> 543
19:14:50.362 -> 528
19:14:50.875 -> 512
19:14:51.387 -> 496
19:14:51.854 -> 479
19:14:52.364 -> 458
19:14:52.877 -> 435

Muss ich etwas an den widerständen ändern?

Das abspielen der Ordner klappt, aber ab und zu kommt es dann zum zufälligen abspielen von anderen Ordnern durch das langsame Abfallen und den zufälligen Werten im Leerlauf.

Grüße

Nicolas

Hallo @Nicolas34,
Hast du diesen Widerstand dran?