Go Down

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

mc-big-d

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.

mc-big-d

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.

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?

agmue

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:

Code: [Select]
#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
    }
  }
}
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

agmue

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.

Code: [Select]
#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();
}
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

mc-big-d

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.

agmue

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.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

noiasca

im Endausbau bin ich auch für "Single Source" - Ein Programm für alle. Eine ID im EEPROM von der dann alle anderen Einstellungen abgeleitet werden, wie viele/welche Taster, LEDs, CAN "Sender" etc.

Aber zunächst soll er mal drei funktionierende Sketche separat machen.
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

mc-big-d

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

postmaster-ino

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

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.

Und wie kann ich zb "F13" oder CAB usw dann ausgeben?
Code: [Select]
#define KEY_F13       0xF0
Findest Du in \libraries\Keyboard\src\Keyboard.h
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

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?!

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.

agmue

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.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

mc-big-d

F13 bis F 24 sind Erweiterungen der Tastatur, die aber im Regelfall nicht auf einer Tastatur zu finden sind. Man verwendet sie aber für Buttonboxen und der gleichen, weil sie so gut wie nie mit Programmen kolidieren und meist nicht unter Verwendung sind. Ich möchte sie über einen Taster am Modul  betätigen und am PC als Keyboardausgabe ausgeben.

noiasca

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.
klappt bei dir schon die Verbindung mit dem Tutorial von http://henrysbench.capnfatz.com/henrys-bench/arduino-projects-tips-and-more/arduino-can-bus-module-1st-network-tutorial/ ?

Hast du dann schon einen zweiten Sender aufgebaut? klappt das auch schon?

Das RX/TX zusammenfügen scheint mir nicht das große Problem zu sein (zumindest kompiliert das ganze), ich im Urlaub und habe hier aktuell keine 3 freien Unos rumliegen.
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

mc-big-d

WAS willst Du jetzt senden/empfangen?
CAN, oder die TastenKeys zum PC?
Ich möchte über den CAN Bus die Module vernetzen, die dann auf einem DUE zusammen laufen und von da die Daten an den PC ausgeben.

Beispiel 1:

-Taster 1 an Modul 1 wird betätigt und erzeugt den Buchstaben "a"
-Modul 1 sendet diese info an den DUE (über CAN)
-Due verarbeitet diese info und gibt sie an den PC  (über USB)
-PC erkennt das es der Buchstabe "a" ist und reagierst wie wenn man es per Tastatur eingeben würde(er schreibt ein "a")

Beispiel 2:

-Software auf dem PC sagt LED 7 bis 12 sollen rot leuchten und sendet es an den DUE (über USB)
-Due gibt diese Info an die Module aus (über CAN)
-Modul 1 erkennt das es an die LED s bei ihm gerichtet ist und nimmt diese infos auf
-er verarbeitet sie und LED 7 bis 12 werden rot

vielleicht ist es jetzt verständlicher (hoffe ich)

mfg

Go Up