Forum: Mikrocontroller und Digitale Elektronik Servo Ansteuerung


von Dani (Gast)


Lesenswert?

Hallo,

es sind geneug Beiträge zum Thema Servoansteuerung im Forum zufinden. 
Aber ich komme trotzdem nicht weiter. Ich möchte einfch nur, dass mein 
Servo aus dem Modellbau die Position (Links Anschlag)einnimmt. Mit dem 
folgendem Code tut sich aber nichts. Es wäre nett, wenn jemand einen 
Blick drüber wirft und mir einen Tipp gibt.
1
/*
2
Alle 20ms (periodenlänge) einen Impuls senden--->f=50Hz
3
Links  --> Pulsweite: 1ms 
4
Mittelstellung --> Pulsweite: 1.5ms
5
Rechts --> Pulsweite: 2ms
6
Timer Konfiguration:
7
Timer1: 16Bit Timer zählt von  0...65536
8
Alle 100µs soll ein Interrupt ausgelöst werden
9
*1ms sind es 10 Takte -->Links Abschlag
10
*20ms sind es 200 Takte
11
12
Prescaler:1
13
TopWert: 16000000 Hz*100µ= 1600 Schritte <65536
14
*/
15
#define F_CPU 16000000UL
16
#include <avr/io.h>
17
#include <avr/interrupt.h>
18
#include <util/delay.h>
19
20
volatile uint8_t count;
21
22
23
void Init_Timer1(void);
24
ISR(Timer1_COMPA_vect); 
25
26
//-----------------------------------------
27
28
int main(void)
29
{
30
//Servoausgang
31
//Richtungsregister PortB Pin PB1
32
//Pin PB1 als Ausgang setzen
33
DDRB|=(1<<PB1);
34
//Pin PB1 auf High setzen
35
PORTB|=(1<<PB1);
36
while(1)
37
{
38
}
39
}
40
41
//------------------------------------------
42
//Konfigurations des Timer1
43
void Init_Timer1(void)
44
{
45
//Modus 4:CTC-Modus, Topwert: OCR1A
46
TCCR1B|=(1<<WGM12);
47
//Prescaler 1, 16MHz/1=16MHz Frequenz des Timers
48
TCCR1B|=(1<<CS10);
49
//Timer/Counter1 Output Compare A Match interrupt ist freigegeben
50
TIMSK1|=(1<<OCIE1A);
51
// Werte für OCR1A 16MHz*100µs=1600
52
OCR1A=1600;
53
54
//Globalen interrupt freigeben
55
sei();  
56
}
57
58
//Interruptserviceroutine
59
ISR(Timer1_COMPA_vect)
60
{
61
if(count<10)              //Links
62
PORTB|=(1<<PB1);
63
else 
64
PORTB&=~(1<<PB1);
65
if(count<200)        //alle 20 ms , 20ms/100µ=200;
66
count++;
67
else
68
count=0;
69
}

von Dieter F. (Gast)


Lesenswert?

Einen Funktions-Prototypen für eine ISR sehe ich hier zum ersten Mal - 
interessant ...

Es wäre auch ganz praktisch, wenn Du in main() auch mal Timer1_Init 
aufrufen würdest - so wird der Timer nie gestartet.

Welchen AVR nutzt Du?

von spess53 (Gast)


Lesenswert?

Hi

>//Modus 4:CTC-Modus, Topwert: OCR1A
>TCCR1B|=(1<<WGM12);

Was willst du mit CTC? Am einfachsten geht es mit Timer1 im PWM-Mode 14 
oder 15. Vorteiler 8.

Mit Top = 40000 (20ms) und 2000 für 1ms bzw 2000 für 2ms erzeugst du ein 
passendes Signal.

MfG Spess

von Dani (Gast)


Lesenswert?

spess53 schrieb:
> Hi
>
>>//Modus 4:CTC-Modus, Topwert: OCR1A
>>TCCR1B|=(1<<WGM12);
>
> Was willst du mit CTC? Am einfachsten geht es mit Timer1 im PWM-Mode 14
> oder 15. Vorteiler 8.
>
> Mit Top = 40000 (20ms) und 2000 für 1ms bzw 2000 für 2ms erzeugst du ein
> passendes Signal.
>
> MfG Spess

