RE: Arduino - Weichensteuerung mit Servos

#1 von Bierrudl , 06.05.2014 22:28

Hallo, zusammen,

angeregt durch "Herbert's belebtes Haus" habe ich meine ersten Gehversuche mit Arduino und ATtiny gestartet. Bei der Gelegenheit ein großes Dankeschön an all diejenigen, die einem Laien wie mir mit ihren Kommentaren und Sketches den Einstieg in die sehr interessante Thematik möglich machen.

Ich möchte u.a. künftig meine Weichen mittels Servos steuern und habe mir in dem Zusammenhang das nachstehende Programm unter Zuhilfenahme von Sketches aus dem Stummi-Forum u.a. zusammengeschrieben, wobei meine Einfügungen minimal sind (um mich nicht mit fremden Federn zu schmücken):

#include <WProgram.h>

int myservo;

int KippschalterPin = 0;
int Servo_Pin = 2;

int Stellung1 = 28;//ServoStellung 1 (Einstellbar zwischen 0° bis max. 180°)
int Stellung2 = 0;//ServoStellung 2 (Einstellbar zwischen 0° bis 180°)
int Stellung_bisher;//Für Vergleich
const int Warten = 19;//19 MilliSekunden Warten nach Stellschritt. Nicht verändern!
void Servo_move(int servo,int Stellung_neu);

void setup()
{
pinMode(KippschalterPin, INPUT);
digitalWrite(KippschalterPin, HIGH);
pinMode(Servo_Pin, OUTPUT);

Stellung_bisher=Stellung1;//Ruhestellung
}

void loop()
{
if(digitalRead(KippschalterPin)==HIGH)
Servo_move(Servo_Pin, Stellung1);
if(digitalRead(KippschalterPin)==LOW)
Servo_move(Servo_Pin, Stellung2);
delay(20);
}

void Servo_move(int servo,int Stellung_neu){
int Schritt;
if(Stellung_neu==Stellung_bisher)return;
Schritt=(Stellung_neu>Stellung_bisher)?1:-1;
while(Stellung_bisher!=Stellung_neu){
Stellung_bisher+=Schritt;

digitalWrite(servo, HIGH);
delayMicroseconds((Stellung_bisher*8)+500);
digitalWrite(servo, LOW);
delay(Warten);
}
}
Kurze Anmerkung: "KippschalterPin = 0" und "Servo_Pin = 2" ist schon für den ATttiny eingestellt

Ergänzende Bemerkung:
Nach diversen Versuchen war der o.g. Sketch bisher der einzige, den ich sowohl auf dem Arduino als auch auf dem ATttiny erfolgreich speichern konnte.
Das o.g. Programm selbst läuft einwandfrei. Die Servos werden problemlos geschaltet.
Es gibt im Betrieb keinerlei Zuckungen bei den Servos, weder in Ruhestellung, noch bei der Bewegung.

Nun zu meinem Problem:
Einzig beim Einschalten der Stromversorgung schalten die Servos jeweils um, und zwar - soweit ich das beobachten kann - in die
"Stellung 1" bzw. "Stellung_bisher", egal, in welcher Stellung die Servos beim Ausschalten der Stromversorgung gestanden haben.

Ich habe schon versucht, den Sketch abzuändern, jedoch aufgrund meiner beschränkten Kenntnisse ohne Erfolg.

Meine Frage bzw. Bitte:
Kann man den Sketch so modifizieren, dass die Servos beim Einschalten der Stromversorgung stillhalten?

Im Voraus ein kräftiges Dankeschön für Eure Hilfe.

Einen schönen Abend wünscht
Bierrudl


Bierrudl  
Bierrudl
S-Bahn (S)
Beiträge: 16
Registriert am: 23.12.2012


RE: Arduino - Weichensteuerung mit Servos

#2 von Der Ruinenbaumeister , 06.05.2014 23:05

Dein Programm startet ja jedes Mal neu, wenn du die Stromversorgung einschaltest. Dann wird Stellung_bisher auf den Wert 1 zurückgesetzt, also fährt auch der Servo die entsprechende Position an.

Du solltest in setup() die Zeile

Zitat
Stellung_bisher=Stellung1;


ersetzen durch

Zitat
if (HIGH == digitalRead(KippschalterPin)){
Stellung_bisher = Stellung1;
} else {
Stellung_bisher = Stellung2;
}



Damit fährt dein Servo beim Einschalten stets die vom Kippschalter vorgegebene Stellung an.

