Go Down

Topic: 6 Taster sollen Buchstaben a bis f ausgeben und WS2812B 1 bis 6 den Status  (Read 2503 times) previous topic - next topic

Tommy56

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

mc-big-d

Das habe ich auch schon gefunden. Aber es hilft mir noch nicht so wie ich das will ich möchte mit einem MCP2515 senden und emfangen.

Sprich zb:

Arduino 1:
Sendet Tasterausgaben und empfängt den Hex Code für die LEDs

Arduino 2:
Empfängt den Hex Code für die LEDs und Werte für Servos

Arduino 3:
Empfängt die Tasterausgaben und sendet die Signale via USB an den Rechner
gleichzeitig empfängt er die Hex Codes für die LEDs über USB

Dafür suche ich ein Beispiel bzw welches Modul wäre dafür notwendig und welche herangehensweise?

noiasca

Die im verlinkten Tutorial verwendeten Module basieren auf dem MCP2515.
D.h. das Tutorial ist eine gute Ausgangsbasis

Meine Herangehensweise wäre
- zunächst den Umgang Senden-> Empfangen, zu lernen
- Dann 3 Module: Zwei Sender ein Empfänger
- Dann einen Sender zu einem Sender/Empfänger machen und somit Sender ->Sender/Empfänger->Empfänger aufzubauen.

P.S.: Mein Zeitplan sieht die nächsten Wochen andere "Projekte" vor, aber Module in ausreichender Menge schaden in der Bastelkiste nie ;-)
DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

ArduFE

Wichtig zu wissen ist, dass bei einem CAN-Bus nicht "jemand an jemand" sendet. Bei CAN senden Teilnehmer Botschaften an alle anderen Teilnehmer, diese entscheiden dann jeweils selbst, was sie damit machen.

Beispiel: Es gibt mehrere Lichtschalter und mehrere Lampen. Jeder Lichtschalter kann "Licht an" oder "Licht aus" senden, interessiert sich aber nicht dafür, was damit dann passiert. Jede Lampe sucht in den empfangenen Daten nach "Licht an" und "Licht aus" Paketen und schaltet dann entsprechend. Um alle anderen Daten kümmert sie sich nicht. Man kann bei CAN sogar Empfangsfilter setzen, um sich nicht mit unerwünschten Teilen des Netzwerkverkehrs herumschlagen zu müssen.

Hier mal ein minimales Blinkbeispiel, aber für den Teensy, nicht für den MCP2515:

Der Sender schickt jede Sekunde eine CAN-Message mit dem gewünschten LED-Zustand
Code: [Select]

#include <FlexCAN.h>

const int led = 13;

void setup() {               
  pinMode(led, OUTPUT);   

  Can0.begin(500000);
}

bool state = false;

void loop() {

  CAN_message_t txmsg;
  txmsg.id = 0x222;
  txmsg.len = 1;

  if (state) {
    digitalWrite(led, HIGH);
    txmsg.buf[0] = 1;
  }
  else {
    digitalWrite(led, LOW);
    txmsg.buf[0] = 0;
  }

  Can0.write(txmsg);
 
  state = !state;
  delay(1000);
}


Der Empfänger empfängt alle Messages, reagiert aber nur auf die richtige
Code: [Select]

#include <FlexCAN.h>

const int led = 13;

void setup() {               
  pinMode(led, OUTPUT);   

  Can0.begin(500000);
}

void loop() {
  if (Can0.available()) {
    CAN_message_t rxmsg;
   
    if (Can0.read(rxmsg)) {
      if (rxmsg.id == 0x222 && rxmsg.len == 1) {
        if (rxmsg.buf[0] != 0) {
          digitalWrite(led, HIGH);
        }
        else {
          digitalWrite(led, LOW);
        }
      }
    }
  }
}



Eine wichtige Rolle dabei spielt die Message ID. In einem größeren Projekt muss man sich eine Tabelle machen, wo drin steht, welche Bedeutung welche Message hat, wer sie sendet und wer darauf reagiert. Man kann sich die Messages als eine Art "Ereignis" vorstellen, die ID ist der Typ des Ereignisses, die Datenbytes eventuelle Parameter dazu.

