6 Taster sollen Buchstaben a bis f ausgeben und WS2812B 1 bis 6 den Status

postmaster-ino:
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.

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.

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

postmaster-ino:
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.

Danke euch für die Hilfe und Anregungen.

Hier ist mal der Code

//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

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

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:

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)

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
  3. 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.

#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):

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:

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.

16 weil 3 * 4 fach Strips und um das zu testen, haben wir die auf 6 links für die Taster genommen und die 6 rechts für die dauer LEDs. Die restlichen waren nur zur Trennung da, bzw weil die Riegel so waren.

agmue:

#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):

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:



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.

Nur um das richtig zu verstehen. Der Code, so wie er da steht, muss dann nur um die
Befehlszeilen für ein Taster erweitert werden?

mc-big-d:
Nur um das richtig zu verstehen. Der Code, so wie er da steht, muss dann nur um die
Befehlszeilen für ein Taster erweitert werden?

Ja, könnte man wohl so sagen.

Anmerkung: Mein Ansatz mit verschiedenen Feldern, wobei Index 0 zum ersten Taster gehört, wird nicht von allen Aktiven dieses Forums gemocht. Ich halte ihn aber für anfängerfreundlich, weshalb ich ihn hier vorschlage. Wenn Du "meine" Felder um 90 Grad drehst, kannst Du eine Struktur daraus machen. Dann kann man mit taster[j].pin auf die Daten zugreifen. In Taster taster[] {} habe ich das so gemacht. Bitte wähle, was Dir eher zusagt.

Prozeduraler Ansatz mit Daten in einer Struktur:

#include "FastLED.h"
#define NUM_LEDS 16
#define DATA_PIN 9
CRGB leds[NUM_LEDS];
const unsigned long debounceDelay = 50;
unsigned long jetzt;                     // Variable für den aktuellen Zeitpunkt

struct Taster {                          // Struktur mit Konstanten, Variablen und Methoden
  Taster(const byte pin, const char zeichen, const byte ledindex): pin(pin), zeichen(zeichen), ledindex(ledindex), ledZustand(0), aktZustand(0), altZustand(0), vorhin(0) {}

  const byte pin;
  const char zeichen;
  const byte ledindex;
  bool ledZustand;
  bool aktZustand;
  bool altZustand;
  unsigned long vorhin;
};

Taster taster[] {                           // hier wird je Taster ein Objekt mit der Struktur Taster angelegt
  // Tasterpin, Buchstabe, LED-Index
  {3, 'a', 0},                              // taster[0]
  {4, 'b', 1},
  {5, 'c', 2},
  {6, 'd', 3},
  {7, 'e', 4},
  {8, 'f', 5}                               // taster[5]
};

void setup() {
  Serial.begin(9600);
  Serial.println("Anfang");
  FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
  FastLED.show();
  for (Taster &t : taster)
  {
    pinMode(t.pin, INPUT_PULLUP);
    t.aktZustand = digitalRead(t.pin);
    t.altZustand = t.aktZustand;
    leds[t.ledindex] = CRGB(CRGB::Red);
    FastLED.show();
  }
}

void loop() {
  jetzt = millis();                         // aktuelen Zeitwert merken
  tasterAuswertung();
}
void tasterAuswertung()
{
  for (Taster &t : taster)
  {
    t.altZustand = t.aktZustand;
    if (jetzt - t.vorhin >= debounceDelay)  // Entprellen
    {
      t.aktZustand = digitalRead(t.pin);
      if (t.altZustand != t.aktZustand)
      {
        t.vorhin = jetzt;
      }
    }

    if (!t.altZustand && t.aktZustand)          // Taster wird gedrückt, nicht losgelassen
    {
      Serial.print(t.zeichen);              // Zeichenausgabe (anstelle CAN)
      t.ledZustand = !t.ledZustand;         // LED-Farbe umschalten
      if (t.ledZustand) {
        leds[t.ledindex] = CRGB(CRGB::Green);
      } else {
        leds[t.ledindex] = CRGB(CRGB::Red);
      }
      FastLED.show();                       // LEDs aktualisieren
    }
  }
}

Hier nochmal die OOP-Variante mit ein paar Kommentaren. In der Struktur steht der Code für einen Taster, wobei mit Taster taster[] {} mehrere Objekte erzeugt werden, für jeden Taster ein Objekt. Das, was Du mehrfach untereinander geschrieben hast, wahrscheinlich mit C&P vervielfältigt, macht der Compiler für Dich, nur effizienter.

#include "FastLED.h"
#define NUM_LEDS 16
#define DATA_PIN 9
CRGB leds[NUM_LEDS];
const unsigned long debounceDelay = 50;
unsigned long jetzt;                     // Variable für den aktuellen Zeitpunkt

struct Taster {                          // Struktur mit Konstanten, Variablen und Methoden
  Taster(const byte pin, const char zeichen, const byte ledindex): pin(pin), zeichen(zeichen), ledindex(ledindex), ledZustand(0), aktZustand(0), altZustand(0), vorhin(0) {}

