PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Vollfarbige 7-Segmentanzeigen (RGBDIGIT) direkt ansteuern, wie



hardware.bas
04.01.2024, 21:48
Hallo, liebe Community,
seit geraumer Zeit versuche ich, eine mehrstellige 7-Segmentanzeige aus RGBDIGITs mittels BASCOM anzusteuern,
diese RGBDIGITs bestehen aus 8 adressierbaren RGB-LEDs WS 2812 und es gibt seit einiger Zeit im BASCOM eine sogenannte rainbow.lib, welche diese LED-Strings aus einem einzigen Port gezielt adressieren sollte, nun meine Fragen;
- gibt es schon praktische Erfahrungen mit RGBDIGITs
- kann man die rainbow.lib auch in alte BASCOM-Versionen
nachträglich integrieren
Vielen Dank für Euer Feedback
Micha

Crazy Harry
05.01.2024, 09:59
Hallo,

deine Frage kann ich dir leider nicht beantworten, da ich einen anderen Compiler benutze, aber die Ansteuerung dieser LEDs ist nicht ganz einfach, da das Timing genau passen muß. Deshalb habe ich mir einen Ansteuerplatine geholt: https://www.led-genial.de/DIGI-DOT-Booster-WS2812-und-SK6812-ueber-SPI-Schnittstelle-ansteuern

Gruss
Harry

hardware.bas
05.01.2024, 21:50
Vielen Dank für die schnelle Antwort.
Da ich die RGBDIGIT-Ansteuerung eh mit einem expliziten AVR gemacht hätte, ist dieser Vorschlag sehr interessant, wenn ich also im AVR-BASCOM programmierten Hauptchip meine beiden 4-stelligen Anzeigen (also 64 mal ws2812) mit dem entsprechenden Bitmuster bei Anzeigenaktualisierung füttern kann, währe das ok ... muss mit der SPI- Programmierung jedoch klarkommen, im Datasheet des Boosters sind da noch einige Fragen offen ... Mal schauen, vielleicht kommt doch noch ein Vorschlag mit der Rainbow.lib ... bin für alles offen, wenn es sich im Bereich BASCOM befindet

R2D2 Bastler
07.01.2024, 09:42
Hi Micha,

ich habe schon eine Menge WS2812b-Projekte in Bascom realisiert.
Die originale rainbow.lib, die man ganz zu Anfang mal extra einbinden musste, brauchst Du heute nicht mehr. Soweit ich weiß, ist sie mittlerweile selbst in der Demo-Version von Bascom mit dabei. Die Ansteuerung ist damit kein Problem mehr. Bedingt durch das vorgeschriebene Timing der WS2812b's darf Dein AVR allerdings nicht zu langsam laufen (1MHz wäre definitiv zu langsam).

Auf welchem AVR soll Dein Programm laufen?
Was genau sollen Deine Digits anzeigen (Uhr, Temperatur, Zähler usw)?

Nette Grüße
Rob

hardware.bas
09.01.2024, 20:29
Hallo, Rob,
vielen Dank für den Lösungsansatz.
Obwohl ich eine ca 15jahr alte Kaufversion von BASCOM habe, ist es beruhigend zu wissen, daß die rainbow.lib jetzt bei der Demoversion verfügbar ist, vielleicht reicht die ja für mein Projekt.
Realisiert werden soll eine 2-reihige numerische Anzeige von jeweils 4 RGBDIGITs für das Monitoring des Elektroenergieverbrauches, der PV-Anlage und des späteren Speichermanagementsystem im Haus, dazu nehme ich (wie so oft) einen Atmega162 im DIL-Gehaeuse, allerdings möchte ich Diesen nicht unbedingt für die Anzeige zusätzlich belasten, so dass es mir eigentlich egal ist, welchen AVR ich für die Anzeige nehme (DIL-Bauform ist Bedingung).
Ich würde in diesen (kleinen und schnellen) Anzeige-AVR dann nur das bereits aufgearbeitete und aktualisierte Bitmuster der 64 Segmente und der Farben reinshiften und der Anzeige-AVR macht den Rest, die Helligkeit wird im Anzeige-AVR hinterlegt ... das war mein erster Gedankenansatz.
VG Micha

R2D2 Bastler
10.01.2024, 10:40
Hi Micha,

wenn Du eine Kaufversion von Bascom hast, kannst Du sie ja kostenlos updaten (es hat sich in den letzten 15 Jahren viel getan in Sachen Bug-Fixes). :roll:

