Thought i'd share with you my current project. I built a railroad control system with a Mega. It handles everything from monitoring crossing gates, controlling a signal bridge, and controlling some track turnout. Some technologies used: relays, servos, dc motor, ble chip, electromagnet, and more). Had a lot of fun building this prototype!
Check out the video explaining the setup here: Link
And a bonus video where I added a car system: Link
If you have ANY questions about anything, please let me know. Thanks for viewing.
Nice project, I assume by your comment that you had "tried a current sense to trigger the crossing" that you are running DC not DCC, I like the sonics idea and servos are a great animation technique.
As it turns out I am also in the throws of developing a full featured DC system, but mine is based on the UNO, less pins but there is sufficient for the project, my points control uses a separate UNO and a 16 servo driver board that only uses 2 wires, this may be useful to you as your project develops to the layout stage. Link here http://www.ebay.com.au/itm/191736126715?_trksid=p2057872.m2749.l2648&ssPageName=STRK%3AMEBIDX%3AIT
Keep up the good work, there are not many Arduino Railroaders around that i have come across.
The key requirement is a very fast response time, about 100-150ms, I think this board will do it but cant get the data to prove it. There are other options out there but they start around $60 Australian plus post.
If you or anyone has used this item, all help appreciated.
Thanks.
Hey WL888! thanks for checking it out I actually run DCS, for ho the voltage on the track is around 19 vdc, about 3 amps. The current sensor I spoke of actually just reports voltage to the Arduino, but divided by 5 so the Arduino pin can handle it. With DCS, and DCC, the voltage on the track is pretty constant, however when the engine passes over a isolated block of track, you can measure the slight drop from it drawing current. This is similar to what real trains do. I might experiment more with this technique as I plan to add end of train devices to my trains which would draw current and help me detect the end of the train!
Yep..looked at the Adafruit but their postage is more than the item is worth...thats why i was looking at the chinese board.
The sound card is to hold several series of sound files, each series related to a specific Loco, which is selected from the LCD menu and controlled from the Throttle pot, as i don't run DCC the sound will come from the controller.
That is until I can figure a way to Selectively send them to the Loco to a Bluetooth Speaker.
I have just finished my crossing control using the 16 servo board and IR sensors, the sound will come from an Ebay MP3 player. This leaves me with potentially 14 more animations available from the same hardware.
My layout is Australian theme circa 1906 Narrow Gauge ON30.
So, everything is either scratch or bash...layout is work in progress, but have had some trains running.
Don't know about a video but here is a proof of concept snap of the crossing.
/* Level Crossing Control
* converted to use the Adafruit I2C 16 servo controller
* with UNO R3
* Version V2.1 25/05/2016
* Doug wl888
* credits for original sketch to
* Version 1.4 Geoff Bunza 2015
*/
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); // called this way, it uses the default address 0x40
int gate1servo = 0;
int gate2servo = 1; //ASSUMPTION Gate is down at position gatedownposition and up at position gateuppostion
int gateuppostion = 475; // servo position for gate up
int gatedownposition = 175; // servo position for gate down
int sensor1 = 8; // IR sensor pin Assumption== Pin goes LOW when train detected
int sensor2 = 9; // IR sensor pin Assumption== Pin goes LOW when train detected
int led1 = 2; // Led 1 pin first alternating flasher
int led2 = 4; // Led 2 pin first alternating flasher
int Bell = 3; //<<<<<<<at present this switches a LED but will trigger sound from an Ebay MP3 player
int gateposition = 120; // variable to store the servo gateposition
int leaving_sensor; // = 6; // this will tell which sensor shows train leaving
int gates_started = 0; // this says if the crossing is active
int flash_state = 0;
long flash_time = 0;
long flash_interval = 900; // time in milliseconds between alternating flashes
int sensor_count = 0;
unsigned long previousMillisWAIT=0; //Wait Millis() setup
int intervalWAIT = 30;
//=========================================================
void setup()
{
Serial.begin(9600);
pwm.begin();
pwm.setPWMFreq(60);
pinMode(sensor1, INPUT);
pinMode(sensor2, INPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(Bell,OUTPUT);
digitalWrite(led1, LOW); // Start with all flashers off
digitalWrite(led2, LOW);
digitalWrite(Bell, LOW);
flash_time = millis();
}
//========================================================
void loop()
{
if ((digitalRead (sensor1)==LOW)&& (gates_started==0)) {
gates_started = 1;
leaving_sensor = sensor2;
starting_sequence();
}
if ((digitalRead (sensor2)==LOW)&& (gates_started==0)) {
gates_started = 1;
leaving_sensor = sensor1;
starting_sequence();
}
if (gates_started) flash_leds(); //gates are down continue flashing
if ((digitalRead(leaving_sensor)==LOW)&&(gates_started==1)) { //train is starting to leave
//as long as the leaving sensor is active the train is still in the crossing
while (gates_started==1) { //now check if train is REALLY gone
sensor_count = 0;
for (int i=1; i<40; i++) {
if (digitalRead(leaving_sensor)==LOW) sensor_count++;
delay (30);
flash_leds();
}
if (sensor_count==0) gates_started=0;
flash_leds();
}
// we only get here if the train has really left the crossing
ending_sequence();
}
}
//==============================================================
void starting_sequence() {
digitalWrite(Bell,HIGH);
long wait_time;
flash_time = millis();
wait_time = millis()+3000;
while (wait_time > millis()) flash_leds(); //flash before dropping gates
for(gateposition = gateuppostion ; gateposition>gatedownposition ; gateposition-=1) // goes from gateuppostion degrees to gatedownposition degrees
{
pwm.setPWM(0, 0, gateposition);
pwm.setPWM(1, 0, gateposition);
flash_leds(); // keep flashing leds
delay(40); // waits 40ms to slow servo
}
}
//===============================================================
void ending_sequence() {
for(gateposition = gatedownposition ; gateposition<gateuppostion ; gateposition++) // goes from gatedownposition degrees to gateuppostion degrees
{
pwm.setPWM(0, 0, gateposition);
pwm.setPWM(1, 0, gateposition);
flash_leds(); // keep flashing leds
delay(40); // waits 40ms to slow servo
}
digitalWrite(led1, LOW); // flashers completely off
digitalWrite(led2, LOW);
digitalWrite(Bell,LOW);
}
//==============================================================
void flash_leds() {
if (flash_time > millis()) return;
flash_state = ~flash_state;
digitalWrite(led1, flash_state); // Alternate flashers
digitalWrite(led2, ~flash_state);
flash_time = millis()+flash_interval;
}