De pulsbreedte besturingMet pulsbreedte besturing kan analoog worden gereden en zijn er mogelijkheden voor geluid aan boord van de treinen. Ook zonder geluid is deze besturing te gebruiken voor analoge treinen. Het voordeel is dat (langzaam) rijden beter gaat.
In dit bericht een filmpje over de bediening van de pulsbreedtebesturing, het aansluitschema, de code voor de Arduino, een stuklijst en wat aanwijzingen voor de opbouw.
BedieningHoe het een en ander in de praktijk werkt, is te zien in dit filmpje.
AansluitschemaVoeding, motorcontroller, Arduino en de bediening wordt als volgt aangesloten.

De ingang van de besturing neemt elke gelijk of wisselspanning tussen 5 en 35 V, dus ook een conventionele treintrafo voldoet. Belangrijk is dat de trafo niet te sterk is; het is de bedoeling dat de spanning 'dipt' als er kortsluiting op de baan ontstaat. Een trafo van rond de 35 Watt (VA) is prima.
De gelijkrichter zorgt er voor dat de ingangstroom altijd goed op de step up/down print komt. Deze is ingeregeld op een uitgangsspanning van 11,5 V. Let op: Deze spanning moet worden ingeregeld voor de rest wordt aangesloten (bij mij was de uitgang 20V af fabriek, en dat is meer dan de Arduino aan kan).
De voeding levert stroom aan de motorcontroller (en daarmee ook aan de trein) en aan de V-IN van de Arduino. De Arduino heeft een ingebouwde uitgang voor een gestabiliseerde 5V, waarmee de potmeter als 'spanningsdeler' naar de massa wordt aangesloten.
De stand van de potmeter wordt uitgelezen op de analoge ingang A7. Deze wordt omgerekend naar een puls voor de rijstroom op 'analoge' uitgangen D09 en D10 van de Arduino. Deze zijn verbonden met de aansturing van de motorcontroller (een pin voor elke richting).
Verder zijn 6 druktoetsen op pinnen A0-A5 verbonden met de massa, dit zijn de functietoetsen voor de geluidsmodule. Een LED op pin D13 geeft informatie over de rijstroom. Dit is dezelfde pin als de op de Arduino ingebouwde LED, dus eventueel kan van deze LED worden afgezien.
Programmacode (sketch)De code voor de Arduino:
/* PULSBREEDTEBESTURING VOOR MODELTREIN
* versie 2.0 - mei 2018
* Rob van Deursen
*
* Motor snelheids regeling met potmeter of Infrarood (IR) afstandsbediening.
* Ook geschikt voor "analoge" geluidsmodules middels 6 functietoetsen.
*
* ==> Kies hier welke besturing wordt gebruikt: <==
*/
const bool IRbesturing = false; // zet deze waarde op true als IR ontvanger wordt gebruikt
// bij false is de besturing met een potmeter en functietoetsen
/*
* De motorbesturing gebeurt over 2 'analoge' uitvoer pinnen. Hier wordt met pulsbreedte modulatie
* de (effectieve) uitgangsspanning ingesteld.
* Elke rij-richting heeft 1 pin waarmee de pulsbreedte tussen 0 (uit) en 255 (maximaal) wordt geregeld.
*
* Potmeter bediening
* ------------------
* De potmeter bestuurt de rijstroom volgens het het principe: "draai naar rechts, rij naar rechts".
* Vanuit de middenpositie kan de snelheid daarmee in 2 richtingen worden geregeld.
*
* Bij starten van de Arduino moet de potmeter in de nul stand staan. Zo wordt bij een reset na kortsluiting
* voorkomen dat er meteen weer spanning op de uitgang komt te staan. De indicator led knippert snel als
* de potmeter niet op nul staat. De potmeter kan dan alsnog in het midden worden gesteld, waarna de bediening
* start.
*
* Indicaties van de LED:
* - continue brandend: potmeter staat in "stop" bereik. Er is geen rijstroom.
* - langzaam knipperend: potmeter staat in "geluidsfunctie" bereik. Er is enige rijstroom om de geluidsmodule
* te starten, maar niet genoeg om de motor te laten draaien.
* - uit: gewone rijstroom in een van de rijrichtingen.
* - snel knipperend: potmeter moet eerst naar 0 (midden) worden gedraaid. Geen rijstroom.
*
* Functietoetsen:
* Er zijn tot 6 functietoetsen aan te sluiten. Elke toets verandert kort de frequentie van de rijstroom.
* Deze frequentie-veranderingen worden door een geluidsmodule herkent en start daarmee speciale functies.
*
*
* IR afstandsbediening
* --------------------
* Infrarood afstandbedieningen kunnen ook worden gebruikt voor deze pulsbreedtebesturing.
* Deze werkt als volgt:
* Een InfraRood ontvanger vangt de signalen van de afstandsbediening op.
* Deze wordt gedecodeerd en omgezet naar een rijrichting en snelheid.
* Snelheid wordt geleidelijk geregeld. Elk commando levert een 'gewenste' snelheid
* en rijrichting op. Vervolgens wordt langzaam geaccelereerd of gedecelereerd.
* Rijrichting wisselt alleen als de snelheid 0 is.
*
* Indicaties met 3 leds:
* 2 richting leds: geven draai-of rijrichting aan.
* - continue brandend: rijrichting is ingesteld en snelheid is de gewenste snelheid
* - knipperen: andere gewenste snelheid en/of rijrichting. Verandering is bezig
* 1 'stop' led:
* - continue brandend: motor staat stil (snelheid = 0}
* - knipperend: er wordt afgeremd tot stop {gewenste snelheid = 0)
* - uit: motor draait / rijdt
*
* Voor het ontvangen van het IR signaal is gebruik gemaakt van de IRremote bibliotheek
* Elke IR afstandbediening kan worden gebruikt, daarvoer moeten de overeenkomstige codes in
* dit programma worden gezet. De decosering wordt gedaan in de functie "VertaalIR()".
* Er is standaard voorzien in het gebruik van de Keyes afstandsbediening, maar deze heeft geen
* functietoetsen voor eventuele geluidsmodules.
*/
// ------------ Instellingen per invoer apparaat ----------
// === potmeter besturing ===
// gebruiksinstellingen
#define potmeterRuis 3 // drempelwaarde voor ruis op de potmeter, voorkomt 'jutteren'
#define potmeterMidden 512 // middenstand (= 0 stand) van de potmeter. Normaal ligt de waarde tussen 0 en 1023.
#define nulbereik 60 // bereik van de potmeter buiten het midden waarop de rijstroom 0 blijft
#define geluidbereik 120 // bereik van af de nul-grens waarop de rijstroom op de minimale waarde blijft voor de geluidsmodule
#define maximaalbereik 500 // bereik waarop de maximale waarde wordt bereikt
// pin definities
#define potmeter A7 //potmeter (snelheidsregelaar) pin
#define functietoets1 A0 // functietoetsen 1 t/m 6
#define functietoets2 A1
#define functietoets3 A2
#define functietoets4 A3
#define functietoets5 A4
#define functietoets6 A5
#define ledIndicator 13 // pin voor indicator led (bij gebruik potmeter bediening)
// === IR afstandsbediening ==
// gebruiksinstellingen
#define lusVertraging 30 // delay in ms in de hoofdlus
#define acceleratieStap 0.025 // stappen waarin snelheid toe- of afneemt
#define sprongWaarde 2.5 // snelheids 'sprong', bijvoorbeeld om te koppelen bij rangeren
// pin definities
#define receiver 7 // pin 1 van IR ontvanger naar Arduino digitale pin
#define ledVooruitPin 4 // pinnen voor vooruit/achteruit indicatie (alleen gebruikt bij IR)
#define ledAchteruitPin 2
#define ledStopPin 3 // pin voor stop
// ------------ Instellingen motor controller ----------
// uitvoer pinnen
#define richtingPin1 10 // pinnen voor vooruit en achteruit (dit moeten beide PWM pinnen zijn)
#define richtingPin2 9
#define aanloopPWM 65.0 // Pulsbreedte waarde (0-255) om aanloopweerstand motoren te overwinnen
#define maxPulsBreedte 250 // Maximale pulsbreedte voor de rijstroom (255 of kleiner, met geluid: max 250)
// ------------- Potmeter rijregeling variabelen ------
const int rijbereik = maximaalbereik - geluidbereik;
int potmeterWaarde = potmeterMidden ;
int vorigePotmeterWaarde= potmeterMidden ;
int functietoets[] {functietoets1, functietoets2, functietoets3, functietoets4, functietoets5, functietoets6};
#define aantalFunctietoetsen 6
// // -------------- Objecten en variabelen t.b.v. IR bediening ------
#include <IRremote.h>
IRrecv irrecv(receiver); // IR ontvanger object maken
decode_results results;
int IRcode = 0; // code afgelezen uit IR ontvanger
String IRknop = ""; // de ingedrukte knop (of ingedrukt gehouden)
// regeling van snelheid en richting
int richting = 0; // rijrichting
int gewensteRichting = 0; // gewenste rijrichting (rijrichting schakelt pas om bij snelheid 0)
float snelheid = 0; // huidige snelheid
float gewensteSnelheid = 0; // gewenste snelheid
float acceleratie = acceleratieStap;
float sprong = 0; // toename in snelheid bij indrukken 'spring' knop
int richtingPin[] {richtingPin1,richtingPin2}; // pinnen voor vooruit en achteruit (PWM pinnen)
// ------------- Definities en variabelen voor geluidsmodule pulsen -----
#define geluidAan -.825 // snelheid om geluidsmmodule te starten (kleiner dan 0, snelheid 0 is aanloopPWM motoren)
// rijstroom ~ 490.0 // gemeten periode (trilligstijd) 2020 us foor standaard PWM rijstroom (~490 Hz)
#define freqFunctie1 667.0 // 667 Hz (periode ~1500 us) ==> 1500
#define freqFunctie2 800.0 // 800 Hz (periode ~1250 us) ==> 1250
#define freqFunctie3 1000.0 // 1000 Hz (periode ~1000 us) ==> 990
#define freqFunctie4 1250.0 // 1250 Hz (periode ~800 us) ==> 790
#define freqFunctie5 1667.0 // 1667 Hz (periode ~600 us) ==> 590
#define freqFunctie6 2000.0 // 2000 Hz (periode ~400 us) ==> 490
#define pulsFunctie 40 // tijdsduur van de puls in ms
#define functiepulsCorrectie 5.0 // correctie voor "handmatige" puls - Arduino tijd 1/4 periode
#define functiePulsIRfactor 0.8 // correctie voor vertraging Arduino door IR
float freqFunctie[] {freqFunctie1, freqFunctie2, freqFunctie3, freqFunctie4, freqFunctie5, freqFunctie6};
#define aantalFreqFuncties 6
int geluidFunctie = 0 ; // huidige geluid functietoets
// -------------- Overige variabelen ------------------
int t=0; // algemene teller voor for... loops
int waardePWM; // huidige waarde van de pulsbreedte.
int vorigeWaardePWM; // vorige waarde van de pulsbreedte.
// LED indicatoren
unsigned long prevms = 0; // knipperen laatste keer aan/uit
unsigned long curms = millis(); // knipperen nu
const long blnkint = 250; // knipper-interval
int ledPins[] {ledVooruitPin, ledAchteruitPin, ledStopPin, ledIndicator} ;
int ledStatus[] {2,0,2,0}; // vooruit (aan), achteruit (uit), stop (aan), indicator (uit).
int blnk = HIGH;
//--------------- Setup na starten Arduino ---------------------
void setup()
{
pinMode(LED_BUILTIN, OUTPUT); // ingebouwde led op pin 13 uit
digitalWrite(LED_BUILTIN, LOW);
// in- en output pinnen initialiseren
pinMode (richtingPin[0], OUTPUT);
pinMode (richtingPin[1], OUTPUT);
pinMode (potmeter, INPUT);
for (t = 0; t < aantalFunctietoetsen; t++) {
pinMode (functietoets[t],INPUT);
digitalWrite(functietoets[t],HIGH);
}
for (t=0; t<4; t++) {
pinMode (ledPins[t],OUTPUT);
}
// de gewenste besturing starten
if (IRbesturing) { // IR bediening
irrecv.enableIRIn(); // Start de IR ontvanger
}
else { // potmeter bediening
// bij potmeterbesturing moet bij het opstarten snelheid 0 zijn ingesteld
// bij een reset door kortsliting wordt zo voorkomen dat de rijstroom vanzelf aan gaat
// led indicator knippert snel zolang potmeter niet op 0 is gesteld
while (HaalSnelheid(analogRead (potmeter)) != 0) {
// rijstroom uit bij opstarten
analogWrite (richtingPin[0], 0);
analogWrite (richtingPin[1], 0);
digitalWrite(ledIndicator,digitalRead(ledIndicator) == 0);
delay(100);
}
digitalWrite (ledIndicator,LOW);
}
}
// --------------- Hoofd lus Arduino ---------------------------
void loop() {
// === IR besturing ===
if (IRbesturing) {
sprong = 0;
if (irrecv.decode(&results)) {
IRcode = results.value;
if (IRcode != 0xFFFFFFFF) { // Geen toets herhaling
IRknop = VertaalIR(IRcode);
}
ZetGewensteSnelheidEnRichting (IRknop);
irrecv.resume(); // Doorgaan met IR codes ontvangen
}
// snelheid en richting aanpassen
SnelheidAanpassen() ;
SnelheidNaarPWM () ;
if (snelheid == 0) { //motor staat stil, dus eventuele richtingverandering doorvoeren
richting = gewensteRichting ;
}
// geluidsmodule bedienen
if (IRknop.startsWith("-1G0")) { // geluid functieknop
geluidFunctie = VertaalIRfunctie (IRknop);
}
}
// === potmeter besturing ===
else { // geen IR besturing, maar potmeter met functieknoppem
potmeterWaarde = analogRead (potmeter);
if (abs(potmeterWaarde - analogRead (potmeter)) < potmeterRuis) { // stabiele uitlezing
// verander de snelheid met ruisonderdrukking van de ruis op de potmeter.
if (abs (potmeterWaarde - vorigePotmeterWaarde) > potmeterRuis) { // verandering groter dan de ruis
snelheid = HaalSnelheid (potmeterWaarde);
vorigePotmeterWaarde = potmeterWaarde;
ledStatus[3] = 2; // stop = led continu aan
if (snelheid == geluidAan) {
ledStatus[3] = 1; // geluid bereik (niet rijden) = lijd knipperen
} else if (snelheid > 0) {
ledStatus[3] = 0; // rijden = led uit
}
}
richting = (potmeterWaarde < potmeterMidden);
SnelheidNaarPWM () ;
}
// Functietoetsen uitlezen
geluidFunctie = HaalFunctieToets();
}
// === voor zowel IR als potmeter ===
// functie uitvoeren
if (geluidFunctie > 0) {
stuurPuls (freqFunctie[geluidFunctie-1],pulsFunctie, true); // stuur een puls voor functie 1-6 op geluidsmodule
delay(93); // voorkom ongewenste herhaling
geluidFunctie = 0; // functie is uitgevoerd
}
// led indicators bijwerken
ZetLedIndicators();
for (t=0; t < 4; t++) {
setLed(t,ledStatus[t]);
}
delay(lusVertraging);
}
//---------------- Functies --------------------
// === Algemene functies ===
// SNELHEID NAAR PWM OMREKENEN EN OP JUISTE PIN ZETTEN
// naar een pulsbreedte en op de juiste uitvoer pin gezet.
void SnelheidNaarPWM () {
if (snelheid != 0) {
waardePWM = aanloopPWM + (maxPulsBreedte-aanloopPWM)/9 * (snelheid + sprong);
}
else {
waardePWM = 0;
}
analogWrite(richtingPin[richting == 0],0); // niet richting pin altijd uit
if (abs(waardePWM - vorigeWaardePWM) >1) { // significante verandering PWM
// voorkom onnodig PWM schrijven: dit verandert de puls
}
analogWrite(richtingPin[richting],(waardePWM)); // PWM op richting pin
vorigeWaardePWM = waardePWM; // onthou vorige waarde
//Serial.print(waardePWM);
}
// ====
// LED AAN, UIT OF KNIPPEREN
// input: led number (0-3)
// func: 0 = uit, 1=knipper, 2 = aan
void setLed (int led, int func) {
// knipperstatus bijwerken
curms = millis();
if (curms - prevms >= blnkint) {
prevms = curms;
blnk = !blnk; // wissel blnk status
}
// leds uit, aan of knipperstatus
if (func == 1) { // dan knipperen
digitalWrite(ledPins[led], blnk);
}
if (func == 0) { // uit
digitalWrite(ledPins[led], LOW);
}
if (func == 2) { // aan
digitalWrite(ledPins[led], HIGH);
}
}
// ====
// STUUR PULS
// zet een signaal puls op de rijstroom met een andere frequentie dan de rijstroom
// Input: frequentie (maximaal 2.000 Hz)
// tijdsduur van de puls (ms)
// boolean PWM correctie of niet
void stuurPuls (unsigned int frequentie , unsigned long tijdsduur, boolean PWMcorrectie) {
unsigned long s;
//golf lengte en -vorm berekenen
unsigned int kwartGolf = (250000/frequentie) - functiepulsCorrectie; // lengte kwart cyclus in micro sec, minus Arduino tijd
if (IRbesturing) {kwartGolf = functiePulsIRfactor * kwartGolf; }
unsigned int hc = 3* kwartGolf; // lengte hoge cyclus, standaard is 3/4 hoog.
unsigned int lc = kwartGolf; // lengte lage cyclus
if (PWMcorrectie) { // PWM correctie gevraagd
if (waardePWM < 90) { // grove PWM correctie in 1/4, 1/2 of 3/4 pulsbreedte (3/4 is standaard)
hc = kwartGolf;
lc = 3 * kwartGolf;
} else if (waardePWM < 170) {
hc = 2 * kwartGolf;
lc = 2 * kwartGolf;
}
}
//puls op de rijstroom pin zetten
s = millis() + tijdsduur;
while (millis() < s) {
digitalWrite(richtingPin[richting],HIGH);
delayMicroseconds (hc);
digitalWrite(richtingPin[richting],LOW);
delayMicroseconds (lc);
}
analogWrite(richtingPin[richting],(waardePWM));
}
// ===
// === potmeter bediening functies ===
// POTMETER WAARDE OMREKENEN NAAR SNELHEID
// input: AD waarde potmeter
float HaalSnelheid (int ADwaarde) { // snelheid instellen op basis van de potmeter
float s = abs (ADwaarde - potmeterMidden);
if (s < nulbereik) {
s = 0;
}
else {
if ( s < geluidbereik ){
s = geluidAan;
//Serial.println("!!!!");
}
else {
s = (constrain (s, geluidbereik, maximaalbereik) ) - geluidbereik;
s = 10 * s / maximaalbereik;
}
}
return s;
}
//===
// FUNCTIETOETSEN UITLEZEN
// geeft het volgnummer van de ingedrukte functietoets.
// 0 = geen toets
int HaalFunctieToets () {
int f = 0; // toets volgnnummer
int k = 0; // ingedrukte toets (0 = geen)
for (f=0; f < aantalFunctietoetsen; f++) {
if (digitalRead(functietoets[f]) == LOW) { //Deze toets is ingedrukt
k = f+1; // onthou toets volgnummer
//Serial.print(k);
}
}
if (k > 0) { delay (60);}
return k;
}
// ===
// === IR bediening functies ===
// IR CODE VERTALING
// Vertaling van de IR codes naar knoppen c.q. acties
// input: integer met de ontvangen IR code
// output: string met code of actie
// Numerieke toetsen geven het cijfer als string terug.
// Alle niet-numerieke toetsen beginnen met "-1", zodat
// deze makkelijk zijn te onderscheiden van de numerieke toetsen.
String VertaalIR(int code){
String b = "";
switch(code) {
// code vertaling KEYES afstandsbediening
case 0xFFA25D: b="1"; break; //numerieke toets is snelheid 0-9
case 0xFF629D: b="2"; break;
case 0xFFE21D: b="3"; break;
case 0xFF22DD: b="4"; break;
case 0xFF02FD: b="5"; break;
case 0xFFC23D: b="6"; break;
case 0xFFE01F: b="7"; break;
case 0xFFA857: b="8"; break;
case 0xFF906F: b="9"; break;
case 0xFF9867: b="0"; break;
case 0xFF6897: b="-1*"; break; //* = sprong knop snelheidssprong (t.b.v. koppelen bij rangeren, bijvoorbeeld)
case 0xFFB04F: b="-1#"; break; //# = direct naar gewenste snelheid (geen acceleratie/deceleratie)
case 0xFF18E7: b="-1^"; break; //omhoog
case 0xFF10EF: b="-1<"; break; //links
case 0xFF38C7: b="-1STOP"; break; //OK = noodstop
case 0xFF5AA5: b="-1>"; break; //rechts
case 0xFF4AB5: b="-1V"; break; //omlaag
case 0xFFFFFFFF: b="-1R"; break; //herhaal (repeat) laatste knop blijft ingedrukt
// code vertaling SHARP GA074WJSA afstandbediening
case 0x885B30D5: b="1"; break;
case 0xE7E0CFB1: b="2"; break;
case 0xA34F5A01: b="3"; break;
case 0x22614D75: b="4"; break;
case 0x96C5A8AB: b="5"; break;
case 0x44ABD1FD: b="6"; break;
case 0x1A5C4D: b="7"; break;
case 0x57A67691: b="8"; break;
case 0x9543D7CF: b="9"; break;
case 0xF4C976AB: b="0"; break;
case 0x5CC96CE7: b="-1*"; break; //kanaal wissel = sprong knop snelheidssprong (t.b.v. koppelen bij rangeren, bijvoorbeeld)
case 0xCC00A5B7: b="-1#"; break; //TV/VIDEO = direct naar gewenste snelheid (geen acceleratie/deceleratie)
case 0x3E0C7005: b="-1^"; break; //omhoog
case 0xB10C7C8B: b="-1^"; break; //channel up = ook omhoog
case 0x503D6F71: b="-1V"; break; //omlaag
case 0x10921B67: b="-1V"; break; //channel down = ook omlaag
case 0x25D2E369: b="-1STOP"; break; //OK = noodstop
case 0x6D5D1DB3: b="-1STOP"; break; //AAN/UIT = ook noodstop
case 0xF43135: b="-1>"; break; //rechts
case 0x4B12992B: b="-1>"; break; //volume + = ook rechts
case 0xA574865B: b="-1<"; break; //links
case 0x1BE8C80D: b="-1<"; break; //volume - = ook links
// functietoetsen geluidsmodule
case 0x47071827: b="-1G01" ; break; //rood = F1
case 0xAA849FD1: b="-1G02" ; break; //groen = F2
case 0xA0A3EAD: b="-1G03" ; break; //geel = F3
case 0xC578C8FD: b="-1G04" ; break; //blauw = F4
case 0xAE90AC1D: b="-1G05"; break; //sound = F5
case 0xC7E0BECF: b="-1G06" ; break; //menu = F6
case 0x28CBA803: b="-1G04" ; break; //mute = F4
case 0x3FE6: b="-1G<" ; break; //subtitle = minimalw PWM links
case 0xA07CF2DB: b="-1G>" ; break; //end = minimale PWM rechts
// case 0xFFFFFFFF: b="-1R"; break; //herhaal (repeat) laatste knop blijft ingedrukt
// Hier is ruimte om eventueel codes van andere afstandbedieningen te vertalen
default:
b = "-2Onbekend";
}// End Case
return b ;
}
// ====
// SNELHEID AANPASSEN - IR
// Deze functie berekent de nieuwe snelheid op basis van de
// ingestelde acceleratie.
void SnelheidAanpassen() {
if (abs(snelheid - gewensteSnelheid) <= (acceleratieStap / 2)) {
snelheid = gewensteSnelheid;
acceleratie= 0;
} else {
snelheid += acceleratie;
}
}
// ===
// ZET DE GEWENSTE SNELHEID EN RICHTING -IR
// Functie zet de gewenste snelheid, gewenste richting en gewenste
// versnelling (of vertraging) op basis van de knoppen die zijn
// ingedrukt op de afstandsbediening.
void ZetGewensteSnelheidEnRichting (String laatsteKnop) {
if (laatsteKnop.toFloat() >= 0) { //numerieke toets
gewensteSnelheid = laatsteKnop.toFloat();
if (snelheid < gewensteSnelheid) { acceleratie = acceleratieStap; }
if (snelheid > gewensteSnelheid) {acceleratie = - acceleratieStap; }
}
else { // niet een numerieke toets
if (laatsteKnop == "-1STOP") { // noodstop
acceleratie = -snelheid;
gewensteSnelheid = 0;
}
if (laatsteKnop == "-1>") { // knop naar rechts
if (richting == 1) { // omkering tijdens het rijden
gewensteSnelheid = 0; // eerst afremmen naar 0
acceleratie = - acceleratieStap;
gewensteRichting = 0;
laatsteKnop ="";
}
else { // rijrichting hetzelfde
if (snelheid == gewensteSnelheid && snelheid < 9 && richting == 0) { // gewenste snelheid is bereikt en nog niet max
gewensteSnelheid += .5 ;
acceleratie = acceleratieStap;
}
}
}
if (laatsteKnop == "-1<") { // knop naar links
if (richting == 0) { // omkering tijdens het rijden
gewensteSnelheid = 0; // eerst afremmen naar 0
acceleratie = - acceleratieStap;
gewensteRichting = 1;
laatsteKnop ="";
}
else { // rijrichting hetzelfde
if (snelheid == gewensteSnelheid && snelheid < 9 && richting == 1 ) { // gewenste snelheid is bereikt en nog niet max
gewensteSnelheid += 0.5;
acceleratie = acceleratieStap;
}
}
}
if (laatsteKnop == "-1V") {
if (snelheid == gewensteSnelheid && snelheid > 0 ) { // gewenste snelheid is bereikt en nog niet max
gewensteSnelheid -= 0.25;
acceleratie = -acceleratieStap;
}
}
if (laatsteKnop == "-1^") {
if (snelheid == gewensteSnelheid && snelheid < 9 ) { // gewenste snelheid is bereikt en nog niet max
gewensteSnelheid += 0.25;
acceleratie = acceleratieStap;
}
}
if (laatsteKnop == "-1#") {
snelheid = gewensteSnelheid; // sla het accelereren/decelereren over: direct naar gewenste snelheid
}
if (laatsteKnop == "-1*" && snelheid < 9 - sprongWaarde) {
sprong = sprongWaarde; // zet "sprong" aan zolang deze toets is ingedrukt.
}
if (snelheid == 0 && gewensteSnelheid == 0) {
if (laatsteKnop == "-1G<" ) { // minimale stroom geluidsmodule aanzetten
snelheid = geluidAan ;
gewensteSnelheid = geluidAan;
richting = 1;
gewensteRichting = 1;
}
if (laatsteKnop == "-1G>" ) { // minimale stroom geluidsmodule aanzetten
snelheid = geluidAan ;
gewensteSnelheid = geluidAan;
richting = 0;
gewensteRichting = 0;
}
}
}
}
// ====
// ZET LED INDICATOREN - IR
// zet juiste waarden op LED pinnen: indicatoren voor acties die bezig zijn
// (richting, snelheidsverandering en stop)
void ZetLedIndicators (){
if (snelheid == 0) {
for (t = 0; t < 2 ; t++) {
ledStatus [t] =0 ; // richting Leds uit
}
ledStatus [2] = 2; // stop led aan
ledStatus [richting] = 2; // juiste richting led aan
}
else { // motor draait
if (gewensteSnelheid == 0) {
ledStatus [2] = 1; // stop led laten knipperen
} else {
ledStatus [2] = 0;
}
if (gewensteRichting != richting) { //richting verandering gewenst
ledStatus [gewensteRichting] = 1; // gewenste richting knipperen
}
else {
ledStatus [1-gewensteRichting] = 0; // andere richtingsled uit
if (gewensteSnelheid != snelheid) { // snelheidsverandering bezig (en niet naar 0)
ledStatus [gewensteRichting] = 1;
}
else {
ledStatus [gewensteRichting] = 2;
}
}
}
}
// ===
// HAAL IR FUNCTIETOETS OP
int VertaalIRfunctie (String g) {
int f = 0;
if (g == "-1G01") {
f = 1; // functie 1
}
if (g == "-1G02") {
f = 2; // functie 2
}
if (g == "-1G03") {
f = 3; // functie 3
}
if (g == "-1G04") {
f = 4; // functie 4
}
if (g == "-1G05") {
f = 5; // functie 5
}
if (g == "-1G06") {
f = 6; // functie 6
}
return f;
}
// ===
// --------------- einde schets ----------------
De code voorziet in bediening van de pulsbreedte met potmeter en functietoetsen of met infrarood afstandsbediening. Standaard staat deze op "potmeter".
Lijst van onderdelenDe volgende onderdelen zijn gebruikt (aangegeven prijzen zijn Nederlandse prijzen)
- Voeding - step up/down 4A | 4,95
- Motorcontroller 4A | 4,95
- Arduino Nano met pinnen | 5,95 (zonder pinnen, zelf solderen 4,95)
- Brugcel, gelijkrichter 6A | 0,70
- Potmeter 10k ohm | 0,50
- LEDje | 0,10
- Weerstandje 1 k ohm | 0,10
- Breadboard draadjes fem-fem | 3,95
- Druktoetsen 6x | 3,00 (0,50/stuk, prijs afhankelijk van type)
Totale prijs komt dan op 24,20, zonder verzendkosten.
Bij bestelling van (een deel) van de spullen bij tante Ali, kunnen de kosten flink omlaag (en levertijden omhoog). Zo heb ik 5 Arduino's gekocht voor $12. Deze Arduino's kunnen ook in de geluidsmodules worden gebruikt.
Enkele aanwijzingen voor de opbouwEnig gereedschap is nodig, zoals een voltmeter (multimeter) voor het instellen van de voeding, een soldeerbout, een computer met de Arduino software (de zogenaamde IDE, gratis te downloaden), en een USB kabel met mini USB (niet de micro USB van je telefoon, maar de iets grotere stekker).
Zoals gezegd: let op met de voeding: eerst het uitgangsvoltage instellen, dan pas andere spullen aansluiten.
Als de pulsbreedte besturing klaar is, kan elke analoge loc hierop rijden. Dus je hoeft niet te wachten op de geluidsmodules om deze rijstroom besturing te gebruiken.
Tot zover de bouwbeschrijving.
Rob