Was die "Belastung" Deines AVRs angeht: Solange Du keine extrem zeitkritischen Dinge nebenher machen musst, hält sich die Belastung durch die WS2812b's in Grenzen. Ein Datenstrom muss ja nur gesendet werden, wenn sich an Deiner nummerischen Anzeige etwas ändert. Damit sie "ablesbar" bleibt, macht es auch wenig Sinn, sie mehr als 1-2x pro Sekunde zu aktuallisieren.
Natürlich kann man die Steuerung der Anzeige auch, wie von Dir geplant, in einen weiteren AVR auslagern.

Wenn Dein externer "Anzeige-AVR" ansonsten nix zu tun hat, reicht hierfür schon ein Attiny85 mit internen 8Mhz. In den folgenden Beispielen arbeitet je ein Attiny85:


Attiny85 mit 60 WS2812b's


https://youtu.be/CepzJujXEsM


Attiny85 mit 90 WS2812b's


https://youtu.be/Q_YpYrAWZCc



Ich persönlich nehme für größere Projekte gerne einen Arduino Nano (Clone) mit einem ATmega328P drauf.
Der Nano passt auch ins 2,54mm Raster, läuft mit 16Mhz, verfügt über ausreichend Speicher und ist über USB (Bootloader) programmierbar. :cheesy:

Nette Grüße
Rob

hardware.bas
11.01.2024, 21:53
Vielen Dank, Rob,
dann sollte ich das tatsächlich mit nur einem Atmega machen, jedoch erste Versuche mit einem LED-Stripe (WS2612) realisieren.
Was ich noch nicht weiss, da ich die RGBDIGs nicht zerschießen will, wie reagieren die WS2612 beim Anlegen der 5V-Betriebsspannung ohne Daten, ich hoffe, die sind dann dunkel ...
VG Micha

Crazy Harry
12.01.2024, 09:42
OT @Rob: Wieviele Ufo-Sichtungen gab es, als du das getestet hast? :D

Gruss
Harry

R2D2 Bastler
12.01.2024, 10:07
Hi Micha,

Du meinst bestimmt WS2812, nicht WS2612, oder?

Von den WS2812b's gibts ne Menge Clons. Ich hatte schon welche, die beim Anlegen der 5 Volt auf "100% an" gegangen sind (normalerweise sollten sie alle aus bleiben). Dies wirkt sich nicht nur extrem negativ auf die Stromaufnahme aus, sondern "flasht" einen richtig, wenn man gerade davor sitzt. :cool:
Auch gibts welche, bei denen die Farbreihenfolge nicht stimmt (kann man aber problemlos im Code beheben).

Worauf Du besonders achten musst: Die Spannung am Dateneingang einer WS2812b darf niemals höher sein, als die Spannung an deren VCC. Dies kann schnell passieren, wenn die Spannungsversorgungen von AVR und WS2812b's unterschiedlich sind (z.B. Netzgerät für WS2812 und USB für AVR) oder es zu Spannungsschwankungen durch große Änderungen der Stromaufnahme kommt (z.B. durch alle LEDs an/aus schalten). Ich empfehle an dieser Stelle immer, zusätzlich eine Schutzschaltung mit einzubauen, siehe
www.led-studien.de/schutzschaltung-fuer-ws2812-pixel

Da Du Deinen LED-Stripe ohnehin zerschneiden wirst, um Deine 7-Segment-Anzeigen zu bauen, kannst Du zu Beginn erst mal mit einem kurzen Stripe von z.B. 5 LEDs experimentieren. Da hält sich die Stromaufnahme in Grenzen und Du zerschießt Dir nicht den ganzen Strip, falls doch mal irgendetwas schief gehen sollte. :roll:

Sag einfach Bescheid, falls etwas nicht klappt. :)

Nette Grüße
Rob

- - - Aktualisiert - - -

OT @Harry: Beim kleinen Nurflügler gabs weniger Meldungen, als bei diesem hier :cheesy:


https://youtu.be/naPeRhJJCds

