BeneluxSpoor.net forum
Vraag en antwoord => Elektronica en analoog => Topic gestart door: Hans Mol op 27 July 2017, 21:30:32
-
Beste mensen,
Allereerst wil beginnen met de mededeling dat ik echt een beginner ben met Arduino. Heb al wel heel veel tutorials gevolgd maar daarmee ben je nog geen deskundige.
Wat ik wil doen is een servo de opdracht geven om na het indrukken van een button 180 graden te draaien en te wachten tot de volgende druk op de button waarna de servo weer 180 graden terugdraait.
Nu ben ik op zoek naar een sketch hiervoor maar kan deze nergens op het internet vinden. Heeft iemand deze functie al werkend middels een Arduino?
Zo ja zou iemand die skegtch willen delen?
Alvast bedankt!
Hans
-
Heeft je vraag te maken met het laten draaien van poppetjes op het perron? (Mijn)Artikel uit het laatste blad van De Modelbouwer?
Over servo's staat veel in de encyclopedie. En er is een apart draadje over de Arduino en de programmeertaal Mardec (zie onder digitaal).
Ronald Visser
-
Ehhh.... dit is niet echt moeilijk... 10 of 20 regels code. Vooral gedoe met contact dender van de knop...
Wat wil je? Dat iemand het precies voorkauwt en je het resultaat stuurt of dat iemand je het voordoet?
Het eerste is met testen een uurtje werk, voor het tweede is het wel zo handig om samen te zitten.
Als je het wilt begrijpen en er wat van leren is de tweede methode wel de manier...
-
Nee, ik wil gewoon een servo gebruiken voor het openen en dichtdoen van loodsdeuren middels een push button aangestuurd door een Arduino Uno. :)
En ja HansQ. Ik ben op zoek naar een pasklare oplossing. Vandaar mijn zoektocht naar een sketch ;)
-
Gewoon gaan spelen met de Arduino. Er staan standaard voorbeeld programma's in om een servo te bewegen. Ook zijn er voorbeeld programma's om een knopje iets te laten doen. Deze met elkaar combineren en in het begin gaat het misschien fout maar uiteindelijk zal je je zelfgemaakte/aangepaste programma aan het draaien hebben.
Succes,
Frits
-
... Arduino en de programmeertaal Mardec
'Mardec' is geen programmeertaal voor de Arduino.
... ik wil gewoon een servo gebruiken voor het openen en dichtdoen van loodsdeuren middels een push button aangestuurd door een Arduino Uno.
Hoe hard is die eis? Je kunt ook iets eenvoudigs maken met een motortje, twee microschakelaars en een schuif- of tuimelschakelaar, of een servo met een 555.
-
Je zou er de adServo sketch voor kunnen pakken als je gewoon iets wilt hebben dat werkt :)
In de basis allemaal niet zo lastig.Maar inderdaad state change detection, ontdenderen enz. En ik denk niet dat je die 180 graden draai in TGV snelheid wilt doorlopen ;D Als je daar niet iets voor maakt zal de servo gewoon proberen zo snel mogelijk de nieuwe positie te bereiken.
Timo
PS Heb ik het najaar hopelijk weer wat tijd op adServo weer eens van een update te voorzien :) Dan volgt hopelijk ook eindelijk het d-deel (digital) ::) ;D
-
// Zoiets, nog niet getest met hardware:
#include <Servo.h>
Servo servo; // servo object, wordt op pin 3 gezet
int swtch; // switch pin, word op pin 4 gezet
int led; // onboard LED, zit altijd op pin 13
int hoek; // de hoek voor de servo, 0 of 180 graden
int test1; // eerst test van de switch pin toestand
int test2; // tweede test van de switch pin toestand
int test3; // derde test van de switch pin toestand
int dender; // aantal msec delay voor contact dender
int pressed; // bijhouden of de schakelaar al is ingedrukt
//NB: Servo aansluiten op massa (bruin), +5V (rood) en pin 3 (oranje).
// Switch aansluiten op massa en pin 4, met een pull-up van 1K of 10K naar +5V.
void setup() {
servo.attach(3);
swtch = 4;
led = 13;
hoek = 0;
test1 = 1;
test2 = 1;
test3 = 1;
dender = 10; // XX msec
pressed = 0;
pinMode(swtch, INPUT);
pinMode(led, OUTPUT);
digitalWrite(led, 0);
servo.write(hoek);
}
void loop() {
delay(10); // wacht XX msec om contact dender te vermijden
test1 = digitalRead(swtch); // lees de switch toestand
delay(10); // wacht XX msec om contact dender te vermijden
test2 = digitalRead(swtch); // lees de switch toestand
delay(10); // wacht XX msec om contact dender te vermijden
test3 = digitalRead(swtch); // lees de switch toestand
if ((test1 == 0) && (test2 == 0) && (test3 == 0)) { // switch is echt ingedrukt?
if (pressed == 0) { // indien niet eerder ingdrukt
pressed = 1; // nu dus wel
if (hoek == 0) { // verander de hoek
hoek = 180; // was 0, wordt 180
}
else {
hoek = 0; // was 180, wordt 0
}
}
}
else { // switch is losgelaten
pressed = 0; // switch niet langer ingedrukt.
}
servo.write(hoek); // updat de servo hoek
if (hoek == 180) {
digitalWrite(led, 1); // LED aan
}
else {
digitalWrite(led, 0); // LED uit
}
}
-
Verrek, ik begrijp wat Hans geschreven heeft! :o En ik heb al jaaaaren niet meer geprogrammeerd... Goh, dan zou zelfs ik met Arduino's kunnen spelen!
En nee, dat ga ik nu niet doen. Eerst Grasland afmaken...
-
Beste HansQ,
Dat heb je snel gedaan. Maar begrijp ik het goed dat in jouw sketch je de pushbutton wel vast moet houden totdat de servo zijn eindpunt bereikt heeft?
Misschien even ter ondersteuning. Bijgaand filmpje geeft aan wat ik wil bereiken
https://www.youtube.com/v/HQX-MEe5fe8
Voor zover, en zeker HansQ een ieder bedankt voor de aangedragen suggesties.
Vandaag aan het werk. Ik ga het komende weekend weer eens lekker spelen met de Arduino en kijken of ik e.e.a. kan realiseren.
Groeten,
Hans
-
Programmeertaal (decoder): weet ik, maar hoe leg je dat aan een ... (gebruiker) uit.
Ronald Visser
-
Ik begrijp dat je dit wilt (bijvoorbeeld):
...hoek is initieel 0 graden.
1e keer knop drukken: hoek naar 180 graden.
2e keer knop drukken: hoek naar 0 graden.
3e keer knop drukken: hoek naar 180 graden.
4e keer knop drukken: hoek naar 0 graden.
5e keer knop drukken: hoek naar 180 graden.
6e keer knop drukken: hoek naar 0 graden.
...
-
... begrijp ik het goed dat ... je de pushbutton wel vast moet houden totdat de servo zijn eindpunt bereikt heeft?
Nee, als je de knop kort indrukt (tenminste 30 msec) dan verandert de servo van stand 0° --> 180° of 180° ---> 0°.
Bij inschakelen draait de servo naar 0° (als die daar niet al stond).
De servo wordt wel constant aangestuurd, ook als de knop niet is ingedrukt, zou wat onrustig kunnen zijn. Er zou een extra loop ingebouwd kunnen worden waarbij de servo alleen wordt aangestuurd bij een verandering van de knopstand.
Als je de knop te lang ingedrukt houdt, draait de servo ook meteen weer terug, er zou nog een extra test (of delay) in moeten om te kijken of de schakelaar al weer losgelaten is.
(Het filmpje is niet te zien... :-( )
-
Hoi HansQ,
Dat is idd de bedoeling en dan in een in te stellen snelheid. Dat is volgens mij met de delay functie in te stellen.
@72sonett.
Hierbij een link naar het filmpje.
https://youtu.be/HQX-MEe5fe8 (https://youtu.be/HQX-MEe5fe8)
-
Neen. Als je de snelheid waarmee de servo beweegt wilt beïnvloeden wordt het en stuk complexer.
Om dat toe te passen moet je de materie goed begrijpen en dat is lastig via dit medium...
-
Neen. Als je de snelheid waarmee de servo beweegt wilt beïnvloeden wordt het en stuk complexer.
Om dat toe te passen moet je de materie goed begrijpen en dat is lastig via dit medium...
Begrijpen we elkaar goed! Met het instellen van de snelheid bedoel ik de notatie in de sketch (dus eenmalig bepalen van de snelheid) en niet dat je de snelheid van de servo tijdens het proces nog aan kan passen. Dus delay(15) wordt bijvoorbeeld delay(100). Dit werkt in de sweep sketch van Arduino wel.
-
Ehh. Nee. Zo werkt het niet... Zonder maatregelen wordt de snelheid van de servo bepaald door de mechanische eigenschappen van de servo zelf.
-
Het aanbrengen van een extra vertraging (rondsels/tandwieletje etc.) is ook een oplossing.
Ja, dat is dan wel een mechaniekje.
Ronald Visser
-
...
servo.write(hoek); // update de servo hoek
if (hoek == 180) {
digitalWrite(led, 1); // LED aan
}
else {
digitalWrite(led, 0); // LED uit
}
// toevoegen
delay (1000); // geef servo 1 sec om te verdraaien voordat indrukken knop weer effect heeft
//
}
-
Dit heeft geen zin... de servo wacht nergens op, het enige wat je hiermee bereikt is dat de knop slecht reageert.
-
Het is opgelost. Ik heb een prima sketch en uitleg gevonden op Fritzing.org dat precies doet wat ik wilde. Heb er even een filmpje van gemaakt en op YT geplaatst.
https://youtu.be/9UekVBVndJg (https://youtu.be/9UekVBVndJg)
De sketch met uitleg vind je hier:
http://fritzing.org/projects/arduino-servo-motor-control-with-pushbutton (http://fritzing.org/projects/arduino-servo-motor-control-with-pushbutton)
Het enige wat ik nog moet uitvogelen is hoe ik de stand van de servo kan bewaren wanneer de stroom er af is geweest. Moet iets zijn met een functie EEPROM.
Mogelijk iemand daar nog een advies in?
Voor zover iedereen bedankt voor jullie adviezen.
Hans
-
Dit heeft geen zin... de servo wacht nergens op, het enige wat je hiermee bereikt is dat de knop slecht reageert.
Als de knop langer dan 30 msec ingedrukt wordt, laat het programma de servo draaien, die heeft tijd nodig om naar de andere stand te draaien, maar het programma is zo snel dat er direct al weer naar de knop gekeken wordt en als die nog steeds ingedrukt is, wordt de servo alweer terug gedraaid.
De servo moet dus even tijd krijgen om te verdraaien, b.v. 1000 msec, en er moet even gewacht worden tot de knop losgelaten is, tenzij de servo.write(hoek) routine het programma al genoeg vertraagt.
Maar het is een non-probleem, de OP heeft blijkbaar al wat beters gevonden...
-
Hallo allemaal,
Of de gevonden oplossing beter is, kan ik niet beoordelen. In de gevonden oplossing wordt de servo afgeremd door deze per stap aan te sturen, en iedere stap een vertraging mee te geven.
Ik ben benieuwd of het daarmee mogelijk wordt de servo ook soepel te laten draaien, op lage snelheden, of dat het geheel toch schokkerig wordt.
Groet,
Tjalling
-
Ja, ik denk dat het schokkerig wordt hoewel het er in het filmpje wel goed uitziet.
De for .. lus wordt in 180 stappen doorlopen en in iedere stap wordt 15 msec gepauzeerd.
De hele beweging is dan tenminste 15 * 180 = 2700 msec, plus wat overhead = +/- 3000 msec = 3 seconden.
-
en in iedere stap wordt 15 msec gepauzeerd.
Hoi 72sonett. In de download van het script staat een delay van 15ms. Ik heb deze aangepast naar 100ms. Dat is wat je ziet op mijn filmpje. Misschien is het schokkerig maar dat is voor mij niet zichtbaar. Ik ben voor zover blij met het resultaat. Nu nog iets verzinnen dat de stand van de servo onthouden wordt bij een stroomonderbreking.
-
... Nu nog iets verzinnen dat de stand van de servo onthouden wordt bij een stroomonderbreking.
Zoiets?
(Compileert OK maar ongetest.)
#include <Servo.h>
#include <EEPROM.h>
const int servoPin = 8; // Servo pin
const int buttonPin = 9; // Pushbutton pin
const int LEDpin = 13; // LED pin op Arduino pcb
const byte del = 100; // vertraging servo
int directionState = 0;
Servo myservo;
byte pos;
// -------------------------------------------------
void draaiservo (byte hoek) {
myservo.write(hoek);
EEPROM.write(1,hoek); // schrijf servopositie naar adres 1 van de eeprom
delay(del); // wacht op servo
}
// -------------------------------------------------
void setup() {
myservo.attach(servoPin);
pinMode (buttonPin,INPUT);
pos = constrain (EEPROM.read(1), 0, 180); // lees oude servopositie uit adres 1 van de eeprom
draaiservo(pos); // draai naar oude positie binnen bereik 0..180°
}
// -------------------------------------------------
void loop(){
digitalWrite (LEDpin, directionState); // LED aan of uit
if (digitalRead (buttonPin) == HIGH) // alleen als knop ingedrukt
if (directionState == 0) { // stand is 0, draai servo naar 180°
for (pos = 0; pos < 180; pos += 1)
draaiservo(pos);
directionState = 1; // stand is nu 1 (180°), volgende keer naar 0° draaien
}
else { //(directionState == 1) // stand is 1 (=180°), draai servo naar 0°
for (pos = 180; pos>=1; pos -=1)
draaiservo(pos);
directionState = 0; // stand is nu 0, volgende keer naar 180° draaien
}
}
Maar eigenlijk hoef je de stand niet op te slaan want de servo blijft bij onderbreking gewoon in de oude stand staan en draait bij de eerstvolgende druk op de knop altijd naar 0°.
-
@Hans Mol, je weet dat ik je reactie 6 ook al naar een prima werkende sketch had aangedragen? ;) Werkt voor 4 servo's. Toegegeven, ik had het makkelijker kunnen maken met een linkje (https://forum.beneluxspoor.net/index.php/topic,61213.msg3221534127.html#msg3221534127) (en beschrijving (https://forum.beneluxspoor.net/index.php/topic,61213.msg3221545054.html#msg3221545054)). Niet dat ik per se mijn software wil pushen maar dan was de discussie dan afgelopen geweest ;D
Timo
-
Hoi 72sonett,
Ik heb je sketch zojuist ingevoerd. Het werkt prima maar inderdaad 1 kant op . In de 180 graden stand gaat hij na een contactherstel bij een druk op een knop snel naar de 0 stand. Vanuit de 0-stand werkt het prima na een contactherstel.
Bedankt voor alle moeite die je er voor doet. Ik ben er nu al erg blij mee.
Is het misschien ook te regelen dat hij ook in de 180 graden stand na een contactherstel en een druk op de knop langzaam naar de 0 gaat? Misschien vraag ik teveel maar weet dat je mij inmiddels al heel blij gemaakt hebt.
Het is in ieder geval voor mij een prima werkbare situatie.
PS: wanneer de stroom er weer op komt zie je de servoarm wel even op en neer gaan. Is dat wat men noemt het denderen??
Is daar iets aan te doen??
Groeten,
Hans
-
Wel "ouderwets" >>> een vertragings mechaniekje ??
Ronald
-
... Is het misschien ook te regelen dat hij ook in de 180 graden stand na een contactherstel en een druk op de knop langzaam naar de 0 gaat?
Probeer deze eens:
#include <Servo.h>
#include <EEPROM.h>
const int servoPin = 8; // Servo pin
const int buttonPin = 9; // Pushbutton pin
const int LEDpin = 13; // LED pin op Arduino pcb
const byte del = 100; // vertraging servo
int directionState;
Servo myservo;
byte pos;
// -----------------------------------[ subroutines ]--------------
void draaiservo (byte hoek) {
myservo.write(hoek); // draai servo naar opgegeven hoek
EEPROM.write(1,hoek); // schrijf servohoek naar adres 1 van de eeprom
delay(del); // wacht op servo
}
// -----------------------------------[ init ]--------------
void setup() {
byte oudestand;
pinMode (servoPin,OUTPUT);
pinMode (buttonPin,INPUT);
pinMode (LEDpin,OUTPUT);
myservo.attach(servoPin);
oudestand = constrain(EEPROM.read(1), 0, 180); // lees oude servopositie uit adres 1 van eeprom
for (pos = oudestand; pos = 0; pos--) // draai servo langzaam naar 0°
draaiservo(pos);
directionState = 0;
}
// ------------------------------------[ hoofdprog ]-------------
void loop(){
digitalWrite (LEDpin, directionState); // LED aan of uit
if (digitalRead (buttonPin) == HIGH) // alleen als knop ingedrukt
if (directionState == 0) { // stand is 0, draai servo naar 180°
for (pos = 0; pos = 180; pos++)
draaiservo(pos);
directionState = 1; // stand is nu 1 (180°), volgende keer naar 0° draaien
}
else { //(directionState == 1) // stand is 1 (=180°), draai servo naar 0°
for (pos = 180; pos = 0; pos--)
draaiservo(pos);
directionState = 0; // stand is nu 0, volgende keer naar 180° draaien
}
}
// -------------------------------------- [ einde ] ------------
Contactdender van de schakelaar maakt hier niet uit, bij de eerste keer 'hoog' van de schakelaar gaat de servo draaien, tegen de tijd dat de servo klaar is, is de schakelaar al losgelaten of uitgedenderd.
Het bewegen van de servo bij inschakelen ligt aan de servo, zie ook de discussie hierover in het Mardec topic.
-
72sonett
Nee, deze werkt niet. Bij druk op de knop gaat hij snel naar 180 graden en doet verder niets meer.
Groeten,
Hans
-
Met een druktoets de servo laten draaien?
Daar is de ASAR sketch voor.
https://forum.beneluxspoor.net/index.php/topic,69109.0.html (https://forum.beneluxspoor.net/index.php/topic,69109.0.html)
Nico
-
... deze werkt niet.
Ik ben met vakantie en heb geen hardware bij me om het programma'tje te testen, er zal wel een domme denkfout in zitten... ???
Zet die andere versie maar weer terug... :)
-
Debouncen van schakelaars kun je denk ik beter doen met bounce library
https://github.com/thomasfredericks/Bounce2/wiki
Hoef je niet te knoeien met delays e.d.
Mvg
Robert