Hallo,

mit deR PWM habe ich bereits schon ausbrobiert und es funktioniert. Ich 
möchte später mehrere Servos ansteuern, daher befasse ich mich momenta 
mit dem CTC..

von spess53 (Gast)


Lesenswert?

Hi

Hast du dir den Beitrag

Beitrag "Re: Servo Ansteuerung"

durchgelesen?


MfG spess

von Dieter F. (Gast)


Lesenswert?

Der Compiler müsste eigentlich auch anmeckern, dass Du TIMER1_COMPA_vect 
falsch (Groß-/Kleinschreibung) geschrieben hast - und wird gar keine ISR 
erzeugen ...

von Dani (Gast)


Lesenswert?

Dieter F. schrieb:
> Einen Funktions-Prototypen für eine ISR sehe ich hier zum ersten
> Mal -
> interessant ...
>
> Es wäre auch ganz praktisch, wenn Du in main() auch mal Timer1_Init
> aufrufen würdest - so wird der Timer nie gestartet.
>
> Welchen AVR nutzt Du?

AVR Studio4

oh ich habe es vergessen gehabt, die Funktion aufzurufen. Habe den Code 
korrigiert und der Servo bewegt sich trotzdem nicht in die eingestellte 
Position.
1
/*
2
Alle 20ms (periodenlänge) einen Impuls senden--->f=50Hz
3
Links  --> Pulsweite: 1ms 
4
Mittelstellung --> Pulsweite: 1.5ms
5
Rechts --> Pulsweite: 2ms
6
Timer Konfiguration:
7
Timer1: 16Bit Timer zählt von  0...65536
8
Alle 100µs soll ein Interrupt ausgelöst werden
9
*1ms sind es 10 Takte -->Links Abschlag
10
*20ms sind es 200 Takte
11
12
Prescaler:1
13
TopWert: 16000000 Hz*100µ= 1600 Schritte <65536
14
*/
15
#define F_CPU 16000000UL
16
#include <avr/io.h>
17
#include <avr/interrupt.h>
18
#include <util/delay.h>
19
20
volatile uint8_t count;
21
22
23
void Init_Timer1(void);
24
ISR(Timer1_COMPA_vect); 
25
26
//-----------------------------------------
27
28
int main(void)
29
{
30
//Servoausgang
31
//Richtungsregister PortB Pin PB1
32
//Pin PB1 als Ausgang setzen
33
DDRB|=(1<<PB1);
34
//Pin PB1 auf High setzen
35
PORTB|=(1<<PB1);
36
37
Init_Timer1();
38
while(1)
39
{
40
}
41
}
42
43
//------------------------------------------
44
//Konfigurations des Timer1
45
void Init_Timer1(void)
46
{
47
//Modus 4:CTC-Modus, Topwert: OCR1A
48
TCCR1B|=(1<<WGM12);
49
//Prescaler 1, 16MHz/1=16MHz Frequenz des Timers
50
TCCR1B|=(1<<CS10);
51
//Timer/Counter1 Output Compare A Match interrupt ist freigegeben
52
TIMSK1|=(1<<OCIE1A);
53
// Werte für OCR1A 16MHz*100µs=1600
54
OCR1A=1600;
55
56
//Globalen interrupt freigeben
57
sei();  
58
}
59
60
//Interruptserviceroutine
61
ISR(Timer1_COMPA_vect)
62
{
63
if(count<10)              //Links
64
PORTB|=(1<<PB1);
65
else 
66
PORTB&=~(1<<PB1);
67
if(count<200)        //alle 20 ms , 20ms/100µ=200;
68
count++;
69
else
70
count=0;
71
}

von Dieter F. (Gast)


Lesenswert?

Dani schrieb:
> AVR Studio4

Da habe ich falsch gefragt - ich meinte den µC. Aber es wird wohl ein 
ATMega 88/168/328 sein.

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Dieter F. schrieb:
> Der Compiler müsste eigentlich auch anmeckern, dass Du TIMER1_COMPA_vect
> falsch (Groß-/Kleinschreibung) geschrieben hast - und wird gar keine ISR
> erzeugen ...

