Forum: Mikrocontroller und Digitale Elektronik Ich verstehe ein Programmablauf nicht.


von Erik H. (erik_h)


Lesenswert?

Guten Tag,

Evtl kann mir jemand da helfen. Ich versuche ein ATtiny13V zu 
programmieren und der soll ein Servo hin und her von 0 bis 180 Grad 
drehen.
Pin 1 ist die LED die am Board verlötet ist. Die Blinkt auch wie 
erwartet. Nur pwm wird nicht geändert und der Servo bleibt bei 500. Oder 
wenn der Servo bei ca 90Grad mal war(Durch eigene Manipulation), dann 
bewegt der sich nicht sofort auf die 1500, die ja am Anfang festgelegt 
ist und bewegt sich erst wenn die LED ausgeht.
Wenn ich die ganze Sache ohne die IF ablaufen lasse und pwm fest 
einstelle, dann bewegt der sich auch einmal. Also Servo funktioniert.

1
int pwm = 1500;
2
int c = 0;
3
bool b = false;
4
5
void long_delay(int us)
6
{
7
    for(; us>0; us--) delayMicroseconds(1);
8
}
9
10
void setup() {
11
  // put your setup code here, to run once:
12
pinMode(3,OUTPUT);
13
pinMode(1,OUTPUT);
14
}
15
16
void loop() {
17
  // put your main code here, to run repeatedly:
18
  if (c >= 100)
19
  {
20
    if(b==false)
21
    {
22
      pwm = 1500;
23
      //digitalWrite(1,true);
24
    }
25
    else
26
    {
27
      //digitalWrite(1,false);
28
      pwm = 500;
29
    }
30
    b = !b;
31
    c = 0;
32
  }
33
  else
34
  {
35
    c = c+1;
36
  }
37
digitalWrite(1,b);
38
digitalWrite(3,HIGH);
39
long_delay(pwm);
40
digitalWrite(1,b);
41
digitalWrite(3,LOW);
42
long_delay(20000-pwm);
43
}

von wer (Gast)


Lesenswert?

Du schon wieder.

Fahr doch erstmal eine fixe Position mit festen delays an, bevor du 
unüberlegt dein Timing mit naiven Schleifen zerschießt.

von Rolf M. (rmagnus)


Lesenswert?

Erik H. schrieb:
> void long_delay(int us)
> {
>     for(; us>0; us--) delayMicroseconds(1);
> }

Bei einem Takt von 9,6 Mhz vergehen in einer Mikrosekunde 9,6 
Taktzyklen. Natürlich kann der Prozessor keine 9,6 Taktzyklen 
"verbummeln", also werden es vermutlich 10 werden. Viel schlimmer ist 
aber die Schleife selbst, die auch ein paar Takzyklen pro Durchlauf 
benötigt. Damit wird das Delay deutlich zu lang ausfallen.

> Evtl kann mir jemand da helfen. Ich versuche ein ATtiny13V zu
> programmieren und der soll ein Servo hin und her von 0 bis 180 Grad
> drehen.

Normalerweise liegt der übliche Bereich so um ±45°.

von leo (Gast)


Lesenswert?

Erik H. schrieb:
> Evtl kann mir jemand da helfen. Ich versuche ein ATtiny13V zu
> programmieren und der soll ein Servo hin und her von 0 bis 180 Grad
> drehen

Das Timing passt da nicht: " ... signal with a period of 20 ms is used 
to control the motors.". Nix µs.

e.g. https://dronebotworkshop.com/servo-motors-with-arduino/

leo

von wer (Gast)


Lesenswert?

Rolf M. schrieb:
> Normalerweise liegt der übliche Bereich so um ±45°.

Nö, da bist du falsch informiert.

leo schrieb:
> Das Timing passt da nicht: " ... signal with a period of 20 ms is used
> to control the motors.". Nix µs.

Und 20.000us sind was?

Also das die Antworten noch doofer werden als die Frage überrascht mich

von leo (Gast)


Lesenswert?

wer schrieb:
> Und 20.000us sind was?

Ja, man kann auch 20M ns angeben, stimmt.

