Forum: Mikrocontroller und Digitale Elektronik Servo Arduino


von 12V DC (Gast)


Lesenswert?

ICh habe folgendes Problem: Ich habe einen Servo an meinem Arduino Uno 
mit Arduino Motorshield. Der Servo alleine Funktioniert prima. Ob mit 
5V-Pin oder mit 7V Batterie es geht. Wenn ich jetzt aber ein LCD und 
einen Abstandssensor  dazunehme, geht er nichtmehr(das heißt, er geht, 
macht aber lauter schwindsüchtige zuckungen. Egal, ob ich das mit oder 
ohne Batterien versuche. Daraus schließe ich, das das irgendwie mit dem 
Steuer-anschluss zu tun hat.
Mein Servo: http://www.segor.de/#Q%3DArduinoMicroServo%26M%3D1
Mein LCD: http://arduino.cc/en/Main/GTFT
Mein Abstandssensor: http://www.segor.de/#Q%3DHC-SR04%26M%3D1

Ich hoffe ihr könnt mir helfen. Wenn euch irgendwelche Dinge fehlen, 
dann schreibt mir bitte.

12V

von 12V DC (Gast)


Lesenswert?

Der Servo soll sich immer einfach nur von 45°-135° drehen. Gibt es da 
irgendwelche einfache Schaltungen?

von Hubert G. (hubertg)


Lesenswert?

Es wird an deinem Programm scheitern. Das Ansteuern des LCD und Sensor 
braucht Zeit und diese Zeit wird dir in deinem Servoprogramm fehlen.
Mit delay usw. geht da nichts mehr.

von 12V DC (Gast)


Lesenswert?

Aber das erklärt doch nicht diese seltsamen Zuckungen, die können doc 
nur durch falsche Ansteuerung/Hardwarefehler entstehen. Letzteres 
schließe ich aus, da er ja im alleinbetrieb wunderbar funktioniert.

von Karl H. (kbuchegg)


Lesenswert?

12V DC schrieb:
> Aber das erklärt doch nicht diese seltsamen Zuckungen, die können doc
> nur durch falsche Ansteuerung/Hardwarefehler entstehen. Letzteres
> schließe ich aus, da er ja im alleinbetrieb wunderbar funktioniert.

Ich schliesse das keineswegs aus.
Wenn ein Servo zuckt, kann das auch daran liegen, dass die 
Versorgungsspannung zusammenbricht, wenn der Motor anfährt.

Aber du bist lange genug hier im Forum, um zu wissen, dass unsere 
Glaskugeln nicht besonders gut funktionieren und das normalerweise immer 
noch einem Schaltplan und dem Programm gefragt wird. Eigentlich solltest 
du das schon wissen, wie hier der Hase läuft.

: Bearbeitet durch User
von Hubert G. (hubertg)


Lesenswert?

Doch, erklärt es schon. Du musst dir nur die Impulse zum Servo ansehen 
und zwischen den beiden Programmvarianten vergleichen.
Lies dir den Artikel: 
http://www.mikrocontroller.net/articles/Modellbauservo_Ansteuerung

von 12V DC (Gast)


Angehängte Dateien:

Lesenswert?

Also hier ist das Programm und mit nem Schaltplan kann man hier nicht so 
viel anfangen glaub ich. Das Programm sollte selbsterklärend sein. 
Aufbau hab ch oben schon mal beschrieben.

von 12V DC (Gast)


Lesenswert?

Karl Heinz schrieb:
> Wenn ein Servo zuckt,

Er zuckt ja nicht, sondern macht unkonntrollierte Bewegungen, d.h. Er 
fährt eine halbe sekunde, stoppt, fährt wieder, diesmal kürzer usw. Es 
sind einfach unkontrollierte Bewegungen, allerdings immer in eine 
Richtung.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

12V DC schrieb:
> mit nem Schaltplan kann man hier nicht so viel anfangen glaub ich.

Warum nicht?

Sind wir hier im Strickforum?

von Karl H. (kbuchegg)


Lesenswert?

12V DC schrieb:
> Karl Heinz schrieb:
>> Wenn ein Servo zuckt,
>
> Er zuckt ja nicht, sondern macht unkonntrollierte Bewegungen, d.h. Er
> fährt eine halbe sekunde, stoppt, fährt wieder, diesmal kürzer usw. Es
> sind einfach unkontrollierte Bewegungen, allerdings immer in eine
> Richtung.

Mein Bauchgefühl, dass das Problem in der Stromversorgung zu suchen ist, 
verstärkt sich.


Hier mal das Programm in einer lesbaren Form
1
#include <TFT.h>
2
#include <SPI.h>
3
#include <Servo.h> 
4
#define echo 4
5
#define trig 10
6
#define CS A3
7
#define DC A2
8
#define RES 7
9
#define MOSI 6
10
#define SCLK 2
11
12
Adafruit_ST7735 screen = Adafruit_ST7735(CS, DC, MOSI, SCLK, RES);
13
Servo myservo;  // create servo object to control a servo 
14
                // a maximum of eight servo objects can be created 
15
int dis;
16
char disC[5];
17
String disS;
18
int pos = 0;    // variable to store the servo position 
19
20
void abstand(){
21
  digitalWrite(trig, LOW);
22
  delayMicroseconds(2);
23
  digitalWrite(trig, HIGH);
24
  delayMicroseconds(10);
25
  digitalWrite(trig, LOW);  
26
  dis = pulseIn(echo, HIGH);
27
  disS = String(dis/58);
28
  disS.toCharArray(disC, 5);
29
}
30
void lcdtext(char *distance, char *text){
31
  screen.stroke(255, 255, 255);
32
  screen.setTextSize(2);
33
  screen.text(text, 0, 0);
34
  screen.setTextSize(5);
35
  screen.text(distance, 0, 25);
36
  screen.stroke(0, 0, 0);
37
  screen.text(distance, 0, 25);
38
}
39
void setup() { 
40
  screen.initR(INITR_REDTAB);
41
  screen.setRotation(1);
42
  screen.background(0, 0, 0);
43
  screen.setTextSize(5);
44
  pinMode(echo, INPUT);
45
  pinMode(trig, OUTPUT);
46
  myservo.attach(5);  // attaches the servo on pin 9 to the servo object 
47
} 
48
 
49
 
50
void loop() {
51
  
52
  for(pos = 90; pos <180; pos += 1)  // goes from 0 degrees to 180 degrees 
53
  {                                  // in steps of 1 degree 
54
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
55
    abstand();
56
    lcdtext(disC, "Abstand(cm):");
57
    delay(75);                       // waits 15ms for the servo to reach the position 
58
  } 
59
  for(pos = 180; pos>=90; pos-=1)     // goes from 180 degrees to 0 degrees 
60
  {                                
61
    myservo.write(pos);                // tell servo to go to position in variable 'pos' 
62
    abstand();
63
    lcdtext(disC, "Abstand(cm)");
64
    delay(75);                       // waits 15ms for the servo to reach the position 
65
  } 
66
 
67
}

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

void setup()

Beabsichtigst du die Routine auch mal aufzurufen?

von Karl H. (kbuchegg)


Lesenswert?

Werden eigentlich die Arduino Servo Objekte per Timerinterrupt 
betrieben?
Ich hoffe das mal, denn im Programm wimmelt es wieder mal von 
Verzögerungssachen.

von Karl H. (kbuchegg)


Lesenswert?

Magnus M. schrieb:
> void setup()
>
> Beabsichtigst du die Routine auch mal aufzurufen?


Das ist Arduino.

Stell dir ein dazu ein main vor, dass so aussieht
1
int main()
2
{
3
  setup();
4
5
  while( 1 )
6
    loop();
7
}
und vordefiniert ist.
Als Modell für den Programmierer reicht das, wenn auch das Arduino 
System noch ein paar Sachen zusätzlich macht (wie zb eine Systemuhr, 
Timerinterrupts etc.)

: Bearbeitet durch User
von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Karl Heinz schrieb:
>> Beabsichtigst du die Routine auch mal aufzurufen?
>
> Das ist Ardunio.

Ich glaube ich werde mich zukünftig aus allen Arduino Threads raus 
halten. Das ist ja peinlich!

von Karl H. (kbuchegg)


Lesenswert?

Magnus M. schrieb:

> halten. Das ist ja peinlich!

So schlimm ist es nicht.
Das Hauptproblem bei der Arduino Programmierung besteht darin, dass es 
da ein mitlerweile recht großes Framework gibt, welches einem viel 
Arbeit abnimmt, aber auch das Problem hat, dass man wissen muss, wie 
sich die einzelnen vordefinierten Klassen (ja, ist C++), die Resourcen 
teilen und wo die Einschränkungen liegen.
Und natürlich, dass die hier aufschlagenden Arduino Programmierer 
meistens die Doku nicht lesen. Den Teil finde ich persönlich viel 
peinlicher: wenn ich als nicht-Arduino Programmierer in Google Stichwort 
eingebe, in 5 Sekunden auf der Arduio Hompage die Doku zu einer 
Funktion/Klasse finde und dort dann ganz genau steht, wies geht.

Aber im konkreten Fall hab ich immer noch die Stromversorgung im Auge. 
Servos können nun mal schlimme Finger auf der Stromversorgung sein.

: Bearbeitet durch User
von 12V DC (Gast)


Lesenswert?

Karl Heinz schrieb:
> Mein Bauchgefühl, dass das Problem in der Stromversorgung zu suchen ist,
> verstärkt sich.

Das war auch mein erster Gedanke, weil ich das schon mal hatte, aber 
nachdem das über Batterien mal geht mal nicht(wenn mehr am Arduino 
hängt), dachte ich, das es etwas mit dem Signal zu tun hat. Evtl. kommt 
es zu schwach an und wird falsch interpretiert

Magnus M. schrieb:
> Warum nicht?
>
> Sind wir hier im Strickforum?

Nein sind wir nicht ;) Aber wenn der Schaltplan nur aus Verbindungen 
besteht, die man aus dem Programm entnehmen kann, halte ich dies für 
unnötig. Wenn du dazu Fragen hast dann frag. Aber extra nen Schaltplan 
dafür zu basteln ist doch iwie unnötig, oder?

