INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Falsche Ergebnisse beim potenzieren
18.11.2020, 08:20 (Dieser Beitrag wurde zuletzt bearbeitet: 18.11.2020 08:28 von Marco.R.)
Beitrag #1
Falsche Ergebnisse beim potenzieren
Hallo,
Ich möchte einen Sensor digital auslesen, dabei soll jeder fünfte Impuls an LEDs per Shiftout über einen Schieberegister ausgegeben werden: Dazu teile ich die Impulse durch 5, nehme dieses Ergebnis als Exponent zur Basis 2, sprich:
4 Impulse = 4 / 5 = (int) 0 -> 2^0 = 1 = (bin) 1 (0-4 erste LED)
9 Impulse = 9 / 5 = (int) 1-> 2^1 = 2 = (bin) 10 (5-9 zweite LED)
10 Impulse = 10 / 5 = (int) 2 -> 2^2 = 4 = (bin) 100 (10-14 dritte LED)
14 Impulse = 14 / 5 = (int) 2 -> 2^2 = 4= (bin) 100 (10-14 dritte LED)
15 Impulse = 15/ 5 = (int) 3 -> 2^8= 8 = (bin) 1000 (15-19 vierte LED) usw
Nun schaut Euch bitte diesen Probesketch an, die Impulse habe ich durch eine Schleife ersetzt.
Ab 2^2 = 4 habe ich zwar 4, diese 4 (dezimal) ergeben aber binär 11 (=3), bei 8 sind es binär 111 (=7)
Die Impulse musste ich als Integer deklarieren, andere Variablen als float (pow liefert Fliesskomma)
Desweiteren musste ich das float Ergebnis mit einer int Variable umwandeln (float als bin ausgeben geht nicht).
Bin für jede Idee dankbar. Kann zwar mit einer Bedingung ab 3 auf's richtige Ergebnis kommen, möchte aber gerne wissen ….
Code:
//74HC595
int latchPin = 9;
int clockPin = 8;
int dataPin = 10;

int impuls;
float exponent;
int wandel;
float data;


void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  digitalWrite(latchPin, LOW);
  digitalWrite(clockPin, LOW);
  
Serial.begin(9600);

    for(impuls = 1;impuls <= 500;impuls++) {
      exponent = impuls/5;
      data = pow(2,exponent);
      wandel = data;

      shiftOut(dataPin, clockPin, MSBFIRST, wandel >> 8);
      shiftOut(dataPin, clockPin, MSBFIRST, (wandel));
      digitalWrite(latchPin, HIGH);
      digitalWrite(latchPin, LOW);
      
      Serial.print(impuls);
      Serial.print("/5 ->  2^ ");
      Serial.print(exponent);
      Serial.print(" = (data dec) ");
      Serial.print(data);
      Serial.print(" (data bin) ");
      Serial.println(wandel,BIN);
      
        
      delay(2000);
    }

    

  
}

void loop() {



}


Angehängte Datei(en) Thumbnail(s)
   
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
18.11.2020, 11:27
Beitrag #2
RE: Falsche Ergebnisse beim potenzieren
Hallo Marco,

habe Dein Script ( ohne die Portausgaben) mal bei mir laufen lassen und siehe da bei mir kommt ein anderes Ergebnis raus
2 ^2 --> 100
2 ^3 --> 1000
2 ^4 --> 10000

Bernd
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
18.11.2020, 14:57 (Dieser Beitrag wurde zuletzt bearbeitet: 18.11.2020 14:59 von GuaAck.)
Beitrag #3
RE: Falsche Ergebnisse beim potenzieren
Hallo,

Folgendes könnte die Ursache sein:

Die pow-Funktion wird nicht erkennen, dass es sich im Grunde um zwei ganze Zahlen handelt. Intern wird für die Berechnung eine Näherungsfunktion genutzt. Diese ergibt bei Marco möglicherweise einen Wert geringfügig kleiner als 8, bei Bernd (andere Prozessor, andere Library?) ist es es genau 8 oder sogar etwa mehr. Sei der kleinere Wert z. B. 7,99999, der dann auf den Integerwert zugewiesen ergibt 7 (also binär 111 statt der erwarten 1000), die Nachkommmastellen werden bei der Zuweisung abgeschnitten. Bei Bernd passt es gerade.

Abhilfe:
a) wandel = int(data+0.5);

b) M.E. viel besser: Alles Integer rechnen:
Code:
statt (float data, float exponent)
  data=pow(2,exponent);

dann (int data, int exponent):
  data = 1 << exponent;

Gruß
GuaAck
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
18.11.2020, 22:37 (Dieser Beitrag wurde zuletzt bearbeitet: 18.11.2020 23:01 von GuaAck.)
Beitrag #4
Nachtrag: Stimmt, es ist ein Abschneideproblemnzieren
Hallo,

