wie berechne ich 11 analoge tasten

Hallo zusammen,

ich baue gerade ein mp3 player für meine kinder und wollte euch fragen, wie genau ich ein 11 Tasten Feld berechnen kann und anschliessend in mein project einbauen kann, dass ich mein "MP3 Shield Vs1053" damit steuern kann.taste 0-8 sollten jeweilige playlists sein (mp3 files in einem ordner) die 9 Next und die 10 Pause/Play.
Ich wollte deshalb ein analog tastenfeld, da warscheinlich alle digital pins des UNO fürs MP3 Shield Vs1053 draufgehen und ich noch ein analog poti als volumenregler gebaut habe und ein MEGA für ein soches projekt sicherlich das falsche ist (kosten / grösse /auslastung / stromverbrauch)

anbei ist zu bemerken, dass ich ein Arduino anfänger bin und bis jetzt nur sketches übernommen habe für kleine lernübungen.

vielen dank für eure hilfe

Freundliche Grüsse Daniel

Die einfachste Lösung dürfte eine IR Fernsteuerung sein, die gibt es als Set mit Fernbedienung und Empfänger. Der Empfänger belegt nur einen einzigen Pin des Arduino und ist einfach anzuschließen. Die Kommandos können mit der bewährten IRremote Bibliothek empfangen und ausgewertet werden.

11 Tasten analog abzufragen ist praktisch kaum möglich, 5+6 vielleicht schon, aber dann werden schon mehr Eingänge belegt als mit der IR Fernbedienung. Und alle analogen Eingänge lassen sich auch als digitale benutzen, falls Du das noch nicht wußtest.

Das IC MCP23017 erweitert mit zwei I2C-Pins am UNO um 16 I/Os. Von Adafruit gibt es eine schöne Bibliothek.

Alternativ mit Wartezeit: Mega 2560 PRO

Hallo,

das funktioniert über eine Widerstandsmatrix die einem analogen Eingang zugeführt wird. Es werden dann 11 Bereiche definiert die einer Taste zugeordnet werden. Google mal nach Widerstandsmatrix oder AVR analog Tastatur oder ähnlichen. Bin sicher da findest du viel zum Thema. Mit switch case kannste auf dem Arduino auch Bereiche abfragen.

switch (value) {
      case 0 ... 80:    // dein Tasten-Code
                        break;
                      
      case 81 ... 160:  // dein Tasten-Code
                        break;
      default: break;
  }

Hallo

such mal nach Manual DF mini Player da ist ein Vorschlag drin wie man das bei dem Modul machen kann, so ähnlich könnte das auch mit einem UNO gehen, aber eigendlich brauchst Du den dann nicht.

Manual

Heinz

Bin gerade über diesen, wie ich finde, guten Beitrag gestolpert: Kommandozeilen-Berechnung von Tastenfeldern an einem ADC-Eingang

Hallo Leute

RuDaIno:
Hallo Leute

Äußerst informativer Beitrag.

Gruß Tommy

Hehe, ja habs auch gerade gesehen das mit dem smili alles danach fehlte.
Werd ich nicht mehr so machen. Hihi
Also noch einmal,

Vielen dank für eure anregungen.
Da meine beiden kinder 1 & 2 Jahre alt sind muss das ganze robust gebaut werden und kann so nicht auch wenn es super einfach wäre mit einer ir fernbedienung realisiert werden.
Da ich alle komponenten für die variante von agmue bei mir rum liegen habe werde ich es so versuchen (auch wenn es die für mich schwierigste lösung ist)
Ich werde dieses wochenende mal versuchen die ganzen berechnungen umzusetzten und werde das resultat hier melden, auch was den arduino sketch angeht. Ich hoffe dass ich das ganze gebacken kriege mit meinen spazenhirn.

Vielen dank und noch einen schönen abend euch allnen.
Mit freundlichen Grüßen aus der Schweiz Daniel

RuDaIno:
Ich werde dieses wochenende mal versuchen die ganzen berechnungen umzusetzten ...

Die fertigen Widerstandswerte stehen doch im Beitrag, die ADC-Werte auch.

Hallo Leute,
lange hats gedauert und dann hab ich es doch noch geschafft trotz dem turbulenten wochenende und neujahr mit meiner familie. wir husten und keuchen alle gerade.

ICH möcht mich erst mal bei allen hier bedanken für den richtigen gedanken anstoss, um die richtigen suchparameter zu finden um dieses kleine Projekt (was mein Spazenhirn echt zum grübeln gebracht hat) zu vollenden.

VIELEN VIELEN DANK!!!

Hier der schaltplan:
https://drive.google.com/open?id=1JYW1sMOSOZH6Y99nyB8MJNVbdtDwyKXj

Ansicht vorne:
https://drive.google.com/open?id=1DaLhjZ4JZeHmzGDgssfV_H1bSKK-lYBK

Ansicht hinten:
https://drive.google.com/open?id=1wqHthp2ceewVAl-3tFcve2DBYlsZsjdj