Theoretisch könntest du auch jeden Stellbefehl im EEPROM - das ist der Speicher, dessen Inhalt auch im stromlosen Zustand erhalten bleibt - abspeichern. Damit wüsste der Arduino nach dem Einschalten immer, welchen Befehl er zuletzt gesendet hat. Der Servo würde also selbst dann, wenn du den Kippschalter während der stromlosen Zeitspanne betätigt hast, seine Endposition nicht ruckartig anfahren. Allerdings beträgt die Lebensdauer des EEPROM nur etwa 100.000 Schreibzugriffe. Daher halte ich diese Möglichkeit nicht für sinnvoll.

Übrigens wäre dein Programm einfacher zu lesen, wenn du dich an gewisse Konventionen halten würdest. Dazu gehört:

  • Variablen werden als camelCases geschrieben, d.h. der erste Buchstabe ist klein, Großbuchstaben stehen an jedem Wortanfang. Also stellungBisher statt Stellung_bisher. Sieht komisch aus, erleichtert aber im Programmtext die Orientierung.
  • Konstanten werden über #define festgelegt und in GROSSBUCHSTABEN geschrieben. Du brauchst dafür keine Variable.
  • Auch eingerückte Zeilen sind nützlich. Innerhalb eines Blockes, der durch geschweifte Klammern gebildet wird, rückt man alles ein wenig nach rechts, so dass man gleich sieht, dass es eine untergeordnete Einheit bildet.


Gruß
Clemens

Mein Blog.


 
Der Ruinenbaumeister
EuroCity (EC)
Beiträge: 1.191
Registriert am: 01.04.2011


RE: Arduino - Weichensteuerung mit Servos

#3 von Bierrudl , 09.05.2014 10:44

Hallo, Ruinenbaumeister,

vielen Dank für Deine prompte Antwort und die grundsätzlichen Tipps darin.

Ich habe Deine Änderung in das Programm eingearbeitet mit folgendem Ergebnis:
1.) Wenn der Servo beim Ausschalten der Stromversorung in der "Stellung 1" ist (Kippschalter_Pin, HIGH),
bleibt der Servo auch beim Einschalten der Stromversorgung in der Stellung 1. Dies ist eine Verbesserung
zum bisherigen Stand: Hier hatte der Servo beim Einschalten von Stellung 1 zur Stellung 2 und wieder zurückgeschaltet.
2.) Wenn der Servo beim Ausschalten der Stromversorgung in der "Stellung 2" ist (Kippschalter_Pin, LOW);
schaltet der Servo beim Einschalten der Stromversorung in die Stellung 1 um und bleibt auch in dieser Stellung, solange
ich den Kippschalter nicht bediene.

Nachstehend vorsorglich nochmal das vollständige Programm mit Deiner eingearbeiteten Änderung:

#include <WProgram.h>

int myservo;

int Kippschalter_Pin = 0;//Betrifft Pin beim ATtiny 45
int Servo_Pin = 2;//betrifft Pin beim ATtiny 45
int Stellung1 = 28;// Servostellung 1 (einstellbar zwischen 0° und 180°)
int Stellung2 = 0;//Servostellung 2 (einstellbar zwischen 180° und 0°
int Stellung_bisher;//Für Vergleich
const int WARTEN = 19;//19 Millisekunden Warten nach Stellschritt. Nicht verändern!
void Servo_move(int servo,int Stellung_neu);

void setup()
{
pinMode(Kippschalter_Pin, INPUT);
digitalWrite(Kippschalter_Pin, HIGH);
pinMode(Servo_Pin, OUTPUT);

if(HIGH==digitalRead(Kippschalter_Pin)){
Stellung_bisher=Stellung1;
}else{
Stellung_bisher=Stellung2;
}
}

void loop()
{
if(digitalRead(Kippschalter_Pin)==HIGH)
Servo_move(Servo_Pin, Stellung1);
if(digitalRead(Kippschalter_Pin)==LOW)
Servo_move(Servo_Pin, Stellung2);
delay(20);
}

void Servo_move(int servo,int Stellung_neu)
{
int Schritt;
if(Stellung_neu==Stellung_bisher)return;
Schritt=(Stellung_neu>Stellung_bisher)?1:-1;
while(Stellung_bisher!=Stellung_neu){
Stellung_bisher+=Schritt;

digitalWrite(servo, HIGH);
delayMicroseconds((Stellung_bisher*8)+500);
digitalWrite(servo, LOW);
delay(WARTEN);
}
}

Hast Du hierfür eine Erklärung? Hängt dies evtl. mit der Zeile im "void Servo_move" zusammen, wo es heißt:
"if(Stellung_neu==Stellung_bisher)return;"?