  void init()
  {
    pinMode(pin, INPUT_PULLUP);
    aktZustand = digitalRead(pin);
    altZustand = aktZustand;
    leds[ledindex] = CRGB(CRGB::Red);
    FastLED.show();
  }
 void run()
 {
    aktualisieren();                        // Tastenzustände aktualisieren
    if (steigend())                         // Taster wird gedrückt, nicht losgelassen
    {
      Serial.print(zeichen);                // Zeichenausgabe (anstelle CAN)
      ledZustand = !ledZustand;             // LED-Farbe umschalten
      if (ledZustand) {
        leds[ledindex] = CRGB(CRGB::Green);
      } else {
        leds[ledindex] = CRGB(CRGB::Red);
      }
      FastLED.show();                       // LEDs aktualisieren
    }
  }
  
  void aktualisieren()
  {
    altZustand = aktZustand;
    if (jetzt - vorhin >= debounceDelay)    // Entprellen
    {
      aktZustand = digitalRead(pin);
      if (altZustand != aktZustand)
      {
        vorhin = jetzt;
      }
    }
  }

  bool steigend()                           // steigende Signalflanke
  {
    if (!altZustand && aktZustand)
    {
      return true;
    }
    return false;
  }
/* nicht benutzt
  bool zustand()
  {
    return aktZustand;
  }

  bool fallend()
  {
    if (altZustand && !aktZustand)
    {
      return true;
    }
    return false;
  }
*/
  const byte pin;
  const char zeichen;
  const byte ledindex;
  bool ledZustand;
  bool aktZustand;
  bool altZustand;
  unsigned long vorhin;
};

Taster taster[] {                           // hier wird je Taster ein Objekt mit der Struktur Taster angelegt
  // Tasterpin, Buchstabe, LED-Index
  {3, 'a', 0},                              // taster[0]
  {4, 'b', 1},
  {5, 'c', 2},
  {6, 'd', 3},
  {7, 'e', 4},
  {8, 'f', 5}                               // taster[5]
};

void setup() {
  Serial.begin(9600);
  Serial.println("Anfang");
  FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
  FastLED.show();
  for (Taster &t : taster) t.init();
}

void loop() {
  jetzt = millis();                      // aktuelen Zeitwert merken
  for (Taster &t : taster) t.run();
}

Danke dir erstmal für die Hilfe. Ich schaue mir das Morgen mal genauer an und versuche es mal voll nach zu vollziehen und zu verstehen. Melde mich dann wieder.

Kleine Motivationshilfe: Du hast sicherlich bemerkt, daß in den Strukturen taster[] die modulspezifischen Werte enthalten sind und daher kompakt modulspezifisch geändert werden können.

Mal in die Zukunft gedacht: 20 verschiedene Programme zu warten ist natürlich mühsam. Da wäre es einfacher, nur ein Programm zu haben und die Werte für die 20 Strukturen im Programmspeicher zu halten und die Nummer des Moduls im EEPROM abzulegen. Oder man legt alle modulspezifischen Werte im EEPROM ab, was aber bei Programmänderungen weniger flexibel ist.

Konstanten, die erst zur Laufzeit ihren Wert bekommen, müssen dann halt Variablen werden.

Hallo zusammen,

agmue ich würde das so, wie du es im 2ten gemacht hast, weiter machen. Hierzu versuche ich gerade mal alles auf zu listen und zu erweitern. Einmal mache ich es alles in einen Skatch und einmal auf das jeweilige Modul abgestimmt.

Mir ist es immer noch ein Rätzel, wie das mit den Sender und Empfänger mit einem Modul klappen soll? Kann mir da jemand mal helfen und das erklären, den ich finde nichts dazu im Netz.

Und wie kann ich zb "F13" oder CAB usw dann ausgeben?

Danke euch für die Hilfe

Hi

Du redest wirres Zeug - WAS willst Du jetzt senden/empfangen?
CAN, oder die TastenKeys zum PC?

Gerne auch in deutscher Sprache und mit logischen Zusammenhängen.

MfG

PS: Der SkAtch will eigentlich SkEtch heißen

mc-big-d:
Mir ist es immer noch ein Rätzel, wie das mit den Sender und Empfänger mit einem Modul klappen soll? Kann mir da jemand mal helfen und das erklären, den ich finde nichts dazu im Netz.

Versuche CAN Bus Grundlagen.

mc-big-d:
Und wie kann ich zb "F13" oder CAB usw dann ausgeben?

#define KEY_F13       0xF0

Findest Du in \libraries\Keyboard\src\Keyboard.h

Also das mit dem F13 klappt nicht. Der gibt immer eine 0 oder 3 aus aber keine F13 Taste. keyboard.h ist drinne und #define KEY_F13 auch aber es klapp nicht?!

Zum Thema CAN geht es mir darum wie sich der Code zusammen setzt sprich anhand eines Beispiels indem zb je 3 Tasten von a und b nach c gesendet werden sollen und je 3 Led Werte von c nach a und b.

mc-big-d:
Also das mit dem F13 klappt nicht. Der gibt immer eine 0 oder 3 aus aber keine F13 Taste. keyboard.h ist drinne und #define KEY_F13 auch aber es klapp nicht?!

Wie testest Du das? F13 gibt es auf meiner Tastatur nicht.