Servo Einstellung und Anzeige in Grad

Gast #7089878
Lesenswert?

Hallo
Habe gerade einen Servotester mit Timer programmiert:
1
void timer_init()
2
  {            // Timer 1 16 Bit konfigurieren
3
  TCCR1B = (1<<WGM11)|(1<<CS11);//|(1<<CS10);  // CTC Modus, Prescaler 8
4
  TIMSK1|=(1<<OCIE1A)|(1<<OCIE1B);      // Interrupt erlauben
5
  OCR1A=3999;    // Timer 1 Register A
6
  OCR1B=1220;    // Timer 1 Register B  Mittelstellung
7
  }
8

9
// Impuls starten 
10
ISR(TIMER1_COMPA_vect)
11
  {
12
  PORTA &=~(1<<PINA1);
13
  }
14
  
15
  // Impuls stoppen
16
ISR(TIMER1_COMPB_vect)
17
  {
18
    PORTA |=(1<<PINA1);
19
  }
20

21
if ( !(PINA & (1<<PINA7)) )
22
      {        
23
      if(OCR1B < 3999);
24
        {
25
        OCR1B = OCR1B + 10;
26
        }
27
      if(OCR1B>=2870)
28
        {
29
        OCR1B = 2870;
30
        }     
31
      _delay_ms(1);
32
      }  
33

34
if ( !(PINA & (1<<PINA3)) )
35
      {        
36
      lcd_printlc(3,1,"Ta 1 - dreht links ");  
37
      PORTC |= (1<<PINC5);
38
      PORTC &= ~(1<<PINC6);
39
      if(OCR1B > 80);
40
        {
41
        OCR1B = OCR1B - 10;
42
        }
43
      }  
44

45
 itoa(OCR1B,wert,10);        // Berechne wert von OCR1B
46
     lcd_printlc(4,1,"OCR1B=");  
47
     lcd_printlc(4,7,"             ");  
48
     lcd_printlc(4,8,wert);        // Anzeige wert 
49
     _delay_ms(30);
Läuft mit Timer 1 16 Bit CTC Prescaler 8 auf 20ms. Mit den beiden Tasten 
kann ich links oder rechts drehen. Funktioniert super. Mit itoa wird 
OCR1B angezeigt. Die Begrenzung nach oben funktioniert auch, wird aber 
noch verbessert.
Das Problem ist itoa. Als Wert für OCR1B kann doch eigentlich nur ein 
positiver Wert angezeigt werden. Bekomme aber Werte von -400 bis +2870.
Möchte auch den Wert in Grad von 0 bis 180° anzeigen lassen. Positver 
Winkel von -410?
Wie kann ich am besten in Grad umrechnen? Hat jemand eine Idee dazu?
LG P.
Gast #7089910
Lesenswert?

Dein itoa scheint den Eingabewert als 16-bittig, vorzeichenbehaftet 
anzusehen. Pech.

Vielleicht gibt es ja auch ein ltoa. Dann nimm das.

Wenn nicht musst Du das ganz schwere Geschütz snprintf auffahren oder 
selber was stricken.

Sollte der Zusammenhang zwischen Tastverhältnis und Winkel linear sein, 
hilft entweder die Funktion map() beim Arduino oder das Kapitel "lineare 
Gleichungen" im Mathebuch.

Aber auch dabei immer darauf achten, dass alle Variablen genügend Platz 
bieten.
Moderator (Firma: Titel) Persönliche Seite #7089934
Lesenswert?

Ein Neuling schrieb:
> Läuft mit Timer 1 16 Bit CTC Prescaler 8 auf 20ms.
Bei mir läuft dieser Code nirgends. Du kannst einfach genaus die 
Sourcedatei anhängen, die den Fehler zeigt und dann noch sagen, auf 
welcher Plattform mit welchem compiler du das Problem beobachtest (ich 
weiß schon: man könnte sich das auch erraten, aber ich bin da grade zu 
faul dazu...).