Nochmal vielen Dank für Deine Hilfestellung.

Einen schönen Tag
Bierrudl


Bierrudl  
Bierrudl
S-Bahn (S)
Beiträge: 16
Registriert am: 23.12.2012


RE: Arduino - Weichensteuerung mit Servos

#4 von Der Ruinenbaumeister , 10.05.2014 09:00

Ja, die Zeile muss weg. Andernfalls werden keine Befehle an den Servo gesandt.

Probier mal das hier:

#include <WProgram.h>

#define KIPPSCHALTER 0
#define SERVOPIN 2
#define STELLUNG_1 28
#define STELLUNG_2 0
#define WARTEN 19

int myservo;
int stellungBisher;

void Servo_move(int servo,int Stellung_neu);

void setup(){
pinMode(KIPPSCHALTER, INPUT);
digitalWrite(KIPPSCHALTER, HIGH);
pinMode(SERVOPIN, OUTPUT);

if(HIGH == digitalRead(KIPPSCHALTER)){
stellungBisher = STELLUNG_1;
}else{
stellungBisher = STELLUNG_2;
}
}

void loop(){
if(HIGH == digitalRead(KIPPSCHALTER))
Servo_move(SERVOPIN, STELLUNG_1);
else
Servo_move(SERVOPIN, STELLUNG_2);
delay(20);
}

void Servo_move(int servo,int stellungNeu){
int schritt;
schritt = (stellungNeu > stellungBisher)?1:-1;
while(stellungBisher != stellungNeu){
stellungBisher += schritt;
digitalWrite(servo, HIGH);
delayMicroseconds((stellungBisher*8)+500);
digitalWrite(servo, LOW);
delay(WARTEN);
}
}

Du siehst, dass ich einige der Variablen durch #define ersetzt habe. Wenn dein Programm kompiliert wird, läuft erstmal der Präprozessor drüber und ersetzt alles, was oben definiert wurde durch den entsprechenden Wert. Anstelle von "WARTEN" in der vorvorletzten Zeile hättest du auch gleich "19" einsetzen können. Mit #define kannst du Korrekturen zentral vornehmen und musst nicht im Programmtext suchen, wo und wie oft du den Zahlenwert verwendet hast.

Den Zahlenwert als int-Variable zu definieren ist unnötig aufwendig. Die Werte bleiben ja, solange das Programm läuft, unverändert. Es reicht also, die festen Werte in den Programmtext einzutragen. Der Platz in den REgistern bleibt frei für die Variablen, die auch wirklich variabel sind.


Gruß
Clemens

Mein Blog.


 
Der Ruinenbaumeister
EuroCity (EC)
Beiträge: 1.191
Registriert am: 01.04.2011


RE: Arduino - Weichensteuerung mit Servos

#5 von Bierrudl , 10.05.2014 21:55

Hallo, Clemens,

vielen Dank für Deinen Sketch und die sehr hilfreichen Erläuterungen.

Ich habe den Sketch ausprobiert. Leider ändert sich das Verhalten des Servo ggü. meinen Angaben von gestern, 09. Mai, nicht.
Ich habe meine Schaltung überprüft; diese passt, soweit ich das beurteilen kann.
Evtl. liegt es an den verwendeten Servos selbst. Es sind relativ billige.

Ich bin schon froh, dass die Weichensteuerung mittels Servos überhaupt funktioniert.

Falls sich nicht noch etwas auftut, werde ich die Weichen einfach so stellen, dass sie beim Einschalten der Stromversorgung ruhig bleiben.
Ich habe nicht so viele Weichen.

Auf jeden Fall nochmals vielen Dank und ein schönes Wochenende wünscht

Bierrudl


Bierrudl  
Bierrudl
S-Bahn (S)
Beiträge: 16
Registriert am: 23.12.2012


RE: Arduino - Weichensteuerung mit Servos

#6 von michl080 , 11.05.2014 15:08

Hallo,

ich verwende keine Arduino software, also kann ich keine weiteren Details beisteurn ausser folgendem: Ich schicke keine Impulse zu den Servos, wenn sie sich nicht bewegen sollen. Konkret mache ich es mit meinen Atmegas so, dass die Timer, die die Impulse erzeugen, erst dann eingeschaltet werden, wenn der Servo sich in einen neue Postion bewegen soll. So liegen meine Servos immer ruhig und still an ihren Positionen.

Michael


meine Anlage findest Du unter viewtopic.php?f=64&t=65847


 
michl080
InterCity (IC)
Beiträge: 995
Registriert am: 21.11.2010


