Servosignal mit Atmega328 in C auswerten

Gast #4656994
Lesenswert?
• ▲
▼
Hallo,

ich bastle seit Tagen an einem Problem:
Ziel ist es ein Servosignal, momentan von einem ServoTester später 
funkempfänger, auszuwerten.

Hardware: Atmega328 auf 20MHz. Intialisiert sind:
Timer1 (16bit) - normal mode, no prescaling d.h. overflow bei ca 3,2ms
INT0 - rising edge (hier liegt das signal an)

Das ist mein code. alle variablen sind volatile und rising ist mit 1 
initialisiert.
1
ISR(INT0_vect)
2
{
3
  if(rising == 1) //also rising edge
4
  {    
5
  start =  ((uint16_t)TCNT1H << 8) | TCNT1L; //Timer auslesen
6

7
  rising = 0;
8
  EICRA &= ~(1 << ISC00); //jetzt auf fallende flanke triggern
9
  }
10
  else
11
  {
12
  end = ((uint16_t)TCNT1H << 8) | TCNT1L; //Timer auslesen
13
  rcsig = end - start;
14

15
  rising = 1;
16
  EICRA |= (1 << ISC00);
17
  }
18
}

in der main teste ich folgendermaßen:
1
    while(1)
2
    {   
3
    
4
  if (rcsig > 30000) //30000 entspricht 1,5ms also genau hälfte
5
  color[0] = 255;
6
  else
7
  color[0] = 0;
8

9
    }



leider leuchtet die led garnicht. ich hab jetzt schon verschiedenes 
ausprobiert aber weiß mittlerweile nicht mehr weiter.

vielleicht könnt ihr mir helfen!

viele Grüße Alex
Moderator (Firma: Titel) Persönliche Seite #4657000
Lesenswert?
• ▲
▼
Alex schrieb:
> ich hab jetzt schon verschiedenes ausprobiert aber weiß mittlerweile
> nicht mehr weiter.
Du vermittelst dir ja schon ein sehr binäres Bild der Welt.
Wenn du mehrere LEDs hast, dann könntest du doch mal ein paar Bits 
deines Zählerwertes ausgeben und abschätzen, wo dein Wert eigentlich 
liegt...

Du kannst auch mal die LED in der ISR toggeln, um zu sehen, ob du 
überhaupt da reinkommst...

Ein Debugger ist natürlich auch was supertolles. Oder wenigstens eine 
serielle Schnittstelle.

Alex schrieb:
> start =  ((uint16_t)TCNT1H << 8) | TCNT1L; //Timer auslesen
Schreib das kürzer. Das kann der Compiler super selber richtig machen:
 start =  TCNT1; //Timer auslesen

BTW: Einrückungen unterstützen die Lesbarkeit des Codes.
Und hier im Forum kannst du die [c] Tags verwenden. Siehe dazu die 
Bedienungsanleitung der Eingabebox...
#4657007
Lesenswert?
• ▲
▼
Zeig deinen ganzen Code. In dem Auschnitt oben ist nicht erkennbar, 
warum da überhaupt eine LED leuchten sollte.

Abgesehen davon ist das Netz voll mit Codebeispielen zur Asuaertung 
eines Servosignals. Da könntest du dir noch ein paar Anregungen holen. 
So fehlt z.B. eine Behandlung des Timerüberlaufs.

Oliver
Gast #4657011
Lesenswert?
• ▲
▼
ES FUNKTIONIERT :D wahnsinn ich arbeite seit knapp 3 tagen an diesem 
Problem.

"start =  TCNT1;" das war das problem. ich verstehe nur nicht warum 
meine schreibweise nicht geklappt hat..

vielen vielen dank!
#4657016
Lesenswert?
• ▲
▼
An welcher Stelle wird dein Timer denn überhaupt eingeschaltet?

Sinnvoll wäre ja, den Timer bei einer steigenden Flanke einzuschalten, 
bei der fallenden Flanke auslesen und wieder auf 0 setzen.
Zu sehen ist zwar nur ein Bruchteil deines Codes, aber das sieht für 
mich so aus, als würde der Timer nonstop rennen. Wenn dieser nun 
zwischen steigender und fallender Flanke überläuft ist deine Differenz 
Käse.
Gast #4657039
Lesenswert?
• ▲
▼
wie die led genau angeschlossen ist spielt doch keine rolle.
Ich hab deren funktion generell gestet.

mit color[0] = 255; led wird mit fast pwm gedimmt.

Ja, der Timer läuft nonstop.
Ich habe nachgelesen, dass es zu viel zeit kostet den timer auf null zu 
setzt.
(https://www.mikrocontroller.net/articles/High-Speed_capture_mit_ATmega_Timer) 
siehe abschnitt keine Angst vor überläufen.

die richtige differenzberechnung muss ich noch implementieren.
Gast #4657051
Lesenswert?
• ▲
▼
Warum es jetzt klappt.....

ganz klar !!!!

8 Bit CPU   und Zugriff auf 16 Bit Register

start =  ((uint16_t)TCNT1H << 8) | TCNT1L; //Timer auslesen

ist falsch.

Laut Datenblatt erfolgt der Zugriff immer beim Low Register.
Das High Register geht immer in einen Buffer

Bedeutet: Beim Lesen
Erst auf TCNT1L zugreifen --> High geht in den Buffer
Danach High Lesen... Kommt aus dem Buffer

Bedeutet: Beim schreiben
Erst TCNT1H setzen --> High geht in den Buffer
Danach Low Setzten ... High wird aus dem Buffer mit übertragen.

Gruß Thomas
#4657077
Lesenswert?
• ▲
▼
Frickelfritze schrieb:
> Alex schrieb:
>> wie die led genau angeschlossen ist spielt doch keine rolle.
>> Ich hab deren funktion generell gestet.
>
> Wenn man sieht was hier "täglich" an banalen Fehlern auftaucht
> ist meine Art der Fragestellung(en) nicht abwegig .....

Vor allem, wenn es nur heißt:

Alex schrieb:
> leider leuchtet die led garnicht.

Da ist es doch nicht so abwegig, zu denken, dass vielleicht schon die 
Ansteuerung der LED nicht klappt. Das hier konnte ja vorher keiner 
wissen:

Alex schrieb:
> Ich hab deren funktion generell gestet.
Gast #4657092
Lesenswert?
• ▲
▼
Habt recht, bei der LED-Steuerung hätte durchaus was nicht passen 
können. Ihr konntet nicht wissen, dass ich diese vorher ausgibig 
getestet habe.

vielen Dank an alle!

muss ich den Beitrag irgendwie als gelöst kennzeichnen?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren