Forum: Mikrocontroller und Digitale Elektronik Servo dreht nur nach Links


von DhscR (Gast)


Lesenswert?

Hallo kann mal einer schnell über mein Programm gucken ! Hab versucht 
über die Schleifen ne höhere Auflösung für meinen Servo zu bekommen, da 
ich nur einen Attiny13 habe und die Auflösung mit TC ist zu niedrig.

Der Tiny läuft mit 1,2 Mhz, in der ersten Schleife wird bis 12 gezählt 
ergibt meiner Rechnung nach 0,01 ms !

Danach wird in einer zweiten Schleife der umgerechnete ADC-Wert x den 
0,01 ms aus der ersten Schleife gezählt.

Am Ende noch eine Pausenschleife.


Der Servo dreht allerdings nur langsam auf Linksanschlag.

Danke



 #include <avr/io.h>


int main(void)
{

  unsigned ADCWERT;
  unsigned Zaehler;
  unsigned Zaehler2;
  unsigned Zaehler3;
  Zaehler = 0;
  Zaehler2= 0;
  Zaehler3= 0;
  unsigned Ergebnis;
  Ergebnis = 0;

    while(1)
    {

  DDRB = (1<<DDB0);
  Anfang:
  ADMUX = (1<<ADLAR)|(1<<MUX1)|(1<<MUX0); // 8Bit , PB3
  ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS2); // Start, Vorteiler 16
  while  (ADCSRA & (1<<ADSC)){} //Warten bis Fertig
  Ergebnis = ADCH;


  ADCWERT = ((Ergebnis*100)/256)+100 ;//ADC Wert in Schleifendurchläufe 
umrechnen

  PORTB = (1<<PB0);

  Schleife:
  if(Zaehler == 12)    //Zaehler für 0,01 ms
    goto Schleife2;

    else Zaehler++;
      goto Schleife;

  Schleife2:
  Zaehler = 0;               //Zaehler wieder auf 0 setzen
  if(Zaehler2 == ADCWERT)
    goto Pause;
    else Zaehler2 ++;
       goto Schleife;

  Pause:
  Zaehler2 = 0;             // Zaehler 2 wieder auf 0 setzen
  PORTB =(0<<PB0);
  if(Zaehler3 == 1000)      //10 ms Pause
    goto Anfang;

    else Zaehler3++;
    goto Pause;



    }
}

von mr. mo (Gast)


Lesenswert?

goto ist wohl eher fehl am platz ... ansonsten for oder while schleifen 
verbauen.

für pausen gibt es die delay funktion, da kannst einen wert in ms bzw. 
us reinpacken also _delay_ms(zeit); oder _delay_us(zeit);

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29

von Karl H. (kbuchegg)


Lesenswert?

DhscR schrieb:
> Hallo kann mal einer schnell über mein Programm gucken ! Hab versucht
> über die Schleifen ne höhere Auflösung für meinen Servo zu bekommen, da
> ich nur einen Attiny13 habe und die Auflösung mit TC ist zu niedrig.
>
> Der Tiny läuft mit 1,2 Mhz, in der ersten Schleife wird bis 12 gezählt
> ergibt meiner Rechnung nach 0,01 ms !

Wie kommst du da drauf?
Ich sehe in deinem Programm nichts, was mir eine Zeit von 0.01ms 
erklären würde.

> Der Servo dreht allerdings nur langsam auf Linksanschlag.

Warum benutzt du denn nicht die Information in diesem Link
Modellbauservo Ansteuerung

gleich das erste Programm (das mit delays arbeitet). Einfach abwandeln, 
so dass der Delay Wert vom ADC kommt (du kannst allerdings nicht eine 
Variable für _delay_us benutzen, aber das lässt sich lösen). Fertig ist 
die Schose.

von DhscR (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wie kommst du da drauf?
>
> Ich sehe in deinem Programm nichts, was mir eine Zeit von 0.01ms
>
> erklären würde.

1200000/12 = 100000
1/100000 = 0,00001 Sekunden = 0,01 ms

oder lieg ich da Falsch ?

von Karl H. (kbuchegg)


Lesenswert?

DhscR schrieb:
> Karl Heinz Buchegger schrieb:
>> Wie kommst du da drauf?
>>
>> Ich sehe in deinem Programm nichts, was mir eine Zeit von 0.01ms
>>
>> erklären würde.
>
> 1200000/12 = 100000

dein µC macht ca. 1 Mio Instruktionen pro Sekunde.
Aber das sind keine C-Instruktionen!

von DhscR (Gast)


Lesenswert?

Ok hab es mit delay Versucht nur nimmt er mir Jetzt kein DDRB an und die
Ports lassen sich nicht mehr ansteuern ?

(wenn ich bei AVR-Studio Simuliere)

von Karl H. (kbuchegg)


Lesenswert?

Ich würde die beiden von dir erzeugten Threads gerne zu 1 
zusammenführen. Vereinfacht die Sache normalerweise.
Den anderen Thread hab ich geschlossen.
Beitrag "ADC Werte (Formel)?"


delays kannst du im AVR-Studio vergessen. So ein delay auf zb 1
Millisekunde bedeutet, dass der µC ein paar Hundertausend mal in einer
Schleife Däumchen drehen muss. Da simuliert sich der Simulator zu Tode.
(Es geht schon, nur dauert die Simulation der Warteschleife entsprechend
lange).

Brenne es in den Tiny, häng dein Servo an, sorg für eine stabile
Versorgungsspannung und die _delay_us, wie im Link angegeben, wird
funktionieren (wenn deine Taktfrequenz stimmt)
Wenn dein Servo dann korrekt reagiert, fängst du an den ADC einzubauen.

Aber bitte nicht wieder mit so einer goto Orgie.

1
#define F_CPU 1000000UL
2
 
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
void delay( uint8_t us10 )
7
{
8
  uint8_t i;
9
  for( i = 0; i < us10; ++i )
10
    _delay_us( 10 );
11
}
12
13
int main (void)
14
{
15
  uint8_t servoPos;
16
17
  DDRB = (1<<PB0);
18
19
  servoPos = 150;
20
 
21
  while( 1 ) {
22
 
23
    PORTB |= (1<<PB0);
24
    _delay_us( servoPos );
25
    PORTB &= ~(1<<PB0);
26
 
27
    _delay_ms( 10 );      // ist nicht kritisch
28
29
    // hier kommt deine ADC Abfrage und Wertumrechnung rein
30
    // die Werte für servoPos sollten sich im Bereich ~90 bis ~210
31
    // bewegen.
32
  }
33
 
34
  return 0;
35
}

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.