hardware.bas
12.01.2024, 21:02
Hallo, Rob,
natürlich meine ich die WS2812; die LED-Stripes zum Testen nutze ich dann für andere Zwecke; für die 7-Segmentanzeigen (neue Planung 2x6stellig untereinander) sollen, wie schon erwähnt, die bereits fertig erhältlichen RGBDIGITs Verwendung finden. Natürlich würde ich niemals höheren Datenpegel als Ub an die Eingänge geben, bei mir spielt sich dass ausschließlich mit 5VDC ab und die RGBDIGITs werden von der gleichen Stromversorgung gespeist, wie der AVR. Vielleicht sollte man als Erstroutine alle LEDs ein paarmal auf Dunkel setzen, um die Anstiegsrampe der Spannungsversorgung zu überbrücken?
Viele Grüße, Micha

R2D2 Bastler
13.01.2024, 10:16
Hi Micha,

ah, ok, fertige RGBDIGITs. Hab ich überlesen. :oops:

Bei den fertigen RGBDIGITs geh ich ganz stark davon aus, dass die aus sind, wenn die Versorgungsspannung angelegt wird. Während der Anstiegsrampe der Spannungsversorgung sollte man keine Daten zu den LEDs senden (der AVR wird zu diesem Zeitpunkt ohnehin noch nicht arbeiten, falls doch, könnte die Spannung am Datenpin unter ungünstigen Bedingungen bereits höher sein als die Spannung am VCC Pin der LEDs). Daher auch die empfohlene Schutzschaltung.

Halte uns über Fortschritte auf dem Laufenden, ich bin sicher, dieses Thema interessiert auch den ein oder anderen Mitleser. :)

Nette Grüße
Rob

hardware.bas
14.01.2024, 21:01
Hallo, Rob,
vielen Dank erst mal allgemein und natürlich auch für die realisierten Demo-Videos. Ich beabsichtige nun doch die Anzeige auf einem Extra-AVR zu legen, damit ich bei der Entwicklung der Hauptschaltung die Anzeigeroutine aus den experimentellen Flashroutinen raushalten kann.
Beim Studium des Impulsdiagrammes scheint ja die Taktfrequenz von 10 MHz das Optimum zu sein, da die geringste Auflösung des Impulsdiagrammes 50 ns beträgt, wenn 8 oder 16 MHz oder gar ein Baudratenquarz in diesem Bereich auch noch funktioniert, wäre das toll.
Letztendlich würde ich dann die 12x8x24 Bits, also 2304 Bits vom Haupt-AVR in einen "Farbspeicher" im Anzeige-AVR bei Bedarf relativ langsam reinshiften und diese 2304 Bits müsste dann die rainbow.lib für eine Kette von 96 WS2812 aufbereiten, also volle Adressierbarkeit aller LEDs in einer Kette, könnte dieser Gedankengang richtig sein ... die Übertragung vom Haupt-AVR zum Anzeige-AVR kriege ich hin, bin ziemlich BASCOM-erfahren, jedoch bisher nur bis ca 4 MHz und programmiere über DIY-Dongle basierend auf der LPT-Schnittstelle meines WIN-XP-Laptops ...
VG Micha

R2D2 Bastler
14.01.2024, 23:49
Hi Micha,

die Bascom Hilfe schreibt zur Frequenz folgendes:
"A minimum CPU-speed of 8 MHz is required. Tests with WS1812b- types showed, it also works with frequencies down to 6.5 MHz because of the tolerance bandwidth by the chips."
Ab 8 Mhz bist Du auf jeden Fall auf der sicheren Seite.

Zu Deinem Gedankengang:
Wenn Dein "Haupt-AVR" die Daten schon so weit vorbereitet, ist die meiste Arbeit ja schon erledigt. Ob Du nun die 2304 Bits zu Deinem Anzeige AVR oder gleich direkt zu den LEDs sendest, ist eigentlich nur noch eine Zeitfrage.
Die reine Datenübertragung zu den 96 LED würde ca 2,93 ms dauern (falls ich mich nicht verrechnet habe).

Die Rainbow.Lib arbeitet nämlich genau nach dem von Dir beschriebenen Gedankengang:
Sie legt einen "Farbspeicher" in Form eines Arrays an. Die Größe des Arrays entspricht der LED Anzahl x 3 (also Deine 96 LEDs * 3 = 288 Bytes bzw 2304 Bits).
Beim Senden wird der Inhalt des Farbspeichers zu den LEDs geschoben (mit dem passenden Timing).

