Juhu, hier ist mal wieder der Moba-Opa. Ich habe meine alte Märklin H0 mit K-Gleis aus den Kinder und Jugendtagen aufgebaut. Habe alle meine Loks digitalisiert und fahre dies mit einere MS2. Dei Gleisanlage aber will ich weiterin analog betreiben. Für die Weichenantriebe, Beleuchtung usw. benutze ich den Trafo eines ausgedienten Laptops mit 19,4V. Soweit funktioniert inzwischen "fast " alles so wie ich es auch wollte.
Jetzt aber. Habe ein paar Servos für Lokschuppen und Bahnschranken eingebaut die ich mit dem Arduino über Taster ansteuere. Habe den Sketch soweit, dass sich die Servos auch so wie gewünscht bewegen.
Problem ist: Wenn ich die Anlage neu einschalte und den Servo das erste mal schalte und ebenso wenn ich aus versehen den zuvor betätigen Taster nochmals betätige rast der Servo in der urspünglichen Geschwindigkeit in seine Ausgangsposition zurück.
Hat jemand einen Tip oder ein Beispiel wie man das im Sketch verhindern kann. Würde mich riesig freuen wenn mir da jemand aus dem Form helfen könnte.
Ohne dein Programm im Detail zu kennen: 1. Einen Locking-Mechnismus einbauen der während das Servo läuft weitere Eingaben für dieses Servo blockiert. Vermutlich zählst du die Variable für die Servo-Position hoch bzw. runter um die Geschwindigkeit der Bewegung zu steuern, also einfach solange bis der Zielwert erreicht ist Eingaben ignorieren. 2. In der init()-Funktion für alle Positionsvariablen Start-Werte definieren, erst danach die Servos initialisieren. Eventuell ein externes EEPROM anbinden in dem jeweils die aktuellen Servo-Positionen gespeichert werden und die beim Initialisieren genutzt werden. Externes EEPROM deshalb weil das Internet der Arduinos nicht sooo viele Schreibzyklen verdaut.
vielen dank für den Tip und die schnelle Antwort. Den einen Teil habe ich irgendwie lösen können. Als das mit dem hintereinander betätigen des selben Tasters ist jetzt für mich gelöst. Was bleibt ist noch das schnelle zurückfahren des Servos beim Einschalten der Anlage. Das mit dem EEPROM hab ich versucht, kriegs aber nicht gebacken.
Bin halt noch ein blutiger Anfänger mit Arduino und der Programier -sprache -technik. Meine Progamierkenntnisse als Opa basieren noch auf den alten PC's mit BASIC, Lotus, -EXCEL.
Ich kopiere mal den Sketch unten an diese Nachricht. Vielleicht gibts nochmal einen guten Rat. Gruss Peter
// Sketch überarbeitet zurlangsamen Steuerung der Servos mit Taster und LED's. // Problem: Beim Einschalten ruckt der Servo zu schnell auf Ausgangsposition. // Das zweite Problem mit der zweimaligen Betätigung der selben Tast ist gelöst.
int T1 = 5; //Definition Taster "T1" hängt an pin 5 int T2 = 6; //Definition Taster "T2" hängt an pin 6 int LED1 = 7; //Definition "LED1" hängt an pin 7 int LED2 = 8; //Definition "LED2" hängt an pin 8 int pos_min = 0; //Servo position 1 Definition (in grad) int pos_max = 120; //Servo position 2 Definition (in grad) int pos_act = 0; //Aktuelle Servo positions variable int ismax = 0; Servo schranke; // Servo objekt "schranke" erstellen
void setup() { schranke.attach(9); // servo objekt "schranke" an pin nummer 9 verknüpfen pinMode(T1, INPUT); // Taster "T1" als input definiert pinMode(T2, INPUT); // Taster "T2" als input definiert pinMode(LED1, OUTPUT); // Taster "LED1" als input definiert pinMode(LED2, OUTPUT); // Taster "LED2" als input definiert digitalWrite(LED2, LOW); // Damit beim Start nur eine LED an ist digitalWrite(LED1, HIGH); // Damit beim Start nur eine LED an ist }
void loop() { if ((digitalRead(T1) == HIGH) && (digitalRead(T2) == LOW) && (ismax != 1)) { //sicherstellen das nicht bei gleichzeitig "True" sein können digitalWrite(LED2, LOW); //LEDs nach Laune setzen digitalWrite(LED1, HIGH); //LEDs nach Laune setzen
for (int pos_act = pos_min; pos_act < pos_max; pos_act++) { //solange "pos_act" > als pos_min ist, verringere pos_act um Wert "1" schranke.write(pos_act); //schreibe bei jedem "for" durchlauf den Wert "pos_act" raus auf das servo objekt "schranke" delay(20); //delay verlangsamt nach Wert die "for" Schleife. Höherer delay. Langsamere Servo Bewegung } ismax = 1; }
if ((digitalRead(T2) == HIGH) && (digitalRead(T1) == LOW) && (ismax != 2) ) { digitalWrite(LED1, LOW); digitalWrite(LED2, HIGH); for (int pos_act = pos_max; pos_act > pos_min; pos_act--) { //solange "pos_act" < als pos_max ist, erhöhe pos_act um Wert "1" schranke.write(pos_act); delay(20); } ismax = 2; } }
Zitat von Stahlblauberlin im Beitrag #2Eventuell ein externes EEPROM anbinden in dem jeweils die aktuellen Servo-Positionen gespeichert werden und die beim Initialisieren genutzt werden. Externes EEPROM deshalb weil das Internet der Arduinos nicht sooo viele Schreibzyklen verdaut.
Ich hab ja keine Idee, welcher Controller hier Verwendung findet. Arduino ist eine Entwicklungsumgebung, mit der ein ganzer Zoo von Controller-Familien betrieben werden kann. Gehen wir aber mal nur zum Beispiel von einem AVR aus, dann sagt das Datenblatt 100.000 Lösch-Zyklen. (Atmega8515/Attiny85/und die meisten anderen auch ), Ich vermute mal, daß der Servo bereits bei 1/10 der EEPROM Zyklen schon völlig in Einzelteile zerfallen ist :-)
Abgesehen davon kann man auch mehrere EEPROM-Zellen zum Speichern verwenden, was dann entsprechend ein vielfaches der Zyklen ergibt. Einfach jedes Byte bitweise benutzen und dann mehrere Bytes zusammen fassen. Da Endstellung links/rechts ja nur ein bool ist, kann man ziemlich banal einfach über alle gesetzten Bits ausrechnen, ob die Summe aller Bits gerade oder ungerade ist und schon ist das Thema erledigt. Damit dürfte man dann locker die Lebenszeit des Anwenders erreichen :-)
Also überhaupt kein Grund externe Hardware zu nutzen, wenn man auch Software verwenden kann!
Zum EEprom: - Wert nur Schreiben wenn er sich vom gespeicherten unterscheidet. Also erst lesen, dann wenn nötig schreiben. (Das Servo wird in den allermeisten Fällen ja in einer der Endstellungen stehen.)
- Man kann nach x Schreibzyklen die Speicherzelle wechseln. Das erhöht nochmals die Gesamtlebensdauer um ein vielfaches.
Zum Programm: - Delay hat (außer im allerersten Blink-Programm) in einem Programm nichts verloren. Es funktioniert zwar, wenn man nichts anderes tun will oder muss. Aber in der jetzigen Fassung kann man so nur ein einziges Servo betreiben und sonst absolut nichts, da das Programm 99.99% der Zeit einfach wartet!
Zum Ruckeln generell: - Manche billigen Servos ruckeln einfach beim anlegen der Versorgungsspannung. Evtl. mal anderes Servo testen oder Servo erst mit Spannung versorgen, wenn die Lage stabil ist und gültige Pulse bereitstehen. Pins sind ja noch genügend frei.
1. Delay() umgehen in dem man mittels millis() eine Verzögerung baut. long Startzeit,0; . . if (millis()>Startzeit+20){ Startzeit=millis(); Tue_etwas_sinnvolles; } 2. Externe EEPROMs wie 24c01 werden per i2c angebunden, gibt's fertige Bibliotheken für die einem viel Arbeit abnehmen.