von Helge A. (besupreme)


Lesenswert?

Laß das Programm so laufen wie es ist, aber ohne LCD drangesteckt. 
Bleiben die Zuckungungen, liegts an deinem Programm.

von Jürgen S. (jurs)


Lesenswert?

Magnus M. schrieb:
> void setup()
>
> Beabsichtigst du die Routine auch mal aufzurufen?

Das braucht er bei Arduino-Programmen nicht. Für Arduino wird keine 
"main" Funktion geschrieben, sondern eine "setup" (wird einmal 
ausgeführt) und eine "loop" (wird immer wieder ausgeführt). Darum, dass 
setup (einmalig) und loop (immer wieder) gestartet werden, braucht man 
sich bei Arduino nicht zu kümmern. Solche Programme heißen daher bei 
Arduino auch nicht "Programm" sondern "Sketch". Wahrscheinlich, weil es 
für C-Programmierer so komisch aussieht.

@"12V DC": Wenn Du gut funktionierende Arduino-Software mit komplexen 
Funktionabläufen schreiben möchtest, solltest Du Dich dringend darum 
kümmern, die "Komfort-Funktionen" und die "Library-Funktionen" zu 
verstehen, die Du verwendest!

Und dann alles an "Komfortfunktionen" weglassen, das kontraproduktiv für 
Dein Vorhaben ist.

