Problem bei Scoreboard - 7 Segment Display

Hallo,

ich bin Andreas und recht neu im Thema. Ich probiere viel selber, allerdings stoße ich hier jetzt an meine Grenze.

Ich habe mir mit dem 3 D Drucker 4 - 7 Segment Displays gedruckt - in jedem Segment befinden sich 4 NeoPixel.
Ziel ist es ein Scoreboard zu bauen das bis 20 zählt. (Heim und Gast) Das klassische halt.

Bisher habe ich mir alles selber ausgedacht und es schon mal geschafft das ein einzelnes Display von 0 bis 9 zählt.

Es sollen dann 2 - 7 Segment Displays hintereinander geschaltet werden.
So kann ich dann mit einem Zähler, bei drücken einer Taste der Fernbedienung, hoch zählen lassen.

Das zweite paar 7 Segment Displays steuere ich über einen anderen Pin. So sind beide unabhängig voneinander. Das funktioniert auch schon.

Adafruit_NeoPixel strip1 = Adafruit_NeoPixel (NUMPIXELS, Digit1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel (NUMPIXELS, Digit2, NEO_GRB + NEO_KHZ800);

So sieht meine Definition der einzelnen Zahlen aus:
(Noch keine Fernbedienung drin, das bekomme ich aber hin)

//Ziffer 1
for (int i=4 ;i<12;i++)
strip1.setPixelColor (i,strip1.Color(150,0,0));
strip1.show();
delay (1500);
strip1.clear();

//Ziffer 2
for (int i=0 ;i<4;i++)
strip1.setPixelColor (i,strip1.Color(150,0,0));
for (int i=8 ;i<16;i++)
strip1.setPixelColor (i,strip1.Color(150,0,0));
for (int i=20 ;i<28;i++)
strip1.setPixelColor (i,strip1.Color(150,0,0));
strip1.show();
delay (1500);
strip1.clear();

Geht sicher eleganter, funktioniert aber.

Jetzt die Frage:

Das ganze soll wie ja schon erwähnt mit einer Fernbedienung gesteuert werden.
Das mache ich mit einem Zähler der hoch läuft, kein Problem.

Allerdings will ich im Loop nur noch die Ziffer aufrufen und nicht immer die Definition rein schreiben.
Denke ich muss im Setup definieren was die einzelnen Ziffern sind.
Hier kann ich ja auch wieder meine Schleifen einbauen, oder?
Aber wie?

Sinngemäß dachte ich mir das so:

Ziffer1 = for etc.
Ziffer2 = for etc.
u.s.w.

Und hier sind wir beim Problem. Das bekomme ich nicht hin.
Ist sicher einfach, aber für mich im Moment nicht lösbar. :wink:

Vielen Dank schon mal für Eure Hilfe!

Dafür müßte ich aber wohl im Setup Bereich erst mal definieren wie sich Ziffer 1,2,3 etc. aufbauen.
(Oh man, ich hoffe ihr versteht was ich versuche zu sagen...:wink: )

Genau hier scheitere ich im Moment.
Ich weiss das dieses Thema wohl schon mal diskutiert wurde, ich verstehe den Code aber nicht, daher habe ich mir das so selber ausgedacht und denke das ich so zum Ziel kommen kann.

Ich würde ein Array aus 10 Byte benutzen (Ziffern 0 bis 9).
Die Bits jedes Bytes zeigen mit 1 an, ob das jeweilige Segment leuchtet.
Dann musst Du nur noch für jedes Segment und jede Stelle die LEDs bestimmen.
Das ist dann von Deinem Aufbau abhängig, den wir nicht kennen.

Gruß Tommy

@andi1107
magst dir mal meine Library ansehen?

http://werner.rothschopf.net/202005_arduino_neopixel_display_en.htm

du definierst einmal welcher Pixel welchem Segment gehört und dann kannst du mit einfachen "print" Ausgaben in das Display drucken.

1 Like

Kurze Frage: Orientierst Du Dich mit Deinen Segmenten an der 7-Segmentanzeige, was die Zählweise angeht? Also:
a - pixel 0-3
b - pixel 4-7
c.. usw...
g - pixel 24 - 27
??

Erst mal vielen Dank für die Antworten.

Das mit dem Array finde ich schon mal gut.
Hab das auch gleich mal gemacht (Nachdem ich mir angeschaut habe was ein Array überhaupt ist) :slight_smile:

So habe ich das gemacht:

int Ziffer1 [8] = {4,5,6,7,8,9,10,11};
int Ziffer2 [20] = {3,2,1,0,23,22,21,20,24,25,26,27,8,9,10,11,12,13,14,15};
int Ziffer3 [20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,27,26,25,24};

Dann in den Loop:

//Ziffer 1
for (int i = 0; i<9; i++)
{
strip1.setPixelColor (Ziffer1[i],strip1.Color(150,0,0));
strip1.show();
delay (100);
}
delay (3000);
strip1.clear();

//Ziffer 2
for (int j=0 ;j<20;j++)
{
strip1.setPixelColor (Ziffer2[j],strip1.Color(150,0,0));
strip1.show();
delay (100);
}
delay (3000);
strip1.clear();

Das funktioniert auch wunderbar - so lange ich nur zwei Array anspreche.
Sobald ich dritte dazu nehme macht er nach dem hoch laden garnichts mehr.
Überfordere ich das Ding schon mit 3 Arrays?
Ich benutze im Moment einen MH Tiny88 - kann aber auch auf einen Uno gehen wenn das Problem hier liegt.

@noiasca
Diese Library habe ich schon mal gesehen, fand ich nur etwas unkomfortabel mit den langen Adressen. ich schau mir das aber nochmal an, danke Dir!

@my_xy_projekt
Ja, genau so habe ich es aufgebaut.
a 0-3 unten
b 4-7 rechts unten
c 8-11 rechts oben
d 12-15 oben
e 19-19 links oben
f 20-23 links unten
g 24-27 Mitte

Na dann such ich mal, ich hatte mal ne Vorlage; Mal sehen, ob ich das gebaut bekomme :wink:

Super! Vielen Dank!

Ach ja, ich kann meine NUMPIXEL auch nicht größer als 80 machen. Ab 81 geht auch nichts mehr.
Glaube ich tausche mal den Tiny gegen einen Uno aus....
kann sich das jemand (oder besser mir) erklären?
Vielen Dank schon mal

Speicher?
Jedes Pixel braucht 3 bytes für die Farbe.
UNO ist ok.

also wenn man die Segmente den Buchstaben gem. Wikipedia zuordnet kommt man auf das:

ich weis zwar nicht was du mit "unkomfortabel mit den langen Adressen" meintest, aber das ist ein vollständiger Sketch für ein Scoreboard auf zwei Pins inkl. 3er Tasten zum Hochzählen / Resetten

const byte ledPin = 11;                // Which pin on the Arduino is connected to the NeoPixels?
const byte ledPinB = 12;                // Which pin on the Arduino is connected to the NeoPixels?

const byte numDigits = 2;              // How many digits (numbers) are available on each display
const byte pixelPerDigit = 28;         // all pixels, including decimal point pixels if available at each digit
const byte addPixels = 0;              // unregular additional pixels to be added to the strip

const byte startPixelA = 0;            // start pixel of display A
const byte startPixelB = 0;           // start pixel of display B (assumption: 2 x 14 used by displayA + 4 additional Pixels)

const byte buttonApin = A3;            // button pin player A, connects to GND
const byte buttonBpin = A0;            // button pin player B, connects to GND
const byte buttonResetPin = A1;        // button to reset scores, connects to GND
byte counterA;                         // counts/goals/score for player A
byte counterB;                         // counts/goals/score for player B

const uint16_t ledCount(pixelPerDigit * numDigits + addPixels);
/*
   Segments are named and orded like this

          SEG_A
   SEG_F         SEG_B
          SEG_G
   SEG_E         SEG_C
          SEG_D          SEG_DP

  in the following constant array you have to define
  which pixels belong to which segment
*/

typedef uint32_t segsize_t;                               // fit variable size to your needed pixels. uint16_t --> max 16 Pixel per digit
const segsize_t segment[8] {
  bit(12) | bit(13) | bit(14) | bit(15),  // SEG_A
  bit(8) | bit(9) | bit(10) | bit(11),  // SEG_B
  bit(4) | bit(5) | bit(6) | bit(7),  // SEG_C
  bit(0) | bit(1) | bit(2) | bit(3),  // SEG_D
  bit(20) | bit(21) | bit(22) | bit(23),  // SEG_E
  bit(16) | bit(17) | bit(18) | bit(19),  // SEG_F
  bit(24) | bit(25) | bit(26) | bit(27),  // SEG_G
  0b0000000000000000   // SEG_DP if you don't have a decimal point, just leave it zero
};

#include <Adafruit_NeoPixel.h>                                       // install Adafruit library from library manager
Adafruit_NeoPixel strip(ledCount, ledPin, NEO_GRB + NEO_KHZ800);     // create neopixel object like you commonly used with Adafruit
Adafruit_NeoPixel stripB(ledCount, ledPinB, NEO_GRB + NEO_KHZ800);     // create neopixel object like you commonly used with Adafruit

#include <Noiasca_NeopixelDisplay.h>                                      // download library from: http://werner.rothschopf.net/202005_arduino_neopixel_display.htm
// in this sketch we handle displayA and displayB as two individual displays:
Noiasca_NeopixelDisplay displayA(strip, segment, numDigits, pixelPerDigit, startPixelA);  // create display object, handover the name of your strip as first parameter!
Noiasca_NeopixelDisplay displayB(stripB, segment, numDigits, pixelPerDigit, startPixelB);  // create display object, handover the name of your strip as first parameter!

#include <OneButton.h>                                               // install OneButton library from library manager
OneButton buttonA(buttonApin, true);
OneButton buttonB(buttonBpin, true);
OneButton buttonReset(buttonResetPin, true);

void clickA()
{
  counterA++;
  Serial.print(F("PlayerA ")); Serial.println(counterA);
  displayA.setCursor(0);
  if (counterA < 10) displayA.print(" ");
  displayA.print(counterA);
}

void clickB()
{
  counterB++;
  Serial.print(F("PlayerB ")); Serial.println(counterB);
  displayB.setCursor(0);
  if (counterB < 10) displayB.print(" ");
  displayB.print(counterB);
}

void resetScore()
{
  Serial.println(F("Reset Score"));
  counterA = 0;
  counterB = 0;
  displayA.clear();
  displayA.print(" 0");
  displayB.clear();
  displayB.print(" 0");
}

void setup()
{
  Serial.begin(115200);
  Serial.println(F("\nNoiascaNeopixelDisplay\n40 scoreboard two displays"));

  strip.begin();                       // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();                        // Turn OFF all pixels ASAP
  strip.setBrightness(50);             // Set BRIGHTNESS to about 1/5 (max = 255)
  strip.clear();
  stripB.begin();                       // INITIALIZE NeoPixel strip object (REQUIRED)
  stripB.show();                        // Turn OFF all pixels ASAP
  stripB.setBrightness(50);             // Set BRIGHTNESS to about 1/5 (max = 255)
  stripB.clear();

  displayA.setColorFont(0xAA0000);     // each display gets its own color, e.g. corresponding to the button color
  displayB.setColorFont(0x00AA00);

  Serial.println(F("test display"));
  for (byte i = 99; i > 0; i = i - 11)
  {
    displayA.print(i);
    displayB.print(i);
    delay(200);
  }
  displayA.print(" 0");
  displayB.print(" 0");
  buttonA.attachClick(clickA);
  buttonB.attachClick(clickB);
  buttonReset.attachLongPressStart(resetScore);
  Serial.println(F("Start Loop"));
}

void loop()
{
  // put here other code which needs to run:
  buttonA.tick();
  buttonB.tick();
  buttonReset.tick();
}

Das basiert auf Beispiel 40 umgebaut auf zwei getrennte Neopixel Pins.

Nicht zu früh freuen...
Das Ding ist jetzt noch recht unübersichtlich, aber wenn der geht, kürze ich die Hälfte raus.
Ich hab keine nopixel - ich mach das blind. Also wenns nicht geht, ist es so.

In der ersten Zeile gibst Du deine PIN an, welche die Stripes ansteuern.

Im setup in der vorletzten Zeile gibst Du eine Zahl für den ersten stripe (12) und darunter iene Zahl für den zweiten stripe (8) ein.
Mal sehen, was bei raus kommt.
Egal was es ist -> bei fehlern keine Fotos machen. erkläre, wenn Du willst.

const byte zahlPin[2]     = {6, 8};                                    // PIN an denen die Stripes hängen
const byte pixelSegLen[2] = {4, 4};                                    // Anzehl Pixel je Segment
const byte numPixel[2]    = {pixelSegLen[0] * 7, pixelSegLen[1] * 7};  // Anzahl der Pixel je Stripe

#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel strip[] = {  Adafruit_NeoPixel (numPixel[0], zahlPin[0], NEO_GRB + NEO_KHZ800),
                               Adafruit_NeoPixel (numPixel[1], zahlPin[1], NEO_GRB + NEO_KHZ800)
                            };

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  strip[0].begin();
  strip[1].begin();
  printZahl(12, 0);  // Darstellung der Zahl auf erstem stripe
  printZahl(8, 1);  // auf zweitem stripe
}

