Hallo Leute, ich sitze momentan vor einem kleinen Problem. Ich möchte zwei LEDs über einen bestimmten Zeitraum automatisch faden und dabei manuell dimmen können. Dabei können beide LEDs einen unterschiedlichen Wert haben; z.B. LED1 = 52 und LED2 = 220. Wenn ich jetzt BEIDE heller oder dunkler machen möchte, kommt automatisch eine vor der anderen an die Grenze. Den Helligkeitswert (0...255) muß ich über eine Geradengleichung ausrechnen, da ein Lookuptable bei meiner Aufgabe zu umfangreich wäre. Die Gleichung sieht aus wie folgt: Ergebnis = ( ( m * x ) / 100 ) + n + Verschiebung Dabei sind m (-200...+200) und n (0...255) fix ;x ist die Zeit. Die Verschiebung stellt nun meine Helligkeit höher oder tiefer WÄHREND des fadens. Das Problem ist, dass ich jedes mal über die Grenze hinausschiesse und der uc alles macht; nur nie das Richtige ;-). Für meine Grenzen habe ich if ( Ergebnis > 255 ) OCR1A = pgm_read_word( &pwmtable_16 [255] ); if ( Ergebnis < 0 ) OCR1A = pgm_read_word( &pwmtable_16 [0] ); if ( Ergebnis > 255 ) OCR1B = pgm_read_word( &pwmtable_16 [255] ); if ( Ergebnis < 0 ) OCR1B = pgm_read_word( &pwmtable_16 [0] ); Kann mir einer erklären, warum die Grenzen NICHT beachtet werden und der uc jedes mal son Mist macht? Wäre schön, wenn einer ne Idee hat. LG Jens
Der Jens schrieb: > Kann mir einer erklären, warum die Grenzen NICHT beachtet werden und der > uc jedes mal son Mist macht? Ohne komplettes Program: Nein
Je nach Datentyp kann dein Ergebnis nie größer als 255 und nie kleiner als 0 werden, was deine Abfragen natürlich ad absurdum führt.
OK. Hier mal die wesentlichen Teile . Zur Zeit sei noch dazu gesagt. Sie wird in einer ISR von 0...100 gezählt
1 | int main (void) { |
2 | |
3 | int16_t Verschiebung = 0; |
4 | uint8_t Ergebnis; |
5 | |
6 | if (!(PINB & (1 << PB0))) { // dunkler |
7 | Verschiebung--; |
8 | long_delay(20); // 20 * 1ms |
9 | }
|
10 | |
11 | if (!(PINB & (1 << PB1))) { // heller |
12 | Verschiebung++; |
13 | long_delay(20); // 20 * 1ms |
14 | }
|
15 | |
16 | Ergebnis = ( ( 100 * Zeit) / 100 ) + (50 + Verschiebung); |
17 | if ( Ergebnis > 255 ) OCR1A = pgm_read_word( &pwmtable_16 [255] ); |
18 | if ( Ergebnis < 0 ) OCR1A = pgm_read_word( &pwmtable_16 [0] ); |
19 | OCR1A = pgm_read_word( &pwmtable_16 [Ergebnis] ); |
20 | |
21 | Ergebnis = ( ( -100 * Zeit) / 100 ) + (50 + Verschiebung); |
22 | if ( Ergebnis > 255 ) OCR1B = pgm_read_word( &pwmtable_16 [255] ); |
23 | if ( Ergebnis < 0 ) OCR1B = pgm_read_word( &pwmtable_16 [0] ); |
24 | OCR1B = pgm_read_word( &pwmtable_16 [Ergebnis] ); |
25 | |
26 | }
|
Hallo, was passiert denn wenn eine 8 bit Variable (uint8_t) den Wert 255 hat und ich 1 addiere ? Sie wird 0 ;-) Umgekehrt passiert ägnliches. IMO kann ein uint8 NIE größer 255 oder kleiner 0 werden. Und das ist das Problem bei den Abgragen. S.
Hallo, OCR1B wird überschrieben: if ( Ergebnis > 255 ) OCR1B = pgm_read_word( &pwmtable_16 [255] ); if ( Ergebnis < 0 ) OCR1B = pgm_read_word( &pwmtable_16 [0] ); OCR1B = pgm_read_word( &pwmtable_16 [Ergebnis] ); besser: if ( Ergebnis > 255 ) Ergebnis = 255; if ( Ergebnis < 0 ) Ergebnis = 0; OCR1B = pgm_read_word( &pwmtable_16 [Ergebnis] ); aber warum nimmst du nicht gleich eine 8 bit Variable für das Ergebnis? Dann kannst du die Prüfung weglassen. (Achtung: bei den Berechnung in größeren Variablen bzw. float rechnen) MFG weene
Der Jens schrieb:
> uint8_t Ergebnis;
Das heißt "unsigned int mit 8 bit". Der Wertebereich ist 0 bis 255.
Das kann also nie zutreffen:
1 | > if ( Ergebnis > 255 ) OCR1A = pgm_read_word( &pwmtable_16 [255] ); |
2 | > if ( Ergebnis < 0 ) OCR1A = pgm_read_word( &pwmtable_16 [0] ); |
3 | > if ( Ergebnis > 255 ) OCR1B = pgm_read_word( &pwmtable_16 [255] ); |
4 | > if ( Ergebnis < 0 ) OCR1B = pgm_read_word( &pwmtable_16 [0] ); |
5 | > OCR1B = pgm_read_word( &pwmtable_16 [Ergebnis] ); |
weene schrieb: > aber warum nimmst du nicht gleich eine 8 bit Variable für das Ergebnis? > Dann kannst du die Prüfung weglassen. Das ist eine 8 bit Variable.
Christian H. schrieb:
> Das kann also nie zutreffen:
Ich meinte nur die If-Anweisungen, nicht die OCR1B-Zuweisung.
Der Jens schrieb: > OK. Hier mal die wesentlichen Teile . Zur Zeit sei noch dazu gesagt. Sie > wird in einer ISR von 0...100 gezählt >
1 | > Ergebnis = ( ( 100 * Zeit) / 100 ) + (50 + Verschiebung); |
2 | > if ( Ergebnis > 255 ) OCR1A = pgm_read_word( &pwmtable_16 [255] ); |
3 | > if ( Ergebnis < 0 ) OCR1A = pgm_read_word( &pwmtable_16 [0] ); |
4 | > OCR1A = pgm_read_word( &pwmtable_16 [Ergebnis] ); |
5 | |
6 | >
|
Selbst wenn Ergebnis ein int16_t wäre (was es sein müssen wird): Gehs durch. Du rechnest dir ein Ergebnis aus. Ist das Ergebnis zu groß setzt du einen Wert Wenn das Ergebnis zu klein ist setzt du einen anderen Wert Und dann: Dann setzt du auf jeden Fall noch den Wert, den du durch die Rechnerei erhalten hast. D.h. Deine if sind völlig für die Katz, weil du danach immer auf jeden Fall noch dein Rechenergebnis benutzt. Wenn schon, dann so
1 | Ergebnis = ( ( 100 * Zeit) / 100 ) + (50 + Verschiebung); |
2 | if ( Ergebnis > 255 ) |
3 | Ergebnis = 255; |
4 | else if ( Ergebnis < 0 ) |
5 | Ergebis = 0; |
6 | |
7 | OCR1A = pgm_read_word( &pwmtable_16 [Ergebnis] ); |
Dazu muss aber Ergebnis überhaupt in der Lage sein, Werte größer 255 bzw. kleiner 0 annehmen zu können. Ein uint8_t kann das per Definiton schon mal nicht.
>uint8_t Ergebnis; >if (Ergebnis > 255) >if ( Ergebnis < 0 ) beide Bedingungen können nie vorkommen, da der Wertebereich der uint8 von 0 - 255 geht. Auch die Berechnung >( 100 * Zeit) / 100 ) ist ziemlich sinnfrei, da sich das zu Zeit kürzt. Wenn ich Dich richtig verstehe willst Du daß beim Fading deiner LEDs es bei einer LED die auf dem Helligkeitswert 200 steht genau so lange dauert wie wenn die Diode den Helligkeitswert 50 hat. Dann ist die Steigung deiner Geraden eben nicht konstant, sondern die ist abhängig von dem Startwert. Bei der Diode mit dem Startwert 200 muss die Änderung der Helligkeit pro Zeit viermal höher ausfallen als bei der mit dem Wert 50.
Karl heinz Buchegger schrieb: > D.h. Deine if sind völlig für die Katz, weil du danach immer auf jeden > > Fall noch dein Rechenergebnis benutzt. genau DAS war mein Problem!! Das mit uint8_t <-> int16_t ist mir vorhin dann doch noch selber aufgefallen. Krass; wie seht ihr sowas nur immer?! wunderbar! :-) Danke nochmal. Eine kleine Formfrage hätte ich aber noch. Du schreibst die Abfrage so: > if ( Ergebnis > 255 ) > > Ergebnis = 255; > > else if ( Ergebnis < 0 ) > > Ergebis = 0; ich würde sie so schreiben: if ( Ergebnis > 255 ) Ergebnis = 255; if ( Ergebnis < 0 ) Ergebnis = 0; Also warum benutzt du ein else if? Gibt es Geschwindwigkeits-/Codegrößenvorteile oder ist es so nur besser zu sehen, dass beide if's zusammen gehören?
Der Jens schrieb:
> Krass; wie seht ihr sowas nur immer?! wunderbar! :-)
z.B. in dem wir nicht versuchen maximal viel Befehle in eine Zeile zu
quetschen... Ich weiß gar nicht wo so was herkommt wird das als
besonders 'cool' angesehen?
Und ich persönlich gehe sogar soweit das ich immer Klammern setze auch
wenn die Bedingung/Schleife nur eine Anweisung umfasst...
Der Jens schrieb: > ich würde sie so schreiben: > > if ( Ergebnis > 255 ) > Ergebnis = 255; > if ( Ergebnis < 0 ) > Ergebnis = 0; > > Also warum benutzt du ein else if? Weil, wenn schon feststeht das Ergebnis größer als 255 ist, es nicht mehr sein kann, das Ergebnis kleiner als 0 ist. Wozu etwas abtesten, von dem ich den Ausgang sowieso schon kenne?
Die Zeile finde ich auch noch fragwürdig: Ergebnis = ( ( -100 * Zeit) / 100 ) + (50 + Verschiebung); Wenn Zeit von 0 - 100 geht, dann kann Ergebnis je nach Verschiebung auch negativ werden. Durch die 8 bit Variable liegt ne negative Variable dann im Bereich 128-255. Beim Übergang von einem positiven Ergebnis zum negativen Ergebnis springt also der PWM-Wert von z.B. &pwmtable_16[0] um auf @pwmtable_16[255]. Ob das so gewollt ist?
Und um die Frage zu beantworten: Eigentlich kann er nur addieren... (duck, und wech)
MagIO schrieb: > Beim Übergang von einem positiven Ergebnis zum > negativen Ergebnis springt also der PWM-Wert von z.B. &pwmtable_16[0] um > auf @pwmtable_16[255]. Ob das so gewollt ist? Was meinst du wohl, was diese Zeile hier bewirken soll? ;-) Der Jens schrieb: > if ( Ergebnis < 0 ) > Ergebnis = 0;
MagIO schrieb: > Die Zeile finde ich auch noch fragwürdig: > Ergebnis = ( ( -100 * Zeit) / 100 ) + (50 + Verschiebung); > > Wenn Zeit von 0 - 100 geht, dann kann Ergebnis je nach Verschiebung auch > negativ werden. Er hat aber auch im Eröffnungspoting geschrieben, dass die erste 100 hier > Ergebnis = ( ( -100 * Zeit) / 100 ) + (50 + Verschiebung); **** eigentlich ein m ist mit einem Wertebereich von -200 .. 200. Fass diese 100 und die 50 und die Verschiebung einfach nur als x-beliebige Werte auf, mit denen zur Zeit einfach nur getestet wird. Die werden sich sicherlich noch ändern.
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.