Ja - ich habs (mit AVR Studio 6) ausprobiert (Bild).

Es wird keine ISR erzeugt - Dein ATMega wird permanent per 
"bad_interrupt" "resetten".

von Dani (Gast)


Lesenswert?

Dieter F. schrieb:

> Da habe ich falsch gefragt - ich meinte den µC. Aber es wird wohl ein
> ATMega 88/168/328 sein.

ja, ich verwende Atmega 328.

von Dani (Gast)


Lesenswert?

Dieter F. schrieb:
...
>
> Ja - ich habs (mit AVR Studio 6) ausprobiert (Bild).
>
> Es wird keine ISR erzeugt - Dein ATMega wird permanent per
> "bad_interrupt" "resetten".

Vielen Dank. Komisch, dass ich im AVR Studio 4 keine Fehlermeldung 
erhalte.
Ich habe jetzt Timer1 in der ISR groß geschrieben und immer wird kein 
Puls der Länge 1ms (10 Takte) erzeugt.

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Dani schrieb:
> Ich habe jetzt Timer1 in der ISR groß geschrieben und immer wird kein
> Puls der Länge 1ms (10 Takte) erzeugt

Dann hast Du wohl einen anderen (oder kaputten) ATMega328(P)
1
/*
2
Alle 20ms (periodenlänge) einen Impuls senden--->f=50Hz
3
Links  --> Pulsweite: 1ms
4
Mittelstellung --> Pulsweite: 1.5ms
5
Rechts --> Pulsweite: 2ms
6
Timer Konfiguration:
7
Timer1: 16Bit Timer zählt von  0...65536
8
Alle 100µs soll ein Interrupt ausgelöst werden
9
*1ms sind es 10 Takte -->Links Abschlag
10
*20ms sind es 200 Takte
11
12
Prescaler:1
13
TopWert: 16000000 Hz*100µ= 1600 Schritte <65536
14
*/
15
#define F_CPU 16000000UL
16
#include <avr/io.h>
17
#include <avr/interrupt.h>
18
#include <util/delay.h>
19
20
volatile uint8_t count;
21
22
23
24
void Init_Timer1(void);
25
26
ISR(TIMER1_COMPA_vect);
27
28
//-----------------------------------------
29
30
int main(void)
31
{
32
  Init_Timer1();
33
  //Servoausgang
34
  //Richtungsregister PortB Pin PB1
35
  //Pin PB1 als Ausgang setzen
36
  DDRB|=(1<<PB1);
37
  //Pin PB1 auf High setzen
38
  PORTB|=(1<<PB1);
39
  while(1)
40
  {
41
  }
42
}
43
44
//------------------------------------------
45
//Konfigurations des Timer1
46
void Init_Timer1(void)
47
{
48
  //Modus 4:CTC-Modus, Topwert: OCR1A
49
  TCCR1B|=(1<<WGM12);
50
  //Prescaler 1, 16MHz/1=16MHz Frequenz des Timers
51
  TCCR1B|=(1<<CS10);
52
  //Timer/Counter1 Output Compare A Match interrupt ist freigegeben
53
  TIMSK1|=(1<<OCIE1A);
54
  // Werte für OCR1A 16MHz*100µs=1600
55
  OCR1A=1600;
56
57
  //Globalen interrupt freigeben
58
  sei();
59
}
60
61
//Interruptserviceroutine
62
ISR(TIMER1_COMPA_vect)
63
{
64
  if(count<10)              //Links
65
    PORTB|=(1<<PB1);
66
  else
67
    PORTB&=~(1<<PB1);
68
    
69
  if(count<200)        //alle 20 ms , 20ms/100µ=200;
70
    count++;
71
  else
72
    count=0;
73
}

gibt bei mir anliegendes Signal an PB1.

von Dani (Gast)


Lesenswert?

Danke, sieht toll aus. Kann es auch am Oszilloskop liegen? VG

von Dietrich L. (dietrichl)


