-
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
-
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
-
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
-
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
-
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
Code:
' =====================================================================
' 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)