Ich verwene eine trimpoti (10 umdrehungen) an der forgesehene eingang von OP177. Geht problemlos, aber auch muss ich genau abregelen zwischen beide max.
Ich verwene eine trimpoti (10 umdrehungen) an der forgesehene eingang von OP177. Geht problemlos, aber auch muss ich genau abregelen zwischen beide max.
Ok habe das gemacht was im Hanbuch als "Anfänger fehler" verbucht wirdhatte zur Berechnung eines Mittelwerts uint8 verwendet, was dann bei hohen Werten diese Sprünge ins niedrige verursacht haben muss...
Habe grad kein Trimpoti hier, desshalb habe ich einen 2,5k Poti mit 2X 33k Widerständen benutzt, das schränkt zwar den Radius ein, aber zum Glück passt das und ist präzise genug ^^
So noch mehr Fragen zur Software:
-warum schmeißt folgender code nur falsche Werte aus?
im Endeffekt soll KMZ0 ein wert zwischen -1 und 1 sein mit dem Faktor 1000, da es keine Nachkommastellen gibtCode:#define KMZ0MAX 750 #define KMZ0MIN 60 int32_t KMZ0 = 0; (...) KMZ0 = (adc0 - KMZ0MIN -(KMZ0MAX-KMZ0MIN)/2)*1000/(KMZ0MAX-KMZ0MIN); (...) writeInteger(KMZ0 , DEC);im Taschenrechner funktioniert diese "Formel" ...
*die Werte liegen grundsätzlich zwischen 6 und 70 o.ä.
*einmal hatte ich 1000 durch 100000 ersetzt, und einen richtigen Wert erhalten, andere Werte sponnen trotzdem
* habe noch nie ein negativen Wert ausgegeben bekommen, aber eine Bedingung für ein negativen Wert wurde mal erfüllt, kann writeInteger negative Werte ausgeben?
- Wie funktioniert das mit dem include math.h ? ist das schon in der RP6 lib? Wo finde ich die doku?
mfg Axel
Hallo,
writeInteger ist für 16 Bit Werte! Mit 32 Bit gibts dann Müll
Aber ich kann mir auch nicht vorstellen das Du wirklich 32 Bit Wert brauchst.
(nein ich hab nicht den ganzen Thread gelesen)
Jedenfalls wenn Du das unbedingt brauchst kannst Du das mal hiermit probieren:
Und ja, das kann negative Werte ausgeben!Code:// Original - nur um die Änderungen zu verdeutlichen: /* void writeInteger(int16_t number, uint8_t base) { char buffer[17]; itoa(number, &buffer[0], base); writeString(&buffer[0]); } */ // Geänderte Version: void writeInteger32(int32_t number, uint8_t base) { char buffer[33]; // 33 wegen BIN! Für DEC wärs natürlich nicht nötig... itoa(number, &buffer[0], base); writeString(&buffer[0]); }
AVRLibC Doku:
http://www.nongnu.org/avr-libc/user-manual/index.html
MfG,
SlyD
naja auf 32Bit kann ich denke ich verzichten... aber warum wirft er nun für z.b. den Wert(ADC0) "111" "52" statt "-42,..." aus? Also ich seh immer noch keine negativen werte?!
mfg und Danke für die Antwort Axel
EDIT: Hatte den Faktor mal auf 100 reduziert, um sicher nicht aus den 16Bit zu fallen ^^
Mach mal ein paar mehr Klammern um die Berechnung drum - damit auch die Reihenfolge korrekt eingehalten wird.
(düfte zwar daran nicht liegen, aber schaden kann es nicht)
Dann könnte es noch sein, das der Compiler einige Werte nicht als 16 Bit signed Integer behandelt - also mach mal z.B. vor den adc0 Wert ein
(int16_t)
und auch nochmal vor den ganzen Ausdruck.
(das nennt sich "type cast" also Typumwandlung)
Also so:
(int16_t)((((int16_t)adc0 - KMZ0MIN - ((KMZ0MAX-KMZ0MIN)/2))*1000)/(KMZ0MAX-KMZ0MIN));
Ich hoffe mal die Klammerung ist so wie Du es gemeint hast
MfG,
SlyD
also mit dem (int16_t)adc0 wurden schonmal die ersten negativen Zahlen gesichtetaber ich bewege mich noch im Wertebereich von -50 bis 50 anstatt -1000 bis 1000 ich spiel mal noch etwas mit den Klammern...
besten Dank Axel
EDIT: Habe es jetzt schon auf
KMZ0 = (((int16_t)adc0 - 405)*1000)/690;
reduziert, aber ich erhalte immer noch falsche werte![]()
also wenn man den Faktor auf 100 reduziert, habe ich schon viele richtige Werte erhalten, aber nicht an allen Stellengeh also davon aus das die Klammerung etc richtig ist
ich poste mal die Werte, vielleicht fällt ja jemanden etwas auf:
KMZ0 = (((int16_t)adc0 - 405)*100)/690;Code:KMZ0=-44KMZ1=-26 ---> Stimmt ADC0= 98ADC1= 183 KMZ0=-38KMZ1=34 ADC0= 137ADC1= 154 KMZ0=-16KMZ1=-18 ---> Stimmt auch ADC0= 293ADC1= 122 KMZ0=10KMZ1=-36 ADC0= 474ADC1= 177 KMZ0=14KMZ1=-6 ADC0= 506ADC1= 195 KMZ0=22KMZ1=-34 ADC0= 560ADC1= 244 KMZ0=23KMZ1=-35 ADC0= 565ADC1= 243 KMZ0=22KMZ1=-32 ADC0= 561ADC1= 245 KMZ0=23KMZ1=-30 ADC0= 567ADC1= 246 KMZ0=22KMZ1=-27 ADC0= 559ADC1= 248 KMZ0=22KMZ1=-30 ---->Stimmt auch ADC0= 559ADC1= 246 KMZ0=23KMZ1=-25 ADC0= 565ADC1= 249 KMZ0=22KMZ1=-24 ADC0= 560ADC1= 250 KMZ0=23KMZ1=-27 ADC0= 564ADC1= 248 KMZ0=23KMZ1=-30 ADC0= 564ADC1= 246 KMZ0=23KMZ1=-20 ADC0= 566ADC1= 252 KMZ0=22KMZ1=-25 ADC0= 562ADC1= 249 KMZ0=23KMZ1=-27 ADC0= 564ADC1= 248 KMZ0=22KMZ1=-19 ADC0= 562ADC1= 253 KMZ0=27KMZ1=-45 ADC0= 598ADC1= 303 KMZ0=28KMZ1=-10 ADC0= 605ADC1= 455 KMZ0=9KMZ1=18 ADC0= 468ADC1= 603 KMZ0=8KMZ1=24 ADC0= 465ADC1= 607 KMZ0=9KMZ1=24 ADC0= 472ADC1= 607 KMZ0=8KMZ1=28 ADC0= 465ADC1= 609 KMZ0=8KMZ1=21 ADC0= 465ADC1= 605 KMZ0=8KMZ1=18 ADC0= 467ADC1= 603 KMZ0=8KMZ1=21 ADC0= 467ADC1= 605 KMZ0=9KMZ1=23 ADC0= 468ADC1= 606 KMZ0=8KMZ1=26 ADC0= 465ADC1= 608 KMZ0=8KMZ1=23 ADC0= 466ADC1= 606 KMZ0=8KMZ1=26 ADC0= 466ADC1= 608 KMZ0=9KMZ1=21 ADC0= 469ADC1= 605 KMZ0=9KMZ1=26 ADC0= 470ADC1= 608 KMZ0=-37KMZ1=6 ADC0= 143ADC1= 596 ---> Stimmt KMZ0=43KMZ1=-7 --->Stimmt nicht KMZ0=-51 ADC0= 51ADC1= 522 KMZ0=43KMZ1=0 ADC0= 50ADC1= 527 KMZ0=43KMZ1=-7 ADC0= 48ADC1= 522 KMZ0=43KMZ1=-6 ADC0= 51ADC1= 523 KMZ0=43KMZ1=-9 ADC0= 48ADC1= 521 KMZ0=44KMZ1=-6 ADC0= 54ADC1= 523 KMZ0=43KMZ1=-12 ADC0= 48ADC1= 519 KMZ0=43KMZ1=-4 ADC0= 48ADC1= 524 KMZ0=43KMZ1=-9 ADC0= 48ADC1= 521 KMZ0=43KMZ1=-9 ADC0= 49ADC1= 521 KMZ0=43KMZ1=-4 ADC0= 49ADC1= 524 KMZ0=44KMZ1=-7 ADC0= 55ADC1= 522 KMZ0=43KMZ1=-9 ADC0= 48ADC1= 521 KMZ0=43KMZ1=-7 ADC0= 50ADC1= 522 KMZ0=43KMZ1=-14 ADC0= 50ADC1= 518 KMZ0=43KMZ1=-6 ADC0= 49ADC1= 523 KMZ0=43KMZ1=-12 ADC0= 50ADC1= 519 KMZ0=43KMZ1=-6 ADC0= 51ADC1= 523 KMZ0=43KMZ1=-11 ADC0= 47ADC1= 520 KMZ0=43KMZ1=-16 ADC0= 50ADC1= 517 KMZ0=43KMZ1=-16 ADC0= 53ADC1= 517 KMZ0=42KMZ1=-4 ADC0= 46ADC1= 524 KMZ0=42KMZ1=-16 ADC0= 43ADC1= 517
naja bei der Auswertung ist mir noch aufgefallen, das meine Formel noch nen Inhaltlichen Fehler hat, da sie bei 60 nicht -100 istaber das erklärt ja nicht, warum mirco Prozessor und Taschenrechner zu unterschiedlichen Werten kommen
abgesehn davon hätte ich schon gern den Faktor 1000, weil 100 "schritte" bei 360° nicht so genau ist
mfg Axel
Habe es jetzt wie folgt gelöst:
und für den Faktor 100 macht er das jetzt ganz brav, nur beim Faktor 1000 bekomme ich komische Werte (zwischen ca -104 bis 103)Code:(...) ZW0A=(KMZ0MAX-KMZ0MIN)/2; ZW0B=KMZ0MIN + ZW0A; KMZ0 = (((int16_t)adc0 - ZW0B)*100)/ZW0A; (...)
habe mal überschlagen das er an den max Werten Zwischenwerte +/- 345.000 berechnen muss!!! Das fällt natürlich aus dem 16Bit Rahmen.
Kann ich mit dem type cast den irgendwie dazu bringen die Rechnung in 32Bit durchzuführen, sich das aber als 16Bit Variable zu speichern?
Oder muss ich mir für die Rechnung ne extra Variable in 32Bit einrichten?
mfg Axel
kann mir einer von denen, die sowas schonmal programmiert haben zeigen wie sie das gelöst haben?
Logisch ja kein Ding, aber beim umrechen von (uint16_t)adcX zu einem double für acos( x double) habe ich nur Probleme.
entweder erhalte ich Werte >1 oder nur 1; 0; -1![]()
@RP6conrad
läuft das bei dir mit dem atan ? arctan hat doch nur ein Wertebereich von -pi/2 bis pi/2 ergo nur 180° und dann wird (atan)' für große Werte so klein, das man doch ziemlich große Fehler erhält?
ich wollte das über den arccos(x) für |x|<0,707 und an den Stellen |x| >0,707 den anderen Sensor (bzw sinus ) zu nehmen.
So werden alle "flachen Stellen" an den kleine Fehler große Wirkung haben ausgeblendet.
Ist zwar noch etwas Arbeit, und dafür muss ich das mit den double erstmal in den Griff kriegen -.-
mfg Axel
Lesezeichen