Model Train Forum banner

Introduction to Arduino part 3 - Our first project

5K views 19 replies 7 participants last post by  time warp 
#1 ·
Now that you have your basic tools in place, it's time to DO something with your arduino. The majority of your work with a microcrontroller will be handling inputs and outputs (commonly known as I/O). We are going to to simulate a train approaching a crossing by pressing a common switch and flash a pair of LED crossing lights until you release the switch.

Lets begin with some basic principles in the arduino code. As seen in the previous Blink code, the control pin for the LED was set as an OUTPUT -- this means you are sending something OUT from the arduino to control a real-world device. And of course we'll be using two LEDs, so we want to set up two different pins.
Code:
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
However for a switch you want to set the control pin as an INPUT, meaning you are receiving a signal INTO the arduino that your program can read.
Code:
pinMode(8, INPUT);
There are a multitude of devices you can hook up to your arduino, but they all follow the same principle... If you want to read the track voltage, you would use an input. If you want to control motor speed, you use an output.

So now we need to decide how our program is going to work. Think of a program as a never-ending flowchart. If something happens, you want to take a different path through your flowchart, but eventually you always want to come back to the start again. For this project, we'll begin by watching for someone to press the switch. If the switch isn't pressed, go back to the start and check again. Once the switch has been pressed, we want to flash the first LED for one second, then flash the second LED for one second. After that we go back to the start and if the switch is still pressed then we would flash the LEDs again. Now keep in mind that the time it takes to go back to the start, check the the switch being pressed, and begin flashing the LEDs again happens so quickly that to your eyes, the LEDs will continue a steady one-second flash back and forth until you relase the switch.

All right, now that we have a plan, lets write some code! Because the different models of arduino may have different pinouts, we are going to start by setting some variables to hold the pin numbers. For instance, "int switch1 = 8" means that I am going to create a reference with the name "switch1" which is an integer number, and set the value of it to 8. Now if you need to change the pin number for your particular arduino, instead of having to change several lines in the program you only have to change this one variable. Plus it makes the code easier to read when you have a meaningful name instead of some seemingly random number.

Code:
// Define our variables
int led1 = 2;
int led2 = 3;
int switch1 = 8;