RE: Arduino - Weichensteuerung mit Servos

#7 von heidebahner ( gelöscht ) , 06.12.2014 01:28

Clemens,

da ich mich in die Programmierung noch nicht sehr weit eingearbeitet hab, mal ein paar Anfängerfragen :

wenn ich dein Programm richtig verstehe, steuerst du damit "nur" einen Servo an.

Was müßte man ändern, um damit weitere Servos (wieviele max ?) ansteuern zu können ?

Und wo werden Servos und Schalter angeschlossen ?

Danke für deine Hilfe.


heidebahner

RE: Arduino - Weichensteuerung mit Servos

#8 von Der Ruinenbaumeister , 06.12.2014 18:58

Hallo Jörg,

die Standardbibliothek des Arduino ist für bis zu 6 Servos zu gebrauchen. Es gibt auch die SoftwareServo-Bibliothek, die 12 oder gar 48 Servos steuern kann. Da stellen sich erstmal die Fragen: Wieviele Servoanschlüsse brauchst du? Welchen Arduino willst du verwenden? Welche Stromversorgung willst du nutzen? Welche Bedienelemente (Taster, Kippschalter, Reedkontakte etc.) willst du verwenden?

Ich werde im Moment aus dem Programm nicht schlau. Es wird eine Variable myservo gesetzt, die nicht ausgelesen wird; es wird ein Pin als Input deklariert und gleich darauf als Output angesteuert ... Das hätte mir eigentlich vor einem halben Jahr schon auffallen müssen. Ich würde das Programm nochmal neu schreiben, so dass es sich besser an mehrere Servos anpassen lässt. Das ist nicht kompliziert, ich brauche nur eine etwas klarere Vorstellung davon, wie der Anwendungsfall aussieht. Ich schlage vor, du beantwortest die obigen Fragen. Dann sehen wir weiter.


Gruß
Clemens

Mein Blog.


 
Der Ruinenbaumeister
EuroCity (EC)
Beiträge: 1.191
Registriert am: 01.04.2011


RE: Arduino - Weichensteuerung mit Servos

#9 von Nichteisenbahner ( gelöscht ) , 06.12.2014 19:44

Zitat von Der Ruinenbaumeister

  • Variablen werden als camelCases geschrieben, d.h. der erste Buchstabe ist klein, Großbuchstaben stehen an jedem Wortanfang. Also stellungBisher statt Stellung_bisher. Sieht komisch aus, erleichtert aber im Programmtext die Orientierung.
  • Konstanten werden über #define festgelegt und in GROSSBUCHSTABEN geschrieben. Du brauchst dafür keine Variable.
  • Auch eingerückte Zeilen sind nützlich. Innerhalb eines Blockes, der durch geschweifte Klammern gebildet wird, rückt man alles ein wenig nach rechts, so dass man gleich sieht, dass es eine untergeordnete Einheit bildet.


Hi,
das findich lustig, es erinnert mich an die Zeit, in der ich noch selbst programmiert habe.

  • Damals (90er?) stritten sich die Erneuerer, die die KamelSchreibWeise einführen wollten, mit den Bewahreren, die ihre Variablern anders_aber_genauso_gut_lesbar schrieben. Der Gipfel der Erneuerung war damals eine Schreibweise, die als ersten Buchstaben den Typ hatte, also ein int einfacher_zaehler wurde nicht etwa zum int EinfachenZaehler, sondern zum int iEinfachenZaehler. Ein Zeiger auf eine nullterminierte Folge von Characters wurde also pzsPointerAufZeroTerminatedString.
  • #define DAS_IST_EINE_NULL 0 war damals noch Standard und ohne Diskussion, heute aber liest man immer mehr, #defines gar nicht mehr zu benutzen. Ein const int nimmt auch nicht mehr Platz weg, da der Compiler ihn ohnehin "wegoptimiert".
  • Nur das mit dem Einrücken, das ist noch nicht in Verruf geraten. Das empfiehlt sich nach wie vor. Wenn man sich streiten will, dannn darüber, wo die geschweifte Klammer hingehört - mit eingerückt, oder nciht?

Ich hab mir übrigens auch einen Arduino zugelegt. Ich will einen Bahnübergang damit steuern. Es gibt da im Netz ein Projekt, mit dem kann der Arduino DCC lesen.
Schaun mer mal.
Aber nciht mehr vor Weihnachten.
Gruß
Martin


Nichteisenbahner

RE: Arduino - Weichensteuerung mit Servos

#10 von heidebahner ( gelöscht ) , 06.12.2014 23:44