Eine CAN-Bibliothek kümmert sich nur um Versand, Empfang und ggf. Eingangsfilterung. Den Rest muss man im Programm selber handhaben.

postmaster-ino

Hi

UND: Eine CAN-ID ist EINDEUTIG und darf nur von EINEM Sender gesendet werden.
Solltest Du Das nicht beherzigen, hebelst Du die Kollisionserkennung aus und der CAN-Bus kann einfrieren, weil zwei 'gleichrangige' Knoten gleichzeitig versuchen, mit der gleichen ID zu senden - Beide erkennen eine Kollision und brechen das Senden ab (damit der ranghöhere weiter senden kann), Beide erkennen, daß der Bus jetzt wieder frei ist, Beide beginnen erneut das Senden, Beide erkennen eine Kollision ... bis einer den Saft abdreht.
Wenn ein CAN-Knoten mehrere Dinge zu versenden hat, kann man Das mit verschiedenen IDs (und erneut EINDEUTIGEN) machen und/oder man benutzt die 8 Datenbytes (Nachrichtenlänge 0-8 Byte).

Selber habe ich nur die von noiasca gezeigten Module.
Noch ein Tip: Die Strecke vom Bus zu den Knoten muß sehr kurz gehalten werden, 30cm werden dort gerne genannt.
Bei meinen Versuchen klappt ein 2m-Stich zwar auch, ein Zweiter (wird schon gut gehen ...) meistens (sporadische Sendefehler) und beim Dritten kommt nur selten ein korrektes Datenpaket an.
Die Restlichen hängen direkt am Bus, Deren Daten sind unauffällig.
Der erste und der letzte Knoten müssen terminiert sein (bei den abgebildeten Modulen Jumper in J1, die Kontakte J3 sind 1:1 mit den Schraubklemmen verbunden, hier kann man den Bus anstecken/abgreifen)

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

ArduFE

Hi

UND: Eine CAN-ID ist EINDEUTIG und darf nur von EINEM Sender gesendet werden.
Yep,
hab ich vergessen, mein Beitrag war aber auch so schon lang genug.

Vielleicht wäre es bei diesem Projekt hilfreich, einen Bitbereich in den Message-IDs für die Modulnummer zu reservieren. Einmal kriegt man damit eindeutige Ids, wenn es jede Modulnummer nur einmal gibt. Zweitens könnte man die Module einheitlich aufbauen (auch von der Software her) und die Modulnummer z.B. mit Codierschalter oder "Mäuseklavier" einstellbar machen.


Wo ich mir nicht sicher bin, ist die Kombination von CAN und WS2812. Der Empfang von CAN-Daten führt ja in der Regel zu einem Interrupt. Bei ARM-Controllern mit integriertem CAN ist die Zeit dafür wahrscheinlich relativ unbedeutend. Aber beim MCP2515 führt ein Interrupt über die IO-Leitung ja dazu, dass eine SPI-Transaktion angestossen wird. Was passiert eigentlich wenn das während einer Kommunikation mit den WS2812-LEDs passiert ? Die Interrupts sperren, kann ja beim MCP2515 zu Paketverlusten führen, weil die Hardware intern nur zwei Pakete puffern kann.

Beim Teensy ständen auch DMA basierte Libs für WS2812 zur Verfügung, außerdem kann die Hardware bis zu 16 Messages intern puffern (falls sie aufs Senden ganz verzichtet). Mir ist aber klar, dass bei der großen Anzahl der hier zu bauenden Module die Teensys wohl zu teuer wären.

postmaster-ino

Hi