Ich hoffe, die links funzen

und hier noch den Code:

**************************************************************************
**************************************************************************


// Konstanten ändern sich nicht

// die Nummer des Pins, der für die Drucktasten verwendet wird

const int buttonsPin = A5;

// Variablen werden sich ändern

// Variable für die gedrückte Taste

int pressedButton = 0;

// Die Setup-Routine wird einmal ausgeführt, wenn Sie das Gerät einschalten oder auf reset drücken

void setup()
{
  // Initialisieren Sie die serielle Kommunikation mit 9600 Bit pro Sekunde

  Serial.begin(9600);
}

// Die Schleifenroutine läuft immer und immer wieder

void loop()
{
  // Prüfen Sie, ob eine Taste gedrückt wird
  pressedButton = CheckButtons();

  if (pressedButton != 0)
  {
      Serial.print("Taste: ");
      Serial.println(Taste gedrückt);
      delay(100);
  }
}

// gibt 0 zurück, wenn keine Taste gedrückt wird,
// sonst wird die Nummer der gedrückten Taste zurückgegeben (1 - 11)

int CheckButtons()
{
  int buttonsPinValue = analogRead(buttonsPin);
  int pressedButton = 0;

  Serial.println(buttonsPinValue);

  if (buttonsPinValue > 823)
  {
      // Taste 6 hat einen Wert von etwa 878
      pressedButton = 6;
  }
  else if (buttonsPinValue > 725)
  {
      // Taste 5 hat einen Wert von etwa 768
      pressedButton = 5;
  }
  else if (buttonsPinValue > 649)
  {
      // Taste 4 hat einen Wert von etwa 683
      pressedButton = 4;
  }
  else if (buttonsPinValue > 586)
  {
      // Taste 3 hat einen Wert von etwa 614
      pressedButton = 3;
  }
  else if (buttonsPinValue > 535)
  {
      // Taste 2 hat einen Wert von etwa 559
      pressedButton = 2;
  }
  else if (buttonsPinValue > 492)
  {
      // Taste 1 hat einen Wert von etwa 512
      pressedButton = 1;
  }
  else if (buttonsPinValue > 450)
  {
      // Wenn keine Taste gedrückt wird, beträgt der Wert etwa 473
      pressedButton = 0;
  }
  else if (buttonsPinValue > 400)
  {
      // Taste 8 hat einen Wert von etwa 427
      pressedButton = 11;
  }
  else if (buttonsPinValue > 340)
  {
      // Taste 10 hat einen Wert von etwa 372
      pressedButton = 10;
  }
  else if (buttonsPinValue > 267)
  {
      // Taste 9 hat einen Wert von etwa 307
      pressedButton = 9;
  }
  else if (buttonsPinValue > 178)
  {
      // Taste 8 hat einen Wert von etwa 228
      pressedButton = 8;
  }
  else if (buttonsPinValue > 0)
  {
      // Taste 7 hat einen Wert von etwa 128
      pressedButton = 7;
  }
  return pressedButton;
}

**************************************************************************
**************************************************************************

Hallo,

jetzt schreiben wir das noch etwas kompakter und damit übersichtlicher inkl. ohne blockierende Tasterentprellung

// Konstanten ändern sich nicht

// die Nummer des Pins, der für die Drucktasten verwendet wird

const int buttonsPin = A5;

// Variablen werden sich ändern

// Variable für die gedrückte Taste

byte button = 0;

// Die Setup-Routine wird einmal ausgeführt, wenn Sie das Gerät einschalten oder auf reset drücken

void setup()
{
  // Initialisieren Sie die serielle Kommunikation mit 9600 Bit pro Sekunde

  Serial.begin(9600);
}

// Die Schleifenroutine läuft immer und immer wieder

void loop()
{
  // Prüfen Sie, ob eine Taste gedrückt wird
  button = CheckButtons();

}

// gibt 0 zurück, wenn keine Taste gedrückt wird,
// sonst wird die Nummer der gedrückten Taste zurückgegeben (1 - 11)

byte CheckButtons()
{
  static unsigned long last_ms = 0;
  byte pressedButton = 0;
    
  if (millis() - last_ms > 30) {
    last_ms = millis();
    unsigned int buttonsPinValue = analogRead(buttonsPin); 
  
    switch (buttonsPinValue) {
      case 824 ... 1023:  pressedButton = 6;
                          break;
      case  726 ... 823:  pressedButton = 5;
                          break;
      case  650 ... 725:  pressedButton = 4;
                          break;
      case  587 ... 649:  pressedButton = 3;
                          break;
      case  536 ... 586:  pressedButton = 2;
                          break;
      case  493 ... 535:  pressedButton = 1;
                          break;
      case  401 ... 450:  pressedButton = 11;
                          break;
      case  341 ... 400:  pressedButton = 10;
                          break;
      case  268 ... 340:  pressedButton = 9;
                          break;
      case  179 ... 267:  pressedButton = 8;
                          break;
      case    0 ... 178:  pressedButton = 7;
                          break;
      default:  break;
    }
  
    Serial.print("Taste: ");
    Serial.print(pressedButton);
    Serial.print('\t');
    Serial.println(buttonsPinValue);
  }
  
  return pressedButton;
}

