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

Hallo zusammen,

ich (Anfänger mit minimalem Basiswissen) bin dabei, mir ein Modul zu bauen, welches die Tasten a, b, c, d, e und f ausgeben soll.
Zudem sollen die RGB LEDs 1, 2, 3, 4, 5 und 6 den Zustand des dazu gehörigen Tasters anzeigen.

(rot bis gedrückt - dann wenn gedrückt wechsel auf grün - grün bis Taster wieder gedrückt wird - wenn wieder gedrückt wechsel auf rot)

Weiterhin sollen 6 weitere WS2812B einen zugewiesenen Farbcode wiedergeben.

Bis jetzt habe ich die Ausgabe der Buchstaben und das entprellen hin bekommen.

Zu meinen Fragen:

Welche Lib ist zu empfehlen?
Welcher Code zb if else oder if else while usw wäre da am besten geeignet?

Nachfolgend der Code, den ich bis jetzt gemacht habe, mit kleinen Erklärungen:

 #include <Keyboard.h>

int Taste1 = 0; //Taste 1 soll ein (a) ausgeben und WS2812B 1 den zustand anzeigen
int Taste2 = 0; //Taste 2 soll ein (b) ausgeben und WS2812B 2 den zustand anzeigen
int Taste3 = 0; //Taste 3 soll ein (c) ausgeben und WS2812B 3 den zustand anzeigen
int Taste4 = 0; //Taste 4 soll ein (d) ausgeben und WS2812B 4 den zustand anzeigen
int Taste5 = 0; //Taste 5 soll ein (e) ausgeben und WS2812B 5 den zustand anzeigen
int Taste6 = 0; //Taste 6 soll ein (f) ausgeben und WS2812B 6 den zustand anzeigen

void setup ()
{
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(A0, INPUT);
  Keyboard.begin();
}

