PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : mehrere Programme



Andri
12.12.2013, 18:34
Hallo,

kann man auf dem Arduino auch mehrere Programme abspielen ohne ein anderes zu unterbrechen? Weil ich baue einen Roboterarm und immer wenn das nächste Programm abgespielt wird fällt der untere Teil wieder runter,weil die Hand schwerer ist als der Unterarm.
Wenn nicht hat jemand eine Idee wie man das beheben kann das der Unterarm nicht immer runter fällt.

Danke im Voraus!

Kampi
12.12.2013, 19:09
Hey,

nein das geht nicht, da ein Mikrocontroller über keinerlei Möglichkeiten verfügt die Ausführung mehrerer Programme zu steuern.
Du musst die Programme zu einem verbinden oder du greifst auf mehrere Mikrocontroller mit einem Kommunikationsbus wie z.B. I²C zurück.

5Volt-Junkie
12.12.2013, 19:46
Wie Kampi schon gesagt hat, ist es möglich, dass man alle Servos mit einem Programm auf einem Mikrocontroller steuern kann. Poste doch mal dein Programm hier rein.

Andri
12.12.2013, 19:52
Ich setzt die Pins und Winkel dem entsprechend immer ein aber das ist so das Musterprogramm. Der Arm belegt die Pwm Pins 2-5.

#include <Servo.h>

Servo myservo;
int pos = 0;

void setup()
{
myservo.attach(5);
for(pos = 0; pos < 180; pos += 1)
{
myservo.write(pos);
delay(15);
}

}

void loop()
{
}

PICture
12.12.2013, 19:57
Hallo !

Mann könnte auch quasi Multitasking machen, indem alle wichtige Daten z.B. nacheinander neu berechnete Positionen von mehreren Servos bis zur nächster Ausrechnung im RAM zwischengespeichert und den Servos ständig zugeführt werden. Über "Cäh" habe ich aber k.A. ;)

Andri
12.12.2013, 20:16
Okay danke erstmal ich schreibe das alles in ein Programm das ist glaub ich am effektivsten.

Klebwax
12.12.2013, 20:27
Ein Servo will immer Pulse haben, so ist es gebaut. Wie man mehrere Servos gleichzeitig und andauernd mit Pulsen versorgt, hat oberallgeier an anderer Stelle gezeigt. Such mal danach.

MfG Klebwax

Kampi
12.12.2013, 21:27
Ist kurz OT, aber das fiel mir gerade ein


Wie Kampi schon gesagt hat, ist es möglich, dass man alle Servos mit einem Programm auf einem Mikrocontroller steuern kann. Poste doch mal dein Programm hier rein.

Wobei....wenn ich es ganz genau nehme, habe ich murks erzählt. Es gibt einen Kerl der hat auf nem 8-Bit Controller einen ARM Emulator gebaut und dadrüber Linux laufen lassen...das ist schon mega krank und wenn man die 2h Bootzeit in Kauf nimmt, hat man auch Multitasking, allerdings mit einer Frequenz von etwa 6kHz meine ich ^.^

http://www.pro-linux.de/news/1/18217/linux-auf-8-bit-prozessor.html

askazo
13.12.2013, 11:20
nein das geht nicht, da ein Mikrocontroller über keinerlei Möglichkeiten verfügt die Ausführung mehrerer Programme zu steuern.
Auch ohne gleich ein Linux aufspielen zu müssen, kann man sich mit einem relativ einfachen Scheduler ein durchaus brauchbares Multitasking für einen ATMega bauen.
Man findet da ne ganze Menge Beispiele im Netz...

Gruß,
askazo

Max Web
13.12.2013, 17:51
Auch ohne gleich ein Linux aufspielen zu müssen, kann man sich mit einem relativ einfachen Scheduler ein durchaus brauchbares Multitasking für einen ATMega bauen.
Man findet da ne ganze Menge Beispiele im Netz...

Wenn's nicht unbedingt ein eigener Scheduler sein soll, dann könnte sich ein Blick auf FreeRTOS o.Ä. lohnen.
Dafür gibt es auch schon Ports für den ATMega, ggfs. muss man dort noch manuell ein Paar Anpassungen machen.
Ein weiterer Vorteil von FreeRTOS ist die Portabilität auf andere µC-Familien, die High-Level-Programmierung
funktioniert auf einem ATMega (fast) genauso wie etwa auf einem ARM Cortex Mx µC.

Das wäre allerdings die "Mit Atombomben auf Ameisen geschossen"-Lösung, die auch nicht gerade die Performanteste ist.