Hallo Doc_Arduino und alle anderen. Vielen dank für deine modifikation. Kannst du mir kurz erklären was dein code anders macht? Was ich heraus lesen konnte ist, dass du für jeden schalter einen bereich aus dem wiederstandswert anschaust. Was macht der break genau?

Eine andere frage noch, kann ich dir den ganzen code vom projekt zeigen?
Vieleicht kannst du dort auch noch optimierungen machen.

Hi

Ohne break; werden ALLE FOLGENDEN CASE ebenfalls ausgeführt.
Also ab Dem, Der 'passt'.
Wenn Keiner passt, wird der case default: benutzt - was passiert, wenn default NICHT benutzt wird und kein case passt ... Da bin ich überfragt.

Bei der Korrektur-Lesung bin ich ja nicht gemeint :wink:

MfG

noch eine andere frage:
wenn die taste im ruhemodus ist, dass heisst wenn keine taste gedrückt wird, schreibt der serial monitor in einer sekunde rund

30x "Taste: 0 471" bis hin zu "Taste: 0 473"

kann mann dem code irgendwie erklären dass er der ruhewert zwischen 470 bis 475 ignorieren soll, oder spielt das für die belastung des arduino's keine rolle?

hängst halt ein if runderhum wenn es dich stört:

if (buttonsPinValue<470 ||  buttonsPinValue >475)
{
    Serial.print("Taste: ");
    Serial.print(pressedButton);
    Serial.print('\t');
    Serial.println(buttonsPinValue);
}

ungeprüft

und wo muss ich dies einfügen, wenn ich es am schluss ergänzend zum Serial.print teil hinzufüge, schreibt es einfach "taste:" nicht mehr.
nun, wenn es nur ein optischer schönheitsfehler ist und es das arduino nicht unnötig beschäftigt, kann ich es auch so sein lassen wie es ist. im finalen zustand kann ich die werte eh nicht abfragen, dann soll es einfach die mp3 playlists starten.

Hallo,

dem Arduino ist das egal. Nur dein Terminal wird immer beschrieben, dass ist unschön, reiner Schönheitsfehler, macht keinen Schaden, aber eben unschön. Deswegen ändern wir das noch ab so wie du das schon bei dir hattest, nur an der neuen Ausgabestelle. 0 Ausgabe wird unterdrückt bzw. rausgefiltert. Ob nun ungleich oder größer 0 ist egal. Den analogen Bereich für die "Taste 0" hatte ich komplett rausgenommen, weil der von dir nicht benötigt wurde. Deswegen gibts dafür auch keinen "case".

Das case switch ist hier im Grunde nur die lesbarere Form deines Codewurms der Bereichsabfragen mit if. Wenn du irgendwann enums verwendest wird du switch case lieben lernen.

Spiel damit rum, nimm paar breaks raus, ändere default, teste und habe deinen Spass. "Nebenbei" liest du in einem Buch was die Funktionen machen.

Apropo Terminal Schönheitsfehler. Wenn ich ich Baudraten von 250k arbeite und ohne Pause Daten ausgeben lasse, dann geht irgendwann das Terminal fest. Zeigt keine Reaktion mehr. Dann hilft nur den Java Prozess zu beenden.

byte CheckButtons()
{
  static unsigned long last_ms = 0;
  byte pressedButton = 0;
    
  if (millis() - last_ms > 30) {
    last_ms = millis();
    unsigned int buttonsPinValue = analogRead(buttonsPin);
  
    switch (buttonsPinValue) {
      case 824 ... 1023:  pressedButton = 6;
                          break;
      case  726 ... 823:  pressedButton = 5;
                          break;
      case  650 ... 725:  pressedButton = 4;
                          break;
      case  587 ... 649:  pressedButton = 3;
                          break;
      case  536 ... 586:  pressedButton = 2;
                          break;
      case  493 ... 535:  pressedButton = 1;
                          break;
      case  401 ... 450:  pressedButton = 11;
                          break;
      case  341 ... 400:  pressedButton = 10;
                          break;
      case  268 ... 340:  pressedButton = 9;
                          break;
      case  179 ... 267:  pressedButton = 8;
                          break;
      case    0 ... 178:  pressedButton = 7;
                          break;
      default:  break;
    }

    if (pressedButton != 0) {
      Serial.print("Taste: ");
      Serial.print(pressedButton);
      Serial.print('\t');
      Serial.println(buttonsPinValue);
    }
  }
  
  return pressedButton;
}

Wenn es sich nicht vermeiden lässt kann ich mir deinen Sketch anschauen. Versprechungen mache ich jedoch keine in der Form ob ich Änderungen vornehme oder nur Hinweise gebe.