Zitat von Der Ruinenbaumeister
Hallo Jörg,

die Standardbibliothek des Arduino ist für bis zu 6 Servos zu gebrauchen. Es gibt auch die SoftwareServo-Bibliothek, die 12 oder gar 48 Servos steuern kann. Da stellen sich erstmal die Fragen: Wieviele Servoanschlüsse brauchst du? Welchen Arduino willst du verwenden? Welche Stromversorgung willst du nutzen? Welche Bedienelemente (Taster, Kippschalter, Reedkontakte etc.) willst du verwenden?



Zu deinen Fragen :
in meinem Modulbahnhof gilt es 8 Servos anzusteuern. Es können ruhig zwei Arduinos eingesetzt werden. Es würde also die Standartbibliothek reichen. Wenn der UNO reicht, nehm ich den.
Jede Weiche soll mit 1 oder zwei Tastern betätigt werden und jeweils 2 LEDs sollen die Weichenlage anzeigen. Stromversorgung über extra 5V-Netz. Es stünden aber auch 12V zur Verfügung.

Zitat von Der Ruinenbaumeister
Ich werde im Moment aus dem Programm nicht schlau. Es wird eine Variable myservo gesetzt, die nicht ausgelesen wird; es wird ein Pin als Input deklariert und gleich darauf als Output angesteuert ... Das hätte mir eigentlich vor einem halben Jahr schon auffallen müssen. Ich würde das Programm nochmal neu schreiben, so dass es sich besser an mehrere Servos anpassen lässt. Das ist nicht kompliziert, ich brauche nur eine etwas klarere Vorstellung davon, wie der Anwendungsfall aussieht. Ich schlage vor, du beantwortest die obigen Fragen. Dann sehen wir weiter.


Danke für deine Hilfe.


heidebahner

RE: Arduino - Weichensteuerung mit Servos

#11 von Der Ruinenbaumeister , 07.12.2014 14:09

Ich würde dir folgendes vorschlagen: Ansteuerung über Kippschalter statt Tastern, LEDs auch über den Kippschalter gesteuert. Dann brauchst du nur sechzehn Ports und kommst mit einem Arduino Uno aus.

Wenn es bei Tastern bleiben soll, braucht es pro Servo [s]vier[/s] drei Ports: zwei für die Taster und die LEDs, einen für die Servos selbst. Du bräuchtest dann zwei Arduinos. Ich würde in dem Fall gleich dazu übergehen, für je zwei Servos einen ATTiny zu verwenden. Die können mit dem Arduino Uno programmiert werden und sind weit günstiger in der Anschaffung.

Welche Methode ist dir lieber?


Gruß
Clemens

Mein Blog.


 
Der Ruinenbaumeister
EuroCity (EC)
Beiträge: 1.191
Registriert am: 01.04.2011


RE: Arduino - Weichensteuerung mit Servos

#12 von digi_thomas2003 , 07.12.2014 20:17

Hallo Clemens,

Zitat von Der Ruinenbaumeister
...
Es wird eine Variable myservo gesetzt, die nicht ausgelesen wird;
...


Stimmt, ist mir auch aufgefallen.

Zitat von Der Ruinenbaumeister
...
es wird ein Pin als Input deklariert und gleich darauf als Output angesteuert
...


Damit wird der interne PullUp-Widerstand des Arduino für den besagten Pin aktiviert.

Ansonsten werde ich das Programm demnächst auch mal austesten.

Freundliche Grüße
Thomas


Thomas
------------------
Anlage H0: U-Form, im kreativen Bau
Fahren: Tams MC
Schalten: IB
Melden: HSI 88
Steuern: TrainController 9.0 Gold
Denken: Brain 4.1


 
digi_thomas2003
InterRegioExpress (IRE)
Beiträge: 305
Registriert am: 03.05.2005
Gleise sind vorhanden
Spurweite H0
Steuerung TrainController
Stromart AC, Digital


RE: Arduino - Weichensteuerung mit Servos

#13 von heidebahner ( gelöscht ) , 07.12.2014 20:54

@Clemens,

es soll bei Tastern und LEDs bleiben.
Das mit den ATtinys hört sich in sofern noch interessanter an, weil es besser zu Verteilung der Weichen auf die 4 Modulkästen passt und den Verkabelungsaufwand geringer hielte.

Thomas,
was bewirkt dieser pullup-Widerstand ?


heidebahner

RE: Arduino - Weichensteuerung mit Servos

#14 von digi_thomas2003 , 07.12.2014 21:03

Hallo Jörg,