Lesenswert?

Dani schrieb:
> Kann es auch am Oszilloskop liegen?

Ja, oder auch am Bediener.
Aber das kannst Du ja testen: ein Oszi hat (üblicherweise) ein 
Test-Signal-Ausgang zum Abgleich des Tastkopfs. Da sollte man einen 
Rechteck sehen.

von Dieter F. (Gast)


Lesenswert?

Dani schrieb:
> Kann es auch am Oszilloskop liegen?

Es kann an allem Möglichen liegen ... :-)

Setze OCR1A auf  einen höheren Wert - z. B. 16000 - und hänge eine LED 
(mit Vorwiderstand) an PB1 - dann kannst Du das Blinken beobachten.

Bist Du sicher, dass Du den ATMega korrekt flasht? Bringt ein Verify das 
gewünschte Ergebnis?


Dani schrieb:
> mit deR PWM habe ich bereits schon ausbrobiert und es funktioniert.


Wenn das so ist, dann muss es eigentlich funktionieren - es sei denn, Du 
hast den ATMega in die ewigen Jagdgründe geschickt.

von Dani (Gast)


Lesenswert?

Dieter F. schrieb:

> gibt bei mir anliegendes Signal an PB1.


Hallo,
ich habe ein altes Oszilloskop der Firma Hameg 203-6. Ich wollte mir ein 
neues holen aber ich weiss nicht welches. Darf ich erfahren, was für ein 
Oszilloskop du verwendest?

BG

von Dani (Gast)


Lesenswert?

Dani schrieb:

> BG
 VG

von spess53 (Gast)


Lesenswert?

Hi

>ich habe ein altes Oszilloskop der Firma Hameg 203-6.

Na und. Wenn dein Oszi noch funktioniert solltest du das gleiche sehen.

MfG Spess

von Dani (Gast)


Lesenswert?

spess53 schrieb:
> Hi
>
>>ich habe ein altes Oszilloskop der Firma Hameg 203-6.
>
> Na und. Wenn dein Oszi noch funktioniert solltest du das gleiche sehen.
>
> MfG Spess

Ja mein Oszi funktioniert.

Ich muss mal was loswerden. Undzwar ich bin total begeistert von diesem 
Forum vorallem von eurer Hilfsbereitschaft.
Danke euch allen für die tollen Antworten.

von Dani (Gast)


Lesenswert?

Hallo,

ich bin es wieder:). Ich habe meinen Fehler gefunden und beseidigt. 
Jetzt kann ich die Position (Links, Mittel und Rechts) des Servos 
verändern in dem ich in der ISR die Werte in der If-Abfrage verändere.
1
ISR(TIMER1_COMPA_vect)
2
{
3
  if(count<10)              //10(Links), 15(Mittel), 20 (Rechts)
4
    PORTB|=(1<<PB1);
5
  else
6
    PORTB&=~(1<<PB1);
7
    
8
  if(count<200)        //alle 20 ms , 20ms/100µ=200;
9
    count++;
10
  else
11
    count=0;
12
}

Nun möchte ich, dass der Servo in alle drei Positionen gefahren wird. 
Die Frage ist, wie realisiere ich das? Ich habe es mal hiermit probiert, 
um zusehen, welches Signal am Pin anliegt.
1
ISR(TIMER1_COMPA_vect)
2
{
3
  if(count<10)              //10(Links), 15(Mittel), 20 (Rechts)
4
    PORTB|=(1<<PB1);
5
  else
6
    PORTB&=~(1<<PB1);
7
    
8
  if(count<15)              //10(Links), 15(Mittel), 20 (Rechts)
9
    PORTB|=(1<<PB1);
10
  else
11
    PORTB&=~(1<<PB1);
12
13
  if(count<20)              //10(Links), 15(Mittel), 20 (Rechts)
14
    PORTB|=(1<<PB1);
15
  else
16
    PORTB&=~(1<<PB1);
17
  
18
if(count<200)        //alle 20 ms , 20ms/100µ=200;
19
    count++;
20
  else
21
    count=0;
22
}

von Dani (Gast)


Lesenswert?