Müssen die Module auch untereinander kommunizieren?
Überschreiben höher priorisierte Nachrichten Unwichtige, wenn der Puffer belegt ist?
Wenn hier 'Nein' und 'Ja' - könnte man die IDs so verteilen, daß die Kleineren (=Wichtigeren, wenn ich's richtig im Kopf habe) von Den Knoten benutzt werden, Die empfangen werden MÜSSEN.

Die oben gezeigten Platinen bieten ja nur einen INT-Pin an, Der zeigt ja nur 'hier ist was' - wie Du bereits geschrieben hast, sind Interrupts ja eh während der Ausgabe an die NeoPixel abgeschaltet (da sonst das Timing gestört wird) - der Arduino also erst NACH der Ansteuerung nach neuen Paketen schauen kann.
Wie viele Pixel wurden hier verarztet? Und wie oft wird Das wiederholt?

Alles nicht so einfach.
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

noiasca

der restliche Sketch hat eh nicht viel zu tun, also kann man auch periodisch fragen ob (gefiltert) eine CAN Nachricht da ist. Ich denke im ersten Schritt kommt man auch ohne Interrupt vom Modul aus.
DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

postmaster-ino

Hi

Anderer Ansatz:
Die Kommunikation des CAN-Bus so langsam machen, daß maximal eine Nachricht während der maximalen 'toten' Zeit einschlagen kann - dafür haben wir Platz im Puffer.
So kann man dann aber halt nicht mehr so viele Daten hin und her schicken.

Wie geschrieben ist der INT-Pin des CAN-Modul nur eine Anzeige, worauf man auch mittels ISR reagieren kann - hat also nur indirekt was mit Interrupt zu tun.
Flag wäre hier passender - wobei man hier schauen müsste, ob der loop()-Durchlauf so schnell bleibt, daß man mit Pollen hin kommt - aber selbst per Interrupt würde man dort (im Normalfall) nur ein Flag setzen, was in loop() abgefrühstückt wird.

Nun denn

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

agmue

Wie viele Pixel wurden hier verarztet? Und wie oft wird Das wiederholt?
6 Taster und 12 Pixel. Die Pixel machen keine Animation, sondern ändern sich nur bei einem Tastendruck oder wenn etwas angezeigt werden soll. Bei geschickter Programmierung also eher selten.

Mit Pixeln vom Typ APA102 oder vergleichbaren, wo Takt und Daten getrennt sind, hat man die geschilderten Probleme nicht, da sie von einem Interrupt unterbrochen werden können.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

mc-big-d

Danke euch für die Hilfe und Anregungen.



Hier ist mal der Code

Code: [Select]


//Code by mc big d
//6 Taster die über je eine RGB LED eine Rückmeldung geben
//Taster nicht gedrückt LED rot, Taster gedrückt LED grün bis noch mal getastet, wen nochmal getastet LED wechselt wieder auf rot
//Zeitgleich wird bei jedem Taster je ein Buchstabe bei jedem Tastvorgang ausgegeben
//Weiterhin sind weitere LEDs auf dauer an in einer frei wählbaren Farbe
//Setup besteht aus 6 Taster mit je einer Zustands-LED und 6 weiteren LEDs für Dekobeleuchtung

#include <Keyboard.h>
#include <FastLED.h>
#define LED_PIN     9
#define NUM_LEDS    16
#define BUTTON_KEY1 97
#define BUTTON_KEY2 98
#define BUTTON_KEY3 99
#define BUTTON_KEY4 100
#define BUTTON_KEY5 101
#define BUTTON_KEY6 102
CRGB leds[NUM_LEDS];

const int buttonPin1 = 3;
const int buttonPin2 = 4;
const int buttonPin3 = 5;
const int buttonPin4 = 6;
const int buttonPin5 = 7;
const int buttonPin6 = 8;

int merker1 = 0;
int merker2 = 0;
int merker3 = 0;
int merker4 = 0;
int merker5 = 0;
int merker6 = 0;

int buttonState1;
int buttonState2;
int buttonState3;
int buttonState4;
int buttonState5;
int buttonState6;

int lastButtonState1 = LOW;
int lastButtonState2 = LOW;
int lastButtonState3 = LOW;
int lastButtonState4 = LOW;
int lastButtonState5 = LOW;
int lastButtonState6 = LOW;


unsigned long lastDebounceTime1 = 0;
unsigned long lastDebounceTime2 = 0;
unsigned long lastDebounceTime3 = 0;
unsigned long lastDebounceTime4 = 0;
unsigned long lastDebounceTime5 = 0;
unsigned long lastDebounceTime6 = 0;

unsigned long debounceDelay = 50;

void setup() {

  Serial.begin(9600);
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);
  pinMode(buttonPin5, INPUT);
  pinMode(buttonPin6, INPUT);
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  Keyboard.begin();
}