Zitat von heidebahner
...
Thomas,
was bewirkt dieser pullup-Widerstand ?



In Zusammenhang mit einem Schalter bzw. Taster: Bei offenem Taster liegt die Versorgungsspannung des Arduinos (+ 5V) über den PullUp-Widerstand am Eingangspin des Mikrocontrollers an (HIGH) und nicht irgendein undefinierter Zustand.
Wird der Taster/Schalter geschlossen, wird der Pin sofort mit dem Massepotential verbunden (LOW).

Wenn Du mehr dazu wissen willst: http://www.elektronik-kompendium.de/publ...aerer/pullr.htm

HTH

Freundliche Grüße
Thomas


Thomas
------------------
Anlage H0: U-Form, im kreativen Bau
Fahren: Tams MC
Schalten: IB
Melden: HSI 88
Steuern: TrainController 9.0 Gold
Denken: Brain 4.1


 
digi_thomas2003
InterRegioExpress (IRE)
Beiträge: 305
Registriert am: 03.05.2005
Gleise sind vorhanden
Spurweite H0
Steuerung TrainController
Stromart AC, Digital


RE: Arduino - Weichensteuerung mit Servos

#15 von heidebahner ( gelöscht ) , 07.12.2014 21:22

Danke dir, Thomas.


heidebahner

RE: Arduino - Weichensteuerung mit Servos

#16 von Der Ruinenbaumeister , 09.12.2014 09:58

Hier ist das Programm, mit dem du bis zu sechs Servos mit einem Arduino ansteuern kannst. Leider funktionieren hier keine Einrückungen, was das Ganze etwas unübersichtlich macht.

#include <Servo.h>
#include <EEPROM.h>

#define SERVOS 2 // Anzahl der angeschlossenen Servos
#define VSERVO 5 // Anschluss an Servo-Versorgungsspannung. Analog-Pin!
#define VCC_SERVO_MIN 512

Servo myservo[SERVOS];
byte servoZiel[SERVOS];
byte servoPos[SERVOS];
byte servoMax[] = {150, 150, 150, 150, 150, 150};
byte servoMin[] = {30, 30, 30, 30, 30, 30};
int inputMaxPin[] = {0,2,7,12,A0,A2};
int inputMinPin[] = {1,4,8,13,A1,A3};
int servoPin[] = {3,5,6,9,10,11,};

void setup()
{
for(int i = 0; i < SERVOS; i++){
//Initialisierung der Servos
myservo[i].attach(servoPin[i]);

//Laden der Position und des Ziels
servoPos[i] = EEPROM.read(i);
servoZiel[i] = EEPROM.read(i+SERVOS);

//Falls kein gültiger Wert im Speicher hinterlegt ist:
if(servoZiel[i] != servoMin[i] && servoZiel[i] != servoMax[i]) servoZiel[i] = servoMin[i];

//Konfiguration der Tastereingänge
if (servoZiel[i] == servoMax[i]){
pinMode(inputMaxPin[i], OUTPUT);
digitalWrite(inputMaxPin[i], LOW);
pinMode(inputMinPin[i], INPUT);
} else {
pinMode(inputMinPin[i], OUTPUT);
digitalWrite(inputMinPin[i], LOW);
pinMode(inputMaxPin[i], INPUT);
}
}
}

void loop()
{
// Auslesen der Taster
for(int j = 0; j < 15; j++){
for(int i = 0; i < SERVOS; i++){
if(servoMin[i] == servoZiel[i] && LOW == digitalRead(inputMaxPin[i])){
servoZiel[i] = servoMax[i];
pinMode(inputMaxPin[i], OUTPUT);
digitalWrite(inputMaxPin[i], LOW);
pinMode(inputMinPin[i], INPUT);
} else if (servoMax[i] == servoZiel[i] && LOW == digitalRead(inputMinPin[i])){
servoZiel[i] = servoMin[i];
pinMode(inputMinPin[i], OUTPUT);
digitalWrite(inputMinPin[i], LOW);
pinMode(inputMaxPin[i], INPUT);
}
}
delay(1);

// Überprüfung der Betriebsspannung und ggf. Speichern
if (VCC_SERVO_MIN > analogRead(VSERVO)){
for(int i = 0; i < SERVOS; i++) {
if (EEPROM.read(i) != servoPos[i]) EEPROM.write(i, servoPos[i]);
if (EEPROM.read(i+SERVOS) != servoZiel[i]) EEPROM.write(i+SERVOS, servoZiel[i]);
}
while(VCC_SERVO_MIN > analogRead(VSERVO));
}
}

// Festlegen der Servoposition und Ansteuern der Servos
for(int i = 0; i < SERVOS; i++){
if(servoPos[i] < servoZiel[i]) servoPos[i]++;
if(servoPos[i] > servoZiel[i]) servoPos[i]--;
myservo[i].write(servoPos[i]);
}
}


