Einstieg Arduino

Hallo zusammen,

Bin neu hier und auch im arduino.
Ich überlege, mir einen zu zu legen, um ein Projekt zu realisieren.

Folgendes möchte ich am ende haben:

16 LEDS(bzw 32, aber 2 sollen immer parallel leuchten) die jeweils über einen ihnen zugeordneten Taster eingeschaltet werden.
Dabei sollen je 8 paare aus je einer grüne und roten LED bestehen, wobei sich die jeweils die passende grüne LED ausschalten soll, wenn die rote aktiv wird und umgekehrt.

Meine Fragen dazu sind:

  • ist sowas sinnvoll realisierbar mit dem arduino oder gibts da ne kostengünstigere analoge schaltung?
  • wenn realisierbar... welchen arduino empfehlt ihr und was brauch ich evtl noch dazu, da ich ja am ende 16 Eingänge und 16 ausgänge brauche?

Vielen Dank schonmal

das ist für einen Microcontroller kein Problem.
Wenn du das "Analog" machen willst, wäre die Frage, wie gut deine Kenntnisse mit "Analogen" Bauteilen ist.

du müsstest noch definieren, wodurch so ein LED-Pärchen dann wieder umgeschaltet werden soll.

Noch besser ist - du beschreibst was du eigentlich genau machen willst. Weil so ein Taster und eine LED ... das kann ja nicht der eigentliche Zweck sein. Sonst könntest ja auch einfache Schalter nehmen.

an deiner Stelle würde ich mit einem Arduino UNO R3 anfangen. Machst halt am Anfang nur 5 Ausgänge/5 Eingänge.

Wenn du mehr brauchst

  • du kannst die zweite "inverse" LED an den gleichen Ausgang hängen
  • du kannst LEDs per Multiplex ansteuern (irgendwer wird jetzt noch Charlieplexing ergänzen)
  • du kannst LED Treiber verwenden
  • du kannst addressiebare LEDs verwenden (Stichwort Neopixel, WS2811, APA106)
  • du kannst deine Tasten in einer Matrix verschalten
  • du kannst deine Tasten über einen IC auslesen ...
  • du kannst immer noch einen Mega kaufen

fang mal klein an. Der Rest ergibt sich dann eh.

Wenn du WS2812 LEDs einsetzten kannst, reicht ein Ausgang zum ansteuern

Ich möchte bei einem Dartturnier an der Turnierleitung visuell anzeigen, welche boards gerade belegt sind, und welche gerade frei sind, um die nächsten Paarungen entsprechend einzuteilen.
Grün für Board ist frei, rot für Board ist belegt.

Warum nicht Leuchtmittel und Schalter? Warum ein µC? Was versprichst Du Dir davon?

An dieser Stelle möchte ich WS2815 (12 V mit weniger Strom) ergänzen, wobei das bei den wenigen Pixeln eher eine Randnotiz ist :wink:

Grundsätzlich stellt sich die Frage nach der notwendigen Helligkeit der Leuchtmittel. Ich habe noch nie ein Dartturnier gesehen, aber wenn es mutmaßlich in einer hell erleuchteten Turnhalle stattfindet, benötigst Du eine genügend hohe Aufmerksamkeitswirkung. Möglicherweise benötigst Du helle LEDs mit mehr Strombedarf. Weil Arduinos nur recht wenig Strom an den Pins vertragen, braucht es eine "Verstärkerschaltung". Dazu eignen sich Relais genauso wie Leistungselektronik mit Transistoren.

Weil LED-Streifen so schön einfach zu handhaben sind, könnten auch mehrere Pixel eines Streifens einen Lichtpunkt rot/grün bilden, also 2x2, 3x3 oder 4x4. Anstelle von Streifen sind auch Pixel-Ketten mit 12 mm Durchmesser denkbar. Bei Interesse einfach fragen. (Die Links dienen nur der Anschauung!)

Dann würde ich an deiner Stelle schöne haptische Kippschalter machen (für den der das schaltet) und mit einem Kabel zur "Turnierleitung" weitergeben.

microcontroller Variante

nicht für alles braucht man einen Microcontroller. Man kann aber.

(LED and Button - Wokwi ESP32, STM32, Arduino Simulator)

/*
    LEDs toggled with buttons
    https://forum.arduino.cc/t/einstieg-arduino/1333397/2

    2024-12-18 by noiasca 

    code not in thread
*/

#include "button.h"

class Led {
  private:
    const uint8_t pin;            // the GPIO
    boolean isActive = false;     // ob diese LED grundsätzlich grad aktiv ist oder nicht

  public:
    Led (uint8_t pin) : pin(pin) {}
    void begin() {
      pinMode(pin, OUTPUT);
    }

    void toggle() {
      if (isActive) {
        digitalWrite(pin, LOW);
      }
      else {
        digitalWrite(pin, HIGH);
      }
      isActive = !isActive;
    }
};