void loop() {

  //*********************Taster 1******************************

  int reading1 = digitalRead(buttonPin1);
  if (reading1 != lastButtonState1) {
    lastDebounceTime1 = millis();
  }
  if ((millis() - lastDebounceTime1) > debounceDelay) {
    if (reading1 != buttonState1) {
      buttonState1 = reading1;
      int reading = digitalRead(buttonPin1);
      if ((buttonState1 == HIGH) && (merker1 == 2)) {
        lastDebounceTime1 = millis();
        leds[0] = 0x00FF00;
        FastLED.show();
        Keyboard.press(BUTTON_KEY1);
        Keyboard.releaseAll();
        merker1 = 1;
      }
      else if ((buttonState1 == HIGH) && (merker1 == 1))
      {
        leds[0] = 0xFF0000;
        FastLED.show();
        Keyboard.press(BUTTON_KEY1);
        Keyboard.releaseAll();
        merker1 = 0;
      }
    }
  }
  else if ((buttonState1 == LOW) && (merker1 == 0))
  {
    leds[0] = 0xFF0000;
    FastLED.show();
    merker1 = 2;
  }
  lastButtonState1 = reading1;

  //*********************Taster 2******************************

  int reading2 = digitalRead(buttonPin2);
  if (reading2 != lastButtonState2) {
    lastDebounceTime2 = millis();
  }
  if ((millis() - lastDebounceTime2) > debounceDelay) {
    if (reading2 != buttonState2) {
      buttonState2 = reading2;
      int reading2 = digitalRead(buttonPin2);
      if ((buttonState2 == HIGH) && (merker2 == 2)) {
        lastDebounceTime2 = millis();
        leds[1] = 0x00FF00;
        FastLED.show();
        Keyboard.press(BUTTON_KEY2);
        Keyboard.releaseAll();
        merker2 = 1;
      }
      else if ((buttonState2 == HIGH) && (merker2 == 1))
      {
        leds[1] = 0xFF0000;
        FastLED.show();
        Keyboard.press(BUTTON_KEY2);
        Keyboard.releaseAll();
        merker2 = 0;
      }
    }
  }
  else if ((buttonState2 == LOW) && (merker2 == 0))
  {
    leds[1] = 0xFF0000;
    FastLED.show();
    merker2 = 2;
  }
  lastButtonState2 = reading2;

  //*********************Taster 3******************************

  int reading3 = digitalRead(buttonPin3);
  if (reading3 != lastButtonState3) {
    lastDebounceTime3 = millis();
  }
  if ((millis() - lastDebounceTime3) > debounceDelay) {
    if (reading3 != buttonState3) {
      buttonState3 = reading3;
      int reading3 = digitalRead(buttonPin3);
      if ((buttonState3 == HIGH) && (merker3 == 2)) {
        lastDebounceTime3 = millis();
        leds[2] = 0x00FF00;
        FastLED.show();
        Keyboard.press(BUTTON_KEY3);
        Keyboard.releaseAll();
        merker3 = 1;
      }
      else if ((buttonState3 == HIGH) && (merker3 == 1))
      {
        leds[2] = 0xFF0000;
        FastLED.show();
        Keyboard.press(BUTTON_KEY3);
        Keyboard.releaseAll();
        merker3 = 0;
      }
    }
  }
  else if ((buttonState3 == LOW) && (merker3 == 0))
  {
    leds[2] = 0xFF0000;
    FastLED.show();
    merker3 = 2;
  }
  lastButtonState3 = reading3;

  //*********************Taster 4******************************

  int reading4 = digitalRead(buttonPin4);
  if (reading4 != lastButtonState4) {
    lastDebounceTime4 = millis();
  }
  if ((millis() - lastDebounceTime4) > debounceDelay) {
    if (reading4 != buttonState4) {
      buttonState4 = reading4;
      int reading4 = digitalRead(buttonPin4);
      if ((buttonState4 == HIGH) && (merker4 == 2)) {
        lastDebounceTime4 = millis();
        leds[3] = 0x00FF00;
        FastLED.show();
        Keyboard.press(BUTTON_KEY4);
        Keyboard.releaseAll();
        merker4 = 1;
      }
      else if ((buttonState4 == HIGH) && (merker4 == 1))
      {
        leds[3] = 0xFF0000;
        FastLED.show();
        Keyboard.press(BUTTON_KEY4);
        Keyboard.releaseAll();
        merker4 = 0;
      }
    }
  }
  else if ((buttonState4 == LOW) && (merker4 == 0))
  {
    leds[3] = 0xFF0000;
    FastLED.show();
    merker4 = 2;
  }
  lastButtonState4 = reading4;

  //*********************Taster 5******************************

  int reading5 = digitalRead(buttonPin5);
  if (reading5 != lastButtonState5) {
    lastDebounceTime5 = millis();
  }
  if ((millis() - lastDebounceTime5) > debounceDelay) {
    if (reading5 != buttonState5) {
      buttonState5 = reading5;
      int reading5 = digitalRead(buttonPin5);
      if ((buttonState5 == HIGH) && (merker5 == 2)) {
        lastDebounceTime5 = millis();
        leds[4] = 0x00FF00;
        FastLED.show();
        Keyboard.press(BUTTON_KEY5);
        Keyboard.releaseAll();
        merker5 = 1;
      }
      else if ((buttonState5 == HIGH) && (merker5 == 1))
      {
        leds[4] = 0xFF0000;
        FastLED.show();
        Keyboard.press(BUTTON_KEY5);
        Keyboard.releaseAll();
        merker5 = 0;
      }
    }
  }
  else if ((buttonState5 == LOW) && (merker5 == 0))
  {
    leds[4] = 0xFF0000;
    FastLED.show();
    merker5 = 2;
  }
  lastButtonState5 = reading5;

  //*********************Taster 6******************************

  int reading6 = digitalRead(buttonPin6);
  if (reading6 != lastButtonState6) {
    lastDebounceTime6 = millis();
  }
  if ((millis() - lastDebounceTime6) > debounceDelay) {
    if (reading6 != buttonState6) {
      buttonState6 = reading6;
      int reading6 = digitalRead(buttonPin6);
      if ((buttonState6 == HIGH) && (merker6 == 2)) {
        lastDebounceTime6 = millis();
        leds[5] = 0x00FF00;
        FastLED.show();
        Keyboard.press(BUTTON_KEY6);
        Keyboard.releaseAll();
        merker6 = 1;
      }
      else if ((buttonState6 == HIGH) && (merker6 == 1))
      {
        leds[5] = 0xFF0000;
        FastLED.show();
        Keyboard.press(BUTTON_KEY6);
        Keyboard.releaseAll();
        merker6 = 0;
      }
    }
  }
  else if ((buttonState6 == LOW) && (merker6 == 0))
  {
    leds[5] = 0xFF0000;
    FastLED.show();
    merker6 = 2;
  }
  lastButtonState6 = reading6;
  leds[10] = 0x0000FF;
  FastLED.show();
  leds[11] = 0x0000FF;
  FastLED.show();
  leds[12] = 0x0000FF;
  FastLED.show();
  leds[13] = 0x0000FF;
  FastLED.show();
  leds[14] = 0x0000FF;
  FastLED.show();
  leds[15] = 0x0000FF;
  FastLED.show();
}




