Hallo zusammen, nachdem ich schon öfter hier mitgelesen habe musste ich
mich nun anmelden da ich bei der Programmierung eines Drehzahlmessers
mit einem Atmega32 auf folgendes Problem gestossen bin und nicht weiter
komme. So wie es aussieht zählt mein ICP Zähler die richtige Anzahl Tics
macht jedoch bei der Umrechnung in 1/min Fehler. Das passiert jedoch
erst ab einer gewissen Anzahl Tics nicht aber bei 56535 was ja auf ein
int16 Überlauf hinweisen würde sondern erst bei höheren Werten.
Die Ausgegebenen Daten sehen z.B. so aus:
Tics - 1/min
16696 - 7107
24695 - 4859
32695 - 3670
40700 - 2948
48700 - 2464
56702 - 2116
64698 - 1854
78998 - 15191 anstatt 1519
86992 - 13794 anstatt 1379
Hat jemand eine Idee woran das liegen kann? Habe ich irgendwas
übersehen?
Vielen Dank im Voraus.
digitalone
F. K. schrieb:> Das passiert jedoch> erst ab einer gewissen Anzahl Tics nicht aber bei 56535 was ja auf ein
^^
> int16 Überlauf hinweisen würde sondern erst bei höheren Werten.
uint16_t
65535
^^
int16_t
32767
Ich seh auch kein ursächliches Problem
Aber ich würde erst mal:
uint64_t drehzahl=0;
kein Grund das als uint64_t zumachen. Das ist nur Beschäftigungstherapie
für den µC
char temp2[6],temp3[6];
die sind ein wenig arg knapp. Bei solchen char-Felder: Nicht kleckern,
klotzen. Auch wenn du nur mit maximal 5 stelligen Zahlen rechnest, es
schadet nichts, diese Felder auf 10 oder 15 zu vergrößern. Und wenn dann
eine Zahl doch einmal etwas größer wird, hat man ein wenig Reserve.
78998 - 15191 anstatt 1519
86992 - 13794 anstatt 1379
Das da ziemlich genau das 10-fache rauskommt, lässt mich nicht an einen
Rechenfehler glauben, sondern an ein Anzeigeproblem, zb. Zahlen die
nicht vollständig von der nächsten überschrieben werden. Aber so wie du
das aufgebaut hast, kann es das eigentlich auch nicht sein.
uint64_t drehzahl=0; hatte ich auch schon auf 32 habe es nur testweise
hochgesetzt. Die char hatte ich auch schon 20 lang - kein Unterschied.
Habe das ganze auch mal rechnen lassen mit 78998 als Festwert für Tics
dann zeigt er richtig an. Deswegen bezweifel ich dass es an der Anzeige
liegt. Bin nur erstmal beruhigt dass euch auf den ersten Blick auch
nichts auffällt aber vielleicht kommt ja noch jmd. drauf.
F. K. schrieb:> 78998 - 15191 anstatt 1519> 86992 - 13794 anstatt 1379
^ ^
Da fehlt eine Stelle, also eventuell Bufferoverflow, wenn uint64_t
drehzahl an ultoa() übergeben wird.
Ich würde versuchsweise temp2 größer machen, damit die abschliessende
0 nicht verloren geht. Und ich würde auch mal drehzahl uint32_t
machen.
> u64_drehzahl=((2000000/60)/u32_tics);
Hmm...
u64_drehzahl = ((uint64_t)2000000 / 60) / u32_tics;
Mit uint32_t:
drehzahl = (2000000UL / 60) / tics;
F. K. schrieb:> Habe das ganze auch mal rechnen lassen mit 78998 als Festwert für Tics> dann zeigt er richtig an. Deswegen bezweifel ich dass es an der Anzeige> liegt.
Wird tics richtig berechnet?
>> u32_tics = u16_zaehler - u16_zaehler_alt;
u32_tics = (uint32_t)u16_zaehler - u16_zaehler_alt;
Oder gemessen?
Was machst du, wenn u8_overflow_status == 1 ist? Du müsstest doch dann
65536 auf u16_zaehler addieren!
Ich kann deine ganze Berechnung nicht nachvollziehen
78998 - 15191 anstatt 1519
86992 - 13794 anstatt 1379
mit der Berechnung
drehzahl=((2000000/60)/tics);
und einem Taschenrechner kriege ich ganz andere Ergebnisse raus.
2000000/60 -> 33333
78998 -> 33333 / 78998 -> 0
Was'n jetzt los?
Zeigst du uns ein anderes Programm, als das was tatsächlich läuft?
Ganz abgesehen davon, dass tics als Differenz zweier unsigned 16 Bit
Werte gar nicht 78998 sein kann! Bei 65535 ist in deinem Code Schluss.
**************************************
-> du hast den falschen Code gepostet!
**************************************
da ist mir beim zurückbauen meines Versuchscodes ein Fehler unterlaufen
es muss natürlich heißen u64_drehzahl=((2000000*60)/u32_tics);
bzw. jetzt u32_drehzahl=((2000000*60)/u32_tics); alos MAL 60 nicht
GETEILT durch 60.
Der Fehler ist natürlich weiterhin vorhanden.
> Ganz abgesehen davon, dass tics als Differenz zweier unsigned 16 Bit> Werte gar nicht 78998 sein kann! Bei 65535 ist in deinem Code Schluss.>> **************************************> -> du hast den falschen Code gepostet!> **************************************
Das habe ich auch gedacht aber es funktioniert so da wird wohl intern
mit overflow bit gerechnet werden!?
> Habe das ganze auch mal rechnen lassen mit 78998 als Festwert für Tics> dann zeigt er richtig an.
Dann würde ich mal ganz stark die Korrektheit der Ausgabe für ticks
bezweifeln. Dort nach dem rechten sehen.
Zählerwerte ausgeben, Anzahl Overflows ausgeben, Berechnungen
kontrollieren, etc.
F. K. schrieb:>> Ganz abgesehen davon, dass tics als Differenz zweier unsigned 16 Bit>> Werte gar nicht 78998 sein kann! Bei 65535 ist in deinem Code Schluss.>>>> **************************************>> -> du hast den falschen Code gepostet!>> **************************************>> Das habe ich auch gedacht aber es funktioniert so da wird wohl intern> mit overflow bit gerechnet werden!?
Nicht mit deinem geposteten Code.
Die Differenz zweier unsigned 16 Bit Zahlen kann nie größer als 65535
sein. Wenn du was anderes schaffst, solltest du sofort einen Vertrag mit
Las Vegas abschliessen, denn dann ist der Copperfield ein popeliger
Trickbetrüger gegen dich.
Dieser Ausdruck hier
1
volatileuint16_tzaehler_alt=0,zaehler=0;
2
3
...
4
5
tics=zaehler-zaehler_alt;
kann nie größer als 65535 werden. Völlig unmöglich.
Ich würde vorschlagen.
Du stellst jetzt in deinem Code wieder die ursprüngliche Version her. So
wie sie richtig ist und wie du denkst dass es sein müsste. drehzahl
machst du als uint32_t und die beiden char-Felder setzt du größer. Dann
kontrollierst du noch ob der Fehler immer noch da ist und notierst dir
die Ausgaben.
An besten veränderst du auch die Ausgabe ganz leicht, so dass du sicher
sein kannst, dass es genau dieser Code und kein anderer ist, der auf dem
µC läuft.
Dann postest du Code und Zahlen
(Ich traue deinem Code nicht mehr. Sobald ich dich einmal dabei erwischt
habe, dass der gepostete Code nicht dem entspricht der den Fehler zeigt,
will ich es ganz genau wissen)
>> kann nie größer als 65535 werden. Völlig unmöglich.
Mhmm das hab ich mir vorher auch gedacht dachte dann durch das Programm
eines besseren belehrt worden zu sein. Aber wenn das nicht funktioniert
gilt es ja eigentlich nur den Fehler zu finden wie er auf die Werte über
65535 kommt und wieso er in der Berechnung auf einmal so einen Sprung
macht.
Ich vermute du hast gar keine 78998 Ticks. Du hast nur 7899 Ticks und
die abschliessende 8 ist ein Überbleibsel von früher, welches nie
gelöscht wurde. Der * soll das anzeigen, indem er klar macht, wo die
Zahl wirklich aufhört.
Auf jeden Fall würde das alles erklären:
7899 ist im möglichen Zahlenbereich
Die Berechnung für 7899 ergibt tatsächlich 15191
> 78998 - 15191 anstatt 1519> 86992 - 13794 anstatt 1379
steht da noch Müll von vorher auf dem Display und wird nicht
überschrieben (die 1 bei 1519_1 bzw. die 4 bei 1379_4)?
Lothar Miller schrieb:>> 78998 - 15191 anstatt 1519>> 86992 - 13794 anstatt 1379> steht da noch Müll von vorher auf dem Display und wird nicht> überschrieben (die 1 bei 1519_1 bzw. die 4 bei 1379_4)?
Bei den Drehzahlen nicht. Das hat er relativ geschickt gelöst. Aber bei
den Ticks! Ich denke dort ist noch Müll von vorhergehenden Durchläufen.
>> Ich vermute du hast gar keine 78998 Ticks. Du hast nur 7899 Ticks und> die abschliessende 8 ist ein Überbleibsel von früher, welches nie> gelöscht wurde. Der * soll das anzeigen, indem er klar macht, wo die> Zahl wirklich aufhört.>> Auf jeden Fall würde das alles erklären:> 7899 ist im möglichen Zahlenbereich> Die Berechnung für 7899 ergibt tatsächlich 15191
Das war der entscheidende Tip!!! Danke
Jetzt muss ich es nurnoch hinbekommen dass er mir zuverlässig im Falle
eines Überlaufes zu den tics overflow_status*65536 hinzuaddiert. Zurzeit
springt er mir leider noch hin und her zwischen mit und ohne 65536...