Lab Exercise 3:
The purpose of this lab time is to give you an introduction to using the IR distance sensor and working with sound frequencies. You'll also get more practice with functions and loops.
Tasks
LCD Display
If you disconnected your LCD display after project 2, please connect it back to your board. The pin connections are shown below. Remember to connect the potentiometer to control the screen contrast. You'll be using your LCD to display various inputs and outputs during both the lab and project.
You can also leave one of your pushbuttons in place, though you won't need it for the lab.
LCD Pin | Connected to | Purpose |
---|---|---|
1 | Ground [GND] | Ground for the backlight |
2 | 5V Power | Power for the backlight |
3 | Middle pin of the Pot | Controls LCD contrast |
4 | Board pin 7 | LCD control pin |
5 | Ground [GND] | Read enable control signal for sending data |
6 | Board pin 8 | LCD control pin |
7 | No Connection | unused data line |
8 | No Connection | unused data line |
9 | No Connection | unused data line |
10 | No Connection | unused data line |
11 | Board pin 9 | Data pin |
12 | Board pin 10 | Data pin |
13 | Board pin 11 | Data pin |
14 | Board pin 12 | Data pin |
15 | 5V Power | Power for the LCD controller |
16 | Ground [GND] | Ground for the LCD controller |
In addition to the pins above, connect one side of the pot to ground and the other to 5V. The middle pin of the pot connects to pin 3 of the LCD.
Make sure your LCD screen is working (for example, by running a Hello World program that just writes a string to cursor location (0, 0)).
IR Distance Sensor
- Create a working directory for project 3. Open the Arduino IDE and create a new file. Put your name at the top and save it as irbasic.ino.
- Delete the existing setup/loop code and
replace it with your standard main function skeleton. The
init() and lcd.begin(16,2) are already included in the
template below.
#include <LiquidCrystal.h> // initialize the LCD library by associating any needed LCD interface pin // with the arduino pin number it is connected to const int rs = 7, en = 8, d4 = 9, d5 = 10, d6 = 11, d7 = 12; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // main function int main() { init(); lcd.begin(16, 2) // variable declaration here // other code here return(0); }
- The IR distance sensor is the device shown below. It works by projecting an IR light and then sensing its brightness. As an object gets closer, the reflection gets stronger.
- The IR distance sensor comes with a wiring kit. Connect the red wire to 5V and the black wire to ground. Connect the yellow wire to one of your analog input pins (e.g. A0). You will probably need to plug it into the breadboard and then run a wire from the breadboard to pin A0 on your metro board.
- In your code file, create a continous loop in your main
function. Inside the loop, read the IR sensor input using
analogRead and assign it to a variable of type int.
Define a character array of size 16, then use sprintf to
write the value to the character array with the format
string "%04d". Set the LCD cursor to (0, 0) and write the
string to the LCD.
Coding guideline: it makes your code easier to read if you put all variable declarations at the beginning of the code blocks in which they are used/defined. Variables you use over your whole function should be declared at the beginning of the function. Variables you use within a for loop should be declared at the start of the for loop, before any other code.
- Test your code by downloading it to the board and then waving your hand in front of the sensor. The values on the LCD should get bigger as your hand gets closer, and smaller as it gets further away. The IR sensor has a near limit of about 6" or 15cm.
- Get a measuring device and find a partner. With one person holding the sensor and object a certain distance apart, have the other person write down the distance and the IR sensor reading on the LCD. Take measurements of the IR sensor output from 6" to 15" in 1" increments (10 measurements). Write the data into a file (one option is to put it into a block comment in your irbasic code file).
- Enter the data into Google Sheets and use the linest function to get the linear regression of the data. Keep track of your function.
- Go back to your code. Write a function that takes in an IR distance sensor value and uses the linear regression equation to convert it to an actual distance value, which it should return. Use this function in your main loop and add this value to the LCD screen so that you can see both the raw sensor value and the estimated distance value. Test your program. Can you ensure the function never returns a negative value?
Frequencies
Musical notes each correspond to a particular frequency. There are 12 notes in a chromatic scale: C, C#, D, D#, E, F, F#, G, G#, A, A#, B. We can also represent these as numbers in the range [1, 12], which is common practice in electronic/computer music programs. A C major scale is [1, 3, 5, 6, 8, 10, 12]. These values repeat in octaves, and each octave is double the frequency of the one below it. The frequencies for the first octave are given in the table below.
Note | Frequency |
---|---|
C | 16.35 |
C#/Db | 17.32 |
D | 18.35 |
D#/Eb | 19.45 |
E | 20.60 |
F | 21.83 |
F#/Gb | 23.12 |
G | 24.50 |
G#/Ab | 25.96 |
A | 27.50 |
A#/Bb | 29.14 |
B | 30.87 |
- Connect the speaker to your board. One side of the speaker should be connected to a PWM pin (e.g. pin 5). The other side of the speaker should be connected to ground.
- Create a new C file called scale.ino. Copy your blank template from above into it.
- Write a function that returns the correct
frequency given a note in the range [1, 12] and an octave
value in the range [2, 6].
unsigned int genTone(int note, int octave)
- given the note and the octave, it multiplies the note's corresponding frequency by 2^octave and returns the frequency as an unsigned int. You will want to put the base frequencies from the table above into a float array in the function.Coding Tip: You can initialize the values in an array by putting the comma-separated values in curly-brackets. For example, to assign five values to an int array, you would use the following symtax.
int seq[5] = {1, 2, 3, 4, 5}; - In your main function, set up the speaker
pin as an OUTPUT (using pinMode). Then use your genTone
function to create frequencies for the (note, octave) pairs
(1, 3), (5, 3), and (8, 3), and use the tone function to play
the notes. Put a 500ms delay in between each call to tone. At
the end of your file, put a call to
noTone()
. Test your program, which should play the three notes of a C-major chord. - After playing the first three notes, have your function play a chromatic scale (notes 1-12 in order), spending 0.5s on each note. Use a for loop for this task, looping twelve times and playing one note each time.
- Make a second for loop enclosing your first one. This one should loop from 2 to 5. Use the outer loop variable as the octave argument to genTone. The result should be a 4 octave chromatic scale.
When you are done with the lab exercises, you may start on the rest of the project.