CS 153: Lab 3

Title image Fall 2018

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 PinConnected toPurpose
1Ground [GND]Ground for the backlight
25V PowerPower for the backlight
3Middle pin of the PotControls LCD contrast
4Board pin 7LCD control pin
5Ground [GND]Read enable control signal for sending data
6Board pin 8LCD control pin
7No Connectionunused data line
8No Connectionunused data line
9No Connectionunused data line
10No Connectionunused data line
11Board pin 9Data pin
12Board pin 10Data pin
13Board pin 11Data pin
14Board pin 12Data pin
155V PowerPower for the LCD controller
16Ground [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

  1. 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.
  2. 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);
    }
  3. 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.
  4. 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.
  5. 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.

  6. 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.
  7. 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).
  8. Enter the data into Google Sheets and use the linest function to get the linear regression of the data. Keep track of your function.
  9. 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.

NoteFrequency
C16.35
C#/Db17.32
D18.35
D#/Eb19.45
E20.60
F21.83
F#/Gb23.12
G24.50
G#/Ab25.96
A27.50
A#/Bb29.14
B30.87
  1. 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.
  2. Create a new C file called scale.ino. Copy your blank template from above into it.
  3. 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};

  4. 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.
  5. 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.
  6. 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.