Led leds[] {8, 9, 10, 11};
constexpr size_t noOfLeds = sizeof(leds) / sizeof(leds[0]);
Button buttons[noOfLeds] {A0, A1, A2, A3};

void setup() {
  Serial.begin(115200);
  Serial.println("Startup");
  for (size_t i = 0; i < noOfLeds; i++) {
    leds[i].begin();
    buttons[i].begin();
  }
}

void loop() {
  for (size_t i = 0; i < noOfLeds; i++) {
    if (buttons[i].wasPressed()) leds[i].toggle();
  }
}
//

button.h

/*
  a class to debounce a button
  the program is based on "state change detection" and converted to OOP to make it reusable
  2024-11-09 by noiasca
*/

class Button {                                // a simple class for buttons based on the "Debounce" example
    const uint8_t buttonPin;                  // the GPIO / pin for the button
    static constexpr byte debounceDelay = 30; // the debounce time; Static because we only need one value for all buttons
    const bool active;                        // is the pin active HIGH or active LOW (will also activate the pullups!)
    bool lastButtonState = HIGH;              // the previous reading from the input pin
    uint32_t lastDebounceTime = 0;            // the last time the output pin was toggled

  public:
    /**
       \brief constructor for a button

       The constructor takes the GPIO as parameter.
       If you omit the second parameter, the class will activate the internal pullup resistor
       and the button should connect to GND.
       If you set the second parameter to HIGH, the button is active HIGH.
       The button should connect to VCC.
       The internal pullups will not be used but you will need an external pulldown resistor.

       \param buttonPin the GPIO for the button
       \param active LOW (default) - if button connects to GND, HIGH if button connects to VCC
    */
    Button(uint8_t buttonPin, bool active = LOW) : buttonPin(buttonPin), active(active) {}

    /**
       \brief set the pin to the proper state

       Call this function in your setup().
       The pinMode will be set according to your constructor.
    */
    void begin() {
      if (active == LOW)
        pinMode(buttonPin, INPUT_PULLUP);
      else
        pinMode(buttonPin, INPUT);
    }

    /**
        \brief indicate if button was pressed since last call

        @return HIGH if button was pressed since last call - debounce
    */
    bool wasPressed() {
      bool buttonState = LOW;                                        // for the current reading from the input pin
      byte reading = LOW;                                            // "translated" state of button LOW = released, HIGH = pressed, despite the electrical state of the input pint
      if (digitalRead(buttonPin) == active) reading = HIGH;          // overwrite the current button state (independent from active LOW or active HIGH)
      if ((millis()  - lastDebounceTime) > debounceDelay) {          // If the switch changed, AFTER any pressing or noise
        if (reading != lastButtonState && lastButtonState == LOW) {  // If there was a change and and last state was LOW (= released)
          buttonState = HIGH;
        }
        lastDebounceTime = millis();
        lastButtonState = reading;
      }
      return buttonState;
    }
};
//
2 Likes

Über welche Entfernungen sprechen wir hier eigentlich?
Und wir groß und hell soll das werden?

Eine 5mm LED am Kontrollpult... super
Eine 5mm LED am der Dartscheibe... zu klein und dunkel

Vielleicht nicht die schönste Lösung, aber schnell aus einer vorhandenen abgeleitet:

/*
   Forum: https://forum.arduino.cc/t/einstieg-arduino/1333397/4?u=ec2021
   Wokwi: https://wokwi.com/projects/417649916925208577

   Matrix keyboard for 4 rows x 4 columns = 16 keys
   requires one Pin per row and one per column = 8 pins in this case
   And a 16 pixel Neopixel ring

   Press the red key to start a game
   Press the button that corresponds to the blue pixel (changes the color to green)
   If a "black pixel" button was pressed the black pixel changes to red
   If all blue pixels have been changed to green the game ends and
   can be restarted with the red button

   2024/03/25 by ec2021

   Modified for "Dart Board Occupancy Display"

   2024/12/18 by ec2021

*/

#include <Adafruit_NeoPixel.h>
#define PIN_NEO_PIXEL 8  // Arduino pin that connects to NeoPixel
#define NUM_PIXELS 16    // The number of LEDs (pixels) on NeoPixel

Adafruit_NeoPixel NeoPixel(NUM_PIXELS, PIN_NEO_PIXEL, NEO_GRB + NEO_KHZ800);
byte pixelColReference[NUM_PIXELS];
const byte clBlack = 0;
const byte clGreen = 1;
const byte clRed   = 2;

// key matrix
int row[] = {2, 3, 4, 5};
int column[] = {13, 12, 11, 10};
int col_scan;
int last_scan = -1;

constexpr int noOfRows  = sizeof(row) / sizeof(row[0]);
constexpr int noOfColumns = sizeof(column) / sizeof(column[0]);

boolean blueModus = false;
int greenPixels = 0;
int redPixels   = 0;