void loop(){
  // Das setzen des Buchstabens funktioniert es fehlen die LED funktionen 

  // Taste 1 ist nicht betätigt WS2812B RGB LED 1 ist auf rot
  // Taste 1 ist betätigt und gibt den Buchstaben "a" aus WS2812B RGB LED 1 wechslt von rot auf gruen 
  // WS2812B RGB LED 1 bleibt auf gruen bis Taste 1 wieder betätigt wird
  // Wenn dann Tsste 1 wieder betätigt wird startet das ganze von vorn 

  
  Taste1 = digitalRead(3);
  if (Taste1 == HIGH)
  {
  Keyboard.press(97);
  delay(500);
  Keyboard.releaseAll();
  }

  
  // Taste 2 ist nicht betätigt WS2812B RGB LED 2 ist auf rot
  // Taste 2 ist betätigt und gibt den Buchstaben "b" aus WS2812B RGB LED 2 wechslt von rot auf gruen 
  // WS2812B RGB LED 2 bleibt auf gruen bis Taste 2 wieder betätigt wird
  // Wenn dann Tsste 2 wieder betätigt wird startet das ganze von vorn 

  
  Taste2 = digitalRead(4);
  if (Taste2 == HIGH)
  {
  Keyboard.press(98);
  delay(500);
  Keyboard.releaseAll();
  }


  // Taste 3 ist nicht betätigt WS2812B RGB LED 3 ist auf rot
  // Taste 3 ist betätigt und gibt den Buchstaben "c" aus WS2812B RGB LED 3 wechslt von rot auf gruen 
  // WS2812B RGB LED 3 bleibt auf gruen bis Taste 3 wieder betätigt wird
  // Wenn dann Tsste 3 wieder betätigt wird startet das ganze von vorn 
  
  
  Taste3 = digitalRead(5);
  if (Taste3 == HIGH)
  {
  Keyboard.press(99);
  delay(500);
  Keyboard.releaseAll();
  }
  
  // Taste 4 ist nicht betätigt WS2812B RGB LED 4 ist auf rot
  // Taste 4 ist betätigt und gibt den Buchstaben "d" aus WS2812B RGB LED 4 wechslt von rot auf gruen 
  // WS2812B RGB LED 4 bleibt auf gruen bis Taste 4 wieder betätigt wird
  // Wenn dann Tsste 4 wieder betätigt wird startet das ganze von vorn 
  Taste4 = digitalRead(6);
  if (Taste4 == HIGH)
  {
  Keyboard.press(100);
  delay(500);
  Keyboard.releaseAll();
  }
  
    // Taste 5 ist nicht betätigt WS2812B RGB LED 5 ist auf rot
  // Taste 5 ist betätigt und gibt den Buchstaben "e" aus WS2812B RGB LED 5 wechslt von rot auf gruen 
  // WS2812B RGB LED 5 bleibt auf gruen bis Taste 5 wieder betätigt wird
  // Wenn dann Tsste 5 wieder betätigt wird startet das ganze von vorn 
  Taste5 = digitalRead(7);
  if (Taste5 == HIGH)
  {
  Keyboard.press(101);
  delay(500);
  Keyboard.releaseAll();
  }

  
  // Taste 6 ist nicht betätigt WS2812B RGB LED 6 ist auf rot
  // Taste 6 ist betätigt und gibt den Buchstaben "f" aus WS2812B RGB LED 6 wechslt von rot auf gruen 
  // WS2812B RGB LED 6 bleibt auf gruen bis Taste 6 wieder betätigt wird
  // Wenn dann Tsste 6 wieder betätigt wird startet das ganze von vorn 
  
  
  Taste6 = digitalRead(A0);
  if (Taste6 == HIGH)
  {
  Keyboard.press(102);
  delay(500);
  Keyboard.releaseAll();
  }
  
  
  // WS2812B RGB LED 7 bis 12 sollen über die nachfolgenden frei definierbaren Werte R 0-255, G 0-255, B 0-255 eingestellt werden können

   
  { 
  leds[7] = CRGB(255, 0, 0);
  FastLED.show();
  delay(500);  
  leds[8] = CRGB(0, 255, 0);
  FastLED.show();
  delay(500);
  leds[9] = CRGB(0, 0, 255);
  FastLED.show();
  delay(500);
  leds[10] = CRGB(150, 0, 255);
  FastLED.show();
  delay(500);
  leds[11] = CRGB(255, 200, 20);
  FastLED.show();
  delay(500);
  leds[12] = CRGB(85, 60, 180);
  FastLED.show();
  delay(500);
  }    
}

Danke für die Hilfe

LG

Dee

Freundlich gemeinte Hinweise:

FastLED.show();

Die Initialisierung der Bibliothek fehlt.

#include <Keyboard.h>

Auf welcher Hardware läßt Du das laufen?

int Taste1 = 0;
...
Taste1 = digitalRead(3);

Da ist int eine unglückliche Typwahl.

delay(500);

Bei dem, was Du vor hast, mußt Du auf delay() gänzlich verzichten. Verwende für Zeiten millis(). Das bedeutet einen Paradigmenwechsel beim Programmkonzept.

Was fehlt: Tastenentprellung und Flankenerkennung des Tastenzustandes sowie das Merken des LED-Zustandes (entspricht rot oder grün).

Als Anregung:

#include "FastLED.h"
#define NUM_LEDS 13
#define DATA_PIN 2
CRGB leds[NUM_LEDS];

unsigned long jetzt;                     // Variable für den aktuellen Zeitpunkt

