Ich habe keine Ahnung von C, aber es müsste im Prinzip ja so aussehen:
100=0
900=255
255/800=0,318
Wert=way_akt*0,318
Hallo zusammen,
Ich komm mal gleich zur Sache:
Zunächst wird eine Hebelstellung per POTI über den ADC ausgelesen.
Dieser Wert liegt zwischen 0 und 1023. = way_akt
Ich nutze aber nicht den vollen weg des Potis, sondern nur
zB von 100 bis 900.
Diese Werte habe ich in way_min und way_max geschrieben.
Ich benötige am scholuss eine 8Bit-breite Zahl.
Also habe ich mir folgende umrechnung ausgedacht:
Code:uint8_t way_rev; // Reverse-Bits uint16_t way_min = 100; // Reverenz Minimalwert uint16_t way_mid; // Reverenz Mittelstellung uint16_t way_max = 900; // Reverenz Maximalwert uint16_t way_akt; // Rohe-Potistellung uint16_t way_neu; // Aufbereitete Stellgröße way_akt = ADC_wert(0); if( way_akt < way_min ){ way_akt = way_min; } if( way_akt > way_max ){ way_akt = way_max; } way_akt = way_akt - way_min; double factor; double x; factor = 1023 / (way_max - way_min); x = (way_akt / factor); way_neu = x; way_neu = ((way_neu)>>2); PORTC = way_neu;
nunja, leider ist die berechnung nicht so genau.
Deshalb erreiche ich nie meine vollen 255!
Wie könnte ich das am dümmsten lösen? Ich habe schon sämtliche formeln und Co ausprobiert....
Für eure Hilfe wäre ich euch mehr als Dankbar!
Gruß,
Franz
Ich habe keine Ahnung von C, aber es müsste im Prinzip ja so aussehen:
100=0
900=255
255/800=0,318
Wert=way_akt*0,318
Hallo Kaiser-F,
Nimm also way_diff = way_max - way_min.Ich nutze aber nicht den vollen weg des Potis, sondern nur
zB von 100 bis 900.
Diese Werte habe ich in way_min und way_max geschrieben.
Jetzt der Dreisatz:
Way_diff/255 = Way_akt/x
x = Way_akt * 255 / way_dif
x ist der gesuchte 8Bit-Wert.
Gruß, Michael
Hi,
@Michael: ich bin mir nicht sicher ob das 100%ig geht, weil uint16 max 65535 sein kann. Also könnte es bei Werten von Way_akt > 257 Probleme geben...
@Kaiser-F: was mir bei deinem code seltsam vorkommt ist
factor = 1023 / (way_max - way_min);
x = (way_akt / factor);
probier das mal mit
factor = 1023.0 / (double)(way_max - way_min);
x = ((double)way_akt / factor);
PS: einfache floats sollten da doch reichen oder?
.... bin mir jetzt nicht sicher ob es das war, aber das könnte es gewesen sein...
MfG Alex
Hallo PasstScho,
das passtscho, setz einfach mal Werte ein und rechne es aus.ich bin mir nicht sicher ob das 100%ig geht,
Besser noch:einfache floats sollten da doch reichen oder?
Kaiser-F wollte nur 8 bit!
Gruß, Michael
Sorry, war gerade nen Happe essen,
Und hab mir 2 Aspirin + C reingehaun.
Evtl hilft mir das mit C
@PasstScho:
factor = 1023 / (way_max - way_min);
(way_max - way_min) ist der "Nutzweg"
durch diesen factor muss ich später teilen.
Das ganze funktioniert wunderbar, nur bekomm ich das mit den Gleitpunktvariablen nicht so hin....
der wert factor, und der spätere Quotient:
way_akt /factor ist dann zu ungenau...
Ich bin mir nicht genau sicher wie ich die Gleitpunktvariablen anwenden muss.
Ich probier gleich mal eire Anregungen aus.
Danke vorerst mal für die Superschnelle Hilfe!
EDIT:
der ADC liefert max. 1023. Da es ein 10Bit ADC ist, bin ich gezwungenZitat von PasstScho
ein uint16_t zu verwenden.
Gruß,
Franz
Also;
Merkwürdigerweise erhalte ich wenn ich es EINFACH so schreibe:
Das "genauste" Ergebnis: 200....Code:uint8_t way_rev; // Reverse-Bits uint16_t way_min = 100; // Reverenz Minimalwert uint16_t way_mid; // Reverenz Mittelstellung uint16_t way_max = 900; // Reverenz Maximalwert uint16_t way_neu; // Aufbereitete Stellgröße uint16_t way_akt; // Rohe-Potistellung uint16_t way_nutz; uint16_t factor; uint16_t x; way_akt = ADC_wert(0); if( way_akt < way_min ){ way_akt = way_min; } if( way_akt > way_max ){ way_akt = way_max; } way_akt = way_akt - way_min; way_nutz = (way_max - way_min); factor = 1023 / way_nutz; x = way_akt / factor; way_neu = x; way_neu = ((way_neu)>>2); PORTC = way_neu;
wenn man rechnet: 1023/800 = 1,27875. mit uint16_t sind macht das: 1
also.... für nix.....
mit
kommt raus: 156... ??Code:uint8_t way_rev; // Reverse-Bits uint16_t way_min = 100; // Reverenz Minimalwert uint16_t way_mid; // Reverenz Mittelstellung uint16_t way_max = 900; // Reverenz Maximalwert uint16_t way_neu; // Aufbereitete Stellgröße uint16_t way_akt; // Rohe-Potistellung uint16_t way_nutz; double factor; double x; way_akt = ADC_wert(0); if( way_akt < way_min ){ way_akt = way_min; } if( way_akt > way_max ){ way_akt = way_max; } way_akt = way_akt - way_min; way_nutz = (way_max - way_min); factor = 1023.0000 / way_nutz; x = way_akt / factor; way_neu = x; way_neu = ((way_neu)>>2); PORTC = way_neu;
Gruß,
Franz
au au au... das wird peinlich!
156 war rechnerisch absolut richtig!
der Fehler lag darin, dass der factor nicht 1023/way_nutz ist,Code:uint8_t way_rev; // Reverse-Bits uint16_t way_min = 100; // Reverenz Minimalwert uint16_t way_mid; // Reverenz Mittelstellung uint16_t way_max = 900; // Reverenz Maximalwert uint16_t way_neu; // Aufbereitete Stellgröße uint16_t way_akt; // Rohe-Potistellung uint16_t way_nutz; double factor; double x; way_akt = ADC_wert(0); if( way_akt < way_min ){ way_akt = way_min; } if( way_akt > way_max ){ way_akt = way_max; } way_akt = way_akt - way_min; way_nutz = (way_max - way_min); factor = way_nutz / 255.0000; x = way_akt / factor; way_neu = x; PORTC = way_neu;
sondern way_nutz/255.
Danke an Michael, durch seinen Tipp "DREISATZ" bin ich draufgekommen.
Vielen Danke nochmal an alle!
Gruß,
Franz
Hi,
Genau das ist der Grund warum ich das zu (double) gecastet habe.
In C oder C++ ist 1000/800 nicht das gleiche wie 1000.0/800.0 ... bei 1000/800 teilt dein Programm mit Zahlen ohne Komma!
Wenn du 1000.0/800.0 machst, sieht er das .0 und erkennt, dass du mit Komma rechnen willst.
Du musst in deinem Programmen also richtig zwischen int und float unterscheiden.
Ich prüfe mal grad die andere Lösung von Michael .... theoretisch könnte sie funktionieren, aber auch nicht so wirklich...
MfG Alex
Hi auch,
@ Passtscho: Du hast vololkommen Recht!
Wenn ich schreibe: (way_max[ch] - way_min[ch]) / 255; ist das Ergebnis ungenau!
Wenn ich aber schreibe: (way_max[ch] - way_min[ch]) / 255.0000;
dann erhalte ich das Richtige ergebnis. wobei 255.0000 etwas übertrieben wirkt
Hier alles in Kurzform in einer Funktion:
( mit globalen Arrays )
Code:void WAY_PROP ( uint8_t ch ){ if( way_akt[ch] < way_min[ch] ){ way_akt[ch] = way_min[ch]; } if( way_akt[ch] > way_max[ch] ){ way_akt[ch] = way_max[ch]; } way_akt[ch] = way_akt[ch] - way_min[ch]; double factor = (way_max[ch] - way_min[ch]) / 255.0000; way_end[ch] = way_akt[ch] / factor; }
Gruß,
Franz
Lesezeichen