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.
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.
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.
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:
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.
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);
Code:
pinMode(8, INPUT);
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
}
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)) {
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.