TauLabs/PicoC: Ansteuerung RGB LEDs WS2812

cGiesen

Erfahrener Benutzer
#22
Der große Vorteil hier wäre, daß man direkt die RGB-Werte (3 Byte pro LED) ausgeben kann, während man die RGB-Werte für die UART-Inverter-Variante erst noch umkodieren muß (12 Byte pro LED).
Das sehe ich weniger als Problem. Das erledigt doch ein Sub mit links.
Hast Du schon einen laufenden Anfangs Test Code?
Ich kann eine Grundlage zum Starten gut brauchen
 

Elyot

Erfahrener Benutzer
#23
@Markus1234 Der Hinweis ist auf jeden Fall hilfreich.

@cGiesen Meine Quantons sind verbaut. Ich habe aber aktuell nur den kleinen Copter da. Ich kann erst praktisch weiter machen, wenn der große Quad wieder zu hause ist. Dort komme ich problemlos an die Quanton ran. Den kleinen müßte ich jedes mal zerpflücken ;)
 
Zuletzt bearbeitet:

ernieift

Erfahrener Benutzer
#25
Ist doch nicht so schlimm:
WS2812.jpg

und hier das Script:
Code:
#include "system.h"

unsigned char outBuf[5*8] = {
//	  G5 G6 G7   G2 G3 G4   R7 G0 G1   R4 R5 R6   R1 R2 R3   B6 B7 R0   B3 B4 B5   B2 B1 B0
	0b11011011,0b11011011,0b10011011,0b11011011,0b11011011,0b11011011,0b11011011,0b11011011, // red
	0b11011010,0b11011011,0b11011011,0b11011011,0b11011011,0b11011011,0b11011011,0b11011011, // green
	0b11011011,0b11011011,0b11011011,0b11011011,0b11011011,0b11010011,0b11011011,0b11011011, // blue
	0b11011011,0b11011011,0b11011011,0b11011011,0b11011011,0b11011011,0b11011011,0b11011011, // black
	0b10010010,0b10010010,0b10010010,0b10010010,0b10010010,0b10010010,0b10010010,0b10010010, // bright white
};

ChangeBaud(2600000);
SendBuffer(outBuf, sizeof(outBuf));
 

cGiesen

Erfahrener Benutzer
#26
Schönes Geburtstags Geschenk.
Was soll uns der Kommentar sagen?
Bleiben aber noch Fragen :( Sorry
- wo weise ich den UART zu?
- verstehe ich das so richtig: sobald Daten kommen, werden die durchgeschoben. Wenn nix mehr kommt werden die Daten übernommen.
- macht es Sinn, die Farben in einer Lookup Tabelle abzulegen?
- oder besser eine Sub die RGB in Pattern umrechnet?
- wird die Zeit zum Umrechnen reichen, das wir keinen Aussetzer bekommen?

Jetzt ist es blöd, dass ich noch so lange auf die Bauteile warten muss
 

ernieift

Erfahrener Benutzer
#27
Herzlichen Glückwunsch,
das war nur ein Proof of concept. Die Daten für wenigstens eine LED sollten im Block übertragen werden.
Ich würde eine Funktion setLED(short number, unsigned char R, unsigned char G, unsigned char B) vorschlagen. Die füllt einen outBuffer[] und mit sendLED() würden alle übertragen.
Der USART ist der eingestellte von picoC. Mit ein wenig Fehlertoleranz, kann man sogar andere Teilnehmer parallel schalten. Die baudraten sind soweit auseinander, das die LEDs bei 9600 nicht reagieren würden, denke ich.
 

cGiesen

Erfahrener Benutzer
#28
Das per Sub in einen Puffer zu schreiben und dann in einen Rutsch zu senden ist das Beste.

dann wollen wir mal überlegen wo wirIich hin wollen:

Disarmed
- Status GPS: Rot keine SATs, Gelb ein paar aber nicht genug, Grün SATs ready for Start
- Status LiPo: Grün > 90%, Gelb > 50%, Rot <50% (Weil dann macht Starten nicht wirklich Sinn, geht aber noch um mal eben was zu schecken

Armed
- Flightmode:
-- Acro: Helles Gelb wie bei Starwars?! Leichtes Pumpen den Helligkeit?!?
-- PosHold: Blau
-- ReturnToHome: Rot
-- Leveling: Grün

Da der Code ja sichtbar ist, kann das ja jeder anpassen.

@Ernieift
Gibt es eigentlich sowas wie einen Event, wenn gearmt wird oder der Flugmodus sich ändert?
Oder muss ich da eine Schleife machen?

So genug Pause gemacht. Weiter Putzen....
 

ernieift

Erfahrener Benutzer
#29
Andere Idee. Ein paar LEDs in den Armen vom Quad.
Wenn disarmed, weißes blitzen wie beim Flugzeug.
Armed und Höhe gering, eine Art Landelicht um die Stelle zu beleuchten.
Sonst farbliche Kennzeichnung der Arme. Die Helligkeit kann man in Abhängigkeit von Höhe sind Entfernung anpassen.
Picoc unterstützt keine Events oder gar ISR. Am besten programmierst Du eine while Schleife ohne/mit Abbruchbedingung.
Betrachte es als eine Art PLC von der SPS. Das darfst Du auch keine Endlosschleifen ala warte-bis-bedingung-erfüllt programmieren. Da musst Du mit Zustandsautomaten arbeiten.
Was jeder mit den LEDs anstellt, bleibt jedem selbst überlassen. Das ist ja gerade das schöne an picoC. Es ist nur ein Werkzeug für Ideen am eigenen Kopter. Wir sollten uns mal überlegen ein paar Scripte im Wiki als Anregung bereitzustellen.
 

cGiesen

Erfahrener Benutzer
#30
Die Idee ist so auch gut. Lässt sich bei meinem Copter jetzt aber leider nicht mehr realisieren, weil ich an den Armen nichts mehr dran machen möchte / kann.
Schade dass das Sparky kein picoC kann, sonst würde ich mir damit ein DevBoard aufbauen.
Ich gebe mich jetzt mal ein Schritt eins. Daraus kann ja dann mehr werden wenn man erst mal eine Vorlage hat. Meine Herausforderung ist erst mal mich wieder hin C rein zu denken. Das wird schwierig genug
 

Elyot

Erfahrener Benutzer
#33
@cGiesen Auch von mir herzlichen Glückwunsch. Wenn Du nicht auf den Inverter warten möchtest und zufällig noch ein paar Transistoren da hast, kannst Du durchaus auch mal die "einfache" Lösung probieren. Die Grenzfrequenz des BC847 liegt z.B. bei etwa 200 MHz. Die Flanken sollten daher noch steil genug sein.

@ernieift Konntest Du auch mal mit 4MBaud testen? Wenn die Datenblatt-Spezifikation des Timings eingehalten werden kann, sollte man dies auch tun. Dennoch gut zu wissen, daß es prinzipiell auch mit der niedrigeren Baudrate funktioniert.
Und wegen Sparky 2.0 würde ich nehmen, nur woher? ;)
 

ernieift

Erfahrener Benutzer
#34
Wenn ich der STM-lib mehr als 2,7MBaud übergebe, dann kommt nicht die erwartete Baudrate raus. Was das Timing angeht, würde ich mir keine so großen Sorgen machen. Zieh Dir einfach mal ein paar verschiedene Datenblätter. Da stehen immer wieder andere Werte drin. Wenn Du Dir die Mühe machst, um mal mit einer Anneliese zwischen die LEDs testest, stellst Du fest, dass da ein anderes Timing weitergegeben wird. Übertragungsfehler hatte ich keine. Was soll auch passieren? Die LEDs gehen von fehlerhaften Daten nicht kaputt.
 

Elyot

Erfahrener Benutzer
#35
An welcher UART hast Du getestet? Ich tippe mal auf einer anderen als 1? Da wären 2,62MBaud die Grenze bei 16fach Oversampling, was sich gut mit Deinem Wert deckt. Ich muß wohl doch mal rüber fahren und den großen Copter holen ;)
 