Also wenn Dein Haupt-AVR die 2,93 ms nicht entbehren kann, und es Dir um ein möglichst große Entlasung des Haupt-AVRs geht, würde ich nur die "Nutzdaten" zum Anzeige-AVR senden. Diese wären:
- Die anzuzeigenden Werte für jede 6-stellige Anzeige (2x DWORD = 8 Byte)
- Die gewünschte Farbe für jede Anzeige (2x 3 Byte = 6 Byte)
So müsste man nur 14 Byte (anstelle 288 Byte) übertragen. Der Anzeige-AVR kann diese Daten anschließend aufbereiten, auf den Farbspeicher mappen und anschließend zu den LEDs senden.

Es führen, wie immer, viele Wege nach Rom. :cheesy:

Nette Grüße,
Rob

hardware.bas
23.02.2024, 22:19
Hallo Rob,
ich will jetzt der Realisierung weiter entgegenschreiten. Die rainbow.lib verlangt ja ein ganzes Byte für ihre Anwendung, jedoch nur einen einzigen PINout für die Aussendung des Impulsdiagrammes der 2612 ... könnte es vielleicht einen Vorteil darstellen, wenn man alle Ports nutzt und pro Port nur einen der 8 Digits bedient ?
Die Ausgangsports würde ich dann über UND-Glieder weiterleiten und entsprechend mit dem Reset-Pin des AVRs verbinden, so dass es keine Probleme mit den RGB-DIGITS beim Flashen gibt

R2D2 Bastler
24.02.2024, 10:42
Hallo Micha,

den Aufwand mit UND-Gliedern würde ICH mir sparen. Probleme beim Flashen seh ich keine (außer dass die Digits dabei vielleicht kurz wild flackern oder aufblitzen).

Zum Thema je einen Pin pro Digit:
Man könnte jedem Digit einen eigenen Pin spendieren, aber warum sollte man? Es führt letztenendes nur zu mehr Verdrahtungsaufwand. Das Mapping ist problemlos im Code zu bewerkstelligen, sodass ein einziger Pin ausreicht. Konkret wären das im Code ein paar Variablen mehr plus eine einzige (!) Codezeile :-)

Schau Dir mal den folgenden (ungetesteten!) Demo-Code an. Hier siehst Du, wie einfach das Mapping sein könnte. Er ist auch problemlos erweiterbar. Vielleicht könntest Du den Code mal bei Dir testen und berichten, ob er funktioniert (ich hab leider keine RGB-Digits hier). Ich bin im Code einfach davon ausgegangen, dass Segment "a" die erste LED in so einem RGB-Digit ist und Segment "g" das siebte.

Der Code arbeitet nach dem Prinzip: Zeige eine bestimmte Ziffer (oder Symbol) auf einem bestimmten RGB-Digit. Die zur Verfügung stehenden Ziffern und Symbole sind in der Segment-Tabelle zu finden.

Nette Grüße
Rob




' ================================================== ===================
' Test-Demo 7-Segment Anzeige mit WS2812b (RGB-Digits)
' Je eine WS2812b-LEDs pro Segment
'
' a
' ****
' * *
' f * * b
' * *
' * g *
' ****
' * *
' e * * c
' * *
' * *
' ****
' d
'
'
' Die Nutzung des Codes (auch auszugsweise) ist ausschließlich für nicht
' kommerziellen Nutzung freigegeben!
' Der Code ist experimentell und die Benutzung erfolgt auf eigene Gefahr!
' Der Sourcecode darf für den Eigenbedarf beliebig geändert werden.
'
' ================================================== ===================

' Autor Robert L. 2024
' Bascom 2.0.8.6
' Version 0.0.1


$Regfile = "m328pdef.dat"
$HWStack = 60
$SWStack = 60
$Framesize = 60
$Crystal = 16000000 ' Ext. Quarz
Waitms 400 ' Warten, bis Spannung stabil anliegt


' --------------------------------------------------------
' Globale Definitionen
Config Base = 0 ' Arrays beginnen bei 0


' --------------------------------------------------------
' Konstanten WS2812b
Const Num_LEDs = 48 ' Anzahl LEDs (für 6 RGB-Digits -> 6 * 8 LEDs = 48)


' --------------------------------------------------------
' WS2812b konfigurieren
Config Rainbow = 1 , Rb0_len = Num_LEDs , Rb0_port = PortB , Rb0_pin = 0
' ^ Angeschlossen an Pinx
' ^------------ Angeschlossen an Portx
' ^-------------------------- Anzahl LEDs auf dem Strip
' ^------------------------------------- Anzahl der Strips