leo

von Rolf M. (rmagnus)


Lesenswert?

leo schrieb:
> wer schrieb:
>> Und 20.000us sind was?
>
> Ja, man kann auch 20M ns angeben, stimmt.

Und für 500 µs Puls und 19500 µs Pause macht man dann 0,5 
Schleifendurchläufe und 19,5 Schleifendurchläufe mit je 1 ms?

von leo (Gast)


Lesenswert?

Rolf M. schrieb:
> macht man dann 0,5
> Schleifendurchläufe

Ok, ok. Ich verwende weder delay noch Schleifen (fuer PWM).
https://www.arduino.cc/reference/en/libraries/servo/
https://github.com/prampec/arduino-softtimer
oder HW:
https://www.adafruit.com/product/815

ldo

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


Lesenswert?

Das Servo soll auch bei jedem Schleifendurchlauf die entgegengesetzte 
Position anfahren? Was ist das für ein Superservo, das sowas in 20ms 
schafft?

Abgesehen davon, das es für Arduino fertige Servobibliotheken gibt, 
ändere pwm mal lieber nur um ein paar µs pro Druchlauf - dann hat das 
Servo eine Chance.

Noch ein Tipp: um b zwischen 0 und 1 zu toggeln, ist sowas sinnvoll:
1
b = 1 - b; // toggle b
Das dings mit !b kann nämlich funktionieren, muss aber nicht.

von Rolf M. (rmagnus)


Lesenswert?

Matthias S. schrieb:
> Das Servo soll auch bei jedem Schleifendurchlauf die entgegengesetzte
> Position anfahren? Was ist das für ein Superservo, das sowas in 20ms
> schafft?

Wieso bei jedem Schleifendurchlauf? Wenn ich mir das Programm so ansehe, 
würde ich es nur bei jedem 101. Schleifendurchlauf erwarten, also unter 
der (falschen) Annahme, dass das Delay die richtige Wartezeit erzeugt, 
alle 2,02 Sekunden.

> Noch ein Tipp: um b zwischen 0 und 1 zu toggeln, ist sowas sinnvoll:
> b = 1 - b; // toggle b
> Das dings mit !b kann nämlich funktionieren, muss aber nicht.

Doch, muss es, zumindest wenn das verwendete bool das aus stdbool.h ist.

: Bearbeitet durch User
von Norbert (Gast)


Lesenswert?

Die 20000µs sind unproblematisch, aber:
Servo Mitte ist 1500µs
Servo Min ist 1000µs
Servo Max ist 2000µs

Je nach Servo kann man vielleicht bis auf 700µs bis 2300µs erweitern, 
das war's dann aber auch.

von Erik H. (erik_h)


Lesenswert?

Es ist zwar interessant mitzulesen, man wird daraus ja auch schlauer, 
aber was müsste ich erstmal machen, damit der servo sich bewegt von 0 
bis 180 und wieder umgekehrt. im takt von 1er oder 2 sekunden.

Dass jetzt der Delay auf 0,5ms ist für 0 und 1500ms für 180, ist nur 
wegen der mega schleife. Das mir egal ist,es soll sich einfach nur 
bewegen. Und wenn ich das immer so durchgehe, habe ich da nix verkehrt 
gemacht. Denn die LED blinkt, Also Pin1. Da wird !b richtig sein.

Mache ich die IF Funktion weg, dann bewegt sich der sero auch zu der 
gesagten eingestellten pwm.

