TauLabs/PicoC: Ansteuerung RGB LEDs WS2812

odwquad

Erfahrener Benutzer
ahh es funktioniert :D:D
das Problem lag, weder an Taulabs, noch an PicoC noch am PC. Es war das Terminalprogramm. Das Empfängt nur Daten, wenn es im Vordergrund ist.
Habe jetzt mal ein anderes Terminalprogramm genommen und nun funktioniert es einwandfrei. Sehr schön. Dann kann ich durchstarten :D
 

odwquad

Erfahrener Benutzer

cGiesen

Erfahrener Benutzer
Mein nun fertiges Script:

Code:
#include "system.h"
#include "gpsposition.h"
#include "flightbatterystate.h"
#include "flightstatus.h"






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


void setLED(unsigned short n, unsigned char r, unsigned char g, unsigned char b) {
	if (n < nLED) {
		unsigned short offset = 3*n;
		bufLED[offset++] = r;
		bufLED[offset++] = g;
		bufLED[offset++] = b;
	}
}


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


/* end of RGB-LED library */


short LEDupdate=1;
short r=0,g=0,b=0;
short pLED=0;


TestValSet(1);


GPSPositionData GPSData;


FlightBatteryStateData BatteryData;


FlightStatusData StatusData;


TestValSet(2);
sync(0);
while(TestValGet() > 0)
{


/* Battery */
	FlightBatteryStateGet(&BatteryData);
	if (BatteryData.Voltage < 10.4)
	{
		setLED(0,170,0,0);
		LEDupdate=1;
	}
	if ((BatteryData.Voltage < 10.8) && (BatteryData.Voltage > 10.4))
	{
		setLED(0,170,170,0);
		LEDupdate=1;
	}
	if (10.8 < BatteryData.Voltage)
	{
		setLED(0,0,170,0);
		LEDupdate=1;
	}
 
/* GPS */
	GPSPositionGet(&GPSData);
	if (GPSData.Satellites < 5) 
	{
		setLED(2,170,0,0);
		LEDupdate=1;
	}
	if ((GPSData.Satellites < 7) && (GPSData.Satellites > 4))
	{
		setLED(2,170,170,0);
		LEDupdate=1;
	}
	if ((6 < GPSData.Satellites) && (GPSData.PDOP <= 3.5))
	{
		setLED(2,0,170,0);
		LEDupdate=1;
	}
 
/* FlightMode */
	FlightStatusGet(&StatusData);
	/* Geofence */
	if (StatusData.ControlSource == 0)
	{


	}
	/* FailSafe */
	else if (StatusData.ControlSource == 1)  
	{
		//TMPtime = ((unsigned long)(time() / 100) % 2);
		if (pLED == 0) {
			pLED=1;
			setLED(1,0,170,0);
			LEDupdate=1;        			
		}
		else {
			pLED=0;
			setLED(1,170,0,0);
			LEDupdate=1;        			
		} 
	}
	/* Transmitter */	
	else if (StatusData.ControlSource == 2)
	{
		switch (StatusData.FlightMode) {
			case 1: //Acro
				setLED(1,170,0,0);
				LEDupdate=1;        			
				break;
			case 2: //Leveling
				setLED(1,0,170,0);
				LEDupdate=1;        			
				break;
			case 3: //VirtualBar
				setLED(1,0,170,170);
				LEDupdate=1;        			
				break;
			case 4: //Stabilized1
				setLED(1,170,170,0);
				LEDupdate=1;        			
				break;
			case 5: //Stabilized2
				setLED(1,170,170,0);
				LEDupdate=1;        			
				break;
			case 6: //Stabilized3
				setLED(1,170,170,0);
				LEDupdate=1;        			
				break;
			case 7: //Autotune
				setLED(1,170,170,170);
				LEDupdate=1;        			
				break;
			case 8: //AltitudeHold
				setLED(1,170,0,170);
				LEDupdate=1;        			
				break;
			case9: //VelocityControl
				setLED(1,75,0,130);
				LEDupdate=1;        			
				break;
			case 10: //PositionHold
				setLED(1,130,0,139);
				LEDupdate=1;        			
				break;
			case 11: //ReturnToHome
				setLED(1,255,0,0);
				LEDupdate=1;        			
				break;
		} 
		if (armed() || (pLED == 1)) {
			pLED = 0;
			LEDupdate=1;        			
		} else {
			pLED = 1;
			setLED(1,0,0,0);
			LEDupdate=1;        			
		}
	}
	/* Tablet */
	else if (StatusData.ControlSource == 3)  
	{


	}
 


// Set LED
	if (LEDupdate == 1) {
		sendLED();
		LEDupdate = 0;
	}


	sync(250);
}
TestValSet(99);
 

odwquad

Erfahrener Benutzer
@cGiesen: könntest du mir dein Programm für den Attiny 85 mal als hex file irgendwie zukommen lassen?
Ich habe probiert den Code direkt in Arduino zu kompilieren, aber da kommt folgende Fehlermeldung:
C:\Program Files (x86)\Arduino\libraries\NeoPixel\Adafruit_NeoPixel.cpp: In member function 'void Adafruit_NeoPixel::show()':
C:\Program Files (x86)\Arduino\libraries\NeoPixel\Adafruit_NeoPixel.cpp:117: error: 'PORTD' was not declared in this scope
Ich weiß nicht warum :confused:
Da ich aber eh mit Atmelstudio das hex file flashen muss, da Arduino meinen programmer nicht erkennt, würde mir das hex file reichen.