Statt die Servos nur zu gewissen Zeiten in irgendeinem Unterprogramm anzusteuern bietet es sich doch an, die eigentliche Servosteuerung (->Pulsgenerierung) interruptgesteuert mit einem
der Timer des ATMega zu erledigen. In Deinen Unterprogrammen berechnest Du dann die neuen Sollwerte, welche dann in der ISR an die Servos weitergegeben werden.
Vermutlich macht Deine Library genau dies - poste doch mal die Inhalte der Servo.h und Servo.c. Ein Auszug aus Deinem Hauptptogramm (wo setup() und loop() aufgerufen werden könnte auch noch hilfreich sein.

Grüße,

Max

Andri
14.12.2013, 00:10
#include*<Servo.h>
*
Servo myservo;
int pos = 0;
*
void setup()
{*
**myservo.attach(5);
**for(pos = 0; pos < 500; pos += 1)
**{**********************************
****myservo.write(pos);
****delay(15);
**}*
*myservo.attach(4);
**for(pos = 0; pos < 30; pos += 1)
**{**********************************
****myservo.write(pos);
****delay(15);
**}*
*myservo.attach(3);
**for(pos = 0; pos < 0; pos += 1)
**{**********************************
****myservo.write(pos);
****delay(15);
**}*
***myservo.attach(2);
**for(pos = 0; pos < 40; pos += 1)
**{**********************************
****myservo.write(pos);
****delay(15);
**}*
*
}*
*
void loop()
{
}



Ich hab mich mal eingelesen über FreeRTOS. Die Idee ist ganz gut und sicher eine gute Lösung,aber ich habe im Moment wenig Zeit um mich in das Programm einzuarbeiten.

5Volt-Junkie
17.12.2013, 22:01
Die Antwort auf alle Fragen lautet nicht immer Linux ;)
@Andri: Dein Programm wird nur 1x im Setup ausgeführt, wenn der Mikrocontroller startet.

Du musst die Ansteuerung schon in die Loop Schleife verlagern, damit die Servos ständig die Soll-Position bekommen und nicht nur einmal. Schau doch mal in das Beispielprogramm


// Sweep// by BARRAGAN <http://barraganstudio.com>
// This example code is in the public domain.




#include <Servo.h>

Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created

int pos = 0; // variable to store the servo position

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}


void loop()
{
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}

Andri
18.12.2013, 13:52
Ich will ja,dass das Programm nur einmal Ausgeführt wird.

Andri
19.12.2013, 18:48
Kann man das in die Loop Schleife packen,ohne dass der Servo ständig hin und her dreht? Also sich nur einmal dreht,die Position hält und dann der nächste Ablauf kommt.
Ich habs mal so Ausprobiert,hat aber nicht geklappt:



//*Sweep
//*by*BARRAGAN*<http://barraganstudio.com>*
//*This*example*code*is*in*the*public*domain.


#include*<Servo.h>
*
Servo myservo; // create servo object to control a servo
****************// a maximum of eight servo objects can be created
*
int pos = 0; // variable to store the servo position
*
void setup()
{*
**myservo.attach(5); // attaches the servo on pin 9 to the servo object

**myservo.attach(4); // attaches the servo on pin 9 to the servo object
}*
*
*
*
void loop()
{*
**for(pos = 0; pos < 80; pos += 1) // goes from 0 degrees to 180 degrees
**{**********************************// in steps of 1 degree
****myservo.write(pos); // tell servo to go to position in variable 'pos'
****delay(15); // waits 15ms for the servo to reach the position
**}*
**
**for(pos = 0; pos < 70; pos += 1) // goes from 0 degrees to 180 degrees
**{**********************************// in steps of 1 degree
****myservo.write(pos); // tell servo to go to position in variable 'pos'
****delay(15); // waits 15ms for the servo to reach the position
**}*
}*

Sisor
13.01.2014, 21:47
Das größte Problem, dass ich bei deinem Source-Code sehe, ist, dass du nur ein Servo-Objekt für 4 Servos erstellst.
Vorschlag:


#include<Servo.h>
// 4 Servos
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;

// Positionen der 4 Servos
int posServo1 = 0;
int posServo2 = 0;
int posServo3 = 0;
int posServo4 = 0;

void setup()
{
// Servos den Pins zuweisen
servo1.attach(2);
servo2.attach(3);
servo3.attach(4);
servo4.attach(5);

// Bewegungen
for(posServo4 = 0; posServo4 < 500; posServo4++)
{
servo4.write(posServo4);
delay(15);
}
for(posServo3 = 0; posServo3 < 500; posServo3++)
{
servo3.write(posServo3);
delay(15);
}
for(posServo2 = 0; posServo2 < 500; posServo2++)
{
servo2.write(posServo2);
delay(15);
}
for(posServo1 = 0; posServo1 < 500; posServo1++)
{
servo1.write(posServo1);
delay(15);
}
}

void loop() {}

Wenn du tatsächlich nur einmal den Bewegungsablauf ausführen willst, ist es ok die Befehle ins setup zu schreiben und die loop leer zu lassen.
Allerdings soll das Programm später bestimmt auf irgendwelche Eingaben reagieren, dann muss das in die loop.
Die vier Variablen für die Positionen kann man später so nutzen:



// weitere Bewegung: Servo4 zurück auf '250'
for(; posServo4 > 250; posServo4--)
{
servo4.write(posServo4);
delay(15);
}