Jump to content

LEDs dimmen bzw. Helligkeitsstufen


Bastl
 Share

Recommended Posts

Hallo,

 

ich habe mal eine Frage.

Ist es irgendwie möglich, mit beispielsweise dem IO16, LEDs mit verschiedenen Helligkeitsstufen (idealerweise 8Bit) anzusteuern?

Ich möchte praktisch mit 3 LEDs (R,G,B) möglichst viele Farben mischen können.

 

Mir würde es allerdings nichts nützen das mit dem Analog Out Bricklet zu realisieren, da ich insgesamt 60 LEDs (20xRGB) ansteuern möchte.

 

Danke schonmal

Link to comment
Share on other sites

wie hoch sind den die maximalen Ströme die durch die LEDs fließen sollen. Sollen alle 60 LEDS unabhängig von einander operieren oder gibt es Gruppen von LEDS die sich gleich Verhalten sollen.

 

Generell gibt es kein TF Produkt, dass eine Konstantstromquelle (KSQ) bereitstellt. Für LEDs mit hohen Leistungen sollte zur Sicherheit aber besser eine KSQ verwendet werden.

Link to comment
Share on other sites

Also der maximale Strom einer LED ist 20mA.

Die LEDs sollten alle unabhängig voneinander steuerbar sein.

 

Ich möchte damit ein Ambilight realisieren. Daher je nach Bildschirminhalt verschiedene Farben anzeigen.

Link to comment
Share on other sites

Also eher kleine Leistung, da kann man sicher einfach mittels der Spannung steuern. wenn du dass mit dem IO16 machen möchtest müssen die LEDs mit 3.3 oder 5V betrieben werden können. Die Helligkeit würdest du dann über schnelles ein und ausschalten regeln. Das IO16 kanst du etwa 1000x pro sekunde schalten. Um eine flackerfreies leuchten zu bekommen braucht man mindesten 25Hz. Das heist du hättest maximal 40 Stufen um die Helligkeit zu regeln.

Deutlich feiner (auch feiner als 8bit) könntest du es mit dem Servo Brick steuern, da kommen aber  "nur" 7 Ausgänge raus.

Link to comment
Share on other sites

Hallo,

 

ich habe das jetzt mal mit dem IO16 ausprobiert.

Allerdings macht es erst Sinn, wenn man 125Hz verwendet. Denn sonst flackert es. Also praktisch 8 Helligkeitsstufen. Was prinzipiell erstmal ok wäre. Komischerweise klappt das nur, wenn ich die LEDs von einem IO16 am Port A mit dieser Methode anspreche. Wenn ich zusätzlich Port B von dem IO16 anspreche flackert es wieder und klappt nur, wenn ich die Freqzenz verdopple.

 

Hier mal eine kleines Codebeispiel (Java) dazu:

 

static void setIntensity(BrickletIO16 io, int intensity)
{
long start = System.currentTimeMillis();
int runtime = 1000;
int hz = 125; //1000/8
int maxIntensity = 255;

while(start + runtime > System.currentTimeMillis())
{
	for(int i=0;i<(1000/hz);++i)
	{
		if (i<(int)(((1000/hz)/(float)maxIntensity)*intensity))
		{
			io.setPortConfiguration('a', (short)(0xFF), 'o', true);
			//io.setPortConfiguration('b', (short)(0xFF), 'o', true);
		}
		else
		{
			io.setPortConfiguration('a', (short)(0xFF), 'o', false);
			//io.setPortConfiguration('b', (short)(0xFF), 'o', false);
		}

		try {Thread.sleep(1);} catch (InterruptedException e) {}
	}
}

io.setPortConfiguration('a', (short)(0xFF), 'o', false);
//io.setPortConfiguration('b', (short)(0xFF), 'o', false);
}

...
setIntensity(io, 50);
setIntensity(io, 100);
setIntensity(io, 150);
setIntensity(io, 200);
setIntensity(io, 255);

 

Ist es irgendwie möglich die Daten an Port A und Port B gleichzeitig zu senden? Denn wenn ich insgesamt 4x IO16 Bricklets mit dieser Methode nutzen möchte, dann könnte ich (durch die Frequenzverdopplung) letztendlich nur 2 Helligkeitsstufen (ein/aus) nutzen.

 

Danke

Link to comment
Share on other sites

Hi, ja die 1000 gelten insgesamt pro USB Verbindung. Man darf also sonst nichts machen.

Da brauchst du für jeden IO16 ein eigenes Brick. Dass man zwei Befehle mit einer USB-Message schicken kann geht glaube ich nicht, wurde zumindest noch nie erwähnt. Da müsste vermutlich die USB-Behandlung im BrickD und auf den Bricks umgestellt werden. Wäre natürlich eine tolle Idee dass der BrickD alle Messages die in einer ms auflaufen bündelt und dann zusammen über den USB-Port schickt.

 