Dann könnte ich als nächsten Schritt die LED stripes mal ausprobieren.
 

odwquad

Erfahrener Benutzer
Du hast 'nur' vergessen die entstprechenden Libraries einzubinden. Bzw. and ie richtige Stelle koppieren.

Wo wird denn das HEX abgelegt?
Bei mir geht das immer direkt ins Tiny rein?!?!

Edit:
HEX anbei
danke ich werde morgen mal die Hex ausprobieren. Hoffe, dass es funktioniert :)
Aber die Libraries sind eingebunden, ich hatte diese auch schoneinmal verwendet für andere Projekte. Ich weiß nicht warum er Portd nicht findet oder damit ein Problem hat.
 

odwquad

Erfahrener Benutzer
Nee eigentlich nicht.
Hab den attiny 85 mit 8mhz ausgewählt
 

odwquad

Erfahrener Benutzer
Danke, das werde ich morgen mal probieren :)
 

odwquad

Erfahrener Benutzer
So anbei mal ein paar Bilder und ein Video zu meiner Beleuchtung :D

[video=youtube;KW9-kISDMcU]https://www.youtube.com/watch?v=KW9-kISDMcU[/video]

Cinetank-Beleuchtung1 (6).jpg

Cinetank-Beleuchtung1 (11).jpg

Cinetank-Beleuchtung1 (13).jpg

Kabelsalat xD
Cinetank-Beleuchtung1 (1).jpg

Cinetank-Beleuchtung1 (15).jpg

Leider sind mir wieder einige LEDs Kaputt gegangen. Zufälligerweise hinten links :D
Diese werde ich noch tauschen.
Warum die WS2812 LEDs bei mir so schnell kaputt gehen weis ich nicht. Bei meinem alten X525 Quad gingen die auch immer recht schnell kaputt :confused:
Vielleicht habe ich einfach schlechte Qualität erwischt.
 
Wieviele LED ' S lassen sich damit ansteuern?
Es kann sein, das hier schon einmal eine theoretische Zahl genannt worden ist. Ich meinte aber, ob jemand schon einmal .mehrere LED angeschlossen hat. Oder anders, wieviele sind noch sinnvoll und was?
 
Zuletzt bearbeitet:

ernieift

Erfahrener Benutzer
Im NeoPixelTranseiver sind 100LEDs definiert. Die wirst Du sicher nicht am Copter verbauen. Es sollte also völlig reichen. Wenn Du mehr haben willst, dann einfach die Source ändern und auf etwas anderem als einem ATtiny laufen lassen (512 Byte RAM). Ich habe schon darüber nachgedacht, den Transceiver um i2C zu erweitern. Damit wäre der PicoC-UART wieder frei. Das sollte auf dem ATtiny auch gehen.

Wieviele Du anschließen willst, hängt zunächst vom Strom ab. Ohne jetzt ins Datenblatt zu schauen: eine RGB-LED (0xffffff) max. 90mA, schätze ich. Mal 100 ergibt das schon 9A bei 5V. Da musst Du schon zusehen, dass Du dafür ein BEC bekommst oder mehrere nimmst. Wenn Du geschickt programmierst, dann kannst Du auch im Nightrider-Style nur soviele einschalten wie nötig.
 
Zuletzt bearbeitet:
Die LED´s habe eine Konstantstromquelle mit max. 18mA pro Farbe. Inkl Controller 60mA max. pro LED.
Braucht der Tiny eigentlich den TX Pin? Ansonsten fände ich es praktischer jedem Arm/Ledkette einen Ausgang zu spendieren das spart Verkabelung.
 

ernieift

Erfahrener Benutzer
Den vom PicoC-Port. Irgendwoher muss doch die Information kommen. Den DOUT vom Streifen kannst Du doch auch mit AWG24 zurückholen. Oder Du änderst den Transceivercode auf 4 Ausgänge. Im PicoC ist es aber weiterhin eindimensional. Wenn ich I2C fertig habe, kannst Du ja auch mehrere Slaves an einem Port ansprechen.
 
Der vom PicoC Port ist klar TX - RX Tiny. Da der Tiny aber nur 5 Pins zur Nutzung hat wars es für mich die Frage ob ich den TX Pin des Tiny frei nutzen kann. Bei mehr 30cm langen Armen geht es mir um die Leitungslänge und Störstrahlung durch die Übertragung. Das Gewicht spielt da bei AWG24 oder 30 nicht die Rolle.
 

ernieift

Erfahrener Benutzer
Du kannst doch mehrere Instanzen vom Stripe im NeoPixel erstellen. Dafür hast Du dann maximal 5 Pins am ATtiny frei. Du musst dann daher den Streifen genau definieren. Z.B. 8 LEDs pro Streifen. Dann kommt bei der Übertragung die 9. LED als erste in den 2. Streifen. Ist doch recht einfach zu ändern. Mehr Speicher im ATiny wird es auch nicht brauchen, da der LED-Puffer sowieso schon in der Instanz definiert wird.
Schön dass man dafür keine Firmware im TL ändern muss ;).
 
FPV1

Banggood

Oben Unten