mfg

mc big d

mc-big-d

Im Endeffekt ist es so, dass ich die Ausgabe der Taster (von einem Micro) auf einen Master (Due oder Lenonardo) schicken möchte und vom Master aus die Werte für die Deko LEDs, Servos, Motoren usw auf die Micros ausgeben möchte.



Werte für DEKO LEDs, Servos, Motoren usw.:

Pc ->über USB-> Master (Due oder Leonardo) ->über CAN-> Modul 1 bis 20

Werte der Taster:

Modul 1 bis 20 ->über CAN-> Master (Due oder Leonardo) ->über USB-> Pc



Eine Adressierung per Mäuseklavier (oder der gleichen) wäre denkbar, ist aber kein muss, da die einzelnen Module feste zuweisungen über den Skatch (jeder Taster hat eine eigene Aufgabe und ist durch einen Buchstaben, den er ausgeben soll, feste zugewiesen) bekommen.  

mfg

mc big d

postmaster-ino

Hi

Warum für zig Taster X Mal den gleichen Code?
DAS sieht für mich irgendwie danach aus, daß man diese Funktionalität in eine Funktion auslagern sollte.
Sowohl der Taster-Pin wie die LED-Nummer sind zuvor bekannt und können der Funktion übergeben werden.

Warum int für Digital-Eingänge?
Erwartest Du mehr als 256 mögliche Antworten, daß Du dafür zwei Byte Speicher verbrasst?
byte oder boolean wäre hier meine Wahl (Beides wird ein Byte Speicher brauchen).