Ansonsten könntest du natürlich auch zwei Dioden parallel an einen IO Port hängen, dann geht dir halt die räumliche Auflösung verloren.

Benutzt du eigentlich eine StepDown Powersupply? weil 60x20mA ist ja deutlich mehr als so ein USB-Port typischerweise schafft.

Link to comment
Share on other sites

Das StepDown Powersupply habe ich schon hier liegen. Aktuell habe ich "nur" ein IO16 mit 16 LEDs bestückt. Ich habe aber noch 3 weitere. Wenn ich dann alle betreiben will werde ich dsa StepDown Powersupply dann natürlich verwenden müssen :)

 

Aber mir ist eben eine andere Idee in den Sinn gekommen. Man könnte doch die Firmware vom IO16 Bricklet anpassen und dann dem Bricklet Daten mit einer Intensität schicken. Sowas wie:

io.setPortConfiguration('a', (short)(1 << 0), 'o', true, intensity);

 

Dann müsste man in der Firmware "nur" mit einer Schleife, basierend auf der Intensität, die LEDs entsprechend oft an und ausschalten, oder?

Wäre sowas realisierbar?

Link to comment
Share on other sites

Also ich habe das die letzten Tage mal ausprobiert die Firmware vom IO16 umzuschreiben und auch die Bindings für Java für meine Zwecke anzupassen.

 

Ich habe es hinbekommen auf einem IO16 für 16 LEDs, Farbintensitäten von 8Bit zu steuern. Das Ganze sogar bei 120Hz.

 

Das funktioniert jetzt allerdings erstmal nur mit einem IO16, da ich aufgrund der 1kHz Tickrate des Tinkerforge Masterbricks Busy-Wait (im Microsekundenbereich) nutzen muss, um die Helligkeitsstufen durch häufiges Ein- und Ausschalten zu steuern, läuft das Masterbrick auf nahezu 100% Auslastung.

Durch eine Anpassung der Master-Brick Firmware werde ich das allerdings so realisieren können, dass ich die Busy-Wait Time auf die Master-Brick Firmware auslagere und dadurch alle 4 IO16 nutzen kann.

 

Hier mal ein paar Codeausschnitte (nicht vollständig) für alle Interessierten:

 

 

Bindings (Java):

public void setLED(char port, short portMask, int intensity) 
{
//map 255 to 1 and 1 to 255, because the standard value for on is 1 (for compatibility reasons)
if (intensity == 255)
	intensity = 1;
else if (intensity == 1)
	intensity = 255;

ByteBuffer bb = ByteBuffer.allocate(;
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put((byte)stackID);
bb.put((byte)FUNCTION_SET_PORT_CONFIGURATION);
bb.putShort((short);
bb.put((byte)port);
bb.put((byte)portMask);
bb.put((byte)'o');
bb.put((byte)intensity);

ipcon.write(this, bb, FUNCTION_SET_PORT_CONFIGURATION, false);
}	

 

Test (Java):

BrickletIO16AmbientLight io = new BrickletIO16AmbientLight(io_uid);
ipcon.addDevice(io);
...
//intensity 0-255
io.setLED('a', (short)(1 << 6), gammaCorrection(intensity));

 

IO16 Firmware ©:

void tick(uint8_t tick_type)
{
if(tick_type & TICK_TASK_TYPE_CALCULATION)
	intensityLoop();
}
...
void intensityLoop()
{
if (BC->ms >= 1000)
{
	BC->ms = 0;
	BC->loopi = 0;
}

char port = 'a';
uint8_t id = 0;

//loop over state changes per ms
for(uint8_t c=1;c<=BC->stateChanges;++c)
{
	port = 'a';
	id = 0;

	//loop over all LEDs
	for(uint8_t i=0;i<16;++i)
	{
		//get current port
		if (i==
			port = 'b';

		//get current id
		id = i%8;

		switch(BC->ledIntensity[i])
		{
			case 0:
				setLED(port,id,false);
				break;
			case 255:
				setLED(port,id,true);
				break;
			default:
				if(BC->loopi%BC->intensities <= BC->ledIntensity[i])
					setLED(port,id,true);
				else
					setLED(port,id,false);
				break;
		}
	}
	BC->loopi += 1;

	//wait some time (busy wait)
	if (c<(BC->stateChanges))
	{
		writeLEDs();
		SLEEP_US((1000/BC->stateChanges)/6);
		taskYIELD();
	}
}
BC->ms += 1;
}

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...