mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Servo Ansteuerung


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Dani (Gast)


Bewertung
0 lesenswert
nicht 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.
/*
Alle 20ms (periodenlänge) einen Impuls senden--->f=50Hz
Links  --> Pulsweite: 1ms 
Mittelstellung --> Pulsweite: 1.5ms
Rechts --> Pulsweite: 2ms
Timer Konfiguration:
Timer1: 16Bit Timer zählt von  0...65536
Alle 100µs soll ein Interrupt ausgelöst werden
*1ms sind es 10 Takte -->Links Abschlag
*20ms sind es 200 Takte

Prescaler:1
TopWert: 16000000 Hz*100µ= 1600 Schritte <65536
*/
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile uint8_t count;


void Init_Timer1(void);
ISR(Timer1_COMPA_vect); 

//-----------------------------------------

int main(void)
{
//Servoausgang
//Richtungsregister PortB Pin PB1
//Pin PB1 als Ausgang setzen
DDRB|=(1<<PB1);
//Pin PB1 auf High setzen
PORTB|=(1<<PB1);
while(1)
{
}
}

//------------------------------------------
//Konfigurations des Timer1
void Init_Timer1(void)
{
//Modus 4:CTC-Modus, Topwert: OCR1A
TCCR1B|=(1<<WGM12);
//Prescaler 1, 16MHz/1=16MHz Frequenz des Timers
TCCR1B|=(1<<CS10);
//Timer/Counter1 Output Compare A Match interrupt ist freigegeben
TIMSK1|=(1<<OCIE1A);
// Werte für OCR1A 16MHz*100µs=1600
OCR1A=1600;

//Globalen interrupt freigeben
sei();  
}

//Interruptserviceroutine
ISR(Timer1_COMPA_vect)
{
if(count<10)              //Links
PORTB|=(1<<PB1);
else 
PORTB&=~(1<<PB1);
if(count<200)        //alle 20 ms , 20ms/100µ=200;
count++;
else
count=0;
}   

