Ich kenn mich mit der Arduino SPI-Implementierung nicht so gut aus, kann
sein dass da auch was faul ist.
Was ich allerdings sehen kann:
Du füllst dein "muster" mit einem Haufen Nullen (die Zuweisung errechnet
der Compiler noch vor dem Upload und das "channel" array ist da voll mit
Nullen) und kopierst das dann in irgendwelche Puffer rein.
Das ganze Bit-Geschiebe und Verknüpfen musst du explizit dynamisch in
der loop machen.
Was das geplante finale Muster ist erschließt sich auch nicht auf den
ersten Blick, aber so kann es nicht funktionieren.
Ich würde mich vlt. erstmal rantasten:
1. LED (PIN13 afaik) blinken, dann ist der Upload geglückt
2. Festes Muster aus dem SPI rausschieben (testet die Hardware)
3. Dann anfangen dynamische Muster zu erzeugen (wenn da was nicht geht,
dann ist nicht die Hardware schuld, sonder nur der neue Code)
michael schrieb:> hallo Leute,>> ich würde gerne ein simples Lauflicht programmieren, das gestaltet sich> nicht so simpel wie ich erhoffte. SPI übermittelt 8 bit, der Chip hat 24> Ausgänge und erwartet sich 12Bit pro Ausgang. also 488 Bit.
Na dann mal los. Wie immer sollte bzw. muss man das Problem in
Teilprobleme zerlegen und einzeln lösen. Das 1. Problem ist das Senden
der Daten an den IC. Das 2. ist die Umrechnung von RGB Farbwerten in das
Sendeformat für den IC. Das 3. isd das eigentliche Lauflicht, sprich,
das Verschieben des Farbmusters.
Löse alle drei Probleme getrennt und du wirst weniger Stress haben.
>kann mir hier jemand helfen und sagen warum das Lauflicht nicht läuft?
Was tut es denn?
>laut meinem Verständnis gebe ich auf jeden channel 4096 pro loop, also>sollte dadurch auch das muster dementsprechend angepasst werden.
Erstmal muss deine LED-Ansteuerung rein statisch funktionieren. D.h.
jede LED muss einzeln steuerbar sein. Sprich, erstmal muss dein Buffer
immer komplett leer sein und nur eine einzelne LED mit RGB=0xFFF geladen
werden. Wenn das läuft sehen wir weiter.
>int channel[24] = { 0, 0, 0, 0, 0, 0, 0, 0,> 0, 0, 0, 0, 0, 0, 0, 0,> 0, 0, 0, 0, 0, 0, 0, 0,> };
Das ist schon mal gut, ein Array mit 24 Elementen für 24 LEDs.
>byte muster [36] = {> channel[0] >> 4, (channel[0] << 4) | (channel[1] >> 8), channel[1],> channel[2] >> 4, (channel[2] << 4) | (channel[3] >> 8), channel[3],
Das ist Käse. Da sieht keiner durch. Vergiss es. Wenn du ein Muster
definieren willst, tu das genau so wie für channel. Ein int/LED! Das ist
DEUTLICH einfacher lesbar! Die Kompression der 12 Bit/LED auf die 8Bit
der einzelnen Bytes macht man hier NICHT! Das macht entweder eine
separate Funktion (einfacher Ansatz) oder man macht es während der
SPI-Ausgabe live (etwas komplexer).
1
intmuster[24]={0xF0F,0xFFF,0xF00.....};
>byte buffer [36];
Schreib erstmal eine Funktion, welche das einfache Muster in muster in
die komprimierte Form hier rein schreibt.
[Wink mit dem Zaunspfahl]
Das hat was mit Bitmanipulation zu tun.
[/Wink mit dem Zaunspfahl]
>void setup() {> pinMode(9, OUTPUT);> SPI.begin();> SPI.setBitOrder(LSBFIRST);> Serial.begin(9600);>}
OK
>void loop() {> SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));> digitalWrite(9, 0);
Hier kommt die Umwandlung von muster in buffer rein, kein einfaches
kopieren.
> memcpy(buffer, muster, sizeof(muster));
Das fliegt raus.
> channel[i] = 4095;> SPI.transfer(buffer, 36);> digitalWrite(9, 1);> SPI.endTransaction();
Ich glaube die beiden Zeilen müssen vertauscht werden, damit sicher erst
alle Daten rausgeschoben werden, ehe das Chip Select bzw. LATCH-Signal
auf HIGH geht.
> delay(3000);> i++;
Hier fehlt wenigstens ein Abfangen des Überlaufs, denn dein Array hat
nur 24 Elemente, nicht unbegrenzt.
if (i>23) i=0;