Schau Dir das an:
dis = pulseIn(echo, HIGH);

Die Arduino-Funktion "pulseIn" sperrt die Interrupts und blockiert den 
Programmablauf, bis entweder der gesuchte HIGH-Impuls aufgetreten ist 
oder das Standard-Timeout von einer Sekunde abgelaufen ist.

Ein Programm mit abgeschalteten Interrupts in der Ausführung total zu 
blockieren ist natürlich völlig kontraproduktiv, wenn mehrere Dinge 
gleichzeitig ablaufen sollen.

Deine "Servo-Library" möchte gerne per Timer-Interrupts alle 20 
Millisekunden den Impuls zum Servo-Refresh senden, und Deine 
pulseIn-Funktion blockiert den Programmablauf für bis zu 1000 
Millisekunden komplett.

Das Programmkonzept mit der "pulseIn" Funktion ist völlig daneben.

Die Komfortfunktion "pulseIn" kannst Du NUR in solchen Sketchen sinnvoll 
verwenden, die nichts anderes machen solllen als diese eine Pulslänge 
messen. Für Sketche, die mehr oder weniger gleichzeitig oder im 
Hintergrund Dinge erledigen sollen, ist "pulseIn" eine Funktion, die Du 
überhaupt nicht verwenden darfst.

von 12V DC (Gast)


