Hey
eine Frage was macht die Funktion millis() ??
Und warum machst du für das zurück nicht auch eine for schleife??
Gruß Jan
hey,
ich bin dabei mir einen avoidance robot zu bauen und habe im Moment ein Problem mit einem Code
Der Servo soll dauerhaft von rechts nach links laufen.
Ich hatte Ihn schon am laufen, wobei ich alles in die for-Servo-Schleife gepackt habe, dabei war der Servo allerdings extrem am ruckeln.
aktueller Versuch ohne delay(); :
Der Servo läuft von rechs nach links und dreht wider um, dann macht er allerdings eine pause von ca. 2s und fängt wieder von vorne an.Code:#include <Servo.h> long previousMillis = 0; Servo myservo; long interval = 5; int pos = 0; void setup() { myservo.attach(10, 1000, 2150); } void loop() { unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval){ for(pos = 0; pos < 180;){ myservo.write(pos); pos += 1; previousMillis = currentMillis; } } else{ myservo.write(pos); pos -= 1; previousMillis = currentMillis; } }
Wieso bitte bleibt er stehen?
Hey
eine Frage was macht die Funktion millis() ??
Und warum machst du für das zurück nicht auch eine for schleife??
Gruß Jan
Bin gerene bereit Hilfe zu leisten, freue mich wenn auch mir geholfen werden kann.
Entschuldigt bitte Rechtschreibfehler falls welche vorkommen
Hey Jan,
die Funktion millis() gibt an wie lang das System am laufen ist, mit currentmillis = millis() kann ich den Wert immer abfragen.
Meinst du das ungefähr so mit der for schleife?:
Bei dem Versuch läuft er dauerhaft ohne Pause nach rechts und links, allerdings schätze ich immer nur um eine posCode:void loop() { unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval){ for(pos = 0; pos < 180;){ myservo.write(pos); pos += 1; previousMillis = currentMillis; } for(pos = 180; pos >= 0;){ myservo.write(pos); pos -= 1; previousMillis = currentMillis; } } }
Hey
wie meinst du das nur mit einer Position, nur um ein Grad ?
Probier mal das:
void loop()
{
unsigned long currentMillis = millis();
bool rueck = false;
if(currentMillis - previousMillis > interval)
{
if (rueck == false)
{
pos++;
}
else
{
pos--;
}
if(pos == 180)
{
rueck = true;
}
if(pos == 0)
{
rueck = false;
}
myservo.write(pos);
}
}
Bin gerene bereit Hilfe zu leisten, freue mich wenn auch mir geholfen werden kann.
Entschuldigt bitte Rechtschreibfehler falls welche vorkommen
genau,wie meinst du das nur mit einer Position, nur um ein Grad ?
mit deinem code hab ich leider das selbe Problem wie am Anfang.
Er macht einen Lauf, d.h. einmal nach links dann wider nach rechts und dort wartet er dann ca 2s und startet wieder erneut.
Trotzdem Danke.
Hey
Mach mal aus:
auch mal ein unsignedlong previousMillis = 0;
Bin gerene bereit Hilfe zu leisten, freue mich wenn auch mir geholfen werden kann.
Entschuldigt bitte Rechtschreibfehler falls welche vorkommen
Hi,
also ich finde die Lib bei Arduino ja prinzipiell gut aber manchmal kriegt man mehr Performance wenn man sich selbst die benötigten Funktionen schreibt.
Deshalb habe ich mir eine eigene Servoroutine geschrieben. Die lässt sich sicher noch deutlich optimieren. Ich werde mich nachher mal ran machen die zu verbessern. Fürs erste möchte ich trotzdem mal zeigen, wie ich das gelöst habe.
Code:byte state = 1; int pwm_hi = 0; int pwm_lo = 0; int led_w = 13; int servo_1 = 12; int servo_1_pos = 150; int servo_state = 0; int n = 0; void setup(){ pinMode(led_w, OUTPUT); pinMode(servo_1, OUTPUT); setup_timer1(); } void setup_timer1(){ cli(); // disable interrupts TCCR1A = 0; // Register TCCR1A auf 0 setzen TCCR1B = 0; // Register TCCR1B auf 0 setzen um Timer zu beenden //CTC setzen OCR1A = 19; // bis 15624 ticken dann interrupt //enable CTC TCCR1B |= (1 << WGM12); // Set CS10 bit so timer runs at clock speed: //Timerresolution: 1/(16*10^6 / 1024) TCCR1B |= (0 << CS10); TCCR1B |= (1 << CS11); TCCR1B |= (0 << CS12); // prescaler 1024 // enable Timer1 compare interrupt TIMSK1 |= (1 << OCIE1A); // enable global interrupts: sei(); } void loop() { if(servo_state == 0) { delay(20); servo_1_pos = servo_1_pos + 1; if(servo_1_pos ==200) { servo_state = 1; } } if(servo_state == 1) { delay(20); servo_1_pos = servo_1_pos - 1; if(servo_1_pos ==100) { servo_state = 0; } } } ISR(TIMER1_COMPA_vect) { if (n == 20000) { digitalWrite(led_w, !digitalRead(led_w)); n = 0; } n++; if (pwm_hi > 0) { digitalWrite(servo_1,HIGH); pwm_hi = pwm_hi - 1; pwm_lo = 0; } else if(pwm_hi == 0) { pwm_lo++; digitalWrite(servo_1,LOW); } if (pwm_lo == 2000 - servo_1_pos) { pwm_hi = servo_1_pos; } }
Unser Sommer ist ein grün angestrichener Winter. Das einzige reife Obst, das wir haben, sind gebratene Äpfel. [Heinrich Heine]
Versuch mal nicht von 0 - 180 zu verfahren. Ich glaube das dein Servo eine Pause einlegt liegt daran, das dein Servo nicht bis 0 bzw. 180 fahren kann. Versuchs mal von 20 - 160. Wird die Pause kleiner bzw verschwindet liegt es da dran. So war es bei mir.
Das mit deiner millis() und ner For schleife funktioniert so nicht. Weil er zwar im passenden Interval zu for schleife kommt diese dann aber mit fullspeed abarbeitet.
Ich habe das ganze jetzt so gelöst:
In der ISR wird n hochgezählt mit "n++;".Code:long interval = 600; void loop() { if(n > interval){ digitalWrite(led_w, !digitalRead(led_w)); if(servo_state == 0) { servo_1_pos = servo_1_pos + 1; n=0; if(servo_1_pos ==185) { servo_state = 1; } } if(servo_state == 1) { servo_1_pos = servo_1_pos - 1; n=0; if(servo_1_pos ==75) { servo_state = 0; } } } }
Das Problem ist allerdings, das es scheint als würde das Servo irgendwann durcheinander kommen. Dann macht es einen Sprung. Je größer der Interval desto länger läuft es bis es springt. Ich vermute irgendwann passt das Timing für die PWM nicht mehr läuft über und das Servo weiss dann kurz nicht was es machen soll.
Geändert von DanielSan (01.08.2013 um 13:46 Uhr)
Unser Sommer ist ein grün angestrichener Winter. Das einzige reife Obst, das wir haben, sind gebratene Äpfel. [Heinrich Heine]
Hat leider keine Wirkung
Bringt auch nichts, der Servo ist ein AS-16 acomsVersuch mal nicht von 0 - 180 zu verfahren. Ich glaube das dein Servo eine Pause einlegt liegt daran, das dein Servo nicht bis 0 bzw. 180 fahren kann. Versuchs mal von 20 - 160. Wird die Pause kleiner bzw verschwindet liegt es da dran. So war es bei mir.
Ich habe deine beiden Codes zusammen kopiert und jetzt läuft er, aber mit den von dir erwähnten Sprüngen in unregelmäßigen AbständenDas Problem ist allerdings, das es scheint als würde das Servo irgendwann durcheinander kommen. Dann macht es einen Sprung. Je größer der Interval desto länger läuft es bis es springt. Ich vermute irgendwann passt das Timing für die PWM nicht mehr läuft über und das Servo weiss dann kurz nicht was es machen soll.
Trotzdem vielen Dank für die Mühen
Ich bin mit dem Ergebniss noch nicht zufrieden. Werde mir das morgen nochmal genauer ansehen. Habe eben noch mit einem Kumpel gesprochen er hat wohl eine "hardware" Lösung mit 2 Timern gemacht. Dasguck ich mir mal an.
Unser Sommer ist ein grün angestrichener Winter. Das einzige reife Obst, das wir haben, sind gebratene Äpfel. [Heinrich Heine]
Lesezeichen