Dani schrieb:
> Hallo,
>

> Nun möchte ich, dass der Servo in alle drei Positionen gefahren wird.
> Die Frage ist, wie realisiere ich das? Ich habe es mal hiermit probiert,
> um zusehen, welches Signal am Pin anliegt.

Ist hierfür eine Winkelberechnung erforderlich?
VG

von Wolfgang (Gast)


Lesenswert?

Dani schrieb:
> Nun möchte ich, dass der Servo in alle drei Positionen gefahren wird.
> Die Frage ist, wie realisiere ich das?

Indem du Pulse ausgibt, deren Länge zu der gewünschten Position gehört. 
Um den Rest kümmert sich dann der Servo.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Dani schrieb:
> #define F_CPU 16000000UL

Mit AVR Studio 4 oder Atmel Studio 6 solltest du das nicht im Code 
angeben, sondern in den Projekteinstellungen. Wenn du es doch im Code 
machst, dann siehe aber zu, das es mit den Projekteinstellungen 
übereinstimmt.

Aber warum denn Soft PWM? Der Mega328 hat eine gut funktionierende 
Hardware PWM mit hoher Auflösung auf Timer 1. Dazu benutzt du am besten 
den Mode 14, wie oben schon mal erwähnt und setzt TOP in ICR1:
1
// ruhig gleich mal beide PWM Kanäle (A und B) - kost' ja nix
2
// Frequenz nahe 50Hz denn: 16 Mhz / 8 = 2 Mhz 
3
// 2Mhz / 40000 = 50Hz. 
4
void Init_Timer_1(void) {
5
ICR1 = 40000; // TOP für 50 Hz 
6
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 WGM11); // positive PWM Signale
7
TCCR1B = (1 << WGM13) | (1 << WGM12) | ( (1 << CS11); 
8
//  besetze OCR1A und OCR1B für Mitte des Servobereiches (1,5ms) 
9
// die Granularität des Timer ist 1/ 2Mhz = 0,5µs 
10
// dann entspricht eine Länge von 1,5ms also 3000 Timertakten
11
OCR1A = 3000;
12
OCR1B = 3000;
13
}
Jetzt musst du nur noch die gewünschten PWM Ausgänge auf Ausgang stellen 
und die ganze Sache läuft ohne Interrupts im Hintergrund:
1
int main(void) {
2
Init_Timer_1();
3
DDRB = ( 1 << PB1) | (1 << PB2);  // beide PWM Kanäle an
4
// Spass in der Hauptschleife
5
6
while (1) {
7
     _delay_ms(1000);    // Zeit verschwenden
8
     OCR1A = 2000; OCR1B = 4000; // Servo 1 nach ganz links, Servo 2 nach ganz rechts
9
     _delay_ms(1000); // Zeit verschwenden
10
     OCR1A = 3000; OCR1B = 3000; // beide Servos auf Mitte
11
     _delay_ms(1000);
12
     OCR1A = 4000; OCR1B = 2000; // na, was wohl?
13
     _delay_ms(1000); // Zeit verschwenden
14
     OCR1A = 3000; OCR1B = 3000; // beide Servos auf Mitte
15
   }  // ende while
16
} // ende main

: Bearbeitet durch User
von Dani (Gast)


Lesenswert?

Matthias S. schrieb:
> Dani schrieb:
>> #define F_CPU 16000000UL
>
> Mit AVR Studio 4 oder Atmel Studio 6 solltest du das nicht im Code
> angeben, sondern in den Projekteinstellungen. Wenn du es doch im Code
> machst, dann siehe aber zu, das es mit den Projekteinstellungen
> übereinstimmt.
>
> Aber warum denn Soft PWM?

Danke für die Antworten,

mit der Hardware PWM habe ich bereits ausprobiert und es funktioniert. 
Ich möchte später mehrere Servos anstuern und daher wollte mit Soft PWM 
weiter arbeiten. Zudem wollte ich mich mit dem Timer/Interrupt 
auseinandersetzen. Jedoch weiss garnicht wie ich das anstellen soll. Wie 
ich den Controllern sagen soll, dass der Servo von einer Position in die 
nächste Position gehen soll?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Dani schrieb:
> Ich möchte später mehrere Servos anstuern und daher wollte mit Soft PWM
> weiter arbeiten.