Lesenswert?

Mm… Sämtliche Servoprobleme bleiben, ob ohne LCD oder Abstand ist egal. 
Könnt ihr mir sagen wo da das Problem im Programm liegt. Ich hatte 
schonmal ein ähnliches, es sah so aus(kann sein, das ein bisschen 
anders, musste was rausnehmen): [c]#include <Servo.h>

#define echo 4                            // Pin to receive echo pulse
#define trig 10  // Pin to send trigger pulse


Servo myservo;  // create servo object to control a servo
int pos = 0; // variable to store the servo position
int vorzurueck;
int entfernung = 1000;

void setup() {
  //Serial.begin(9600);
  pinMode(echo, INPUT);
  pinMode(trig, OUTPUT);
  //Setup Channel A
  pinMode(12, OUTPUT); //Initiates Motor Channel A pin
  pinMode(9, OUTPUT); //Initiates Brake Channel A pin
  //Setup Channel B
  pinMode(13, OUTPUT); //Initiates Motor Channel A pin
  pinMode(8, OUTPUT);  //Initiates Brake Channel A pin
  myservo.attach(6);  // attaches the servo on pin 6 to the servo object
}

void loop(){

  digitalWrite(trig, LOW);   // Set the trigger pin to low for 2uS
  delayMicroseconds(2);
  digitalWrite(trig, HIGH);                  // Send a 10uS high to 
trigger ranging
  delayMicroseconds(10);
  digitalWrite(trig, LOW);                   // Send pin low again
  if(pos < 180 && vorzurueck == 0){
    if(pos == 180){
      vorzurueck = 1;
    }
    else{
      myservo.write(pos);
      pos = pos + 5;
      vorzurueck = 0;
      delay(75);
    }
  }
  else{
    if(pos == 90){
      vorzurueck = 0;
    }
    else{
      myservo.write(pos);
      pos = pos - 5;
      vorzurueck = 1;
      delay(75);
    }
  }
  if(distance < entfernung){

    digitalWrite(12, HIGH);
    digitalWrite(9, LOW);
    analogWrite(3, 100);

    digitalWrite(13, LOW);
    digitalWrite(8, LOW);
    analogWrite(11, 100);

    if(distance > 2000){
      entfernung = 1000;
    }
    else{
      if(entfernung >= 2000){
        entfernung = 1500;
      }
      else{
        entfernung = entfernung + 250;
      }
    }
    if(distance <= 100){
    digitalWrite(12, LOW);
    digitalWrite(9, LOW);
    analogWrite(3, 100);
    digitalWrite(13, LOW);
    digitalWrite(8, LOW);
    analogWrite(11, 101);
    }
  }
  else {
    digitalWrite(12, HIGH);
    digitalWrite(9, LOW);
    analogWrite(3, 100);
    digitalWrite(13, HIGH);
    digitalWrite(8, LOW);
    analogWrite(11, 101);    //der eine motor hakt
  }
}[c]

Und da hats mit 7,5V am Eingang des Motorshields geklappt.

von Karl H. (kbuchegg)


Lesenswert?

Ich geh mal davon aus, dass du Jürgens Post noch nicht gelesen hast.

von 12V DC (Gast)


Lesenswert?

Ja, hab ich übersehn. Das ist ja leifer Gottes der Nachteil von Arduino, 
das man iwelche Dinge einbindet, weil man gesgt bekommt, das das so geht 
ohne sich darum zu scheren, was wirklich drin steht. Jürgens Text im 
Klartext heißt also "Schreib dein Programm komplett um". Dieses PulseIn 
-wenn ich da als dritten Parameter angeben soll, das maximal 10µS bis 
zum beginn des Pulses gewartet werden sollen, dan wäre doch schonmal 
ziemlich viel Zeit gespart, oder?
Aber ich versteh trotzdem nicht, wieso das PulseIn im alten PRogramm 
gefunzt hat…
Kann es sein, das ich eine andere Funktion verwwendet habe, denn -wie 
gesagt- habe ich den Quellcode geändert und versehentlich die Zeile 
mitrausgeschmissen, in der die Zuweisung der Distanz festgelegt war.