struct Taster {
  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;
  }

  void aktualisieren()
  {
    altZustand = aktZustand;
    if (jetzt - vorhin >= 20)
    {
      aktZustand = digitalRead(pin);
      if (altZustand != aktZustand)
      {
        vorhin = jetzt;
      }
    }
  }

  bool zustand()
  {
    return aktZustand;
  }

  bool steigend()
  {
    if (!altZustand && aktZustand)
    {
      return true;
    }
    return false;
  }

  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[] {
  // Tasterpin, Buchstabe, LED-Index
  {3, 'a', 7},
  {4, 'b', 8},
  {5, 'c', 9},
  {6, 'd', 10},
  {7, 'e', 11},
  {A0, 'f', 12}
};

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.aktualisieren();
    if (t.steigend())
    {
      Serial.print(t.ledindex);
      Serial.print('\t');
      Serial.println(t.zeichen);
      t.ledZustand = !t.ledZustand;
      if (t.ledZustand) {
        leds[t.ledindex] = CRGB(255, 0, 0);
      } else {
        leds[t.ledindex] = CRGB(0, 255, 0);
      }
      FastLED.show();
    }
  }
}

agmue:
Freundlich gemeinte Hinweise:

FastLED.show();

Die Initialisierung der Bibliothek fehlt.

#include <Keyboard.h>

Auf welcher Hardware läßt Du das laufen?

int Taste1 = 0;

...
Taste1 = digitalRead(3);



Da ist int eine unglückliche Typwahl.



delay(500);



Bei dem, was Du vor hast, mußt Du auf delay() gänzlich verzichten. Verwende für Zeiten millis(). Das bedeutet einen Paradigmenwechsel beim Programmkonzept.

Was fehlt: Tastenentprellung und Flankenerkennung des Tastenzustandes sowie das Merken des LED-Zustandes (entspricht rot oder grün).

Danke für die Hilfe und Anregung. Ich habe erst vor 24 stunden damit angefangen das zu erlernen bzw zu verstehen und bin deswegen blutiger Anfänger. Deswegen bitte ich um Rücksicht. XP

Wegen der Initialisierung ist es denn die richtige? Weil frag 1000 Leute und du erhälst gefühlte 2000 Antworten.

In den meisten Fällen wird es ein Micro und ansonsten einmal ein Leonardo und einmal ein Due.

Bei dem Rest muss ich mich erst rein fuchsen. Aber Danke für die anhaltspunkte.

LG Dee

mc-big-d:
Wegen der Initialisierung ist es denn die richtige?

Bei dem, was Du vorhast, ist das egal. Ich bevorzuge FastLED.

mc-big-d:
In den meisten Fällen wird es ein Micro und ansonsten einmal ein Leonardo und einmal ein Due.

Die kenne ich alle in der Praxis nicht. Ob das mit Keyboard.h so funktioniert, wie Du Dir das vorstellst, kann ich daher auch nicht einschätzen.

agmue:
Bei dem, was Du vorhast, ist das egal. Ich bevorzuge FastLED.
Die kenne ich alle in der Praxis nicht. Ob das mit Keyboard.h so funktioniert, wie Du Dir das vorstellst, kann ich daher auch nicht einschätzen.

Weshalb bevorzugst du FastLED? Gibt es da Besonderheiten oder der gleichen?

Ja die sind extra dazu da um "Tastaturen" zu simulieren bzw als solche "erkannt" zu werden (so wurde es zumindest empfohlen)?

Ich versuche gerade angestrengt den Code von dir zu verstehen aber steige da nicht so durch. Wäre eine kleine Erklärung bzw kurze Beschreibung zu den Zeilen möglich, wenn du dafür überhuapt Zeit hättest?

Hallo,

hier sollten die Buchstaben dann auch Geschrieben werden wenn man die Jeweiligen Tasten drückt oder bin ich falsch in der Annahme?
Die LEDs reagieren zwar auf die Taste aber der TastenOutput klappt irgendwie nicht.

Taster taster[] {
// Tasterpin, Buchstabe, LED-Index
{3, 'a', 7},
{4, 'b', 8},
{5, 'c', 9},
{6, 'd', 10},
{7, 'e', 11},
{A0, 'f', 12}
};

mc-big-d:
Weshalb bevorzugst du FastLED? Gibt es da Besonderheiten oder der gleichen?