Wieviele Servos sollens denn werden? 6 Stück sind mit der Hardware des 
Mega328 problemlos machbar. Jeder Timer kann 2 ansteuern, Timer 0 und 
Timer 2 allerdings sind nur 8 Bitter, dadurch sinkt die erreichbare 
Auflösung.

Dani schrieb:
> Jedoch weiss garnicht wie ich das anstellen soll.
Lies mal Application Note AVR136. Die Jungs beschreiben da, wie man 
Multichannel Soft PWM mit AVRs realisiert:
http://www.atmel.com/devices/atmega168.aspx?tab=documents

Runterrollen bis AVR136. Da gibts das beschreibende PDF und die Software 
als ZIP.

von Dani (Gast)


Lesenswert?

Ich habe einen Code gefunden ,Link:

Beitrag "Servo-Interrupt Problem"

In diesem Code wurden die Servopositionen berechnet. Ich sehe die 
Gleihung nicht zum ersten Mal aber ich weiß nucht wie ich diese 
herleiten soll.
1
[void loop() {
2
for(pos=0; pos<180; pos++) {
3
  servoPos = ((pos * 11) + 500)/10; ????
4
  delay(10);
5
  }
6
  
7
  for(pos=0; pos>0; pos--) {
8
  servoPos = ((pos * 11) + 500)/10; ????
9
  delay(10);
10
  }
11
}]

von Stefan F. (Gast)


Lesenswert?

Eine genaue Umrechnung von Grad zum PWM Wert ist gar nicht möglich, weil 
das jeder Servo anders umsetzt.

Du kommst so oder so nicht umhin, für jeden einzelnen Servo mindestens 
zwei Werte zu experimentiell zu ermitteln:

- PWM Wert kurz vor dem linken Anschlag
- PWM Wert kurz vor dem rechten Anschlag

Und jetzt kommt noch eine Gemeinheit: Die Mittlere Position liegt 
meistens nicht genau in der Mitte zwischen diesen beiden Werten!

Letztendlich musst du die PWM Werte für alle konkreten Positionen, die 
du anfahren willst, experimentiell ermitteln. Und wenn du den Servo 
auswechselst, geht das Spiel von Vorne los - auch wenn der neue Servo 
vom selben Modell/Typ ist.

Also vergiss die Berechnung, der Aufwand lohnt sich nicht.

von Dani (Gast)


Lesenswert?

Super, danke dür die Info.

von Dani (Gast)


Lesenswert?

Stefan U. schrieb:
> Eine genaue Umrechnung von Grad zum PWM Wert ist gar nicht
> möglich, weil
> das jeder Servo anders umsetzt.
>
> Du kommst so oder so nicht umhin, für jeden einzelnen Servo mindestens
> zwei Werte zu experimentiell zu ermitteln:
>
> - PWM Wert kurz vor dem linken Anschlag
> - PWM Wert kurz vor dem rechten Anschlag

Was heisst kurz vor dem linken Anschlag? Wie weit darf ich den Wert 
(1ms) runtersetzen? Ich habe für die Pulsweite für den linken Anschalg 
den Wert o.5 ms gestzt und der Motor dreht sich  jetzt 90° 
(Mittelstellung) nach Links.

von Stefan F. (Gast)


Lesenswert?

> Wie weit darf ich den Wert (1ms) runtersetzen?

Das musst du heraus finden. Letztendlich ist es wichtig, dass der Servo 
weder an seinen internen noch an irgendeinen externen Anschlag anstößt, 
weil er sonst heiß läuft.

Wie viel Grad das entspricht und bei wie vielen ms das passiert, musst 
du selbst herausfinden. Wie gesagt ist das bei jedem Servo anders.

Also grober Anhalswert gilt: 1ms=links, 1,5ms=mitte, 2ms=rechts

von Wolfgang (Gast)


Lesenswert?

Dani schrieb:
> Was heisst kurz vor dem linken Anschlag? Wie weit darf ich den Wert
> (1ms) runtersetzen?