> Als Wert für OCR1B kann doch eigentlich nur ein positiver Wert angezeigt
> werden. Als Wert für OCR1B kann doch eigentlich nur ein positiver Wert
> angezeigt werden.
Warum? Wo soll der gezeigte Code OCR1B nach unten begrenzen?

> Bekomme aber Werte von -400 bis +2870. ...
> Positver Winkel von -410?
Wie kommst du da auf -410, wenn nur Werte von -400 bis ... angezeigt 
werden?


BTW: das ist schon irgendwie planlos:
1
      if(OCR1B < 3999);
2
        {
3
        OCR1B = OCR1B + 10;
4
        }
5

6
      if(OCR1B>=2870)
7
        {
8
        OCR1B = 2870;
9
        }


Ein Neuling schrieb:
> Werte von -400 bis +2870.
> Möchte auch den Wert in Grad von 0 bis 180° anzeigen lassen.
Stichwort "lineare Interpolation": wenn ein wert von -400 einem Winkel 
von 0° entspricht und +2870 einem Winkel von 180°, welcher Winkel 
entspricht dann einem wert von 1190?

Ein Tipp: es wird einfacher, wenn du erst mal die Baustelle mit den -400 
aufräumst.
Gast #7089970
Lesenswert?

Lothar M. schrieb:
> Ein Tipp: es wird einfacher, wenn du erst mal die Baustelle mit den -400
> aufräumst.
Das ist mir absolut klar.
Arbeite mit C am Atmega 128, AVR Studio 7

Lothar M. schrieb:
> Stichwort "lineare Interpolation": wenn ein wert von -400 einem Winkel
> von 0° entspricht und +2870 einem Winkel von 180°, welcher Winkel
> entspricht dann einem wert von 1190?

OCR1B beginnt ja mit 0, damit ist -400 falsch

Lothar M. schrieb:
> BTW: das ist schon irgendwie planlos:

Das soll noch vereinfacht werden, steht auch drin, muss erst die -400 
loswerden
Moderator (Firma: Titel) Persönliche Seite #7090001
Lesenswert?

Ein Neuling schrieb:
> OCR1B beginnt ja mit 0, damit ist -400 falsch
Mag sein, dass du das so empfindest. Trotzdem steht da offenbar -400 
(oder -410) drin. Wie kommt es also dazu? Wer außer dir manipuliert da 
im OCR1B herum?

Ein Neuling schrieb:
> Wie kann das sein wenn OCR1B max 0 sein kann.
Ich denke, du willst, dass es "minimal 0" sein können. Aber wie gesagt: 
du hast das nirgends begrenzt.

> Wie kann das sein
Stichwort: Zweierkomplement.
Du beginnst bei 0 (0x0000) und ziehst 10 (0x000A) ab, dann kommen 
unsigned 65526 (0xFFF6) heraus. Das machst du dann noch weitere 39 
mal...
Gast #7090406
Lesenswert?

Ich habe nochmal über den Code geschaut. In der Tat sollte unter 
normalen Umständen der Wert von 80 bis 2870 sein. Und das passt alles in 
vorzeichenbehaftete 16 Bit.

OCR1BH und OCR1BL sind im Datenblatt auch als R/W gekennzeichnet, also 
sollte man den Wert auch zurück lesen können, wenn man die richtige 
Reihenfolge einhält. Die sollte aber der C-Compiler kennen und beachten.

Womit Du allerdings was über den Haufen schiessen kannst, ist in einem 
Interrupt auf OCR1xx, ICR1x oder TCNT1x zuzugreifen. Wenn ich mal davon 
ausgehe, dass der Code, den Du hier ausserhalb jeglicher Funktion 
gepostet hast, Teil des Hauptprogramms ist.

Wann kommen den die negativen Zahlen ? Unterhalb von 80, oberhalb von 
2870 oder immer mal irgendwo anders mittendrin ?

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