(Ich glaub ich schau mich mal nach ein anderen Board um, evtl liegt das 
am Board was ich in arduino installiert habe. MicroCore.

von Norbert (Gast)


Lesenswert?

500µs ist so kurz, das ein Servo möglicherweise gar nicht reagiert.
Erst mal die konservativen Werte nehmen um Funktion zu prüfen.

Und wie bereits erwähnt, die long_delay Routine ist zumindest vom 
Timingverhalten fragwürdig.

von Erik H. (erik_h)


Lesenswert?

Danke, es war aber umgekehrt. Ich habe die pwm variable angepasst in der 
if schleife. Ich muss für 0 Grad 400us eingeben und für 180 Grad 1200us. 
Die If schleife nimmt anschein auch sehr viel Zeit in Anspruch. Hätte 
ich nicht gedacht. Diese Werte sind nur durchs probieren gekommen, ich 
will hiermit nichts dolles bewirken, sodass ich alles Zeitlich besser 
programmieren müsste. Bleibt aber im Hinterkopf, falls ich mal was 
besseres machen möchte. Für mein Projekt reicht das aber.

von Rolf M. (rmagnus)


Lesenswert?

Erik H. schrieb:
> Danke, es war aber umgekehrt. Ich habe die pwm variable angepasst in der
> if schleife.

http://if-schleife.de/

> Ich muss für 0 Grad 400us eingeben und für 180 Grad 1200us.

Das liegt dann wahrscheinlich vor allem daran, dass - wie schon mehrfach 
gesagt - deine Delays viel länger brauchen als du angibst. Allerdings 
wäre ich gefühlsmäßig eher so von einem Faktor von 1,5 ausgegangen und 
nicht von 2,5.

von STK500-Besitzer (Gast)


Lesenswert?

Erik H. schrieb:
> if schleife....
Gibt|S nicht.

> Die If schleife
immer noch nicht.

> sodass ich alles Zeitlich besser programmieren müsste.
Oder einfach mal einen Timer verwenden, wie man es bei weniger 
abstrahierte Programmierung macht.

Vielleicht/vermutlich/mit Sicherheit habe ich es überlesen, aber die 
Arduino-Programmier-"Sprache" besitzt den Befehl "pwm()...".

von leo (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> Arduino-Programmier-"Sprache" besitzt den Befehl "pwm()...".

Sprache braucht kein Anfuehrungszeiche, ist C++.
Und ja fast, 
https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/

bzw. https://www.arduino.cc/reference/en/libraries/servo/

leo

von STK500-Besitzer (Gast)


Lesenswert?

leo schrieb:
> Sprache braucht kein Anfuehrungszeiche, ist C++.

C++ mit Erweiterungen.

von leo (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> leo schrieb:
>> Sprache braucht kein Anfuehrungszeiche, ist C++.
>
> C++ mit Erweiterungen.

Die Erweiterungen waerem?
Du kennst den Unterschied zwischen Sprache und Bibliothek?

leo

von STK500-Besitzer (Gast)


Lesenswert?

leo schrieb:
> Du kennst den Unterschied zwischen Sprache und Bibliothek?

"setup()" und "loop()" ?
Oder gibt's das in C++ normalterweise?
Deswegen "Sprache" - ist nicht böse gemeint, aber dann hätte man es auch 
gleich C++ nennen können. Es ist dann wohl eher ein C++-Dialekt.

von leo (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> "setup()" und "loop()" ?
> Oder gibt's das in C++ normalterweise?

Das sind Funktionen. Was ist an Funkionen besonderes dran?
Ca. so:
1
#include <WProgram.h>
2
int main(void)
3
{
4
     init();
5
     setup();
6
     for (;;)
7
           loop();
8
     return 0;
9
}

leo

von STK500-Besitzer (Gast)


Lesenswert?

leo schrieb:
> Das sind Funktionen. Was ist an Funkionen besonderes dran?
> Ca. so:

Dass es anders aussieht?!

von leo (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> leo schrieb:
>> Das sind Funktionen. Was ist an Funkionen besonderes dran?
>> Ca. so:
>
> Dass es anders aussieht?!

Wenn du schon von den paar Zeilen, die das main() verstecken, verwundert 
bist, dann schau dir mal bison (.y) oder flex-Code (.l) an. Da kannst du 
staunen, was Codegeneratoren auffuehren ;-)

leo

von Stefan F. (Gast)


Lesenswert?

Können wir bitte wieder zum Thema des Threads zurück kommen?

von Rolf M. (rmagnus)


Lesenswert?

Stefan ⛄ F. schrieb:
> Können wir bitte wieder zum Thema des Threads zurück kommen?

Gibt es denn zu dem Thema noch irgendwas zu sagen?

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.