Filmpje: https://youtu.be/d_LvIisSmXA

Met een Arduino kun je vrij makkelijk een treintje besturen.
Op internet zijn meerdere websites te vinden met schema's en programma's om dit mogelijk te maken.

Trein automatisch laten rijden

O.a. op de volgende website staat een uitgebreid schema, waarbij de trein ook achteruit kan rijden: http://www.scale-n.nl/ScaleN_Naslag_Arduino_L293D_RijsnelheidEnRichting.aspx

Ik heb zelf een eenvoudige versie gebruikt, waarbij de trein alleen voorruit kan rijden. Gebaseerd op dit schema: http://www.bliksemsnel.net/?p=76
Hieronder het schema, ik had zelf nog een BD679 liggen, met een 2k2 weerstand, maar dit schema werkt ook met andere darlington NPN transistors:

Voorbeeld, aansluitingen van BD679 transistor:
Pen 1 = Emitter (aan aarde).
Pen 2 = Collector (naar rails en diode).
Pen 3 = Basis (naar weerstand en arduino).

Met deze sketch gaat de trein steeds sneller rijden, vervolgens steeds langzamer rijden en stoppen en dan wordt deze cyclus herhaald.
const int analogOutPin = 9; // Analog output pin
int outputValue = 50; // value output to the PWM (analog out)

void setup() {

}

void loop() {
analogWrite(analogOutPin, outputValue);
outputValue++;

if (outputValue > 254) {
// Slow down train
while(outputValue > 0){
outputValue--;
analogWrite(analogOutPin, outputValue);
delay(20);
}

// Stop train
delay(5000);

// Start train
outputValue = 50;
}

delay(200);
}
Foto (met 433 MHz transmitter en ontvanger er nog bij in het blauwe beadboard, de ontvanger wil ik nog gebruiken om draadloos de trein te starten en stoppen):



Trein laten stoppen bij een lichtsensor

Ik wil graag dat de trein stopt op een vast punt (bijvoorbeeld een station), dus heb ik een optische sensor (de TSL256) gebruikt om de trein te detecteren.
Een volledige uitleg van deze sensor is te vinden op: https://learn.adafruit.com/tsl2561?view=all

De trein werkt nu als volgt:
1) De trein gaat steeds sneller rijden.
2) De trein gaat langzamer rijden.
3) De trein rijd nu langzaam totdat hij bij de sensor is gekomen.
4) De trein gaat nu langzaam stoppen.
// *** Use optical sensor ***
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_TSL2561_U.h> Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345); int opticalSensor = 200; // *** Train motor *** const int analogOutPin = 9; // Analog output pin int outputValue = 50; // value output to the PWM (analog out) void setup() { // *** Optical sensor parameters *** /* You can also manually set the gain or enable auto-gain support */ // tsl.setGain(TSL2561_GAIN_1X); /* No gain ... use in bright light to avoid sensor saturation */ // tsl.setGain(TSL2561_GAIN_16X); /* 16x gain ... use in low light to boost sensitivity */ tsl.enableAutoRange(true); /* Auto-gain ... switches automatically between 1x and 16x */ /* Changing the integration time gives you better sensor resolution (402ms = 16-bit data) */ tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS); /* fast but low resolution */ // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS); /* medium resolution and speed */ // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS); /* 16-bit data but slowest conversions */ } void loop() { // *** Increase train speed *** analogWrite(analogOutPin, outputValue); outputValue++; if (outputValue > 254) { // *** Slow down train *** while(outputValue > 60){ outputValue--; analogWrite(analogOutPin, outputValue); delay(20); } // *** Train drives slowly to sensor *** while(opticalSensor > 20){ /* Get a new sensor event */ sensors_event_t event; tsl.getEvent(&event); opticalSensor = event.light; } opticalSensor = 200; // *** Stop train slowly by sensor *** while(outputValue > 20){ outputValue--; analogWrite(analogOutPin, outputValue); delay(20); } analogWrite(analogOutPin, 0); delay(10000); // *** Start train *** outputValue = 50; } delay(200); }

Trein laten stoppen bij een reed contact en geluid toegevoegd

Een lichtsensor gebruiken om de trein te detecteren is eigenlijk niet zo handig... Ik heb enkele reed contacten gekocht, die reageren op een magneet. Onder een wagon heb ik een magneet geplakt, en nu kan de trein stoppen bij het reed contact.