void setup()
{
  Serial.begin(115200);
  NeoPixel.begin();
  NeoPixel.clear();
  for (int i = 0; i < noOfRows; i++)
  {
    //Initialization of row pins
    pinMode(row[i], OUTPUT);
  }
  for (int i = 0; i < noOfColumns; i++)
  {
    //Initialization of column pins
    pinMode(column[i], INPUT);
    digitalWrite(column[i], HIGH);
  }
  setAllTo(clBlack);
  delay(1000);
  setAllTo(clGreen);
  delay(1000);
  setAllTo(clRed);
}

int aRow;
int aColumn;

void loop()
{
  if (buttonPressed(aRow, aColumn)) {
    action(aRow, aColumn);
  }
}

void setAllTo(byte aColor) {
  for (int i = 0; i < NUM_PIXELS; i++) {
    pixelColReference[i] = aColor;
  }
  updateNeoPixels();
}


void updateNeoPixels() {
  for (int pixel = 0; pixel < NUM_PIXELS; pixel++) {
    switch (pixelColReference[pixel]) {
      case clBlack: NeoPixel.setPixelColor(pixel, NeoPixel.Color(0, 0, 0));
        break;
      case clGreen : NeoPixel.setPixelColor(pixel, NeoPixel.Color(0, 255, 0));
        break;
      case clRed:   NeoPixel.setPixelColor(pixel, NeoPixel.Color(255, 0, 0));
        break;
    }
  }
  NeoPixel.show();
}


boolean buttonPressed(int &aRow, int &aColumn) {
  //Check for pressed buttons
  static boolean pressed = false;
  static unsigned long lastPressTime = 0;
  if (pressed && millis() - lastPressTime < 300) { // The 300 ms avoid bouncing and
    // quick key repetitions
    return false;
  }
  pressed = false;
  for (int i = 0; i < noOfRows; i++)
  {
    if (pressed) break;
    for (int j = 0; j < noOfRows; j++) {
      digitalWrite(row[j], HIGH);
    }
    digitalWrite(row[i], LOW);
    for (int j = 0; j < noOfColumns; j++)
    {
      col_scan = digitalRead(column[j]);
      if (col_scan == LOW)
      {
        lastPressTime = millis();
        pressed = true;
        aRow  = i;
        aColumn = j;
        break;
      }
    }
  }
  return pressed;
}


void action(int i, int j)
{
  int keyNo = i * noOfColumns + j + 1;
  switch (keyNo) {
    case 1 ... NUM_PIXELS :
      changeColor(keyNo - 1);
      break;
    default: // and all others here ...
      Serial.println("No action implemented yet ....");
  }
}

void changeColor(byte pixel) {
  byte color = pixelColReference[pixel];
  switch (color) {
    case clRed: color = clGreen;
      break;
    case clGreen: color = clRed;
      break;
  }
  pixelColReference[pixel] = color;
  updateNeoPixels();
}

  • Voraussetzung für die simple Matrixauswertung ist, dass man nicht mehr als eine Taste gleichzeitig betätigt. Sollte aber hier kein Problem darstellen.
  • Die Led-Anzahl kann einfach erweitert werden; jedoch würde man (anders als im Online-Simulator) die Led-Streifen auf separat mit Strom versorgen.
  • Ich habe (weil in meiner Grundlage vorhanden) eine kreisförmige Anordnung genutzt. Die verwendeten digital ansteuerbaren Leds gibt es in Streifenform. Wichtig: Es muss sich um einen ''digitalen" Ledstreifen handeln! Dort ist i.d.R. eine Beschriftung mit GND, D0, DI und Vcc aufgedruckt. Ist dort neben GND auf dem Streifen noch R,G und B zu lesen, können die Leds nicht einzeln sondern nur zusammen angesteuert werden.

Hier gibt es ggf. weitere Erläuterungen zum Thema (nicht von mir im Detail geprüft ...):

https://raydiy.de/neopixel-mit-arduino-und-esp32-der-led-streifen-ultra-guide/

Also praktisch locker machbar, die Ausgestaltung hängt von den noch offenen Anforderungen ab (welche Abmessungen soll die Anzeige haben).

Viel Erfolg!
ec2021

Naja, man kann das auch komplett analog machen.

Man nehme :
1 Schalter 2 UM
Rote + Grüne LEDs.

Montiere das ganze auf eine Tafel.

Der User geht zur Tafel, legt den passenden Schalter um, und die LED wird umgeschaltet.

Fertig ist.

Die Alternative wäre (richtig schön aufwendig).
Man mache das ganze über eine Software auf einen PC.
Da kann man dann die Spieler eintragen, eine Scheibe zuweisen, und durch den Eintrag des Ergebnis die LED umstellen. (Wobei die LED dann nicht mal eine LED sein muss)

Das würde sogar ohne LEDS funktionieren, wenn man ein PC nimmt, der 2 Monitore anklemmen kann. :wink:

Gruß

Pucki

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.