ernieift

Erfahrener Benutzer
#38
Übrigens habe ich mit high-Zeiten von 375/750ns gearbeitet. Das entspricht schon der Spezifikation. Außerdem ist mit 3 Bits pro Byte die Datendichte höher. Die Kommentare bei den Pufferdaten stellen die Bitposition dar.
Bin jetzt endlich auf dem Heimweg...
 

Elyot

Erfahrener Benutzer
#39
Das Timing paßt schon, außer beim Stopbit. Aber Hauptsache ist ja, das es funktioniert. Und das tut es ja. Am WE hole ich den Großen, den Inverter löte ich mir morgen schon mal zusammen. Sonntag ist zwar Hallenfliegen angesagt, aber ich hoffe, es bleibt dennoch Zeit zum Probieren.
 

ernieift

Erfahrener Benutzer
#40
Ich hab da mal was zusammengetragen. Als Library sollte es reichen. Ganz stabil ist es nicht. Eventuell kann man ja die Bits noch verändern oder an einem anderen USART die Rate höher nehmen. Soll erstmal ein Anfang sein.

Code:
#include "system.h"

/* WS2812 library */
#define nLED 8
unsigned char bufLED[nLED*8];

void setLED(unsigned short n, unsigned char r, unsigned char g, unsigned char b) {
	if (n < nLED) {
		unsigned short offset = 8*n;
		bufLED[offset++] = (((g&0x80)>>7)|((g&0x40)>>3)|((g&0x20)<<1))^0xdb;
		bufLED[offset++] = (((g&0x10)>>4)| (g&0x08)    |((g&0x04)<<4))^0xdb;
		bufLED[offset++] = (((g&0x02)>>1)|((g&0x01)<<3)|((r&0x80)>>1))^0xdb;
		bufLED[offset++] = (((r&0x40)>>6)|((r&0x20)>>2)|((r&0x10)<<2))^0xdb;
		bufLED[offset++] = (((r&0x08)>>3)|((r&0x04)<<1)|((r&0x02)<<5))^0xdb;
		bufLED[offset++] = ( (r&0x01)    |((b&0x80)>>4)| (b&0x40)    )^0xdb;
		bufLED[offset++] = (((b&0x20)>>5)|((b&0x10)>>1)|((b&0x08)<<3))^0xdb;
		bufLED[offset++] = (((b&0x04)>>2)|((b&0x02)<<2)|((b&0x01)<<6))^0xdb;

	TestValSet( bufLED[8*n] );

	}
}

void sendLED() {
	ChangeBaud(2100000);
	SendBuffer(bufLED, sizeof(bufLED));
}	

/* end of RGB-LED library */

short r=0,g=0,b=0;

for (int i=0;i<50;i++) {
	for (short n=0; n<8; n++) {
		setLED(n,r++,0,0);
	}
		sendLED();
		delay(100);
}
 
FPV1

Banggood

Oben Unten