Arduino Merkwürdiges verhalten

OP #4058257
Lesenswert?
• ▲
▼
Hallo
Ich will mir mit LEDs eine Ladezustandsanzeige basteln

Ansteuern will ich die mit:
1
byte Zustand =0;
2
byte anz=0;
3
anz = (etwas zwischen 0 und 8);
4
Zustand = byte(pow(2,anz)-1);
Wenn ich anz direkt etwas zwischen 0 und 8 setze leuchten die leds so 
wie sie sollen.
z.B.
1
anz = 4;
2
println(anz,DEC); ->4 angezeigt
3
println(Zustand,DEC); -> 15 angezeigt(leds leuchten entsprechend dem Binärmuster)
Fange ich jetzt an anz zu berechnen aus einem SOC
1
anz=byte(map(SOC,0,100,0,Aufloesung));
oder
1
anz=byte(SOC*Aufloesung/100);
wobei mir Aufloesung angibt ob ich 4 oder 8 oder... LEDs für die Anzeige 
zur Verfügung habe.
kommt die falsche anzeige bei raus obwohl ich an der Zustand berechnung 
nichts ändere kommt z.B. bei SOC 50 folgendes raus
println(anz,DEC); ->4 angezeigt
println(Zustand,DEC); -> 14 angezeigt(leds leuchten entsprechend dem 
Binärmuster)

kann mir mal einer sagen warum einmal
2^4-1=15
und einmal
2^4-1=14
rauskommt?????
und das nur weil die 4 einmal fest geschrieben und einmal ausgerechned 
wird?

beim ausrechnen entsteht ein fehler bei jedem SOC

PS:
Der fehler tritt auch auf wenn ich die einzelnen Schwellen mit if und 
else if bedingungen mache... und immer setze z.B. if(SOC > 45) anz = 4;
nur wenn ich wieder ganz kurz vor dem ausrechnen des Zustandes anz auf 
einen wert z.B. 4 setze, dass wird alles richtig angezeigt...

es ist zum verrückt werden...
#4058351
Lesenswert?
• ▲
▼
Enrico S. schrieb:

> kann mir mal einer sagen warum einmal
> 2^4-1=15
> und einmal
> 2^4-1=14
> rauskommt?????
> und das nur weil die 4 einmal fest geschrieben und einmal ausgerechned
> wird?

Da ist mit Sicherheit irgendwo wieder eine Floating Point Rechnung im 
Spiel. Die Details, wie zb Datentypen oder realen Code, hast du ja nicht 
gezeigt.

Dein Ergebnis ist eben nicht 4, sondern zb. 3.999999.
Bei der Ausgabe wird gerundet. Wenn du aber rechnest, wird tatsächlich 
mit 3.999999 gerechnet. Und das ist nun mal nicht dasselbe wie 4.0


Wo auch immer du mit Floating Point rechnest, füge beim Übergang zu int 
eine Rundungskorrektur ein
1
  int intWert;
2
  float floatWert;
3

4
  floatWert = 3.99999;
5

6
  // Rundungskorrektur
7
  intWert = floatWert + 0.5;
#4058365
Lesenswert?
• ▲
▼
Abgesehen davon, ist die Verwendung von pow hier mit Kanonen auf Spatzen 
geschossen.

Du hast 8 mögliche Ergebnisse.
Die kannst du auch ganz einfach als Fix und Fertiges Ergebnis in einem 
Array vorhalten.
1
  byte LedPattern[] = { 0b00000001,    // 0
2
                        0b00000010,    // 1
3
                        0b00000100,    // 2
4
                        0b00001000,    // 3
5
                        0b00010000,    // 4
6
                        0b00100000,    // 5
7
                        0b01000000,    // 6
8
                        0b10000000,    // 7
9
                        0b11111111,    // 8 -> zu gross
10
                      };
11

12
...
13
  if( anz > 7 )
14
    anz = 7;
15

16
  Zustand = LedPattern[anz];
17
...

keiner muss gross rumrechnen und du hast den Bonus, das Led Muster 
problemlos so anzupassen, wie du das möchtest. Möchtest du den Level als 
einzelne LED angeben, dann ist das kein Problem. Möchtest du ein 
LED-Band dann ist das auch kein Problem. Möchtest du den Level als 2 
nebeneinander liegende LED anzeigen, dann änderst du einfach das Muster 
im Array. Möchtest du anstatt 8 Levels deren 16, indem du zb Abwechselnd 
nur 1 und 2 LED leuchten lässt, dann geht auch das (wenn man das Array 
entsprechend größer macht und die Rechenfaktoren anpasst).

Alles in allem: win win

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.