Zum Prinzip: Anstatt für jeden Servo die Befehle einzeln vorzugeben, habe ich alle nötigen Variablen in Arrays gespeichert. Alle for-Schleifen mit der Variablen int i werden für jeden Servo einmal durchlaufen. Die Anschläge sind in servoMax[] und servoMin[] vorgegeben. Man kann für jeden Servo eigene Werte einstellen, muss aber nicht.

Die Tastereingänge sind in inputMaxPin[] und inputMinPin[] angelegt. Sie dienen gleichzeitig als LED-Ausgänge. Dazu eine kleine Schaltskizze:



Der Taster für die aktuelle Position ist immer inaktiv. Der Ausgang wird auf LOW gesetzt, daher leuchtet die LED. Der Taster für die alternative Position ist als Eingang konfiguriert. Wegen der LED, die so natürlich nicht leuchtet, liegen an ihm stets 5V an; es sei denn, es wird der Taster gedrückt; dann sind es 0V, was als Stellbefehl erkannt wird.

Wenn ein Befehl erkannt wurde, wird erstmal servoZiel[] angepasst. Damit wird dem Servo seine Endlage vorgegeben. Damit er diese nicht ruckartig anfährt, wird die Sollposition separat in servoPos[] gespeichert und langsam nachgeführt. Beide Werte werden bei Bedarf gespeichert, so dass sie nach einem Neustart sofort wieder verfügbar sind.

Natürlich wird nicht ständig gespeichert, da wäre die Zyklenzahl des EEPROM schnell erreicht. Stattdessen wird erst dann gepeichert, wenn die Anlage ausgeschaltet wird. Und das geht folgendermaßen:

1. Die Spannungsversorgung von Arduino und Servos wird getrennt, beispielsweise indem der Arduino mit einem eigenen Netzteil oder aus dem vorhandenen 12V-Netz gespeist wird.

2. Die Servos werden aus dem vorhandenen 5V-Netz gespeist. Dieses ist über den port A5 mit dem Arduino verbunden. So kann jederzeit die Servospannung ausgelesen werden. Falls im 5V-Netz die Spannung zusammenbricht, sieht der Arduino das als Signal, sofort die aktuellen Servopositionen zu speichern.

3. Damit dem Arduino genug Zeit zum Speichern bleibt, muss er entweder später ausgeschaltet werden als das 5V-Netz oder er muss mit einem ausreichend dimensionierten Pufferkondensator versehen werden. Wie groß dieser ist, hängt von der Last durch die LEDs ab. Ich würde einen Goldcap einsetzen.

Da ich keinen passenden ATTiny zum Ausprobieren bei mir herumliegen habe, werde ich jetzt keine Variante für diesen posten. Die Anpassung dürfte aber nicht kompliziert sein. Die Servobibliothek muss auf SoftwareServo umgestellt werden und der Befehl SoftwareServo::refresh(); eingefügt werden, am besten am Ende von loop(). Natürlich kann ein ATTiny45 nur einen oder zwei Servos ansteuern und die Pinbelegung muss angepasst werden.

Aber damit genug für heute.


Gruß
Clemens

Mein Blog.


 
Der Ruinenbaumeister
EuroCity (EC)
Beiträge: 1.191
Registriert am: 01.04.2011


RE: Arduino - Weichensteuerung mit Servos

#17 von heidebahner ( gelöscht ) , 09.12.2014 10:57

Vielen Dank, Clemens

Da muß ich mich erst mal richtig reinlesen.

Allerdings ergeben sich gleich zwei Fragen.

Müßte nicht die Variable SERVOS in der dritten Zeile auf 6 statt auf 2 stehen ?

Und reicht ein 1F, 5,5V Goldcap ?


heidebahner

RE: Arduino - Weichensteuerung mit Servos

#18 von Der Ruinenbaumeister , 09.12.2014 11:01

Bei SERVOS trägst du soviele Servos ein, wie du nutzen willst.

1F sollte auf jeden Fall ausreichen.

Was ich noch erwähnen sollte: Die GND-Pins von Arduino und Servo-Spannungsversorgung müssen miteinander verbunden sein. Falls du keine potentialfreie Spannungsversorgung (also kein eigenes Netztei) für den Arduino hast, dann sollten wir uns deine Spannungsversorgung etwas genauer ansehen. Sonst kann es unerwünschte Nebeneffekte geben.