von Jürgen S. (jurs)


Lesenswert?

12V DC schrieb:
> Aber ich versteh trotzdem nicht, wieso das PulseIn im alten PRogramm
> gefunzt hat…

Dein Programm ist ja bereits ziemlich komplex. Kann auch sein, dass Dir 
was anderes als pulseIn in die Suppe spuckt. Ich habe mal gerade 
versucht den Quelltext von pulseIn einzusehen und konnte dabei entgegen 
meiner Annahme nicht feststellen, dass die Interrupts tatsächlich 
gesperrt werden, während die Funktion läuft. Also es könnte auch sein, 
dass dann die Servo-Library weiterläuft (da timer-interruptgesteuert), 
aber das Problem mit so einem "blockierenden Funktionsaufruf" ist 
trotzdem: Wenn vom Abstandsservo kein Echo kommt, wartet die Funktion 
auf einen Timeout von einer Sekunde und so lange wird das Programm 
ausgebremst (auch wenn der Servo dabei nicht durchdrehen sollte).

Deine loop-Funktion sieht jedenfalls so aus, als wenn der Servo alle 75 
ms eine neue Servoposition anfahren soll, aber wie soll das mit einer 
Funktion funktionieren, wenn die Funktion das Programm zwischendurch für 
bis zu 1000ms bei jedem Schritt der for-Schleife blockiert?

Anyway.
Was mir noch auffällt, ist, dass Du ein Pixel-Display ansteuern möchtest 
und nur einen UNO hast. Bist Du sicher, dass der genug RAM-Speicher zur 
Ansteuerung des Displays und Deinen sonstigen Code hat?

Hast Du mal geprüft, wie viel RAM-Speicher Dein Programm überhaupt noch 
frei hat, wenn die loop-Funktion startet?

von Stefan F. (Gast)


Lesenswert?

Wenn die delayMicroSeconds halbwegs genau arbeiten soll, dann kommt sie 
nicht drumherum, Interrupts zu sperren. Das wiederum dürfte die Signale 
der Servo Klasse erheblich beeinflussen.

Kleiner Tip: Lagere die Servo-Steuerung in einen zweiten Mikrocontroller 
aus. Im Netzt kursieren einige fix und fertige Schaltungsbeispiele z.B. 
auf Basis eines AtTiny2313.

von Stefan F. (Gast)


Lesenswert?

Mit Google habe ich das gefunden: "Wie damals bei der Arduino IDE 0018, 
schaltet die Funktion delayMicroseconds() nicht mehr die Interrupts ab."

Welche Version verwendest du?

von 12V DC (Gast)


Lesenswert?

Stefan us schrieb:
> Welche Version verwendest du?

Arduino 1.5.4

Stefan us schrieb:
> Lagere die Servo-Steuerung in einen zweiten Mikrocontroller

Hatte ich auch schon dran gedacht. Nur bin ich mit meinem STM32f4 noch 
nicht so bewndert. Atiny is ne Option, nur komme ich selten zum 
Elektrohändler. Und ich würde das Problem gerne möglichst schnell lösen.

Jürgen S. schrieb:
> Was mir noch auffällt, ist, dass Du ein Pixel-Display ansteuern möchtest
> und nur einen UNO hast.

Das Hat eigentlich immer Prima gefunzt. auch mit diesem Programm.

Jürgen S. schrieb:
> Hast Du mal geprüft, wie viel RAM-Speicher Dein Programm überhaupt noch
> frei hat, wenn die loop-Funktion startet?

Wie kann ich das? Der Compiler gibt immer den verbrauchten Speicher an, 
aber den Ram?

Mal ne andere Frage, wie viele Timer hat der Atmega? Er hat doch 
bestimmt mehr als einen?

von 12V DC (Gast)


Lesenswert?

Laut Datenblatt hat der 2 8-bit Timer und einen 16bit Timer, aber kann 
ich die über die Skeches einzeln ansteuern, um z.B. den Servo auf einen 
zu legen und den Abstandssensor für den anderen zu benutzen? Muss ich 
das dann in C schreiben?

von Jürgen S. (jurs)


Lesenswert?

12V DC schrieb:
> Wie kann ich das? Der Compiler gibt immer den verbrauchten Speicher an,
> aber den Ram?