Ich habe zwei Lichtstreifen a 5 m mit 150 und 300 Lichtpunkten, auf denen in der Bar eine Animation läuft. Die 300 Lichtpunkte werden von einem Teensy 3.2, die anderen von einem Nano bespaßt, wobei der Nano das per SPI macht. Die Bibliothek ist von Animationspraktikern geschrieben worden, daher gehen beispielsweise RGB genauso wie HSV. Für Dich ist das aber völlig wurscht.

mc-big-d:
Ja die sind extra dazu da um "Tastaturen" zu simulieren bzw als solche "erkannt" zu werden (so wurde es zumindest empfohlen)?

Du stöpselst also 20 Micros an einen Hub, der am PC 20 COM-Ports erzeugt, die Du dann per Programm abfragst? Spannendes Konzept!

mc-big-d:
Ich versuche gerade angestrengt den Code von dir zu verstehen aber steige da nicht so durch. Wäre eine kleine Erklärung bzw kurze Beschreibung zu den Zeilen möglich, wenn du dafür überhuapt Zeit hättest?

Das ist gut, denn ich wollte Dir aufzeigen, wohin Deine Lernkurve sich ausrichten sollte.

Hinsichtlich Erklärung gibt es zwei Probleme: Ich weiß nicht so recht, was ich erklären soll. Außerdem bin ich OOP-Anfänger und würde sicherlich die richtigen Ausdrücke nicht treffen. Ich mache sowas nur zum Spaß, da ist es egal, ob es nun Funktion oder Methode heißt, sind eh nur willkürliche Namen1).

Besser wären Fragen, da kann ich konkret antworten.

Man kann die Funktionalität auch komplett in die Struktur integrieren:

#include "FastLED.h"
#define NUM_LEDS 13
#define DATA_PIN 2
CRGB leds[NUM_LEDS];

unsigned long jetzt;                     // Variable für den aktuellen Zeitpunkt

struct Taster {
  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;
  }
 void run()
 {
    aktualisieren();
    if (steigend())
    {
      Serial.print(ledindex);
      Serial.print('\t');
      Serial.println(zeichen);
      ledZustand = !ledZustand;
      if (ledZustand) {
        leds[ledindex] = CRGB(CRGB::Red);
      } else {
        leds[ledindex] = CRGB(CRGB::Green);
      }
      FastLED.show();
    }
  }
  
  void aktualisieren()
  {
    altZustand = aktZustand;
    if (jetzt - vorhin >= 20)
    {
      aktZustand = digitalRead(pin);
      if (altZustand != aktZustand)
      {
        vorhin = jetzt;
      }
    }
  }

  bool zustand()
  {
    return aktZustand;
  }

  bool steigend()
  {
    if (!altZustand && aktZustand)
    {
      return true;
    }
    return false;
  }

  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[] {
  // Tasterpin, Buchstabe, LED-Index
  {3, 'a', 7},
  {4, 'b', 8},
  {5, 'c', 9},
  {6, 'd', 10},
  {7, 'e', 11},
  {A0, 'f', 12}
};

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();
}

Andii1980:
Die LEDs reagieren zwar auf die Taste aber der TastenOutput klappt irgendwie nicht.

Ich sehe folgende Ausgabe auf dem seriellen Monitor:

Anfang
7 a
8 b

Anm.:

  1. Die Notwendigkeit sprachlicher Vereinbarungen ist mir vollkommen klar, ich gebe mir diesbezüglich ja auch Mühe. Aber der Spaß am Programmieren steht halt im Vordergrund :slight_smile:

Ah Stimmt, den Seriellen Monitor hatte ich nicht an gehabt :slight_smile:
Die Buchstaben sollten aber auch so ausgegeben werden das sie eine Tastatur Simulieren :wink:

PS: Ich Teste im Moment die Sketches noch für mc-big-d an meiner Hardware aus darum frage ich es grade noch :wink:

agmue:
Du stöpselst also 20 Micros an einen Hub, der am PC 20 COM-Ports erzeugt, die Du dann per Programm abfragst? Spannendes Konzept!

Nein es soll lediglich jedes Modul einzeln für sich funktionieren (Standalone Betrieb) und alle zusammen dann über Can-Bus.

