Hallo, ich habe, inspiriert durch http://www.batsocks.co.uk/readme/art_bcm_3.htm versucht, eine BCM zu schreiben. Leider hat es beim dimmen teilweise geflackert, weswegen ich dann direkt den Code aus dem verlinkten Artikeln genommen habe. Hier allerdings selbes Problem: Wenn ich eine LED mit einem bestimmten Wert leuchten lasse ist alles OK. Es ist nur dieses typische, ganz leichte Flackern zu sehen. Ich würd es sogar eher "unruhiges Leuchten" nennen. Das sollte sich ja durch eine höhere Frequenz in den Griff kriegen lassen. Aber sobald ich anfange die LED zu dimmen, also zyklisch den BCM-Wert herunterzähle, wird das flackern "wilder". Ja ich weiß, blöde Beschreibung. Es sind halt teilweise ganz kurze Aussetzer zu sehen. Leider kann ich nicht beurteilen ob dieses Phänomen normal ist oder ob der Code nicht passt. Ich hab den Code mal angehängt. Es handelt sich um den Original Code von der verlinkten Seite, mit Änderungen an den Timer Registern (ich benutze einen ATmega1284P @ 1 MHz), und einer Änderung in der "Animation" um nur eine LED langsam herunterzufaden. Weiß da jemand Rat?
@Stefan M. (Gast) >Aber sobald ich anfange die LED zu dimmen, also zyklisch den BCM-Wert >herunterzähle, wird das flackern "wilder". Ja ich weiß, blöde >Beschreibung. Es sind halt teilweise ganz kurze Aussetzer zu sehen. Klingt nach einer fehlenden Synchronisation zwischen BCM und Dimmung. Die neuen Dimmwerte düfren NUR exakt zum beginn einer neuen BCM Periode übernommen werden. https://www.mikrocontroller.net/articles/Soft-PWM#Intelligenter_L.C3.B6sungsansatz "Dieses Prinzip wird oft angewendet. Würde man allerdings einfach am Ende die Zeiger tauschen käme es zu einem Crash! Der Interrupt kann jederzeit aktiv werden. Wenn dann die Zeiger nur halb kopiert sind greift die Interruptroutine auf zerstückelte Daten zu und macht Müll. Ebenso würde es zu Fehlfunktionen kommen, wenn während es PWM-Zyklus neue Daten in die Arrays kopiert werden. Das muß verhindert werden. Und zwar dadurch, daß über eine Variable eine Synchronisation durchgeführt wird. Diese wird am Ende des PWM-Zyklus gesetzt und signalisiert, daß neue Daten für den nächsten Zyklus kopiert werden können. Deshalb muss die Funktion pwm_update ggf. bis zu 1 vollen PWM-Zyklus warten, bis die Zeiger getauscht werden können. Wichtig ist dabei, daß die Variable pwm_sync, welche sowohl in der Funktion als auch im Interrupt geschrieben wird, als volatile deklariert wird. Denn sonst würde die Sequenz pwm_sync=0; // Sync wird im Interrupt gesetzt while(pwm_sync==0); zum Stehenbleiben der CPU führen, weil der Compiler erkennt, daß die Variable nie ungleich Null sein kann und damit die Schleife endlos ausgeführt wird. Der Compiler kann prinzipbedingt nicht automatisch erkennen, daß die Variable im Interrupt auf 1 gesetzt wird. "
Danke erstmal, Ich habe mal in der Funktion "encode_timeslice" eine while-schleife eingefügt. Direkt vor der Zeile "g_tick=0;" hab ich "while (g_tick != 1);" eingefügt. Sollte dadurch nicht immer bis zum längsten (=letzten) Abschnitt der BCM gewartet werden? Ändert leider garnichts...
Mit ner fast BCM ist das Flackern nicht mehr so kritisch: Beitrag "AVR: Fast-PWM (BAM) 12 Bit für 8 Kanäle"
Danke für den Link. Ich würde aber gerne verstehen was hier falsch läuft. Wie gesagt, das Aktualisieren der Werte ist nun mit dem interrupt synchronisiert. Liegt es wirklich an der niedrigen Frequenz? PS: doch noch eine Frage zu deinem Code: 12 Bit / 2kHz @ 8 MHz ergeben eine Bitzeit von 0.9765625 Takten. Sportlich ;-) oder wo ist mein Rechenfehler?
Falk Brunner schrieb: > Klingt nach einer fehlenden Synchronisation zwischen BCM und Dimmung. > Die neuen Dimmwerte düfren NUR exakt zum beginn einer neuen BCM Periode > übernommen werden. Nicht ganz. Ich fahre BAM mit knapp 1KHz und mache mir keine Sorgen um timing. Main stellt die RGB-Werte, diese werden gleich umgerechnet und ins Port-Array übernommen. Selbstverständlich kann es passieren, dass das beim bit2 oder bit5 passiert, Flackern ist trotzdem nicht zu sehen. Sein Problem wird eher beim Timer liegen. 32 TaktZyklen für bit0 - abzüglich min. 7 für ISR Aufruf und RETI - retten der Register nicht mitgerechnet - ist schon ein bisschen knapp. Dazu die ganzen Abfragen und Umrechnungen - zumindest die niedrigsten 2 bits haben mit Sicherheit Aussetzer. EDIT: Beim bit2 nicht, da die ISR von bit0 bis bit3 nicht verlassen wird.
:
Bearbeitet durch User
Du hast recht. 32 Takte sind natürlich sehr knapp. Ich habe in meinem jugendlichen Leichtsinn den Code von batsocks übernommen und irgendwie impliziert, dass er soweit korrekt ist. Ich werde mal die CKDIV8 fuse entfernen und gleichzeitig den Timer2 Prescaler auf 256 stellen. Dadurch sollte ja die BCM-Frequenz die gleiche bleiben, allerdings die ISR wesentlich mehr Takte zur Verfügung haben, wodurch sich Interrupts definitiv nicht mehr überschneiden können. Glaub aber irgendwie nicht dass es daran liegt, weil dieses nervige Flackern nur beim dimmen/faden richtig sichtbar wird...
Stefan M. schrieb: > Glaub aber irgendwie nicht dass es daran liegt, weil dieses nervige > Flackern nur beim dimmen/faden richtig sichtbar wird... Ja, ich auch nicht. Wenn ich das richtig sehe, hast du nur eine LED an PortD.6, richtig ? Deine ISR ist weit davon entfernt genau zu sein, die ersten 4 bits sind mit Sicherheit zu lang und zu ungenau. Trotzdem solltest du auf eine BCM-Frequenz von knapp 100Hz kommen, da sollte Flackern nicht mehr zu sehen sein. Allerdings dimmst du mit etwa 8-10Hz, wenn da etwas nicht stimmt, ist das deutlich zu sehen. Erhöhe mal den slowtick auf 100 oder mehr, dann siehst du, ob es daran liegt, wenn ja, solltest du ungefähr jede Sekunde einen Aussetzer haben. BTW, gedimmt wird logarithmisch, nicht linear.
Hallo Marc, was meinst du mit "genau" bei der ISR? Alles was sich vor dem Setzen von PORTD abspielt hat ja eine konstante Laufzeit da hier keine Verzweigungen im Spiel sind. Sagen wir, die beiden Zeilen ergeben einen Offset von 10 CPU-Zyklen. Dieser Offset wäre ja bei jedem Schaltpunkt gleich. D.h. die Zeit zwischen den Schaltpunkten würde nicht jittern sondern sich exakt als Zweierpotenz erhöhen, so wie vorgesehen. Richtig? Alles was nach dem Setzen von PORTD kommt braucht keine konstante Laufzeit mehr haben. Natürlich nur, solange die ISR rechtzeitig beendet wird. Das mit dem slowtick werde ich ausprobieren. Hat sonst zufällig jemand den batsocks Code mal ausprobiert? PS: ja, gedimmt wird logarithmisch. Aber Code der im Forum gezeigt wird wird auch soweit abgespeckt, dass das Problem immer noch auftritt.
Stefan M. schrieb: > was meinst du mit "genau" bei der ISR? Jetzt habe ich deinen Code durch Debugger laufen lassen. bit 0 = 95 Taktzyklen sollte sein: 32 Taktzyklen bit 1 = 129 Taktzyklen sollte sein: 64 Taktzyklen bit 2 = 191 Taktzyklen sollte sein: 128 Taktzyklen bit 3 = 321 Taktzyklen sollte sein: 256 Taktzyklen bit 4 = 576 Taktzyklen sollte sein: 512 Taktzyklen bit 5 = 1088 Taktzyklen sollte sein: 1024 Taktzyklen bit 6 = 2111 Taktzyklen sollte sein: 2048 Taktzyklen bit 7 = 4161 Taktzyklen sollte sein: 4096 Taktzyklen ========================================================= Addieren und Genauigkeit ausrechnen kannst du selbst ;-D > Alles was sich vor dem Setzen von PORTD abspielt hat ja eine konstante > Laufzeit da hier keine Verzweigungen im Spiel sind. Wenn der Timer2 CTC feuert, steht der TCNT2 schon auf 0 und das ist genau. Wenn du TCNT2 in der ISR aber nochmal auf Null setzst, hast du mit Sicherheit alles, was zwischen feuern und Nullsetzen passiert, dazuaddiert. Plus Vorteilerstand. EDIT: Beim CTC wird auch die Null mitgezahlt, also immer +1, somit stimmen Soll Taktzyklen nicht, jeweils 32 Zyklen dazuaddieren.
:
Bearbeitet durch User
@ Marc Vesely (Firma: Vescomp) (logarithmus) > Jetzt habe ich deinen Code durch Debugger laufen lassen. > bit 0 = 95 Taktzyklen sollte sein: 32 Taktzyklen > bit 1 = 129 Taktzyklen sollte sein: 64 Taktzyklen > bit 2 = 191 Taktzyklen sollte sein: 128 Taktzyklen > bit 3 = 321 Taktzyklen sollte sein: 256 Taktzyklen Der Witz einr BCM ist ja, dass man die unteren Bits meistens NICHT über mehrfache ISR Aufrufe macht sondern direkt nacheinander mit konstanten Verzögerungen. Erst bei den höheren Bits lohnt sich ein ISR-Aufruf bzw. ist erst dann technisch machbar!
Falk Brunner schrieb: > Der Witz einr BCM ist ja, dass man die unteren Bits meistens NICHT über > mehrfache ISR Aufrufe macht sondern direkt nacheinander mit konstanten Ja. Für die bits 0 bis 3 mache ich mir gar nicht die Mühe, die ISR zu verlassen. Sind 480 Taktzyklen, also 60us bei 8MHz, macht 5,8% der CPU Zeit.
@ Marc Vesely (Firma: Vescomp) (logarithmus) > Für die bits 0 bis 3 mache ich mir gar nicht die Mühe, die ISR zu > verlassen. Muss man nicht, das kann man trotzdem IN der ISR machen. > Sind 480 Taktzyklen, also 60us bei 8MHz, macht 5,8% der > CPU Zeit. Sehr wenig, für das, was man da bekommt.
Guten Abend zusammen, ich habe mal alle Anregungen aus dem Thread in den Code einfliesen lassen: - update-Funktion ist mit ISR synchronisiert, array wird nur in der letzten Bitzeit beschrieben - Zählerregister wird in der ISR nicht mehr explizit genullt (war natürlich Schwachsinn, Schande über mich dass ich das ungeprüft übernommen habe) - Controller läuft jetzt mit 8MHz - Prescaler wurde dafür auch ver-achtfacht => 256 - Erhöhung des slowticks Der neue Code ist angehängt. Marc Vesely, ich trau mich ja fast nicht fragen, aber magst du den Code vielleicht nochmal simulieren um zu bestätigen, dass ich die Bitzeiten jetzt einhalte? Ich bin hier auf Linux unterwegs und habe kein Atmel Studio... Die Änderungen führen jetzt zu folgendem Ergebnis: Grundsätzlich flackert die LED beim Dimmen immer noch. Wohlgemerkt, nur beim Dimmen. Und das ist das, was mich so verwundert. Und niedriger der Wert desto besser sichtbar. Kurz bevor ich den Wert 0 erreiche verhält sich die LED fast wie eine Kerze, die langsam erlischt. Sie wird dunkler, und bäumt sich regelmäsig nochmal gegen das Erlischen auf. Man merkt direkt wie sie für den Bruchteil eines Augenblickes nochmal Heller wird. Ich habe mir jetzt folgendes zusammengereimt: Dieses Flackern liegt an der niedrigen Frequenz. Die Frequenz ist zwar hoch genug dass im statischen Betrieb kein Flimmern zu erkennen ist. Beim Runterdimmen allerdings ändern sich die BCM-Werte. Dabei kippen eben ab und zu die höherwertigen Bits (7,6,5). Die Bitzeiten dieser Bits sind bei der gewählten Frequenz anscheinend lange genug um mit dem Auge sichtbar zu sein. Somit liegt das Flackern eher daran, dass eben ein Sprung 0->1 oder 1->0 an einem Bit auftritt, das lange genug anliegt um sichtbar zu sein. => es liegt also doch an der Frequenz? Kann meinen Gedankengang jemand bestätigen? Danke bisher an alle Helfer!
Stefan M. schrieb: > Marc Vesely, ich trau mich ja fast nicht fragen, aber magst du den Code > vielleicht nochmal simulieren um zu bestätigen, dass ich die Bitzeiten > jetzt einhalte? Ich bin hier auf Linux unterwegs und habe kein Atmel > Studio... Hier die Zeiten: bit 0 = 511 Taktzyklen min. 513 Taktzyklen Max. bit 1 = 767 Taktzyklen min. 769 Taktzyklen Max. bit 2 = 1279 Taktzyklen min. 1281 Taktzyklen Max. bit 3 = 2304 Taktzyklen bit 4 = 4351 Taktzyklen bit 5 = 8449 Taktzyklen bit 6 = 16639 Taktzyklen bit 7 = 33025 Taktzyklen Muss jetzt gehen, werde später etwas genauer durch deinen Code gehen. Vielleicht kommt da etwas gescheites dabei raus, obwohl ich das stark bezweifle.
Danke Marc, das hat zumindest ergeben dass ich mich im Prescaler verhaun hab ;-) Stefan M. schrieb: > Ich habe mir jetzt folgendes zusammengereimt: > Dieses Flackern liegt an der niedrigen Frequenz. > Die Frequenz ist zwar hoch genug dass im statischen Betrieb kein > Flimmern zu erkennen ist. > Beim Runterdimmen allerdings ändern sich die BCM-Werte. Dabei kippen > eben ab und zu die höherwertigen Bits (7,6,5). Die Bitzeiten dieser Bits > sind bei der gewählten Frequenz anscheinend lange genug um mit dem Auge > sichtbar zu sein. Somit liegt das Flackern eher daran, dass eben ein > Sprung 0->1 oder 1->0 an einem Bit auftritt, das lange genug anliegt um > sichtbar zu sein. > => es liegt also doch an der Frequenz? Kann dazu noch jemand was sagen? Mir will sonst einfach nicht einleuchten, wieso statischer Betrieb perfekt funktioniert, aber das Dimmen nicht.
Man muß die Bitzeiten aufsteigend ausgeben und nach dem Setzen der höchstwertigen Bitzeit das komplette Bitmuster updaten. Dann können nicht mitten drin falsche Bits entstehen. Das Main muß allerdings auch immer komplette Bitmuster erzeugen, ehe sie dann der Interrupt in das PWM-Array kopiert. Bei meinem Code habe ich allerdings auch ohne Synchronisation kein Flackern bemerkt. Das kann zum einen daran liegen, daß die PWM sehr hochfrequent ist und auch daran, daß das nächste Bitmuster per Macros sehr schnell in das PWM-Array konvertiert wird. Dadurch ist die Dauer und die Warscheinlichkeit des Flackerns stark reduziert. Wenn man die Umsortierung der Bits mit geschachtelten Schleifen macht, dauert das viel länger. Und wenn man dann mitten drin halb alte und halb neue Daten auf die PWM gibt, flackert es. 100% flackersicher kann man es mit einem Flag machen. Das Main wartet, bis das Flag gelöscht ist, erzeugt das neue Array und setzt das Flag. Der Interrupt wiederum prüft das Flag und ist es gesetzt, kopiert er in der letzen Bitzeit das Main-Array in sein PWM-Array und löscht das Flag.
:
Bearbeitet durch User
PeDa, ich danke dir dass du die Zeit gefunden hast hier ein paar Sätze dazu zu schreiben. Allerdings, alle Dinge die du hier nennst sind in meinem (bzw dem batsocks Code mit meinen Änderungen) bereits enthalten. Die Main ist mit der ISR auf die letzte (=längste Bitzeit synchronisiert). Mir geht es hierbei in erster Linie darum zu verstehen, wo in meinem Code das Problem liegt. Denn meiner Meinung nach hab ich auf alles aufgepasst. Deswegen will ich hier auch nicht auf deine Lösung zurückgreifen.
Stefan M. schrieb: > Allerdings, alle Dinge die du hier nennst sind in meinem (bzw dem > batsocks Code mit meinen Änderungen) bereits enthalten. > while (g_tick != 1); > g_tick = 0; Und wenn jetzt ein Interrupt kommt? Das main freut sich nur, daß das Flag irgendwann mal gesetzt wurde. Das muß nicht gerade eben gewesen sein. 1) g_tick darf erst nach der Umsortierung gelöscht werden. Und der Interrupt muß g_tick testen und nur dann das neue Array in seinen Puffer übernehmen. Du brauchst einen zusätzlichen Puffer. 2) Alternativ könnte ein weiterer Interrupt g_tick wieder löschen, wenn nicht mehr genug Zeit ist für das Main, das neue Array zu erzeugen. 3) Alternativ ginge auch:
1 | g_tick = 0; |
2 | while (g_tick != 1); // wait until next transition |
2), 3) setzen voraus, daß die Umsortierung garantiert kürzer als die längste Bitzeit dauert.
Hach ja, wie recht du doch hast... Kopf => Tisch Werde ich heut Abend gleich mal testen. Auf das Array werde ich erstmal auch verzichten und stattdessen nur mit einem Kanal (= normale Variable) Arbeiten. Dann sollte auch das Berechnen des Bitmusters garantiert nicht zu lange dauern.
Peter Dannegger schrieb: > Bei meinem Code habe ich allerdings auch ohne Synchronisation kein > Flackern bemerkt. Dasselbe hier. Peter Dannegger schrieb: > Der Interrupt wiederum prüft das Flag und ist es gesetzt, kopiert er in > der letzen Bitzeit das Main-Array in sein PWM-Array und löscht das Flag. Habe ich auch gemacht, aber es war weder besser noch schlechter, da habe ich es wieder sein lassen. Von bit0 bis bit3 wird die ISR nicht verlassen, eine Änderung kann also nur von bit4 bis bit7 auftretten. Das sind bei etwas mehr als 1KHz PWM ganze 930us. Es ist 8 Kanal RGB bzw. 24 Kanal Mono. Dimmen und Farbenwechsel wird selten schneller als 50Hz gemacht, das sind 20ms. Ein Verhältnis also von mindestens 20 zu 1. Einfach keine Chance, daß man da etwas merkt, selbst wenn es beim 7-ten bit passieren sollte. Nur ein wechseln zwischen 128 und 127 könnte BAM flackern lassen, aber auch nur dann, wenn dauernd zwischen diesen 2 Werten umgeschaltet wird und die Umschaltfrequenz langsamer als 20-30Hz ist. Somit bleibt beim TO nur die Dimmroutine übrig, die muß ja mit der ISR synchronisiert werden.
Hallo zusammen, ich bin immer noch am Testen meines Codes, heute habe ich endlich wieder Zeit. So ganz hinhauen tuts immer noch ned. Ich könnte natürlich PeDas Code benutzen, aber mir gehts immer noch darum meinen Fehler zu finden. Evtl. liegts aber doch noch an den Parametern, also Frequenz, Auflösung und Update-Rate. Kann hier mir jemand Zahlen aus eigener Erfahrung nennen, bei denen eine BCM ohne flackern funktioniert? Also, z.B.: 300Hz BCM Frequenz, 9 Bit Auflösung, 10Hz Update-Rate Dann könnte ich meinen Code an Parameter anpassen die woanders ja anscheinend laufen, und dort gezielt Fehlersuche betreiben. Viele Grüße, und schönen Sonntag, Stefan
@Stefan M. (Gast) >Ich könnte natürlich PeDas Code benutzen, aber mir gehts immer noch >darum meinen Fehler zu finden. Dann poste vollständigen, aktuellen Quelltext als Anhang.
Gerne, hie rmeine aktuelle Version, bereits mit dem von PeDa angesprochenen Bugfix PS: mir wäre es trotzdem lieb wenn du mir das hier beantwortest (sozusagen als Hilfe zur Selbsthilfe) Stefan M. schrieb: > Kann hier mir jemand Zahlen aus eigener Erfahrung nennen, bei denen eine > BCM ohne flackern funktioniert?
Stefan M. schrieb: > Kann hier mir jemand Zahlen aus eigener Erfahrung nennen, bei denen eine > BCM ohne flackern funktioniert? Habe ich dir doch. BAM mit etwas mehr als 1KHz. Dimmen von 10Hz bis 45Hz ohne flackern. Allerdings: Es wird logarithmisch gedimmt. Bei 10Hz - 20Hz und weniger als etwa 40 Schritten muss man die Übergänge bemerken. Bei linearem dimmen (also 255 Schritte) merkt man nichts, aber es ist halt nicht gleichmässig - von 1 bis 40 ist es sprunghaft, von 180 bis 255 ist kaum ein Unterschied zu merken.
@ Stefan M. (Gast) >Gerne, hie rmeine aktuelle Version, bereits mit dem von PeDa >angesprochenen Bugfix Naja. So richitg gut ist es nicht. Denn du wartest auf das SYNC Signal, aber dann erst leiert die ganze Umwandlung an. Wie man es besser macht, steht im schon verlinkten Artikel. https://www.mikrocontroller.net/articles/Soft-PWM#Intelligenter_L.C3.B6sungsansatz Die Sache mit den Pointern ist optimal, es reicht auch, wenn man zuerst die Daten in einem lokalen Array berechnet und dann nach dem SYNC kopiert. Deine ISR ist auch suboptimal.
1 | // Timer interrupt handler - called once per bit position.
|
2 | ISR( TIMER2_COMPA_vect ) |
3 | {
|
4 | g_bitpos ++ ; |
5 | g_bitpos &= 7; |
6 | PORTD = g_timeslice[ g_bitpos ] ; |
7 | // now set the delay...
|
8 | OCR2A <<= 1 ; |
9 | if (g_bitpos == 0) OCR2A = 1 ; // reset the compare match value. |
10 | if (g_bitpos == 7) g_tick = 1 ; // give the main loop a kick. |
11 | }
|
Hier wird teilweise mehrfach auf OCR2A geschrieben. Das geht einfacher und besser.
1 | // Timer interrupt handler - called once per bit position.
|
2 | ISR( TIMER2_COMPA_vect ) |
3 | {
|
4 | g_bitpos ++ ; |
5 | g_bitpos &= 7; |
6 | PORTD = g_timeslice[ g_bitpos ] ; |
7 | |
8 | if (g_bitpos == 0) { |
9 | OCR2A = 1 ; // reset the compare match value. |
10 | } else { |
11 | OCR2A <<= 1 ; |
12 | }
|
13 | if (g_bitpos == 7) { |
14 | g_tick = 1 ; // give the main loop a kick. |
15 | }
|
16 | }
|
Das ist aber nicht der Grund für das Flackern. Deine BCM hat 8 Bit, das LSB ist 256 Takte, macht bei 8 MHz CPU Takt 122 Hz. Sollte passen. Hmmm? Für die Neukodierung hat die CPU 256*128=32768 takte Zeit, das sollte reichen. Was kann man besser machen? Keine variablen Schiebeoperationen! https://www.mikrocontroller.net/articles/AVR-GCC-Codeoptimierung#Schiebeoperationen
1 | // encode an array of 8 LED brightness bytes into the pattern
|
2 | // to be shown on the port for each of the 8 timeslices.
|
3 | void led_encode_timeslices( uint8_t intensity[] ) |
4 | {
|
5 | uint8_t portbits = 0; |
6 | uint8_t bitvalue ; |
7 | uint8_t mask; |
8 | |
9 | g_tick = 0; |
10 | while (g_tick != 1); |
11 | for ( uint8_t bitpos = 0, mask=1 ; bitpos < 8 ; bitpos++, mask<<=1 ) |
12 | {
|
13 | portbits = 0; |
14 | bitvalue = 1 ; |
15 | for ( uint8_t ledpos = 0 ; ledpos < 8 ; ledpos++ ) |
16 | {
|
17 | if (intensity[ ledpos ] & mask) portbits |= bitvalue ; |
18 | bitvalue = bitvalue << 1 ; |
19 | }
|
20 | g_timeslice[ bitpos ] = portbits ; |
21 | }
|
22 | }
|
Trotzdem sollten die 32k Takte reichen. Hmmm? HUH! Ich glaube ich habs! Wegen deiner schlechten Formatierung (fehlende Einrückung!) steht dein led_encode_timeslices( brightness ) falsch! Besser so!
1 | while(1) |
2 | {
|
3 | while(g_tick==0){ /*wait for g_tick to be non-zero*/ } |
4 | slowtick-- ; |
5 | if (slowtick==0) |
6 | {
|
7 | slowtick = 100; |
8 | position++ ; |
9 | position &= 7 ; |
10 | //for ( uint8_t index = 0 ; index < 8 ; index++ )
|
11 | |
12 | if (brightness[ 6 ] > 0) brightness[ 6 ]-- ; |
13 | else brightness[ 6 ] = 30 ; |
14 | //and now re-encode all the timeslices...
|
15 | led_encode_timeslices( brightness ) ; |
16 | }
|
17 | }
|
18 | return(0); |
19 | }
|
Falk Brunner schrieb: > HUH! Ich glaube ich habs! Wegen deiner schlechten Formatierung (fehlende > Einrückung!) steht dein led_encode_timeslices( brightness ) falsch! > Besser so! Das ist unschön, ja. Allerdings sehe ich nicht, wie sich das problematisch auswirken kann. Momentan wird das Array öfter neu berechnet als notwendig. Solange die Update-Funktion auf die 7te Bitzeit synchronisiert ist sollte es aber deswegen nicht zu Problemen kommen. Werde ich aber trotzdem mal ändern, Danke fürs drüberschauen!
Stefan M. schrieb: > Momentan wird das Array öfter neu berechnet als notwendig. Solange die > Update-Funktion auf die 7te Bitzeit synchronisiert ist sollte es aber > deswegen nicht zu Problemen kommen. Ist es aber nicht unbedingt. g_tick aus led_encode und main() rausschmeissen, in main() led_encode rausschmeissen, brightness als volatile deklarieren. in der ISR nachdem bit7 steht, led_encode aufrufen. Anstatt:
1 | if (g_bitpos == 7) g_tick = 1 ; // give the main loop a kick. |
So:
1 | if (g_bitpos == 7) led_encode_timeslices( brightness ) ; |
slowtick rausschmeissen, mit _delay_ms dimmen.
:
Bearbeitet durch User
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.