In this workshop activity, you will be working in the Arduino microcontroller environment and experiment with a few very essential and basic microcontroller functions, including digital I/O, analog I/"O", and the Serial Peripheral Interface (SPI) serial communication protocol.
Attention: If you would like to read a well written article about how to use breadboards, check out Sparkfun's how to use a breadboard
This lab will provide you with a better, hands-on understanding of how to use microcontrollers and serial communication between electronic primitive devices, fundamental knowledge for most electronics projects.
installing arduino ide
Download and install:
Technically, the online IDE would work too, if that's more your cup of tea.
The Arduino language is built on a C++ base, and each "sketch" has two main functions:
loop . The code in
setup is run once whenever
the Arduino is turned on, and the code in
loop is run, well, forever in a loop after the setup completes.
Want to learn more about the Arduino programming environment/code? Take a look at the offical language reference.
Why Arduino? Because it is convenient and easy to use, though it may be unoptimal for extremely cost and/or space constrained projects
As you learned in lecture, microcontroller General Purpose Input/Output pins have a core set of pins called Digital I/O. We will use these pins on the Ardiuno to control an LED and make it blink at any chosen interval.
Analog VS Digital: In analog circuits, the circuit "understands" a continous range of voltages. In digital, there are only two possible states: 0 and 1. An analogy can be made with light switches. Digital circuits are analogous to classic flip switches, while analog circuits are analogous to dimmer switches.
Arduino Nano breadboard installation
If you are using an Arduino Nano, you will need to install the Nano on the breadboard first. Carefully remove the Nano from its packaging. If you notice bent pins, please let an instructor know. Carefully insert the Nano into the breadboard across the split down the long center (called the "IC ravine"). Make sure to line up the outermost pins with the most extreme holes in the breadboard to allow yourself the most room for other components!
led circuit assembly
You will need an LED and 500 Ω resistor to assemble this circuit.
- Connect the anode (positive terminal) of the LED to the resistor and the cathode (negative terminal) to ground.
- Connect the other end of the resistor to any one of the digital output pins of the Arduino numbered 2 to 13. If you have a Nano, use any of the pins labeled with a "D", which stands for digital.
The Blink Sketch
Find and open the Blink example code in the Arduino IDE. (
File -> Examples -> 01.Basics -> Blink).
If you have a newer version of the Arduino IDE (1.8.9+):
- Add an
LED_PINto the top of the sketch, then changed all the
LED_BUILTINs to your new variable.
LED_PINvariable to the pin number you've connected the LED to. The default value will blink a LED on the Arduino microcontroller board.
- Add an
Upload your program by pressing the on screen upload or
Ctrl + U. When you press upload, Arduino actually first compiles your program. In other words, the Arduino IDE will let you know if there errors in your code before attempting to upload it. If you want to just compile, and not upload, then you can press the compile button in the toolbar or use the shortcut
Ctrl + R.
You may have a communication error between your computer and the Arduino board when you first try to upload. Click and bring down the "Tools" menu (button is at the top) and make sure you see...
- If you have a Uno: "Board: 'Arduino/Genuino Uno'. If you see any other board, change it to 'Arduino/Genuino Uno'.
- If you have a Nano: "Board: 'Arduino Nano'. If you see any other board, change it to 'Arduino Nano'.
Also in the "Tools" menu, click on "Port" and select a different COM, if there exists more than one.
Alter the delay on the program to change how many times the LED blinks, or whether it stays on longer or shorter (this is called the 'duty cycle'. will see more about this shortly).
How would you add more LEDs? Add one more LED and having it blink at a different rate than the first one.
You now have a sweet blinking LED circuit, but wouldn't it cooler if instead of blinking, the LED faded in and out instead? Let's learn about how we can achieve this behavior using only a digital output!
fake analog output
How can a digital signal, which can only be a high or low voltage, simulate an analog range of voltages? By doing something called pulse width modulation (PWM for short). It involves 2 basic ideas:
- We can flip the digital output between HIGH and LOW really fast, essentially creating a relatively high freqency square wave.
- We can control how long the troughs and waves of the square wave are. The ratio of the time the output is on VS off is called the duty cycle.
Notice that we can easily control the average power per unit time by changing the duty cycle. When the unit time becomes very small, human eyes will not be able to percieve on-off switching, but rather just the average value! This means we can fake any value signal we want by simply adjusting the "on"-"off" time ratio of the PWM signal.
PWM is used for many things, such as adjusting LED brightness as you are here, motor/servo control, etc.
Luckily for us, the Arduino software has taken care of the hard part of controlling the PWM signal, wrapping it all up in a nice, abstracted function called
analogWrite (see the documentation for it here). It takes one input: an integer between 0 and 255 that represents the desired duty cycle.
You can use the same circuit that you used for blinking, but you may need to change the pin your LED is connected to with a PWM enabled pin, as well as upload new firmware to the Arduino microcontroller.
- Open up the built-in Fade example via
File -> Examples -> 03.Analog -> Fading
- Change the
ledvariable to the pin number that your LED is connected to. You may need to move your pin connection to a pin that is is PWM-enabled! Refer to the reference images above, look for "Digital PWM".
- Compile and upload the new sketch to your Arduino Uno or Nano, and see if your LED starts to fade in and out!
- Feel free to try changing the code to...
- Make the LED fade in and out faster
- Make the LED fade faster in one direction, or only fade in one direction
- (2 LEDs) Make one LED blink and the other LED fade.
Let's say you want a lot of LEDs. It is a pain to have to set each pin manually for each LED, and that would also mean taking up more of the limited GPIO pins for basic on/off functionality! Thankfully, there exists these wonderful devices called integrated circuits: little black packages that house tiny but complete and robust circuits. Today, you will be working with the Texas Instruments SN74HC595N! Known as a shift register, this IC takes in Serial data and outputs Parallel Data!
You can even multiplex PWM signals this way, if you set things up correctly.
You can read a lot more about how this works with the shift register here but the gist is that a serial string of binary data will go into the system, and the system outputs will be set according to the order of the input bits.
What this IC allows us to do is utilize SERIAL COMMUNICATION over a few data control lines to control lots of on/off outputs. In our case, we will be utlizing the Arduino built-in SPI library and the SPI communication protocol to "program" the shift registers to control an array of LEDs!
The 74HC595N does not actually use the SPI protocol "officially", but works on a serial input, clock, and enable signal, which the SPI protocal helpfully provides (in fact, the SPI protocol consists of exactly those three things).
It will be extremely helpful and informational to have the datasheet for the SN74HC595N open for the next section.
Adding the Shift Register
- Place the shift register IC across the DIP IC ravine on your breadboard.
- Make sure to have the datasheet open! Find the Pin Configuration and Functions section and use it to help you wire up the IC correctly. The first column is the pin on the IC, while the Target column is which pin on the Arduino it should be connected to.
|IC Pin||Target||What it's for|
|OE||GND||Output always Enabled|
|SRCLR||5V||Reclear pin, disabled|
|SER||11||Data Signal, in sync with Clock|
|RCLK||2-13||Chip Enable. Use any avaliable digital I/O|
The Qa and Qb or any Q pins on the 595 are the parallel outputs, with A being the first and Q being the last. For now, simply hook up the one LED you have to the Qa output, through an appropriate resistor of course.
Controlling the Shift Register
Start a new sketch in the Arduino IDE (or just stay with whatever you already have).
Complete the setup part of the sketch as shown below. Make sure to set the csPin to the number you connected the RCLK line too!
- For the actual communication to the device, create a helper function called
writeSPIas shown below. This declaration should be outside of the pre-existing functions of the Arduino sketch (the
To make sure that the serial communication is working properly, make sure an LED is connected to the first output of the shift register, and try writing a
1to the shift register (in
void setup). The LED should light up. If not, double check your connections, LED direction, etc.
- Which LEDs light up given an input value can be analyzed with an understanding of the BINARY NUMBER system. If you are unfamiliar with binary numbers, check out this helpful tutorial.
- The A-H outputs correspond respectively to the least -> most significant bits of the value you send to the 595 shift register (using the above code). If you wanted to make the LEDs attached at outputs A and Q to be the only ones that light up, what binary value would you have to send via SPI?
Once you've verified that your Arduino can properly communicate with the 74HC595 shift register, hook up LEDs to all the outputs (or use an LED segment bar) and try to make them light in a pattern.
inputs are important too
Have you noticed that all the sketches you've uploaded so far included a
pinMode(led, OUTPUT); line in the setup function? We've only gotten the microcontroller to output something so far, so it is time to change that. In the following section, you will implement both analog and digital input features to your LED circuit.
pots and lights
Potentiometers (or pots, for short) are essentially adjustable resistors. Twist the knob, and the resistance between two of its pins changes. Photoresistors are a special kind of resistor: their resistance changes in response to the amount of light it senses. Both of these circuit elements can add an analog environmental input factor to circuits.
Unfortunately, microcontrollers cannot read resistance directly, but they can read analog voltages through specially marked analog pins, which have an A before the (analog) pin number.
These "A" pins are connected to an internal or onboard Analog to Digital Converter (ADC), which is a circuit (that you can learn how to make in classes like EE140) that turns an analog value (typically voltage) into a digital representation that digital circuits such as your microcontroller can then use.
What circuit could you use to "convert" a variable resistance into a variable voltage? (hint: think about a circuit you learned about in EE16A. The answer is also mentioned in the following section)
You can treat the photoresistor as a regular resistor, but the potentiometer needs to be inserted in a specific way.
Since potentiometers are effectively resistors split into 2 by the wiper middle pin, no additional resistors are needed to implement a voltage divider.
- Insert the potentiometer into a free area on your breadboard.
- If you choose to have the potentiometer facing upwards: Orient it such that the potentiometer's fat body legs are in the middle IC ravine; this will help it stay seated in the breadboard.
- If you choose to have the potentiometer facing horizontally: Use pliers to assist in bending the legs of the potentiometer such that you can insert it horizontally. This orientation is usually more convenient with our potentiometers.
- Connect one of the pins on the end to GND (note that this may be easier if you had established power rails)
- Connect the other pin on the end to 5V.
- Connect the middle pin to any analog pin on your Arduino (these will be the pins with an 'A' before the pin number)
To get the analog voltage value from the potentiometer, we use the
analogRead function (read its documentation here). In short, it maps the analog value of the input (a voltage between 0-5V) to an integer between 0 and 1023.
Any guesses as to why 0-1023 is the range of values for analog reads?
First, make sure the sensors are sending data to the Arduino. Make sure you get correct readings for both analog input devices before moving on.
- Copy this code into your Arduino IDE, in either a new sketch or an existing sketch from before. Please change the value of
sensorPinto the analog pin you connected your potentiometer or photoresistor to.
- In the above provided program, we are taking the sensor information from pin A0 and displaying that data in the Serial Monitor. The Serial Monitor is a convenient feature of the Arduino IDE that enables simple communication with the microcontroller during its normal operation, and can be accessed by clicking on the magnifying glass icon in top right corner of the program or pressing
Ctrl + M(or
Command + Shift + Mfor you Mac folks).
Why do you think it is called the Serial Monitor?
- Compile and upload the program to your Arduino. Once you have, open the Serial Monitor. Make sure to set the baud rate to the value specificed in the setup section of the code. You should see values appearing on the screen vertically. If the values change when you twist the potentiometer knob or cover and uncover your photoresistor, you've set up everything right.
buttons (digital boop)
Simple digital inputs such as switches and buttons are essentially ubiquitous in electronic circuits designed for some human interaction in mind. Both are pretty self explanatory mechanically and electronically, but (momentary) buttons have an interesting quirk when you try to implement them:
pot and fade
Now that you have a working analog input system, we can make microcontroller circuits that have both inputs and outputs. Let's try it by using the potentiometer to control the fade speed of your LEDs.
- Merge your previous two sketches (fading LED and potentiometer analogRead) into a new sketch.
- Use the value of the potentiometer to set the fade speed of the LED. You may find Arduino's built-in maps function to be very useful.