// the setup routine runs once when you power on the arduino:
void setup() {
  // initialize the pins we will be using
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(switch1, INPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  // Is the switch being pressed?
  if (digitalRead(switch1)) {

    // Turn on led1, turn off led2, and wait 1 second
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    delay(1000);

    // Turn off led1, turn on led2, and wait 1 second
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    delay(1000);

    // Turn off both LEDs in case the switch is no longer being pressed
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
  }

  // Nothing else to do, so go back to the top and start again
}
Following is the wiring diagram for hooking up the components on your breadboard. A couple of things to be aware of here. First, LED's have a polarity, and if you hook them up backwards you will blow them. If you look at the leads inside the LED, you will see one of them has a 'flag' (see image below). That flag indicates the negative side. Also note that LEDs must always have a resistor with them to prevent drawing too much current (again, they will blow up). You may notice that the switch is connected to both the positive and negative terminals. The in-line resistor prevents a short circuit, and ensures that when you areOT pressing the pushbutton, the arduino sees a ground voltage. This may not always be nessassary, but it's best to play it safe. Finally, the positive and negative terminals at the bottom can be left off if you plug your arduino into the computer's USB port (but you still need to connect the positive line to the switch). The USB port can provide plenty of power for this project, and is much easier than trying to find a separate power supply.


If you wanted to expand this to both sides of your intersection, you could easily add two more LEDs and change their state at the same time you change the first two, so you would have two set to HIGH and two set to LOW (or you could just run multiple LEDs from the same output). If you had a two switches on the track to watch both directions, you could modify the 'if' statement to check both of them like this:
Code:
  if (digitalRead(switch1) || digitalRead(switch2)) {
The double-pipe in the middle (||) in programming means "OR", so it literally reads as IF switch1 is pressed OR switch2 is pressed then do the following...

After playing with this, you may notice that even when you release the switch, the LEDs will finish their 2-second dance before turning off completely. The delay commands are what as known as a "blocking" function -- meaning they block anything else from happening until they complete. So in that 2-second interval, you could release and press the switch again, and when the code gets back to the start of the loop it sees you are holding the switch again and continues to flash the LEDs as if nothing happened. In the next article we are going to add a crossing gate controlled by a small motor. Since many things need to happen at the same time, we will introduce "non-blocking" functions so that multiple devices can be controlled simultaneously.
 
See less See more
1
#2 · (Edited)
Erg... and I just realized there's a mistake in the schematic. The input for 5v-9v is correct, however the switch needs to be connected to the VCC pin (3 pins to the right) and should NOT be connected to the RAW pin if your power supply is higher the voltage your arduino is rated for. If you have a 5v model, you can safely apply 5v to the input pins. If your arduino is rated for 3.3v then you shouldn't have more than a 3.3v signal applied to any of the input pins...

For those who may be wondering, the RAW pin connects to a tiny voltage regulator on the arduino, converting your 5v-9v input to a safe level for that particular board. If you then take a signal from the VCC pins, you will only see a voltage of 5v or 3.3v (again depending on your board).

I'll get the schematic fixed tomorrow, and try to answer questions when I'm more awake. Sorry for the error.

[EDIT] The circuit above has now been corrected. Something else that I forgot to mention is that different arduino boards may use different pin numbers. For example, the board I tested on doesn't have a pin 8, so I had to use pin 5 for the switch. As I mentioned above, you can easily make a change to work on another board and still use the same code to accomplish your task.

If you are using a 3.3v arduino, the LED's might be too dim to see easily. If this is the case, try changing the 330 ohm resistors to 270 ohms or even 220 ohms. Reduce one step at a time, because as I mentioned too much current will destroy your LEDs.

And for those who don't have a degree in electronics, I should probably mention that resistors are marked with color-coded bands that signify their value. Four bands with the last being gold is a 5% tolerance resistor, meaning the value is +/- 5% of the stated value. There are also 5-band resistors where the last band is brown. These are 1% resistors. They are more accurate, however for the experiments we are doing here we won't need a high degree of accuracy.

So... A 330 ohm resistor will be marked on a 5% resistor as orange-orange-brown, or on a 1% resistor as orange-orange-black-black. A 270 ohm resistor will be marked as red-purple-brown or red-purple-black-black. And a 220 ohm resistor will be red-red-brown or red-red-black-black. If this is something I should cover in more detail, ask below and I'll give a quick primer...
 
#3 ·
Just got in the new arduinos last night, figured I would solder the pins on one of them and use it as my test platform.

I've been thinking about the next step though and I think there is too much to cover by jumping directly to the crossing gates, so instead I think I will do a demo for running the motor in a locomotive, in which I will cover getting power from the track, non-blocking timers, and a simple way to work with motors. Then for the crossing gate article that will only leave the discussion of stepper motors, a simple program to calibrate the number of steps required between positions of the gate, and then the full program with gates, flashing lights, and multiple detection switches.
 
#6 ·
It's a prototype


No.

The chimes need air volume, not pressure and a compressor will not work BETTER in this application.

As soon as I am comfortable with the setup (the encoder is a little dodgy) the plan is to sense a threshold on the encoder to actuate a relay to power the blower i.e. a short tug on the chain preps the system.

Stay tuned - same Bat-Channel,
Tom
 
#7 ·
Train Whistle Clock

My latest Arduino project is, what I call, a Train Whistle Clock. In summary, different .WAV files of real steam train whistles are played on the 1/4, 1/2, and 3/4 hours. Bell tolls at 4/4 indicate the hour. Sketch written by me with plenty of help from various Internet sources.

The hardware consists of a DCcduino uno (Chinese Arduino clone), BY8001-16P micro SD card reader, DS3231 RTC, 12 VDC wall wart from my toybox, and a speaker my Dad assembled in 1957 to listen to his Heathkit radio.

The completed project will take the place of a Windows 98 box I used to have in my Shop which essentially performed the same function until it finally expired last year.

Tom

Electronics Audio equipment Technology Electronic device Electronic instrument
 
#11 ·
I agree

Well, the ...That's probably why you got the popping noise. ;)
I was REALLY hoping ED-RRR would chime in & set us all straight since he knows everything. :p But since he's been absent for a while, I feel safe in sharing my sentiment of "excellent observation, GRJ - I totally agree".

Just kidding about the ED-RRR comment.

My son and I are both enjoying building Arduino-based projects. But it is amazing how large the "spare parts stash" can grow, with a minimal investment, in a very short amount of time.

Plastic

Tom
 
#13 ·
Wait... pile? You got all of yours in just a 'pile'??? Let's see, I have parts in trays under the legos, under the trains, next to the video cards and memory sticks, under the wifi routers, under the camera case, beside the plaster halloween mask, beside the 'mad hatter' hat (we did an Alice-in-Wonderland theme of "The Mad Splatter" while competing with the trebuchet), next to the box from the laser jammer, old DSL modems, and laptop screens... Hmm I should get back into making the pieces for those wakizashi blades this Summer, oh look there's that drill I used as the first motor I hooked up to an arduino, and what were we talking about again?
 
#16 ·
Hi,

I've currently got 5 Arduino based projects for my layout.

They are in various stages of completion as I am trying to move ahead on all of them, so I work on each for a period of time and then move on to the next.

A bit of background...

My layout is automated using Train Controller (TC). I have two digital systems connected to TC.

One is a Roco Z21 which is strictly for controlling trains.

The other is a "stand-alone" LocoNet network created using RR-CirKits devices. This network is for all sensing and control functions needed by TC.

So back to the Arduino projects...



Only one is project is currently installed on the layout and is used to tie a servo controlled train order semaphore to TC.


My next project to be installed will serve two purposes.

The first is to process the keypad input of the eight 12 key keypads installed on the fascia for manual turnout and uncoupler control.

The other is to allow using the Roco handheld to issue turnout commands to provide an alternate form of manual turnout control.

The project has hardware to process keypad input and two separate LocoNet network connections.

The first is for connecting to the standalone LocoNet.

The second is for connecting to the otherwise unused LocoNet connector on the Z21.


The keypad input is recognized and converted into LocoNet turnout control messages and sent out over the standalone LocoNet.

That part is working just fine.


The other part is a little more complicated.

Turnout control commands issued on the Roco handheld appear on the Z21 LocoNet connection but for certain reasons related to TC I do not want to connect this LocoNet directly to the standalone LocoNet.

So the project device is receiving the Z21 turnout control messages where they are processed and then the appropriate turnout control messages are issued over the standalone LocoNet.

It's all working but I am in the process of cleaning up the code and be sure all is working as intended.

Fun stuff.

Frederick
 
This is an older thread, you may not receive a response, and could be reviving an old thread. Please consider creating a new thread.
Top