Auch Deine merker=1, merker=2 - gib diesen Nummern sprechende Namen - nutze dafür enum {name_1, name_2, button_gedrueckt, ...};
merker1=button_gedrueckt; (intern wird Das wieder durchnummeriert, kann Dir aber egal sein).

Die an den Stripe übergebenen Farben bietet die Library (mit sehr sehr hoher Wahrscheinlichkeit) selber bereits als Farb-Name an, wenn nicht: selber definieren.

Stichwort: Define
Benutze statt Dessen
const byte name = wert;
So hat der Kompiler die Chance, erkennen zu können, ob Du Dich mit den Datentypen verhaust und kann Dich vor Seiteneffekten warnen (Stichwort: Warnungen einschalten).

Auch solltest Du Dir 'nur' merken, daß Änderungen am Stripe gemacht wurden um an EINER Stelle in der loop() die Daten via
FastLED.show();
an den Stripe zu schicken.
Auch, wenn's hier nur 6 LEDs sind, schickst Du bei jedem .show den ganzen Kram an die LEDs - und weiter oben wurden schon Bedenken geäußert, daß in genau dieser Zeit Befehle vom CAN rein kommen können - also die LED-Zeit möglichst gering halten, man weiß nie, wann wieder mit Einem geschwätzt werden sill.

Wenn ich Deinen Sketch richtig interpretiert habe, macht Der (soll machen) folgendes:
Code: [Select]

for (byte i=0;i<6;i++){
   led[i]=Tasterstatus[i];
   Wenn Taster gedrückt, sende einmalig KeyCode_pressed
   Wenn Taster gelöst, sende einmalig KeyCode_released
}
LED.show();


MfG

PS: Klar, mit einigen Zeilen drüber und einigen Funktionen drunter - also etwas länger wird der Sketch dann doch schon.

PPS: Dann wird das KeyCode_pressed/..._released wohl eher ein CAN.send() sein - aber trotzdem nur einmalig (es sei, es werden Tastenwiederholungen gewünscht, Das sollte aber ein anderer Tastencode sein - Das ist bei mir aber schon einige Jahre her und außerdem eher auf dem PC gewesen)
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

mc-big-d

Danke dir für die Tips werde es mir noch mal genauer abschauen müssen.

Ist halt mein erster Code, denn ich selbst geschrieben habe und ich habe erst vor ein paar Tagen damit angefangen. Deswegen bin ich noch nicht so vertraut mit dem Ganzen. #NOOBLIFE

Die Tasterfunktion in verbindung mit den LEDs hast du leider falsch verstanden.

1. Taster aus und noch nicht getastet = LED Rot
2. Taster getastet = LED Grün; Buchstrabe XY wird ausgegeben
2. Taster losgelassen = LED immer noch Grün
4. Taster wieder gedrückt = LED wechselt zu Rot; Buchstrabe XY wird ausgegeben

und dann wieder von vorn.


agmue

Code: [Select]
#define NUM_LEDS    16
Wie kommst Du auf 16? 6 für Taster plus 6 für Animation sind 12, oder?

Felder erleichtern, wie schon in #27 empfohlen, das Programmieren (unvollständug):

Code: [Select]
const byte buttonKeys[] = {97, 98, 99, 100, 101, 102};
const byte buttonPins[] = { 3,  4,  5,   6,   7,   8};
const byte ANZAHL = sizeof(buttonPins);
bool merker[ANZAHL], buttonState[ANZAHL], lastButtonState[ANZAHL];
unsigned long lastDebounceTime[ANZAHL];
const unsigned long debounceDelay = 50;

Dann kannst Du alle sechs Taster in einer Schleife behandeln:

Code: [Select]
for (byte j = 0; j < ANZAHL; j++) {
    pinMode(buttonPins[j], INPUT);
  }


Die Konstanten und Variablen buttonKeys[0], buttonPins[0], merker[0], buttonState[0], lastButtonState[0] und  lastDebounceTime[0] gehören alle zum ersten Taster.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

Go Up