von Dieter F. (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Hi

Hast du dir den Beitrag

Beitrag "Re: Servo Ansteuerung"

durchgelesen?


MfG spess

von Dieter F. (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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.
/*
Alle 20ms (periodenlänge) einen Impuls senden--->f=50Hz
Links  --> Pulsweite: 1ms 
Mittelstellung --> Pulsweite: 1.5ms
Rechts --> Pulsweite: 2ms
Timer Konfiguration:
Timer1: 16Bit Timer zählt von  0...65536
Alle 100µs soll ein Interrupt ausgelöst werden
*1ms sind es 10 Takte -->Links Abschlag
*20ms sind es 200 Takte

Prescaler:1
TopWert: 16000000 Hz*100µ= 1600 Schritte <65536
*/
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile uint8_t count;


void Init_Timer1(void);
ISR(Timer1_COMPA_vect); 

//-----------------------------------------

int main(void)
{
//Servoausgang
//Richtungsregister PortB Pin PB1
//Pin PB1 als Ausgang setzen
DDRB|=(1<<PB1);
//Pin PB1 auf High setzen
PORTB|=(1<<PB1);

Init_Timer1();
while(1)
{
}
}

//------------------------------------------
//Konfigurations des Timer1
void Init_Timer1(void)
{
//Modus 4:CTC-Modus, Topwert: OCR1A
TCCR1B|=(1<<WGM12);
//Prescaler 1, 16MHz/1=16MHz Frequenz des Timers
TCCR1B|=(1<<CS10);
//Timer/Counter1 Output Compare A Match interrupt ist freigegeben
TIMSK1|=(1<<OCIE1A);
// Werte für OCR1A 16MHz*100µs=1600
OCR1A=1600;

//Globalen interrupt freigeben
sei();  
}

//Interruptserviceroutine
ISR(Timer1_COMPA_vect)
{
if(count<10)              //Links
PORTB|=(1<<PB1);
else 
PORTB&=~(1<<PB1);
if(count<200)        //alle 20 ms , 20ms/100µ=200;
count++;
else
count=0;
}   

von Dieter F. (Gast)


Bewertung
0 lesenswert
nicht 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:

Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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:

Bewertung
0 lesenswert
nicht 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)
/*
Alle 20ms (periodenlänge) einen Impuls senden--->f=50Hz
Links  --> Pulsweite: 1ms
Mittelstellung --> Pulsweite: 1.5ms
Rechts --> Pulsweite: 2ms
Timer Konfiguration:
Timer1: 16Bit Timer zählt von  0...65536
Alle 100µs soll ein Interrupt ausgelöst werden
*1ms sind es 10 Takte -->Links Abschlag
*20ms sind es 200 Takte

Prescaler:1
TopWert: 16000000 Hz*100µ= 1600 Schritte <65536
*/
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile uint8_t count;



void Init_Timer1(void);

ISR(TIMER1_COMPA_vect);

//-----------------------------------------

int main(void)
{
  Init_Timer1();
  //Servoausgang
  //Richtungsregister PortB Pin PB1
  //Pin PB1 als Ausgang setzen
  DDRB|=(1<<PB1);
  //Pin PB1 auf High setzen
  PORTB|=(1<<PB1);
  while(1)
  {
  }
}

//------------------------------------------
//Konfigurations des Timer1
void Init_Timer1(void)
{
  //Modus 4:CTC-Modus, Topwert: OCR1A
  TCCR1B|=(1<<WGM12);
  //Prescaler 1, 16MHz/1=16MHz Frequenz des Timers
  TCCR1B|=(1<<CS10);
  //Timer/Counter1 Output Compare A Match interrupt ist freigegeben
  TIMSK1|=(1<<OCIE1A);
  // Werte für OCR1A 16MHz*100µs=1600
  OCR1A=1600;

  //Globalen interrupt freigeben
  sei();
}

//Interruptserviceroutine
ISR(TIMER1_COMPA_vect)
{
  if(count<10)              //Links
    PORTB|=(1<<PB1);
  else
    PORTB&=~(1<<PB1);
    
  if(count<200)        //alle 20 ms , 20ms/100µ=200;
    count++;
  else
    count=0;
}

gibt bei mir anliegendes Signal an PB1.

von Dani (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Danke, sieht toll aus. Kann es auch am Oszilloskop liegen? VG

von Dietrich L. (dietrichl)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Dani schrieb:

> BG
 VG

von spess53 (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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.
ISR(TIMER1_COMPA_vect)
{
  if(count<10)              //10(Links), 15(Mittel), 20 (Rechts)
    PORTB|=(1<<PB1);
  else
    PORTB&=~(1<<PB1);
    
  if(count<200)        //alle 20 ms , 20ms/100µ=200;
    count++;
  else
    count=0;
}

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.
ISR(TIMER1_COMPA_vect)
{
  if(count<10)              //10(Links), 15(Mittel), 20 (Rechts)
    PORTB|=(1<<PB1);
  else
    PORTB&=~(1<<PB1);
    
  if(count<15)              //10(Links), 15(Mittel), 20 (Rechts)
    PORTB|=(1<<PB1);
  else
    PORTB&=~(1<<PB1);

  if(count<20)              //10(Links), 15(Mittel), 20 (Rechts)
    PORTB|=(1<<PB1);
  else
    PORTB&=~(1<<PB1);
  
if(count<200)        //alle 20 ms , 20ms/100µ=200;
    count++;
  else
    count=0;
}

von Dani (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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:
// ruhig gleich mal beide PWM Kanäle (A und B) - kost' ja nix
// Frequenz nahe 50Hz denn: 16 Mhz / 8 = 2 Mhz 
// 2Mhz / 40000 = 50Hz. 
void Init_Timer_1(void) {
ICR1 = 40000; // TOP für 50 Hz 
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 WGM11); // positive PWM Signale
TCCR1B = (1 << WGM13) | (1 << WGM12) | ( (1 << CS11); 
//  besetze OCR1A und OCR1B für Mitte des Servobereiches (1,5ms) 
// die Granularität des Timer ist 1/ 2Mhz = 0,5µs 
// dann entspricht eine Länge von 1,5ms also 3000 Timertakten
OCR1A = 3000;
OCR1B = 3000;
}
Jetzt musst du nur noch die gewünschten PWM Ausgänge auf Ausgang stellen 
und die ganze Sache läuft ohne Interrupts im Hintergrund:
int main(void) {
Init_Timer_1();
DDRB = ( 1 << PB1) | (1 << PB2);  // beide PWM Kanäle an
// Spass in der Hauptschleife

while (1) {
     _delay_ms(1000);    // Zeit verschwenden
     OCR1A = 2000; OCR1B = 4000; // Servo 1 nach ganz links, Servo 2 nach ganz rechts
     _delay_ms(1000); // Zeit verschwenden
     OCR1A = 3000; OCR1B = 3000; // beide Servos auf Mitte
     _delay_ms(1000);
     OCR1A = 4000; OCR1B = 2000; // na, was wohl?
     _delay_ms(1000); // Zeit verschwenden
     OCR1A = 3000; OCR1B = 3000; // beide Servos auf Mitte
   }  // ende while
} // ende main

: Bearbeitet durch User
von Dani (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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.
[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);
  }
}]

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Super, danke dür die Info.

von Dani (Gast)


Bewertung
0 lesenswert
nicht 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. (stefanus)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Danke, also so:

Pulsweit=(Winkel*150)/90

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.