Ik heb ook een seriële MP3 speler gekocht, zodat er geluid wordt afgespeeld als de trein gaat rijden. Op de serïele MP3 speler zit een SD kaart aansluiting. Op de SD kaart heb ik 3 trein geluiden gezet, zodat er steeds een ander geluid wordt afgespeeld.
Op de SD kaart staat een map 01, met 3 geluidsbestanden:
01/001.wav
01/002.wav
01/003.wav
// *** MP3 player ***
#include <SoftwareSerial.h>
#define ARDUINO_RX 5 // connect to TX of the Serial MP3 Player module
#define ARDUINO_TX 6 // connect to RX of the module
SoftwareSerial mySerial(ARDUINO_RX, ARDUINO_TX);
unsigned char playmode = 1;
#define PLAY 1
#define PAUSE 0
static int8_t Send_buf[8] = {0} ;

/************Command byte**************************/
#define CMD_NEXT_SONG 0X01
#define CMD_PREV_SONG 0X02
#define CMD_PLAY_W_INDEX 0X03
#define CMD_VOLUME_UP 0X04
#define CMD_VOLUME_DOWN 0X05
#define CMD_SET_VOLUME 0X06
#define CMD_SINGLE_CYCLE_PLAY 0X08
#define CMD_SEL_DEV 0X09
#define DEV_TF 0X02
#define CMD_SLEEP_MODE 0X0A
#define CMD_WAKE_UP 0X0B
#define CMD_RESET 0X0C
#define CMD_PLAY 0X0D
#define CMD_PAUSE 0X0E
#define CMD_PLAY_FOLDER_FILE 0X0F
#define CMD_STOP_PLAY 0X16
#define CMD_FOLDER_CYCLE 0X17
#define CMD_SET_SINGLE_CYCLE 0X19
#define SINGLE_CYCLE_ON 0X00
#define SINGLE_CYCLE_OFF 0X01
#define CMD_SET_DAC 0X1A
#define DAC_ON 0X00
#define DAC_OFF 0X01
#define CMD_PLAY_W_VOL 0X22

// *** Train motor ***
const int analogOutPin = 9; // Analog output pin
int outputValue = 50; // value output to the PWM (analog out)

const int reedcontact = 12; // Analog output pin

void setup() {
// *** MP3 Player ***
Serial.begin(9600);
mySerial.begin(9600);
sendCommand(CMD_SET_VOLUME, 255);

// *** Debugging ***
pinMode(13, OUTPUT);

// Reed contact
pinMode(reedcontact, INPUT);
digitalWrite(reedcontact, HIGH); // Activate internal pullup resistor
}

void loop() {
// *** Increase train speed to 254 ***
analogWrite(analogOutPin, outputValue);
outputValue++;

if (outputValue > 254) {
// *** Slow down train, decrease 254 to 60 ***
while(outputValue > 60){
outputValue--;
analogWrite(analogOutPin, outputValue);
delay(20);
}

// *** Train drives slowly to sensor ***
while (digitalRead(reedcontact)==HIGH){
digitalWrite(13, HIGH); // *** turn LED on ***
}

 // *** Debugging ***
digitalWrite(13, LOW); // *** turn the LED off ***

// *** Just some delay, because I want to stop train further from sensor ***
delay(7000);

// *** Stop train slowly by sensor, decrease 60 to 20 ***
while(outputValue > 20){
outputValue--;
analogWrite(analogOutPin, outputValue);
delay(20);
}

// *** Complete stop ***
analogWrite(analogOutPin, 0);

delay(10000);

// *** Start train ***
outputValue = 50;

// *** Play sound ***
sendCommand(CMD_PLAY,0);
}

delay(200);
}

// *** Send command to MP3 player ***
void sendCommand(int8_t command, int16_t dat)
{
delay(20);
Send_buf[0] = 0x7e; //
Send_buf[1] = 0xff; //
Send_buf[2] = 0x06; //
Send_buf[3] = command; //
Send_buf[4] = 0x00;//
Send_buf[5] = (int8_t)(dat >> 8);//datah
Send_buf[6] = (int8_t)(dat); //datal
Send_buf[7] = 0xef; //
for(uint8_t i=0; i<8; i++)//
{
mySerial.write(Send_buf[i]) ;
}
}