Ich verwene eine trimpoti (10 umdrehungen) an der forgesehene eingang von OP177. Geht problemlos, aber auch muss ich genau abregelen zwischen beide max.
Druckbare Version
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 wird :D hatte 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 gibt :( im Taschenrechner funktioniert diese "Formel" ...Code:#define KMZ0MAX 750
#define KMZ0MIN 60
int32_t KMZ0 = 0;
(...)
KMZ0 = (adc0 - KMZ0MIN -(KMZ0MAX-KMZ0MIN)/2)*1000/(KMZ0MAX-KMZ0MIN);
(...)
writeInteger(KMZ0 , DEC);
*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 gesichtet :) aber 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 Stellen :( geh 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 ist :( aber 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