Zitat von
Besserwessi
Wenn die Messung beim langsamen Drehen funktioniert, nicht aber wenn der Motor läuft, könnte das Porblem von Störungen vom Motor kommen, also eine Hardware Problem und keines in der Software.
Hallo,
danke für die Antwort. Ich habe den Kontroller wegen diesem Problem jetzt schon mindestens 20 mal mit einer abgeänderten Software geflasht und er geht immer noch nicht. Ich versuche das noch mal genauer zu beschreiben. Ich hatte den Lüfter mit den Input Capture Interrupt dran, dann noch einen Adc mit Poti und einen Timer der Sekunde für Sekunde nach oben zählt. Alle diese Werte habe ich dem Display ausgeben lassen. Da der Adc auch bei laufenden Lüfter auf jede kleinste Veränderung reagiert und sofort der richtige Wert am Display ausgegeben wird ( was in der while Schleife der main Funktion passiert) kann ich mir nicht vorstellen, dass der Kontroller überlsatet ist.
Ich habe zur Sicherheit trotzdem den Code so abgeändert, dass nur noch der Input Capture Interrupt verarbeitet wird (also kein Adc mehr). Auch das hat nicht gebracht. Auch habe ich die Zeitdifferenz nicht mehr teilen lassen, sondern direkt auf dem Display ausgegeben und auch bringt keine Verbesserung, da er jetzt bei laufendem Lüfter für die Zeitdifferenz nur 256 oder 0 ausgibt
Nebenbei habe ich auch noch eine Led toggeln lassen, wenn der Interrupt auftritt. Das funktioniert komischerweise wunderbar, denn wenn der Lüfter auf voller Drehzahl läuft, wird die Led praktisch gedimmt und wenn ich dne Lüfter mit der Hand abbremse kann man irgendwann bei langsamer Lüfterdrehzahl ein Blinken erkennen.
Auch die Anzahl der Interrupts, die ich ebenfalls auf dem Display ausgeben lasse, werden vernünftig hochgezählt.
Da ich noch Anfänger bin, was die Avrs betrifft, werde ich jetzt doch mal meinen Code ausschnittsweise posten:
Hier die ISR:
Ich lasse die Zeitdifferenz für eine Umdrehung erst nach 4 Interrupts berechnen, weil der Lüfter für eine Umdrehung 4 mal von low auf high wechselt. Sobald "difference_new" ihren Wert verändert, wird der neue Wert in der Hauptschleife auf dem Display ausgegeben.
Code:
ISR(TIMER1_CAPT_vect)
{
PORTC ^= (1<< PC7); //PC7: Led
if (test >9998){ // Test zählt die interrutps und gibt sie auf dem Display aus
test = 1;}
else { test ++;}
if (calculate >= 3){
timer_compare_new= ICR1L;
timer_compare_new= ( ICR1H<< 8);
difference_new = (timer_compare_new - timer_compare_old);
timer_compare_old = timer_compare_new;
calculate =0 ;
}
else{
calculate ++;}
}
Hier ein Auszug aus meinem headerfile, in dem die Variablen deklariert werden:
Alle Variablen, die sowohl von der ISR als auch von den Funktionen aus der Main genutzt werden habe ich als volatile deklariert und ihnen in der Main Funktion, aber noch vor der while Schleife, den Wert 0 zugeordnet.
Ist das in Ordnung mit volatile?
Code:
volatile uint16_t timer_compare_new;
volatile uint16_t timer_compare_old;
volatile uint16_t difference_new;
uint16_t diff_old;
volatile uint8_t calculate;
Den Code aus der main Funktion spare ich mir, weil er ja bei langsamen Drehzahlen (nicht schneller, als man mit der Hand so nen Lüfter drehen kann) vernünftige Werte für die Zeitdifferenz liefert und auch bei laufenden Lüfter die Adc Werte sofort aktuallisiert hat, was darauf schließen lässt, dass die main Funktion noch ausreichend häufig durchlaufen wird, also nicht von Interrupts lahmgelegt ist.
Würde mich sehr freuen, wenn ihr mir noch mal helfen könntet, da ich mit meinem Latein jetzt echt am Ende bin und schon viel Zeit in dieses Projekt investiert habe.
MfG
Destrono
Lesezeichen