Forum: Compiler & IDEs TLC5940 library: Erfassen von Veränderungen


von Ralf S. (durokh)


Angehängte Dateien:

Lesenswert?

Hi zusammen,
erstmal zur Vorgeschichte:
Ich habe einen Atmega644, der einen TLC5940 "programmieren" soll.
Der TLC ist ein Baustein, der bis zu 16 LEDs (ich verwende allerdings 
momentan nur 8) einzeln über eine PWM (12 Bit) modulieren kann.

Wenn der TLC also geupdated werden soll, benötigt er 16 Kanäle x 12 Bit 
(PWM).

Ich habe eine Library (wer genauer hinein schauen möchte, siehe Anhang), 
die den Umgang stark vereinfacht. Es muss lediglich eine Funktion 
aufgerufen werden:
void TLC5940_SetGS(channel_t channel, uint16_t value)

Die Funktion legt also fest, welcher der 16 Kanäle mit welcher 
Intensität / PWM laufen soll. Alle anderen Kanäle bleiben unberührt, 
also PWM = 0 (da liegt nachher auch mein Problem, werdet ihr sehen.

Nun ist mein Ziel folgendes:
Ich möchte eine Art "Terminkalender" anlegen, in die Zustände aller 
Kanäle zu verschiedenen Zeitpunkten speichern und später abrufen kann. 
Ziel wäre also bspw. solch einen Ablauf zu haben:

(3 LEDs an)
- 100 ms: Kanal 1, 4095
- 100 ms: Kanal 2, 4095
- 100 ms: Kanal 3, 2000

(2 LEDs aus)
- 200 ms: Kanal 1, 0
- 200 ms: Kanal 3, 0

(die letzte verbleibende LED aus)
- 310 ms: Kanal 2, 0


Zu diesem Zweck habe ich ein struct erstellt, das folgendes speichert:
- Zeitpunkt
- Kanal
- Intensität/PWM

Dann habe ich ein Array erstellt, das mit den Structs befüllt wird.
Das struct wird dann nach Zeit sortiert (wie das vonstatten gehen soll, 
wurde hier besprochen: Beitrag "Struct Array sortieren")

Der User befüllt den "Terminkalender" / das Array über die Serielle 
Schnittstelle, auf ein Kommando hin arbeitet er dann dieses Array ab und 
danach ist dann Ruhe.

Nun habe ich folgendes Hauptproblem:
Wenn der Serielle Stream geparsed wird, werden daraus beipsielsweise 
folgende  Einträge in dem Array (bitte oben nochmal in das Beispiel 
schauen, ist wichtig):
- 100 ms: Kanal 2, 4095
- 200 ms: neue Konfiguration der LEDs
- 310 ms: Kanal 2, 0

Bei jedem Zeitereigbnis wird der TLC ja neu mit LED-Zuständen gefüllt, 
ABER:
Zum Zeitpunk 100 ms, wird Kanal 2 eingeschaltet,
zum Zeitpunkt 200 ms wird sein Zuständ aber NICHT verändert (er soll 
erst zum Zeitpunkt 310 ms ausgeschaltet werden). Die Library bzw. der 
jetzige Programmierstand bezieht aber alte Zustände nicht mit ein --> es 
findet pro Zeitpunkt sozusagen immer ein "Reset" statt.

Nun kann ich ja schlecht vom Nutzer verlangen, dass er folgendes macht:

- 100 ms: Kanal 1, 4095
- 100 ms: Kanal 2, 4095
- 100 ms: Kanal 3, 2000

- 200 ms: Kanal 1, 0
- 100 ms: Kanal 2, 4095 <--- BLEIB BITTE IMMER NOCH AN!
- 200 ms: Kanal 3, 0

- 310 ms: Kanal 2, 0  <--- Ja, jetzt darfst du endlich aus gehen!

Das ist natürlich sehr Fehleranfällig.

Letztendlich möchte ich also, dass ich innerhalb meiner Programmierung 
also nur VERÄNDERUNGEN erfasse, wohingegen ich mit eine Lib arbeite, die 
nur neue Zustände bearbeitet.

Ich hoffe, ich konnte das Problem deutlich machen, ansonsten gibts dann 
nachher den zweiten Versuch...

Man könnte nun Fragen, warum ich mir nicht meine eigene Lib schreibe, 
wenn die jetzige die Funktionalität nicht aufbringt, die ich benötige:
Ich bin noch nicht 100% ig sicher in C und ich wüsste auch davon 
abgesehen derzeitig nicht wie ich das Problem gelöst bekomme.


Gruß,
Durokh

von Karl H. (kbuchegg)


Lesenswert?

Ralf S. schrieb:


> Ich habe eine Library (wer genauer hinein schauen möchte, siehe Anhang),
> die den Umgang stark vereinfacht. Es muss lediglich eine Funktion
> aufgerufen werden:
> void TLC5940_SetGS(channel_t channel, uint16_t value)
>
> Die Funktion legt also fest, welcher der 16 Kanäle mit welcher
> Intensität / PWM laufen soll. Alle anderen Kanäle bleiben unberührt,
> also PWM = 0 (da liegt nachher auch mein Problem, werdet ihr sehen.

Nö.
Wenn ich den Code beim überfliegen richtig gelesen haben, dann werden 
die mitnichten 0. Sie bleiben unberührt, heißt soviel wie "was immer ihr 
Wert ist, ein Aufruf dieser Funktion ändert sie nicht"



> erst zum Zeitpunkt 310 ms ausgeschaltet werden). Die Library bzw. der
> jetzige Programmierstand bezieht aber alte Zustände nicht mit ein --> es
> findet pro Zeitpunkt sozusagen immer ein "Reset" statt.

Das hätte ich jetzt in dem Code der Funktion aber nicht gesehen.
(Aus dem Grund ist es immer schlecht, wenn du Code als PDF postest. Man 
sieht die Dinge da drinnen so schlecht, weil man kein 
Syntax-Highlighting hat, die Schreift meistens klein ist und man dauernd 
über Seitengrenzen hinweg scrollen muss.)

von Karl H. (kbuchegg)


Lesenswert?

Dieser Code hier
1
void TLC5940_SetGS(channel_t channel, uint16_t value) {
2
  channel = numChannels - 1 - channel;
3
  channel3_t i = (channel3_t)channel * 3 / 2;
4
5
  switch (channel % 2) {
6
    case 0:
7
      gsData[i] = (value >> 4);
8
      i++;
9
      gsData[i] = (gsData[i] & 0x0F) | (uint8_t)(value << 4);
10
      break;
11
12
    default: // case 1:
13
      gsData[i] = (gsData[i] & 0xF0) | (value >> 8);
14
      i++;
15
      gsData[i] = (uint8_t)value;
16
      break;
17
  }
18
}

setzt definitiv nur die Werte des angegebenen Channels. Alle anderen 
bleiben so wie sie sind, also intakt.

Wenn deine Idee also nicht funktioniert, dann hast du einen anderen 
Programmfehler. Die Funktion ist es jedenfalls nicht. Sieh mal deinen 
Code durch, ob du irgendwo 'generelle Löschfunktionen' aufrufst, wo es 
nicht sein sollte. Ich schätze mal, dass du selber dir beim Wechsel in 
den nächsten Zeitpunkt alle Einstellungen löscht, indem du einen
1
  TLC5940_SetAllGS( 0 );
Aufruf machst, wo er nicht sein sollte.
Wenn du einfach nur anhand deiner im Array vorliegenden Anweisungen die 
entsprechenden Kanäle in der TLC5940_SetGS Funktion mit den neuen Werten 
beschickst, dann muss das sauber durchlaufen.

von Ralf S. (durokh)


Lesenswert?

Oh, man. Mist. Du hast Recht. Das war mein Fehler.
Wie blöde.

Vielen Dank fürs drüberschauen!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.