Du kannst diese Funktion in Deinen Sketch einbauen:
1
int freeRam () {
2
  extern int __heap_start, *__brkval; 
3
  int v; 
4
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
5
}

Und dann mal den Rückgabewert am Ende des setups oder am Anfang der loop 
auf Deiner Anzeige ausgeben lassen. Faustformel: Wenn im laufenden 
Sketch noch mindestens 200 Bytes RAM frei sind und Du keine exzessiv 
tiefen Funktionsaufrufe geschachtelt hast oder übermäßig viele Parameter 
übergibst, sollte das ausreichen.

> Mal ne andere Frage, wie viele Timer hat der Atmega? Er hat doch
> bestimmt mehr als einen?

Der UNO (Atmega328) hat drei Timer (Timer0, Timer1, Timer2), wovon 
Timer0 bereits von der Arduino-Software verwendet wird, z.B. für die 
Zeitmessung per millis() Funktion. Und Timer1 wird glaube ich 
standardmäßig von der Servo-Library verwendet.

: Bearbeitet durch User
von 12V DC (Gast)


Lesenswert?

Sketch uses 11.298 bytes (35%) of program storage space. Maximum is 
32.256 bytes. Das wäre die Ausgabe des Compilers zum RAM. Deine Funktion 
funzt iwie nicht.

von 12V DC (Gast)


Lesenswert?

Ach ne sorry, hatte die Schriftfarbe falsch ;)
also: am anfang "1801/1795"
am ende "1781"

von Jürgen S. (jurs)


Lesenswert?

12V DC schrieb:
> Ach ne sorry, hatte die Schriftfarbe falsch ;)
> also: am anfang "1801/1795"
> am ende "1781"

Also noch massenhaft RAM-Speicher frei, wenn die Funktion anzeigt, dass 
Du von den 2048 Bytes RAM eines Atmega328 noch mindestens 1781 Bytes 
frei hast.

Das reicht dicke, der Fehler muß also irgendeine andere Ursache haben.

Oben sehe ich auch das von Dir:
> Arduino 1.5.4

Was passiert denn, wenn Du Dir mal für Dein Board die richtige Version 
der Arduino-Software installierst, statt die Betaversion für den 
32-bittigen Arduino Due?

Die richtige und derzeitig aktuelle Softwareversion hat die Nummer 
1.0.5!

Erst mit der Version 2.0 sollen irgendwann man die 8-bittigen 
Entwicklungszweige 1.0.x und die 32-bittigen Entwicklungszweige 1.5.x zu 
einer gemeinsamen Softwareversion zusammengelegt werden. Bis dahin ist 
die Betaversion 1.5.x NUR für die 32-Bit DUE Boards vorgesehen. Und 
diese DUE-Version ist für die 8-bittigen Atmegas noch relativ buggy. 
Also diese lieber nicht für die 8-bittigen Controller verwenden, sondern 
für diese immer nur die 1.0.5 oder Nachfolger (1.0.x)!

von 12V DC (Gast)


Lesenswert?

Sag mir das doch mal einer! Ich sehe auf der Arduino Homepage die IDE 
1.5.4 und sehe im Menü, das man das Uno als Board auswählen kann und bin 
zufrieden. es geht doch, oder ist das das Problem in der IDE zu suchen? 
Aber anscheind geht das mit der Speicherverwaltung?
Wie hätte ich das erkennen können??

von Markus (Gast)


Lesenswert?

12V DC schrieb:
> Sag mir das doch mal einer! Ich sehe auf der Arduino Homepage die IDE
> 1.5.4 und sehe im Menü, das man das Uno als Board auswählen kann und bin
> zufrieden.

Nur weil du es auswählen kannst, heisst das nicht, dass es auch 
unterstützt ist. Auf der Seite steht klar dass es Beta ist:
http://arduino.cc/en/Main/Software
Bevor du weiterprobierst würde ich schon mal auf die aktuelle 
unterstütze Version 1.0.5 zurückgreifen.

von 12V DC (Gast)


Lesenswert?

Auch mit 1.0.5 Zuckungen, allerdings kleine in beide richtungen. 
Programm dasselbe. Den Ram zu prüfen halte ich für unnötig, da sich ja 
nicht so viel verändert hat(oder irre ich mich?).

12V DC

von Markus (Gast)


Lesenswert?

