My kids have been bugging me for years to get a train set to put under the Christmas tree. They like the thrill of watching train circle the base of the tree, and besides there’s a Christmas train set at Nanny and Pop’s house!
We found a cheap Christmas train set at our local variety store. After putting it together and giving it a run I discovered that the train runs on batteries (not surprise here) and has an on/off switch underneath the loco. One of the track sections has a lever which raises and lowers a cam which turns the train on or off.
The train also plays an audio track when it’s turned on. When the kids hear that sound they come running. They also now bug me to run the train. Time to hack the train set…
I want to be able to automatically turn the train on and off and I want to be able to schedule when the train is turned on and off.
To turn the train on and off I want to use an RC servo controlled by an Arduino to move the lever between the on and off positions. I drew a base plate to be laser cut from 6mm aluminium plate. The track section with the level is placed into the base plate and a RC servo motor mounted on the base plate so that it can actuate the lever.
The Arduino will control the RC servo with the standard Servo library. To keep accurate time I’ll need a real time clock which is not built into the Arduino. I used the DS1307 RTC kit from adafruit. This will allow me to run the train for 1 minute on the half hour in the evenings.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib // RTC communications based on example code here: // http://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/understanding-the-code // // RC servo contorl base on example code here: // http://arduino.cc/en/Reference/ServoWrite #include <Wire.h> #include <Servo.h> #include "RTClib.h" // http://github.com/adafruit/DS1307-breakout-board RTC_DS1307 RTC; // real time clock object Servo servoControl; // rc servo object // pin definitions int pinRTCGnd = 16; // analog pin 2 - used by Wire library int pinRTC5V = 17; // analog pin 3 - used by Wire library int pinRTCSDA = 4; // analog pin 4 int pinRTCSCL = 5; // analog pin 5 int pinLED = 13; // onboard LED/digital pin 13 int pinServoControl = 9; // digital pin 9 int angleOn = 179; // position of rc servo to turn train on int angleOff = 90; // position of rc servo to turn train off // array to look up which hours the train should be turned on int onHours[] = { 0,0,0,0,0,0, // 0-5 0,0,0,0,0,0, // 6-11 0,0,0,0,0,1, // 12-17 1,1,0,0,0,0 // 18-23 }; // array to look up which minutes the train should be turned on int onMinutes[] = { 1,1,0,0,0,0,0,0,0,0, // 0-9 0,0,0,0,0,0,0,0,0,0, // 10-19 0,0,0,0,0,0,0,0,0,0, // 20-29 1,0,0,0,0,0,0,0,0,0, // 30-39 0,0,0,0,0,0,0,0,0,0, // 40-49 0,0,0,0,0,0,0,0,0,0 // 50-59 }; void setup () { //set IO pins pinMode(pinLED, OUTPUT); // onboard LED pinMode(pinRTC5V,OUTPUT); digitalWrite(pinRTC5V,HIGH); // +5V for real time clock pinMode(pinRTCGnd,OUTPUT); digitalWrite(pinRTCGnd,LOW); // GND for real time clock // setup the real time clock Wire.begin(); // setup i2c communication RTC.begin(); // setup real time clock if (! RTC.isrunning()) { Serial.println("RTC is NOT running!"); // following line sets the RTC to the date & time this sketch was compiled RTC.adjust(DateTime(__DATE__, __TIME__)); } // setup the rc servo servoControl.attach(pinServoControl); // attach servo servoControl.write(angleOff); // set to off position // setup serial monitor Serial.begin(57600); // setup serial communication }//end setup void loop () { DateTime now = RTC.now(); // get time from real time clock if(onHours[now.hour()] && onMinutes[now.minute()]) { // train is on digitalWrite(pinLED,HIGH); servoControl.write(angleOn); } else { // train is off digitalWrite(pinLED,LOW); servoControl.write(angleOff); } sendTime(now); // send time from start of loop to the serial monitor delay(1000); // wait 1 second before running through loop again }// end loop void sendTime(DateTime now) { // send time to the serial monitor Serial.print(now.year(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.day(), DEC); Serial.print(' '); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); Serial.println(); } |