Code für automatischen Torzähler mit LED Show

Das kann ich Dir jetzt auch nicht auf die schnelle sagen.
Prinzipiell sind die Datenblätter für die WS28xx schlecht gemacht. Sie sind zweideutig und nicht komplett.

Wenn Du verifizieren willst, ob es einen Widerstand braucht, kannst Du ja ein WS2812B opfern und 5V zwischen GND und Din schalten und schauen ob das Teil danach noch funktioniert.

Grüße Uwe

Hier einige Quellen die ich gefunden habe:
https://learn.sparkfun.com/tutorials/ws2812-breakout-hookup-guide/hardware-hookup

Ich hab Dir mal ewas für das rote Tor gebaut.
Starten soll das Ganze mit einem weissen Spieltisch.
Wenn ein (rotes) Tor erkannt wird, soll die LED blinken, die Neopixel sollen einen laufen Pixel haben und der Score soll hochzaehlen.

Nach 5 Sekunden soll die rote LED aus sein, die Pixel wieder weiss und wenn der Ball aus dem Bereich des Sensors ist, wird wieder auf ein neues Tor gewartet.

(Ob das funktioniert, kann ich nciht sagen - wenn nicht, muss jemand anderes ran... )

#include <Adafruit_NeoPixel.h>
#include <SSD1320_OLED.h>
#include <Adafruit_LEDBackpack.h>
#include <Adafruit_BusIO_Register.h>
#include <Adafruit_I2CDevice.h>
#include <Adafruit_I2CRegister.h>
#include <Adafruit_SPIDevice.h>
#include <SevenSegmentDisplay.h>
#include <DIYables_4Digit7Segment_74HC595.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_7segment matrix = Adafruit_7segment();

constexpr uint16_t numpixels {233};
Adafruit_NeoPixel pixels(numpixels, 12, NEO_GRB + NEO_KHZ800);

enum class PIXELTYPE {weiss, orgel};
PIXELTYPE pixeltype;
PIXELTYPE lastpixeltype;

#define LEDROT 9
#define LEDBLAU 10
constexpr byte goalPinRed {4};
constexpr byte goalPinBlue {2};
constexpr byte scoreResPin {7};
#define PIN 12

constexpr bool isGoal {LOW};  // Tor Sensorpegel, wenn Tor erkannt

bool goalRed = false;
uint16_t scoreRed;
uint32_t goalStartTime;

bool resetState = false;

void setup()
{
  pinMode (LEDROT, OUTPUT);
  pinMode (LEDBLAU, OUTPUT);
  pinMode(goalPinRed, INPUT_PULLUP);
  pinMode(scoreResPin, INPUT_PULLUP);
  matrix.begin (0x70);
  pixels.begin();
  pixels.setBrightness(255);
  lastpixeltype = PIXELTYPE::orgel;
  pixeltype = PIXELTYPE::weiss;
}

void loop()
{
  writeDisplay();
  checkRot();
  checkReset();
  setPixels();
}


void writeDisplay()
{
  matrix.writeDigitNum(0, (scoreRed / 10) );
  matrix.writeDigitNum(1, (scoreRed % 10) );
  matrix.drawColon(true);
  //matrix.writeDigitNum(3, (Blau / 10) );
  //matrix.writeDigitNum(4, (Blau % 10) );
  matrix.writeDisplay();
}

void checkRot()
{
  static uint32_t blinkStart = 0;           // Merker
  if (digitalRead(goalPinRed) == isGoal)    // Prüfung des Sensors erfolgreich
  {
    if (!goalRed)                           // Wenn nicht ausgelöst -> vermeidet Doppelzähler
    {
      scoreRed++;
      goalRed = true;                       // setzen
      goalStartTime = millis();             // und startzeit merken
    }
  }
  //
  if (millis() - goalStartTime < 5000)      // Laufzeit nicht abgelaufen
  {
    if (millis() - blinkStart > 50)         // blinken
    {
      digitalWrite (LEDROT, digitalRead(LEDROT)); // Pin beschreiben
      blinkStart = millis();                // Letzte Ausführung merken
    }
    pixeltype = PIXELTYPE::orgel;
  }
  else
  {
    if (digitalRead(goalPinRed) == !isGoal) // Tor mus s frei sein
    { goalRed = false; }                    //
    digitalWrite (LEDROT, LOW);             // zwangsweise aus
    pixeltype = PIXELTYPE::weiss;
  }
}