agmue:
Hinsichtlich Erklärung gibt es zwei Probleme: Ich weiß nicht so recht, was ich erklären soll. Außerdem bin ich OOP-Anfänger und würde sicherlich die richtigen Ausdrücke nicht treffen. Ich mache sowas nur zum Spaß, da ist es egal, ob es nun Funktion oder Methode heißt, sind eh nur willkürliche Namen1).

Besser wären Fragen, da kann ich konkret antworten.

Am einfachsten wäre es wenn man es wie einem 10 jährigen erklärt.

Sprich int ist dafür Word dafür Wert dafür
int Taster1 0 = 0;

Und danke für eure Hilfe

PS: Das einbinden des MCP2515 müsste auch gemacht werden wollte aber erstmal das mit dem Standalone hin bekommen und vorallem verstehen.

Andii1980:
Die Buchstaben sollten aber auch so ausgegeben werden das sie eine Tastatur Simulieren :wink:

Ich teste mit einem UNO, da geht das nicht. Der serielle Monitor dürfte dem CAN-Bus näher sein als eine Tastatur-Emulation.

Nach meinem Gefühl stecken in diesem Projekt zu viele ungeprüfte theoretische Annahmen.

Im Prinzip sollen die buchstaben a - f auch in Windows als buchstaben ausgegeben werden. Als HID wird erst einmal ein Arduino Leonardo genommen.

Das Projekt soll ja eine Tastatur-Emulation werden. Es wurde empfohlen auf Grund der "weiten Strecken", dass ganze per Can Bus zu realisieren. Aber naja, es ist halt immer wieder so, der eine sagt das, der andere das.

Ich wollte es am Anfang mit Schieberegister usw realisieren, aber da es anscheinend zu lange ist (total 5 Meter), ist es dann darauf heraus gelaufen.

mc-big-d:
Es wurde empfohlen auf Grund der "weiten Strecken", dass ganze per Can Bus zu realisieren.

Diese Empfehlung unterstütze ich, wobei es sich um eine von mehreren handelte und Du CAN ausgewählt hast.

mc-big-d:
Aber naja, es ist halt immer wieder so, der eine sagt das, der andere das.

Sollte sich das auf mich beziehen, so mißverstehst Du meine Aussage.

Eine von verschiedenen CAN-Bibliotheken verwendet sowas:

mcp2515.sendMessage(&canMsg1);

Das ist für mich nicht weit weg von dem von mir verwendeten Serial.print().

Aber wie bei allen Dingen kann ich mich natürlich irren. Schaun wir mal :slight_smile:

Ich bin gerne bereit, mich anderweitig weiter umzuschauen. CAN Bus hat bis jetzt am meisten Vorteile und wird am meisten empfohlen, deswegen habe ich es gewählt, aber wie gesagt, wenn es sinnvolleres gibt, immer her damit.

Nein das wa so nicht gemeint sonmdern es gibt wohl immer mehrere herangehensweisen und naja die eine BESTE gibt es halt wohl nicht.

Viele wege führen nach Rom, passt da wohl ganz gut.

Generell wäre es hilfreich, so eine Art Leitfaden zu haben. Sprich, dass man hinter jeder Zeile eine minimale Beschreibung hat.

So, also die Funktionen habe ich jetzt programmiert bekommen.
Die LED ist auf rot, bis getastet wird, dann wechselt sie auf grün, bis sie noch mal getastet wird, um dann auf rot zu gehen.

Die Grundbeleuchtung funktioniert auch.

Soweit so gut.

Nun suche ich nach einem gescheiten Plan, oder einer Erklärung, wie ich diese Programmierung dann mit dem CAN BUS Modul anstelle.

Wenn einer einen guten Leitfaden, oder ein TUT hat, wäre es super, wenn mir unter die Arme gegriffen wird.

Danke

Als ersten Treffer spuckt Google dieses Tutorial aus.

Gruß Tommy

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?

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 :wink:

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

#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

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

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