void loop()
{
}


void printZahl(const byte zahl, const byte stripeNumber)
{
  uint8_t digit[2] = {0, 0};
  if (zahl > 9)digit[0] = zahl / 10;
  digit[1] = zahl - digit[0] * 10;
  strip[stripeNumber].clear();
  printDigit(digit[0], 0, stripeNumber);
  printDigit(digit[1], 1, stripeNumber);
  strip[stripeNumber].show();
}

void printDigit(const byte ziffer, const byte pos, const byte strippe)
{
  byte digitPos = pos * numPixel[strippe];
  switch (ziffer)
  {
    case 0:
      for (byte b = 0 + digitPos ; b < 4 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 4 + digitPos ; b < 8 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 8 + digitPos ; b < 12 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 12 + digitPos ; b < 16 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 16 + digitPos ; b < 20 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 20 + digitPos ; b < 24 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      break;
    case 1:
      for (byte b = 4 + digitPos ; b < 8 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 8 + digitPos ; b < 12 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      break;
    case 2:
      for (byte b = 0 + digitPos ; b < 4 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 8 + digitPos ; b < 12 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 12 + digitPos ; b < 16 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 20 + digitPos ; b < 24 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 24 + digitPos ; b < 28 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      break;
    case 3:
      for (byte b = 0 + digitPos ; b < 4 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 4 + digitPos ; b < 8 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 8 + digitPos ; b < 12 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 12 + digitPos ; b < 16 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 24 + digitPos ; b < 28 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      break;
    case 4:
      for (byte b = 4 + digitPos ; b < 8 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 8 + digitPos ; b < 12 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 20 + digitPos ; b < 24 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 24 + digitPos ; b < 28 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      break;
    case 5:
      for (byte b = 0 + digitPos ; b < 4 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 8 + digitPos ; b < 12 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 12 + digitPos ; b < 16 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 20 + digitPos ; b < 24 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 24 + digitPos ; b < 28 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      break;
    case 6:
      for (byte b = 0 + digitPos ; b < 4 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 8 + digitPos ; b < 12 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 12 + digitPos ; b < 16 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 16 + digitPos ; b < 20 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 20 + digitPos ; b < 24 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 24 + digitPos ; b < 28 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      break;
    case 7:
      for (byte b = 0 + digitPos ; b < 4 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 4 + digitPos ; b < 8 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 8 + digitPos ; b < 12 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      break;
    case 8:
      for (byte b = 0 + digitPos ; b < 4 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 4 + digitPos ; b < 8 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 8 + digitPos ; b < 12 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 12 + digitPos ; b < 16 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 16 + digitPos ; b < 20 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 20 + digitPos ; b < 24 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 24 + digitPos ; b < 28 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      break;
    case 9:
      for (byte b = 0 + digitPos ; b < 4 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 4 + digitPos ; b < 8 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 8 + digitPos ; b < 12 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 12 + digitPos ; b < 16 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 20 + digitPos ; b < 24 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      for (byte b = 24 + digitPos ; b < 28 + digitPos; b++)
        strip[strippe].setPixelColor (b, strip[strippe].Color(150, 0, 0));
      break;
  }
}

Du meintest zwar den TO, aber ich habe sie mir auch angesehen :wink:
Schöne Lib und prima dokumentiert.

Gruß Tommy

1 Like

Also, vielen Dank für die Hilfe!
Ich habe mit Hilfe Deines Codes meinen so umgebaut das er jetzt einwandfrei läuft.
Jetzt bin ich dabei die Fernbedienung einzubinden und dann sollte das gehen.
Wenn alles fertig ist und funktioniert poste ich den Code hier nochmal.
Da ich halt recht neu in dem Thema bin muss ich das am Ende immer selber geschrieben haben, sonst verstehe ich nur die Hälfte.

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