Gruß
Clemens

Mein Blog.


 
Der Ruinenbaumeister
EuroCity (EC)
Beiträge: 1.191
Registriert am: 01.04.2011


RE: Arduino - Weichensteuerung mit Servos

#19 von heidebahner ( gelöscht ) , 09.12.2014 11:25

Dann hab ich die Variable ja richtig interpretiert.

Danke für den Tip mit dem Gnd-Pins. Ich habe ein Steckernetzteil 5V, 1500mA für meinen Arduino gekauft.

Das wollte ich dafür nutzen. Sollte ja dicke reichen.


heidebahner

RE: Arduino - Weichensteuerung mit Servos

#20 von Nichteisenbahner ( gelöscht ) , 09.12.2014 19:00

Hallo,
ich bin nach dem oben erwähnten Projekt gefragt worden, wo der Arduino das DCC-Signal interpretiert.

Die Grundlagen dazu werden hier in diesem Projekt gelegt. Hier wird das DCC-Signal gelesen, aber noch nicht ausgewertet:
http://www.mynabay.com/arduino/2-uncateg...ino-dcc-monitor
Notabene: Man braucht einen High-Speed-Optokoppler als zusätzliches Bauteil.

In diesem zweiten Projekt, das auf dem erstgenannten aufbaut, wird dann das DCC-Signal auch ausgewertet, um damit einen oder nehrere Servos oder anderes anzusteuern.
https://rudysmodelrailway.wordpress.com/...nction-decoder/

Ich wollte das mal ausprobieren, aber weiter als bis zum Bestellen der besonderen Optokoppler bin ich noch nicht gekommen

Gruß
Martin


Nichteisenbahner

RE: Arduino - Weichensteuerung mit Servos

#21 von Der Ruinenbaumeister , 09.12.2014 20:47

Ich will mich auch schon länger diesem Programm widmen, um es als Basis für eigene Projekte zu nutzen. Dazu gehört dann auch eine neue Hardware - quasi als Alternative zum WeichEi oder SandEi und mit Zugriff auf die umfangreichen Bibliotheken des Arduino.


Gruß
Clemens

Mein Blog.


 
Der Ruinenbaumeister
EuroCity (EC)
Beiträge: 1.191
Registriert am: 01.04.2011


RE: Arduino - Weichensteuerung mit Servos

#22 von digi_thomas2003 , 09.12.2014 22:45

Hallo Martin,

Zitat von Nichteisenbahner
...
Ich wollte das mal ausprobieren, aber weiter als bis zum Bestellen der besonderen Optokoppler bin ich noch nicht gekommen
...



da bist Du aber schon deutlich weiter als ich...
Ich bin derzeit noch dabei, die Library und den Code des zweiten Projektes zu analysieren.

Und dann gibt es ja noch TC...

Freundliche Grüße
Thomas


Thomas
------------------
Anlage H0: U-Form, im kreativen Bau
Fahren: Tams MC
Schalten: IB
Melden: HSI 88
Steuern: TrainController 9.0 Gold
Denken: Brain 4.1


 
digi_thomas2003
InterRegioExpress (IRE)
Beiträge: 305
Registriert am: 03.05.2005
Gleise sind vorhanden
Spurweite H0
Steuerung TrainController
Stromart AC, Digital


RE: Arduino - Weichensteuerung mit Servos

#23 von tom75 , 10.12.2014 12:53

Hallo Martin,

vielen Dank für die Links. ich werd mir das auch mal zu Gemüte führen und in einer ruhigen Minute mal ausprobieren. Die Frage ist, ob man das auch mit nem Attiny oder atmega quasi standalone machen kann. Aber so wie es in dem einen Video heißt sind die Arduino Unos aus Fernost ja mittlerweile so preiswert, das sich das wohl gar nicht mehr rechnen wird..... auf jeden Fall eine spannende Sache

Grüße

Tom75


Schaut doch auch mal bei mir vorbei ;)

Aktuelle Anlage:
http://stummiforum.de/viewtopic.php?f=64&t=123785

Alte Anlage Kellerhausen
viewtopic.php?f=64&t=87438


tom75  
tom75
InterCity (IC)
Beiträge: 625
Registriert am: 08.01.2013
Gleise Märklin K-Gleis
Spurweite H0
Stromart AC


   


  • Ähnliche Themen
    Antworten
    Zugriffe
    Letzter Beitrag
Xobor Einfach ein eigenes Forum erstellen
Datenschutz