Hast du denn schon mal versuchsweise das "unsägliche"
1
dis = pulseIn(echo, HIGH);
 auskommentiert, oder wenigsten das Timeout auf ein paar wenige ms 
gesetzt? Was passiert dann?

Die Funktion abstand() brauchst ja nur nur für die Anzeige. Die könnte 
also auch einfach z.B. nur jede Sekunde im Loop aktualisiert werden, 
oder?

von Jürgen S. (jurs)


Lesenswert?

12V DC schrieb:
> Auch mit 1.0.5 Zuckungen, allerdings kleine in beide richtungen.

Also es hat sich etwas verändert durch den Wechsel der Softwareversion?

Und der Servo fährt seine vorgesehene Position an, und hat dann nur noch 
kleine Zuckungen in beide Richtungen? Mehr so ein "Tickern" oder 
"Zittern" auf der Stelle?

Das passiert mit der standardmäßigen Servo-Library, wenn im Sketch 
Interrupts für längere Zeit gesperrt sind. Die üblichen Verdächtigen 
sind dabei Display-Ausgaben.

Kannst Du mal versuchen, Displayausgaben zu deaktivieren, ob der Servo 
dann immer noch zuckt?

von 12V DC (Gast)


Lesenswert?

Jürgen S. schrieb:
> Kannst Du mal versuchen, Displayausgaben zu deaktivieren, ob der Servo
> dann immer noch zuckt?

Soll ich auskommentieren oder abstecken?

Markus schrieb:
> Hast du denn schon mal versuchsweise das "unsägliche"dis = pulseIn(echo,
> HIGH); auskommentiert, oder wenigsten das Timeout auf ein paar wenige ms
> gesetzt? Was passiert dann?

probier ich mal. Welches Timeout meinst du?

von 12V DC (Gast)


Lesenswert?

Wenn ich dies auskommentiere passiert garnichts
1
dis = pulseIn(echo, HIGH);
2
  disS = String(dis/58);
3
  disS.toCharArray(disC, 5);

von 12V DC (Gast)


Lesenswert?

Garnichts ist falsch. Es gibt -wie immer- diese Zuckungen. Egal ob mit 
5+Pin/7VBatterie/5V Netzteil.

von Jürgen S. (jurs)


Lesenswert?

12V DC schrieb:
> Jürgen S. schrieb:
>> Kannst Du mal versuchen, Displayausgaben zu deaktivieren, ob der Servo
>> dann immer noch zuckt?
>
> Soll ich auskommentieren oder abstecken?

Textausgaben auskommentieren.
Denn es ist ja wenn nur immer das Programm und nicht die Hardware, das 
die Interrupts sperrt wenn es Zeit für exakte Timings bei Textausgaben 
benötigt. Und das Sperren der Interrupts wiederum kann das exakte Timing 
der Refresh-Impulse durch die Servo-Library negativ beeinflussen.

von 12V DC (Gast)


Lesenswert?

Jo, Problem liegt 1.)beim Display, es verursacht die Zuckungen
                  2.)b3eim PulseIn, es macht allse sehr langsam.
Ich habe zuerst die lcdtext() funktion auskommnetiert, und da hat sich 
der servo sehr langsam, aber richtig bewegt und als ich dann noch 
pulseIn weggenommen hab hats ordnungsgemäß funktioniert.

von Stefan F. (Gast)


Lesenswert?

Im Gegensatz zu den Servo-Signalen ist die Displayausgabe ja überhaupt 
nicht Zeitkritisch. ALso würde ich die Display-Ausgabe neu 
programmieren, und zwar so, dass sie keine Interrupts sperrt.

Man könnte z.B. den auszugebenden Text in ein Array ablegen. Und dann in 
einem Timer-Interrupt alle 20 Millisekunden einen Buchstaben davon an 
das Display übertragen. Dadurch entfalen die sonst nötigen Wartezeiten 
zwischen den Buchstaben, wenn man ganze Zeichenketten am Stück ans 
Display sendet.

Für die Servo-Ansteuerung hast Du sowieso schon einen 20ms Timer. Man 
könnte also beide Fliegen mit einer Klappe schlagen - wenn man auf die 
Arduino Libraries verzichtet.

von Markus (Gast)


Lesenswert?