Na, so weit, dass der Servo gerade nicht gegen den linken Anschlag 
stößt. Sonst zieht der Motor dauernd Strom und kann heiß laufen, genauer 
gesagt heiß stehen.

Aber das Thema "Viele Servos" ist ja keine Neuerfindung
Beitrag "Servocontroller mit ATmega8 für 20 Servos"
Beitrag "Re: Mehrere Servos mit OCR1A"

von Mark (Gast)


Lesenswert?

Dani schrieb:
> Ich habe einen Code gefunden ,Link:
>
> Beitrag "Servo-Interrupt Problem"
>
> In diesem Code wurden die Servopositionen berechnet. Ich sehe die
> Gleihung nicht zum ersten Mal aber ich weiß nucht wie ich diese
> herleiten soll.
> [void loop() {
> for(pos=0; pos<180; pos++) {
>   servoPos = ((pos * 11) + 500)/10; ????
>   delay(10);
>   }
>
>   for(pos=0; pos>0; pos--) {
>   servoPos = ((pos * 11) + 500)/10; ????
>   delay(10);
>   }
> }]

Hallo,

wiedermal ne Frage zum Servo. Ich möchte nicht dass der Servo nur die 
drei Positionen (Pulsbreite 100: 1ms, Pulsbreite 150 :1,5 ms und 
Pulsbreite 200:2ms) einnimmt. Ich würde gerne eine von mir definiert 
Winkelposition (45 ° ) eingeben, die der Servo anfahren soll.  Die Frage 
ist, muss ich da eine Formel herleiten?  Kann mir jemand einen 
Denkanstoß geben?
Danke

100 = 1 ms ->0°

150 = 1.5 ms ->90°

von Cyblord -. (cyblord)


Lesenswert?

Mark schrieb:
>> wiedermal ne Frage zum Servo. Ich möchte nicht dass der Servo nur die
> drei Positionen (Pulsbreite 100: 1ms, Pulsbreite 150 :1,5 ms und
> Pulsbreite 200:2ms) einnimmt. Ich würde gerne eine von mir definiert
> Winkelposition (45 ° ) eingeben, die der Servo anfahren soll.  Die Frage
> ist, muss ich da eine Formel herleiten?  Kann mir jemand einen
> Denkanstoß geben?

Ja, den Winkel kannst du mittels Dreisatz berechnen, wenn du die 
minimale und maximale Pulsbreite des Servos (hier geht meist mehr als 
1ms-2ms) kennst und dessen maximal möglicher Arbeitswinkel.
Das Problem: Das ist bei jedem Servo etwas anders. D.h. du musst es für 
einen speziellen Typ bestimmen.
Immerhin sollte im allgemeinen die Pulsbreite ziemlich linear zum 
tatsächlichen Winkel sein. Das hilft dir schon mal.

: Bearbeitet durch User
von Mark (Gast)


Lesenswert?

Cyblord -. schrieb:

> Ja, den Winkel kannst du mittels Dreisatz berechnen,

Beispiel:

90°=150
x=Pulsweite  -> x=(Pulsweite*90)/150

Mittels des Dreisatzes müsste ich immer die Pulsweite eingeben. Das 
heißt, ich müsste vorher für den jeweiligen Winkel die entsprechende 
Pulsweite ausgerechnet haben. Oder?

von Cyblord -. (cyblord)


Lesenswert?

Mark schrieb:
> Cyblord -. schrieb:
>
>> Ja, den Winkel kannst du mittels Dreisatz berechnen,
>
> Beispiel:
>
> 90°=150
> x=Pulsweite  -> x=(Pulsweite*90)/150

Du hast den Rest meines Postings aber schon gelesen und verstanden?

> Mittels des Dreisatzes müsste ich immer die Pulsweite eingeben. Das
> heißt, ich müsste vorher für den jeweiligen Winkel die entsprechende
> Pulsweite ausgerechnet haben. Oder?

Umstellen!

von Mark (Gast)


Lesenswert?

Danke, also so:

Pulsweit=(Winkel*150)/90

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.