void checkReset()
{
  if (!digitalRead(scoreResPin))
  {
    scoreRed = 0;
    goalRed = false;
    digitalWrite (LEDROT, LOW);             // zwangsweise aus
    pixeltype = PIXELTYPE::weiss;
  }
}

void setPixels()
{
  static uint32_t pixelStartTime = 0;
  static uint16_t aktuellerPixel = 0;
  if (pixeltype == PIXELTYPE::weiss)
  {
    if (lastpixeltype != PIXELTYPE::weiss)
    {
      // Pixel mit weiss füllen
      pixels.fill(0xFFFFFF);
      lastpixeltype = PIXELTYPE::weiss;
      aktuellerPixel = 0;
    }
  }
  else if (pixeltype == PIXELTYPE::orgel)
  {
    if (millis() - pixelStartTime > 10)
    {
      pixelStartTime = millis();
      pixels.fill(0x000000);
      pixels.setPixelColor(aktuellerPixel, 0x00FFFF);
      aktuellerPixel++;
      if (aktuellerPixel > numpixels)
      { aktuellerPixel = 0; }
      pixels.show();
    }
  }
}

Es wird öfters zu dem Widerstand geraten.

Du hast Recht daß im Datenblatt dieser nicht auftauscht.

grüße Uwe

grafik

Sobald der Streifen nicht mehr versorgt ist, also VDD = 0 V, aber der µC-Ausgang Spannung hat, befindet man sich außerhalb der Spezifikation. Der Widerstand schützt die Schutzdioden vor Überhitzung. Steht so nicht explizit im Datenblatt, scheint mir aber sinnvoll.

Zumindest vertehe ich das Datenblatt so. Im Zweifel halte ich mich an Adafruit NeoPixel Überguide Powering NeoPixels, denn Lady Ada kennt sich ganz gut aus.

WS2813!!! Nicht 2811, Nicht 2812

(Ok, irgendwo hab ich gelesen, das die sich nicht großartig unterscheiden, aber wenn schon, dann wenigstens richtig)

Der Unterschied zwischen 2812 und 2813 ist ein zweiter Datenkanal. Dadurch kann beim 2813 ein LED kaputtgehen, die Daten aber zum übernächsten LED weitergeleitet werden und dadurch ein kaputtes LED nicht den ganzen restliche Strip verdunkelt sondern nur das betreffende LED. Sind 2 nacheinander kaputt ist der restliche Strip auch dunkel.
Grüße Uwe

Nicht nur, aber das dürfte das Hauptaugenmerk sein.
U.a. ist auch LVin VDD +0,7 als Obergrenze...

Es war von mir aber nur als Anmerkung gedacht....

sollte das nicht schon bei >= auf 0 setzen?

Eigentlich war das Absicht, damit ein Step lang alle aus sind. Aber jetzt wo Du's so explizit ansprichst, könntee es natürlich auch irgendwo zum Überlauf kommen, wenn die lib das nicht abfängt...

Die Antwort lautet daher vorläufig ja. :wink:

Vielen Dank. Ich werde es morgen gleich testen! :pray:

Ich habs mal hochgeladen hier das Resultat:

Die Digitalanzeige leuchtet nur auf der Seite blau. Wenn der Sensor unterbrochen wird, gibt es ein Lauflicht mit einem Pixel.

Ich kenne einfach die Bezeichnungen nicht, die du verwendet hast, da ich, wie du sicher bemerkt hast, ein Anfänger bin.
Nunn müsste ich das selbe für Rot einfügen und dann anstatt Orgel ein Blitz.

Das Stromproblem habe ich gelöst: Schaltnetzteil angeschlossen (5v bis zu 20A).

habe vergessen zu erwähnen, dass die Beleuchtung nicht funktioniert (weiss)

Dann ist das schon von Anfang falsch, aber egal. das bekommen wir hin :slight_smile:
Das Lauflicht ist ok.
Damit funktioniert die Torerkennung.

Da gabs noch eine einzelne LED, die mitblinken sollte

Das ist falsch.
Richtig:
digitalWrite (LEDROT, !digitalRead(LEDROT)); // Pin beschreiben
Dann funktioniert auch das blinken.

Funktioniert der Zaehler auf der Anzeige und das reset?
Das weisse Band hab ich im Blick.

In #22 wird Adafruit_LEDBackpack.h doppelt geladen, hast Du kopiert.

Jo. Ist aber nur ne Zeile. :wink:
Die wird ja nur einmal geladen, wenn tatsächlich verwendet.
Ich nehms aber raus.

Danke.