Hoi A.J.,
eerste wat me opvalt, en bedenk dan dat ik geen expert ben in motoren, is dat je een DC motor wilt gebruiken die 1 omwenteling moet maken.
Misschien is een Stepper motor een betere keuze? Je hebt dan een betere controle over hoe ver de as draait.
Zie ook dit artikel over het kiezen van motoren voor o.a. Arduino projecten.
Maar mijn inzicht in de motor die je wilt gebruiken ontbreekt, dus het kan zijn dat ik voor m'n beurt praat. 😋
Na wat Google werk zie ik dat de Cytron-MD13s dit misschien aan kan 😎
Bij het maken van een sketch zou ik me eerst concentreren op het reedcontact deel.
De beveiliging implementeren we dan later als het motor deel naar wens functioneert.
Om het probleem nog kleiner te maken, zou ik zelfs eerst beginnen met de motor functie, waarbij de motor 1 omwenteling maakt.
Even snel met Google gezocht en er blijkt een specifieke library hiervoor te bestaan (voor de MD13s), en die kun je op Github vinden.
Installatie van de library gaat als volgt:
- Open de Arduino IDE, selecteer Sketch -> Include Library -> Manage Libraries...
- Zoek daar naar Cytron Motor Drivers Library. (niet te verwarren met de Cytron 3A Motor Driver Shield en andere libraries)
- Klik de Install knop, en na installatie suggereert men de Arduino applicatie te herstarten.
Onder Examples in de Arduino IDE zie je dan wat voorbeelden (File -> Examples -> Cytron DC Motors Library).
Je ziet daar ook dat aan het begin van de sketch we de library moeten includen met deze regel:
#include "CytronMotorDriver.h"
Vervolgens definiëren we de pinnen voor de 2 reedcontacten - hiervoor is dit Arduino artikel handig om te zien hoe het gebruik van schakelaars werkt.
N.b. de 2 pinnen heb ik willekeurig gekozen. Je kunt de nummers veranderen indien nodig of wenselijk.
#define rc1pin 2 // gebruik pin 2 voor reedcontact 1
#define rc2pin 3 // gebruik pin 3 voor reedcontact 2
Met de functie digitalRead kunnen we een pin uitlezen, waarbij HIGH wil zeggen dat de schakelaar is gesloten en LOW wil zeggen dat de schakelaar open staat.
Als voorbeeld:
if(digitalRead(rc1pin)==HIGH) { ... }
Zie ook vergelijkingsoperators voor de Arduino.
Nu is het zaak een functie te maken welke de motor start en laat draaien tot rc2 wordt gesloten, of een hele omwenteling is afgerond.
N.b. ik weet niet precies hoe je een enkele omwenteling kunt bewerkstelligen met een DC motor, maar misschien weet jij dat wel.
Ik denk even dat als rc2 gesloten wordt, dat dan de motor uitgezet wordt?
Noem die functie zoiets als "MotorActie", en in basis ziet dat er zoiets uit (ik heb de motor functie gegokt op basis van een van de library voorbeeld):
void MotorActie() {
// de stappen die nodig zijn om de motor aan te zetten en de omwenteling af te handelen
// dus: Motor AAN
motor.setSpeed(128); // 50% snelheid - evt aanpassen aan wat wenselijk is
// Laat motor lopen to rc2 gesloten wordt
while (digitalRead(rc2pin)==LOW) {
// niks doen tot rc2 HIGH wordt, en dus niet meer LOW is
}
// als rc2 gesloten wordt, stop de motor
motor.setSpeed(0);
}
Nu hebben we een functie die de motor start en laat lopen tot rc2 wordt gesloten. Handig want die kunnen we dan eenvoudig aanroepen.
Hier wat meer info over hoe een while-loop werkt.
Als test wil ik het simpel houden, dus als rc1 wordt gesloten, start de motor actie.
De kleine pause is om zogenaamd "bouncing" te voorkomen, maar het kan zijn dat dit niet nodig is voor een reedcontact (het is erg lang geleden dat ik een reedcontact in handen heb gehad).
// deze functie draait 1x als de Arduino aangezet wordt
void setup() {
// nog niks hier
}
// de loop blijft herhalen tot de Arduino wordt uitgezet.
void loop() {
if(digitalRead(rc1pin)==HIGH) {
MotorActie();
}
delay(100); // kleine pauze
}
Alles bij elkaar voor onze eerste test (hopelijk vergeet ik niks):
#include "CytronMotorDriver.h"
#define rc1pin 2 // gebruik pin 2 voor reedcontact 1
#define rc2pin 3 // gebruik pin 3 voor reedcontact 2
// deze functie draait 1x als de Arduino aangezet wordt
void setup() {
// nog doen we nog niks
}
// de loop blijft herhalen tot de Arduino wordt uitgezet.
void loop() {
if(digitalRead(rc1pin)==HIGH) {
MotorActie();
}
delay(100); // kleine pauze
}
void MotorActie() {
// de stappen die nodig zijn om de motor aan te zetten en de omwenteling af te handelen
// dus: Motor AAN
motor.setSpeed(128); // 50% snelheid - evt aanpassen aan wat wenselijk is
// Laat motor lopen to rc2 gesloten wordt
while (digitalRead(rc2pin)==LOW) {
// niks doen tot rc2 HIGH wordt, en dus niet meer LOW is
}
// als rc2 gesloten wordt, stop de motor
motor.setSpeed(0);
}
Dit is maar een begin, maar we weten hierna dat de motor actie correct functioneert.
In de MotorActie functie (o.a. in de while-loop) kunnen we straks de beveiligingen inbouwen.
Als je wilt, dan kun je al de beveiligingen inbouwen, omdat testen nu wat overzichtelijker is, voordat we de andere logica gaan toepassen.
Maar, dat zal nog wel met de nodige uitdagingen komen.
- Voltage te laag
Je zult een stukje electronica moeten toevoegen die een pin HIGH of LOW kan zetten, afhankelijk van het gemeten voltage.
De analoge pinnen op de Arduino gaan waarschijnlijk kapot als je daarmee 12V gaat proberen te meten (werkt maar van 0-5V).
Een voltage deler (zie o.a. dit artikel) zou hiervoor misschien gebruikt kunnen worden.
- Te veel weerstand
Hier zijn twee zaken van belang; waarnemen van de weerstand en motor richting omdraaien.
Dat laatste is eenvoudig, door een min voor de waarde te zetten in motor.setSpeed(). B.v.
motor.setSpeed(-128);
De weerstand meten wordt echter lastiger.
Of we gebruiken een sensor, of we proberen te meten of het stroomverbruik van de motor onverwachts toeneemt - ik weet niet eens 100% zeker of dat laatste een werkbare oplossing is, en ook hiervoor zullen we een stukje elektronica moeten toevoegen om dit waar te nemen.
Had je hiervoor zelf iets in gedachten?
Lang verhaal he? Koste me ook wat meer tijd dan gedacht, maar ik vindt het een leuke uitdaging ... 😉