ich war neugierig und habe den Code mal auf meinem UNO und meinem DUE (32-Bit-Prozessor) laufen lassen. Zusätzlich habe ich mir die float im HEX-Format ausgeben lassen. Hier mein Ergebnis:

Code:
Float UNO
1/5 ->  2^ 0.00 = (data dec) 1.00 = (data hex) 0x3F800000 (statt 0x4F8) (data bin) 1
...
5/5 ->  2^ 1.00 = (data dec) 2.00 = (data hex) 0x40000000 (statt 0x400) (data bin) 10
...
10/5 ->  2^ 2.00 = (data dec) 4.00 = (data hex) 0x407FFFFE (statt 0x408) (data bin) 11
...
15/5 ->  2^ 3.00 = (data dec) 8.00 = (data hex) 0x40FFFFFC (statt 0x410) (data bin) 111
...
20/5 ->  2^ 4.00 = (data dec) 16.00 = (data hex) 0x417FFFFC (statt 0x418) (data bin) 1111
...
25/5 ->  2^ 5.00 = (data dec) 32.00 = (data hex) 0x41FFFFFA (statt 0x420) (data bin) 11111
===========

Mit dem DUE kommen zumindest in dem untersuchten Zahlenbereich die richtigen Werte heraus.

Klare Aussage: Möglichst Integer-Rechnung so früh wie möglich, wenn man ein Integer als Resultat braucht. Geht auch sehr viel schneller. Bei float--> int mit +0.5 runden.

Zur Info: Um sicher zu gehen habe ich die Hex-Darstellung der Float über eine union-Struktur (float über long) gemacht und die long-Interpretation mit print(..,HEX) ausgegeben.

Gruß
GuaAck
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.11.2020, 07:41 (Dieser Beitrag wurde zuletzt bearbeitet: 19.11.2020 07:45 von Marco.R.)
Beitrag #5
RE: Falsche Ergebnisse beim potenzieren
Danke für Eure Antworten!

Scheint tatsächlich ein "Abschneideproblem" zu sein.
Hatte mich mit pow festgefahren, und je mehr ich über die falschen Ergebnisse grübelte, desto mehr entfernte ich mich von der einfachsten Lösung (hat man schon mal gehört), Lösung die absolut gut funktioniert.

Gewünscht :
(5 Impulse) => 1=dec1 (10 Impulse) => 10=dec2 (15 Impulse) => 100=dec4 etc.
Lösung: eine weite Variable, die sich bei jedem 5. Durchgang verdoppelt anstatt zu potenzieren.

Grüße
Marco

void loop() {
if(digitalRead(Sensor) == LOW && set == 0) {
j++;
set = 1;
}

if(digitalRead(Sensor) == HIGH && set == 1) {
set = 0;
delay(100); //Entprellen
if(i==65536){ // = BIN 1 000 000 000 000 000 (16. LED)
i=1; // Bei Led 1 beginnen
}
}
if(j==5) {
shiftOut(dataPin, clockPin, MSBFIRST, i >> 8);
shiftOut(dataPin, clockPin, MSBFIRST, i);
digitalWrite(latchPin, HIGH);
digitalWrite(latchPin, LOW);

i*=2; // Verdoppelt sich bei jedem 5. Durchgang => 1 4 8 16 32 etc
j=0; // zählt die Impulse
}
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  433 MHz Transmitter SX1278: Merkwürdigkeit beim Empfang GuaAck 5 594 20.06.2020 22:20
Letzter Beitrag: hotsystems
  Fehlermeldung beim Sketch hochladen heino_m 12 1.595 28.05.2020 18:25
Letzter Beitrag: Tommy56
  Wo ist der RxD1 beim Wemos D1 mini? DO3GE 3 586 03.05.2020 12:33
Letzter Beitrag: Fips
  Verschiedene Spannungen beim Schalten von Relais? Wosch 4 676 19.04.2020 16:33
Letzter Beitrag: Tommy56
  Fehler beim Kompilieren Lunge 6 946 09.04.2020 14:07
Letzter Beitrag: MicroBahner
  Timeout beim Hochladen freak76 5 910 06.04.2020 08:54
Letzter Beitrag: GuaAck
  Undefined reference-Fehler beim Kompilieren MdE 9 1.117 24.03.2020 21:39
Letzter Beitrag: Tommy56
  Problem beim Hochladen des Sketchs Telefonmann 9 1.548 04.02.2020 10:40
Letzter Beitrag: Blende8
  plötzlich merkwürdige Fehlermeldung beim Übersetzen Jan99 4 771 30.01.2020 16:45
Letzter Beitrag: Tommy56
  Probleme beim zusammenfügen Zweier Sketche Joel 18 2.266 07.01.2020 19:09
Letzter Beitrag: Tommy56

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste