Auteur Topic: Arduino servo uitdaging  (gelezen 5115 keer)

0 leden en 1 gast bekijken dit topic.

Offline mark mms

  • Super Modelspoorder
  • ******
  • Berichten: 1.224
  • Thanked: 26 times
  • Geslacht: Man
Arduino servo uitdaging
« Gepost op: 5 november 2017, 15:35:47 »
Hallo allemaal,

Wie kan mij helpen met een uitdaging (voor mij wel in ieder geval)

Ik ben reeds lange tijd bezig om servo's en LED's aan te sturen m.b.v. Arduino.
Na het lezen van diverse instructies, youtube, forum's en nog veel meer...
Heb ik besloten om maar hulp te vragen.

Het doel is dat ik met een druktoets een servo enkele bewegingen kan laten doen.
Poppetjes laten bewegen en meer van dat.

Op dit moment kom ik niet verder dan één servo per arduino welke ik alleen aan en uit kan zetten door de arduino wel of niet te voorzien van stroom. Tja, dat is niet echt wat ik voor ogen had.  ::) :-[

Is er iemand die al een sketch/programma heeft geschreven voor zoiets?
Al is het een basis waar ik op verder kan proberen.

Mijn dank zou zeer groot zijn. :-*

Bij voorbaat dank, Mark

Offline Dirk T

  • Super Modelspoorder
  • ******
  • Berichten: 1.344
  • Thanked: 98 times
  • Geslacht: Man
  • Tweerail DCC, NL 1950-1975 met ruime blik
Re: Arduino servo uitdaging
« Reactie #1 Gepost op: 5 november 2017, 17:55:26 »
Hier vind je een sketch die zoiets doet voor maximaal 12 servo's per Arduino, maar dan op basis van DCC wisselcommando's. Ik zou zeggen: pas de sketch aan zodat een bepaalde pin als ingang wordt gezien voor een schakelaar, en laat op basis van die ingang een servo bewegen. Het DCC stuk kun je eruit slopen.
Het einde van een weg wordt altijd bereikt door hem stap voor stap af te lopen.

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Arduino servo uitdaging
« Reactie #2 Gepost op: 5 november 2017, 18:05:15 »
Hoi Mark,

Volgens mij lees ik hier twee vragen:
- Hoe kan ik meer dan 1 servo bedienen
- Hoe kan ik de Arduino 'iets' laten doen nadat een knop is ingedrukt en dan weer laten wachten tot de knop nog een keer wordt ingedrukt.

Antwoord op de eerste vraag: een servo bibliotheek gebruiken. Volgens mij zit er standaard een servo library in
#include <Servo.h>`
Ik heb tot nu toe alleen  1 servo gebruikt, maar als het goed is kun je er meerdere  gebruiken (tot 12 stuks)

Voor de 2e vraag: ik heb precies zoiets op mijn module 'hoeve aan het viaduct'. Hier druk ik op een knopje en dan lopen er enige tijd 2 animaties: de kippetjes van Viessman (dat is simpel een relais dat aan of uit gaat) en een boerenknecht die aan een onwillige koe staat te trekken (dat is een relais dat in verschillende patronen wordt aangetrokken).

De truuk is om in de eeuwigdurende lus van de sketch een variabele als een soort schakelaar te gebruiken: deze staat op '0' als er geen animatie bezig is. Dan wordt alleen gekeken of een knop is ingedrukt. Staat deze niet op '0', dan wordt de animatie gedaan (tijdens de animatie doet de knop dan niets).

In mijn geval gebruik ik hiervoor de variabele 'x'. Staat deze op 0, dan is de animatie afgelopen. Wordt de knop ingedrukt, dan gaat deze op een waarde van 2, zodat de animatie 3 keer doorlopen wordt.

Je kunt natuurlijk ook '0' uit en '1'(aan) gebruiken:
---------------------------------------
void loop()
{
  if (x>0) {            // animatie is bezig
   // doe hier je animatie ding

     x = 0;             // animatie is klaar.
  }
  else
 {
    if (readKnop(knoppin) ) {   // knop ingedrukt?
      x = 1;                             // animatie is vanaf nu aan
    }
  }
}
------------------------------------

De knop wordt als volgt gecheckt (Overigens, ik geef naar de functie mee welke knop (pin) ik wil uitlezen. Dan is de functie herbruikbaar als je verschillende knoppen iets wil laten doen):
------------------------------------
// functie om knop uit te lezen en 'spikes' te negeren.
// De knop moet na 150 ms. nog steeds ingedrukt zijn.
boolean readKnop (int knop) {
  boolean knopvalue = false;
  if (digitalRead (knop) == LOW) {
    delay (150);
    if (digitalRead (knop) == LOW) {
      knopvalue = true;
    }
  }
  return knopvalue;
}
-------------------------------

Dit zijn de belangrijkste onderdelen. De hele sketch ziet er bij mij zo uit:

--------------------------------
/* Boerderijbesturing
 * Gebruikt Arduino met 2 relais
 
 *
 */

#define kippenrelais 7   // kippen op deze pin
#define knechtrelais 6   // boerenknecht op deze pin. pin met PWM
#define ON    LOW        // relais aan = low pin
#define OFF   HIGH       // relais uit = high pin
#define knoppin  A1      // input pin knop

int x = 1;               // begin met 1 cyclus bij reset/startup

// functie om knop uit te lezen en 'spikes' te negeren.
// De knop moet na 150 ms. nog steeds ingedrukt zijn.
boolean readKnop (int knop) {
  boolean knopvalue = false;
  if (digitalRead (knop) == LOW) {
    delay (150);
    if (digitalRead (knop) == LOW) {
      knopvalue = true;
    }
  }
  return knopvalue;
}


void trekKnecht (int t, int d) {
  int y = 130;   // pwm
  // voltage op relais spoel langzaam toe- en afnemen (met gebruik van pwm)
  // low = relais aan
  while (y > 30) {
    analogWrite (knechtrelais,y);
    delay (t);   
    y--;
  }
  delay (d); 
  y=70;
  while (y < 200) {
    analogWrite (knechtrelais,y);
    delay (t);   
    y++;
  }
  digitalWrite (knechtrelais,OFF);
}

// 3 patronen waarmee de knecht aan de koe staat te trekken
void trekPatroon1() {
  trekKnecht (7,20);
  delay(500);
  trekKnecht (2,20);
  delay(50);
  trekKnecht (3,40);
  delay(500);
  trekKnecht (10,70);
}

void trekPatroon2() {
  trekKnecht (3,20);
  delay(70);
  trekKnecht (2,20);
  delay(50);
  trekKnecht (3,40);
}

void trekPatroon3() {
  trekKnecht (15,5);
  delay(300);
  trekKnecht (10,20);
}

void setup()
{
// initialiseer sensor pinnen
  pinMode (knoppin,INPUT);
  pinMode (reedpin,INPUT);
  digitalWrite (knoppin,HIGH);
 
// initialiseer relais pinnen
  pinMode (kippenrelais,OUTPUT);
  pinMode (knechtrelais,OUTPUT);
  digitalWrite (kippenrelais,OFF);
  digitalWrite (knechtrelais,OFF);
}

void loop()
{
  while (x>0) {
    digitalWrite (kippenrelais,ON); //kippen aan
    delay(1000);
    // trekken door de knecht in verschillende patronen
    trekPatroon1 ();
    delay(5000);
    trekPatroon2 ();
    delay(3500);
    trekPatroon3 ();
    delay(4500);
    x--;
  }
  digitalWrite (kippenrelais,OFF);
  if (readKnop(knoppin) ) {
    x = 2;
  }
}

--------------------------------------------

Ik hoop dat je hier iets mee kunt.

Ik zou het probleem ok in 2 stukken aanpakken.
Eerst de knopbediening, met bijvoorbeeld de on-board LED aanzetten na een druk op de knop en dan na een tijdje weer uit
Dan de meer-dan-1-servo, door bijvoorbeeld 2 servo's te laten draaien.

En dan alles samenvoegen en verder uitbouwen.

Succes, en als er nog vragen zijn, dan hoor ik het wel.

Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline mark mms

  • Super Modelspoorder
  • ******
  • Berichten: 1.224
  • Thanked: 26 times
  • Geslacht: Man
Re: Arduino servo uitdaging
« Reactie #3 Gepost op: 13 november 2017, 21:38:19 »
Hallo Rob,

Ik heb wat zitten stoeien met mijn zoon op de servo aansturing.
Tot op heden kunnen we één servo aansturen met een potmeter, maar ook met een druktoets.

Hier de sketch;

/*
  Debounce

  Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
  press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's a
  minimum delay between toggles to debounce the circuit (i.e. to ignore noise).

  The circuit:
  - LED attached from pin 13 to ground
  - pushbutton attached from pin 2 to +5V
  - 10 kilohm resistor attached from pin 2 to ground

  - Note: On most Arduino boards, there is already an LED on the board connected
    to pin 13, so you don't need any extra components for this example.

  created 21 Nov 2006
  by David A. Mellis
  modified 30 Aug 2011
  by Limor Fried
  modified 28 Dec 2012
  by Mike Walters
  modified 30 Aug 2016
  by Arturo Guadalupi

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Debounce
*/

#include <Arduino.h>
#include <Wire.h>
#include <SoftwareSerial.h>

#include <Servo.h>

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;    // the number of the pushbutton pin
const int ledPin = 13;      // the number of the LED pin
double angle_rad = PI/180.0;
double angle_deg = 180.0/PI;
Servo servo_9;

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin
int pos = 90;

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  servo_9.attach(9); // init pin
     
   
    for(int __i__=0;__i__<5;++__i__)
  // set initial LED state
  digitalWrite(ledPin, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

                                               // check to see if you just pressed the button
                                               // (i.e. the input went from LOW to HIGH), and you've waited long enough
                                               // since the last press to ignore any noise:

                                               // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState)
  {
     lastDebounceTime = millis();              // reset the debouncing timer
  }

  if ((millis() - lastDebounceTime) > debounceDelay)
  {                                           // whatever the reading is at, it's been there for longer than the debounce
      if (reading != buttonState)             // delay, so take it as the actual current state:
  {   
      buttonState = reading;                  // if the button state has changed:
      for (pos = 0; pos <= 90; pos +=3)
  {
      servo_9.write(pos); // write to servo
      delay(50);
  }   
      for (pos = 90; pos >= 20; pos -=3)
  {   
      servo_9.write(pos); // write to servo
      delay(50);
  }
      for (pos = 20; pos <= 130; pos +=3)
  {
      servo_9.write(pos); // write to servo
      delay(50);
  }   
      for (pos = 130; pos >= 0; pos -=3)
  {   
      servo_9.write(pos); // write to servo
      delay(50);
  }
  }
  }   digitalWrite(ledPin, ledState); 
                                              // save the reading. Next time through the loop, it'll be the lastButtonState:
      lastButtonState = reading;  // set the LED:
 
}


Wat ons niet lukt is meerdere servo's afzonderlijk aansturen met elk zijn eigen drukstoets.
Wellicht dat ik daarom maar voor elke servo een arduino koop bij tante Ali.

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Arduino servo uitdaging
« Reactie #4 Gepost op: 13 november 2017, 23:22:26 »
Hoi Mark,

Misschien is een makkelijke eerste stap: 2 servo's parallel laten draaien.
Dan heb je in ieder geval de 2 servo's onder de knie. Als dat werkt, pak je de 2e button er bij.

De servo gaat natuurlijk op de +5v en GND. De derde draad naar 1 van de pinnen.

Je hebt nu Pin 9 in gebruik. Je zou er nog een kunnen aansluiten op pin 10.
Dan moet je hem ook definiëren.

Dus
Servo servo_9
Servo servo_10 ;   // maak 2e servo object

(...)
  servo_9.attach(9); // eerste servo op pin 9
  servo_10.attach(10); // 2e servo op pin 10

Overal waar servo_9.write() wordt gedaan, voeg je eenzelfde regel toe met servo_10.wrtite()

Als het goed is lopen beide servo's dan parallel.

succes,
Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Arcomora

  • Gast
Re: Arduino servo uitdaging
« Reactie #5 Gepost op: 2 februari 2018, 18:17:08 »
Met de Mardec sketch kun je ook een pin als input aanwijzen. Bij laag worden daarvan kan bv een servo worden omgezet.

Mvg
Nico

Offline mark mms

  • Super Modelspoorder
  • ******
  • Berichten: 1.224
  • Thanked: 26 times
  • Geslacht: Man
Re: Arduino servo uitdaging
« Reactie #6 Gepost op: 2 februari 2018, 21:40:18 »
Hallo Arcomora,

Ik zojuist je voorstel stukje gelezen en zal me nog eens verdiepen in de wondere wereld van arduino.