Dim Color(3) as Byte ' Array, welches die 3 Farbwerte enthält
Red Alias Color(_base)
Green Alias Color(_base + 1)
Blue Alias Color(_base + 2)

Dim Black(3) as Byte ' Array zum Ausschalten der LEDs
Black(_base) = 0
Black(_base + 1) = 0
Black(_base + 2) = 0

RB_Selectchannel 0 ' Strip auswählen


' --------------------------------------------------------
' Variablen

Dim Segment as Byte ' Aktuell zu bearbeitendes Segment
Dim Pixel_No as Byte ' WS2812B LED-Indexnummer

Dim BitPattern as Byte ' Variable zur Aufnahme des benötigten Bitmusters einer Zahl oder eines Symbols
Dim Show_Number as Byte ' Anzuzeigende Zahl
Dim Active_Digit as Byte ' Aktives Digit

Dim Offset_Digit(6) as Byte ' Hier in der Demo für 6 RGB Digit Anzeigen
Offset_Digit(0) = 0 ' Erster LED-Index Digit 0
Offset_Digit(1) = 8 ' Erster LED-Index Digit 1
Offset_Digit(2) = 16 ' Erster LED-Index Digit 2
Offset_Digit(3) = 24 ' Erster LED-Index Digit 3
Offset_Digit(4) = 32 ' Erster LED-Index Digit 4
Offset_Digit(5) = 40 ' Erster LED-Index Digit 5


' --------------------------------------------------------
' Konstanten für Symbole
Const Symbol_Minus = 10 ' Konstante Minus Symbol
Const Symbol_Kapital_C = 11 ' Konstante Buchstabe (großes) C
Const NoNumber = 12 ' Konstante zum vollständigen Ausschalten eines Digits


' --------------------------------------------------------
' Startwerte setzen

' Welche Zahl auf welchem Digit?
Show_Number = 0 ' Anzuzeigende Nummer (bisher möglich: 0-9, Symbol_Minus, Symbol_Kapital_C, NoNumber)
Active_Digit = 0 ' Auf welchem Digit soll die Zahl angezeigt werden (0= Digit 1, 5= Digit 6)

' Welche Farbe?
Red = 0 ' Rotwert (0-255)
Green = 50 ' Grünwert (0-255)
Blue = 0 ' Blauwert (0-255)



' -----------------------------------------
' Hauptprogramm
' -----------------------------------------
Do

BitPattern = Lookup(Show_Number , Segment_Table) ' Anzuzeigendes Bitmuster aus der Lookup Tabelle holen

For Segment = 0 to 6 ' Alle 7 Segmente prüfen, ob sie ein oder aus sein sollen (0=a, 6=g)
Pixel_No = Segment + Offset_Digit(Active_Digit) ' LED Mapping
If BitPattern.Segment = 1 then ' Soll aktuelles Segment leuchten?
RB_Setcolor Pixel_No , Color(_base) ' Farbwerte für LED in den Farbspeicher schreiben
Else ' Soll aktuelles Segment aus sein?
RB_Setcolor Pixel_No , Black(_base) ' Farbspeicher auf 0 setzen
End If
Next Segment

RB_Send ' Daten senden


' Testanimation
Incr Show_Number ' Nächstes Bitmuster anzeigen lassen
If Show_Number > 12 then ' Nach Durchlauf aller verfügbaren Bitmuster...
Show_Number = 0 ' ...wieder von vorne beginnen...
Incr Active_Digit ' ... mit dem nächsten Digit
If Active_Digit > 5 then Active_Digit = 0 ' Am Ende wieder alles auf Anfang
End If
Waitms 500

Loop
End

' -----------------------------------------
' Programmende
' -----------------------------------------




' ----------------------------------------------
' Segment_Table
' In dieser Tabelle stehen alle verfügbaren
' Zahlen und Symbole
' ----------------------------------------------
Segment_Table: ' LookUp Table Index beginnt IMMER bei 0
' xgfedcba
Data &B00111111 ' 0
Data &B00000110 ' 1
Data &B01011011 ' 2
Data &B01001111 ' 3
Data &B01100110 ' 4
Data &B01101101 ' 5
Data &B01011101 ' 6
Data &B00000111 ' 7
Data &B01111111 ' 8
Data &B01101111 ' 9
Data &B01000000 ' 10 (Symbol_Minus)
Data &B00111001 ' 11 (Symbol_Kapital_C)
Data &B00000000 ' 12 (NoNumber)