While you’ve successfully managed to leave the lights on, you’ve so far been limited in that you have only been able to do one thing at a time. With software, we can do multiple things (or at least have the appearance of multiple things) happening.
Software is the realization of Alan Turing’s universal machine. In short, this is a computational machine that can replicate any other computational machine after being fed a set of instructions that indicate the computation to go through and how the machine is set up to do this. Through software, we can reconfigure a machine to do anything we darn well please, including teaching the machine to behave like a different machine (see also, emulators).
There a many many different types of software languages, the ones that I think are most interesting are the least useful to us. Generally speaking, languages can be laid out along a continuum of “high-level” to “low-level”. As we’re not planning on talking directly to the silicon in the chips we’re using, we can use a higher level language that abstracts the basic instruction set.
The general idea behind software is that it abstracts machine instructions (a series of 0s and 1s) and gives us something closer to natural human language to address the computer with. We have limited options for the Arduino that we’re starting off with, an that’s a good thing. The Arduino language is a high level variant of C (the language that makes the Earth spin on its axis).
While you can write software anywhere, a scrap of paper, text pad, back of your hand, it’s best to write it in an application that will compile the code into something meaningful to the machine. With Arduino, the makers of the hardware have created an IDE (Integrated Development Environment) that allows us to write code and compile it to machine language in one place. It will also do the neat backflip of loading the code onto the microcontroller for us. That way, you can upload your code, unplug it from your computer, and let it go on its own very way, running your program all the live long day.
Read this to get a good idea of the ins and outs of the Arduino development environment.
Obviously we need a something to get the software to run on. The Arduino micro controller we’ll be using in class is called the Uno. Thanks to it’s open hardware philosophy (like open source software, but for physical bits) there are as many Arduino clones as there are stars in the sky. This has also cemented its place in the media art world as the cornerstone around which physical things are made. There are a bunch of variants (Leonardo, Micro, Due, Zero, Lilypad, Gemma, Ethernet, etc etc), and they all have a place that we won’t get to in this class.
An Arduino can do a bunch of things, but what it really excels at is gathering information about the physical world through electrical inputs, doing a little processing on the values it reads off those inputs, and spitting back information about that reading. This information can take the form of a motor spinning, a buzzer budding, sending data to a multimedia computer for more processing, or lighting up an LED. This last one is the easiest, so we’ll start there.
I like to divide up the tasks individually when working with software and hardware. I find this makes the task of debugging (which will become your frenemy by the end of this course) much easier. Since we’re delving into programming today start, we can kick off there.
When you first open the Arduino IDE, you get a blank window that has some funny looking writing inside of it.
That’s code! Specifically it’s a pair of functions and comments.
Functions are the parts of code that actually do stuff. you can write your own but we won’t get into that until Processing. However, let’s look at what’s already here. Below is the function declaration for setup().
void setup() { // put your setup code here, to run once: }
The void is what the function will return. Some functions will respond with a number, object or character when called. This one doesn’t return anything, so it’s “void” (not related to the existential dread you get when faced with a blank window when coding).
setup is the name of the function. setup is a special function in Arduino language in that it is needed for every program, and will only run once when the program first runs (after a reset, power on, or new program upload). The () is where you would add any arguments that the function requires to run. setup needs none, and can be left empty.
The curly brackets {} are used to remark the start and end of what the function is supposed to do. You would write all your code for setup() between these. If a function is a paragraph of text, these mark it’s contents.
The // indicates a single line comment. This is something the IDE’s compiler will ignore. Comments are the most helpful thing you will ever use when programming. They are great for reviewing what you were doing 6 months earlier when you first wrote the program. You can write comments over several lines of by encapsulating them with /* ….. */ as seen below
void setup() { /* This is a multi-line comment. Everything between the paired asterisk and slash is ignored by the computer. */ }
After setup(), you need to call the function loop().
void loop() { // put your main code here, to run repeatedly: }
loop() runs over and over again forever until the power goes out. The speed at which it goes through your code depends on what you’re doing. Generally, though, it’s faster than you think.
Now, let’s do the “hello World” of hardware, and get an LED to blink.
In setup(), you need to declare what pin you want to turn into an output. The pinMode() function takes care of this for us. pinMode() takes 2 arguments, the first is the number of the pin we want to set, and the second is what kind of pin we want it to be (INPUT or OUTPUT). In this example, we’ll make pin 7 an OUTPUT.
void setup() { // put your setup code here, to run once: pinMode(7, OUTPUT); }
That ; you see at the end is going to bedevil you for a long time. Think of it like a period at the end of a sentence. While we can be pretty forgiving of run on sentences even when they lack full punctuation we can typically suss out the meaning of the author’s intent. Computers are not so forgiving, and need a semicolon after each line of code.
In loop(), you want to set the voltage of the pin to turn the LED on and off. digitalWrite() allows us to do this by telling a particular pin wether it is HIGH (in which case it turn the pin “on” and putting out 5V) or LOW (“off”, or 0V). We’ll want to alternate between on and off to make the blinking happen.
void loop() { // put your main code here, to run repeatedly: digitalWrite(7, HIGH); delay(1000); digitalWrite(7, LOW); delay(1000); }
The delay() function makes your program stop. You can change the duration of how long it stops as an argument. This value is in milliseconds because computers run crazy fast. This will loop forever and ever and ever.
Let’s build a circuit! It’s very similar to the one you made the other day.
Connect the anode (longer leg) of the LED to pin 7. Connect the cathode (short leg) to ground through a resistor (between 220ohm – 1kilohm is fine). Plug the Arduino into your computer and get ready to upload the code!
But first, you need to select which board you’re using in the “Tools” menu, and the port the board is connected to. This insures the IDE prepares the code for the right kind of board, and tries to communicate on the proper port.
Hooray! you should see some lights on the board flash, then the LED will start to blink!
Now let’s try and get some input. We’ll start with the code again.
void setup() { // put your setup code here, to run once: pinMode(7, OUTPUT); pinMode(8, INPUT); }
Here, we’re adding pin 8 as an INPUT. The Arduino can now read the voltage on the pin and let us know if it is HIGH or LOW.
Now on to the loop() where there’s some more new things than you might like :
void loop() { // put your main code here, to run repeatedly: if (digitalRead(8) == HIGH) { digitalWrite(7, HIGH); delay(1000); digitalWrite(7, LOW); delay(1000); } else { digitalWrite(7, LOW); } }
This introduces a number of new ideas in one swoop. Let’s start with something you;re already failure with. digitalRead() is a function that will check the voltage of the pin you give as an argument. digitalRead() returns a value, either HIGH or LOW, depending on the state of the pin. If there is 5V on the pin, it will give us HIGH, 0V will give us LOW.
We want the LED to blink when the button is pressed, that is, the voltage on the pin is HIGH. We can test this condition with an if() statement. if() check to see if something is true or false. If the condition is met (true) it will execute the code in the curly brackets that follow it. If not, it will ignore that code.
Note that we’re using == in the if() statement. This is very different than a single =. This is one of those lovely aspects of programming that is going to cause you more headaches moving forward. Sorry about that. The == is a comparison. A single = sets a value (which we will address next week).
We can read the code above like this : “Read the value of pin 8, if it is HIGH, blink the LED… “. The else is an aspect of the if() statement that helps control the flow of your program a bit better. It’s not necessary in this instance, but it’s not the worst thing to include either. All it’s doing here is adding an addendum to the above : “Read the value of pin 8, if it is HIGH, blink the LED. Else, if the value is LOW, don’t turn the LED on at all”.
Now that we have the code, let’s adjust our circuit by adding a switch. This is not as straightforward as you want it to be either.
You’re probably asking what the devil that 10kilohm resistor is doing in there.
When you press the button as wired above, the voltage flows to the Arduino pin, bypassing the 10k resistor (because electricity follows the path of least resistance, and the 10k is pretty big). When the button is not pressed, it provides the pin a reference to ground. Without that reference, the pin would be “floating” and may pick up all sorts of stray electricity. This 10k resistor is your insurance that you will always get the proper reading from the switch.
Now that you’ve mastered the basics of writing code for digital input and output, get the Arduino to do multiple things at once. Flash a light when one button is pressed, flash another when it’s released. Get some lights to alternate their rhythm. Make a career out of flashing lights on and off.
These are the 2 additional circuits we made in class :
2 LEDs, 1 switch
2 LEDs, 2 switches (for use with the and/or program)