12V DC schrieb:
> Hast du denn schon mal versuchsweise das "unsägliche"dis = pulseIn(echo,
>> HIGH); auskommentiert, oder wenigsten das Timeout auf ein paar wenige ms
>> gesetzt? Was passiert dann?
>
> probier ich mal. Welches Timeout meinst du?

Das Timeout des
1
pulseIn(pin, value, timeout);
Gib doch da mal ein tiefer Wert. z.B. 100 us an.

Und eben das Display weniger häufig. z.B. nur noch alle Sekunde, 
aktualisieren, das reicht doch.

von 12V DC (Gast)


Lesenswert?

Ein bisschen Zeit könnte ich mir auch sparen, wenn ich SPI benutzen 
würde, das kann ich aber nicht, weil das Motorshield die MOSI und SCLK 
pIndś benutzt. Da geht halt auch so ca. eine haalbe skeunde jedesmal 
verloren.
Wobei ja das Display die Zuckungen verursacht. Und die können doch nicht 
durch Interrrupts entstehen, oder? Die PulseIn Funktion ist langsam, wie 
oben beschrieben. Da merkt man das richtig. Keine Zuckungen, nur alles 
sehr langsam.
Aber mein Hauptproblem sind die Zuckungen. Das es langsam ist stört 
nicht so. Wenn man die Ursache dafür feststellen könnte(genau, nicht 
"das lcd ist schuld"). Hat jemand das schon mal gehabt und kann mir 
sagen, wie er es gelöst hat?
Ich habs damals(ich hatte das Problem schon mal ohne LCD) mit mehr 
Batterien(Vin) gelöst, das hilft hier aber anscheined nicht.

von Jürgen S. (jurs)


Lesenswert?

12V DC schrieb:
> Aber mein Hauptproblem sind die Zuckungen. Das es langsam ist stört
> nicht so. Wenn man die Ursache dafür feststellen könnte(genau, nicht
> "das lcd ist schuld"). Hat jemand das schon mal gehabt und kann mir
> sagen, wie er es gelöst hat?

Wie viele Servos sind denn anzusteuern?

Wenn es nur ein oder zwei Servos sind, dann machst Du Dir am besten eine 
eigene ServoRefresh-Funktion, die dann im Programm laufend aufgerufen 
wird, und zwar aus der loop heraus (und nicht in timergesteuerten 
Interrupts wie bei der Servo-Library).

von 12V DC (Gast)


Lesenswert?

Ich hab einen Servo ;)

Jürgen S. schrieb:
> Wenn es nur ein oder zwei Servos sind, dann machst Du Dir am besten eine
> eigene ServoRefresh-Funktion, die dann im Programm laufend aufgerufen
> wird, und zwar aus der loop heraus (und nicht in timergesteuerten
> Interrupts wie bei der Servo-Library).

versteh ich nicht.

von 12V DC (Gast)


Lesenswert?

Meinst du damit, das ich die Servo.h weglassen soll und meine eigenen 
Funktionen schreiben soll?

von Frank (Gast)


Lesenswert?

Also ich habe vor einger Zeit eine Ansteuerung für zwei Servos und einen 
Laser zum X-Y-gesteuerten Zeigen auf ein Lager-Regal gebaut, die wurde 
per USB-UART angesteuert - da hatte ich niemals Probleme mit zuckenden 
Servos. Während der Entwicklung hatte ich auch zeitweise noch ein 
serielles LCD an einer Soft-UART dran ...

Ich habe die Servo-Routinen als Funktionen selber geschrieben, ohne 
Interrupts einfach mit delay-microseconds (oder wie das hieß). 
Allerdings habe ich digitale Servos verwendet - denen ist nach meinen 
Erfahrungen ziemlich "wurscht" in welchem Abstand die Inpulse kommen, 
lediglich deren korrekte Länge wird ausgewertet (und bis zu einer 
Änderung auch gehalten).

Da hat nie irgendwas gezuckt oder gerüttelt, wollte ich nochmal 
wiederholen, trotz der Tatasache, dass ich beide (Micro-) Servos aus der 
gemeinsamen USB-Versorgung des Arduino mitversorgt habe.

von 12V DC (Gast)


Lesenswert?

Ok, also servo.h neumachen/schaun was drinsteht und selbst Impulse 
schicken.

Beitrag #5665600 wurde von einem Moderator gelöscht.
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.