E15 Laboratory 2
A/D & D/A

This lab will introduce you to some fundamental skills, many of which will be used in later labs. You will:

 

You will notice that throughout the lab the instructions become less and less explicit. This is by design to get you to think about how to attack larger problems. If you feel completely at sea, please ask for help. Throughout the next several labs, you will be given more freedom (i.e., less direction) as you solve problems. But... you should always feel free to ask for help.


Lab Groups for Lab 2

https://docs.google.com/spreadsheets/d/15VwEE7w59QeIROxAi00whOWd_xkeiUVw6wHln9kT5hE


The Schematic & Layout

Below are images of the schematic of the board you made as well as the silkscreen of the layout that you may find useful during the lab.


The Serial Monitor

The Arduino is capable of user interaction through your computers monitor and keyboard. A simple program that is often used to make sure the connection to the computer is working is called "Hello, world." Run the program hello.ino, given below. You will have to open the serial monitor to see the text displayed; you can do this by going to Tools→Serial Monitor. Make sure the baud rate (lower right corner) is set to 9600.

 

The "hello, world." program prints to your computer screen, you can also get input from the keyboard. Try the following code and enter the number "55"into the top line of the console, then hit the "Send" button..

 

Single bit (digital) I/O

In the first lab you controlled an LED with a single bit from the processor that was an output, this week we will start with a single bit input. Download and run the code Button.ino. Discuss among members of your group until you can all explain to each other how it works.

Now repeat for the shorter program ButtonShort.ino (which is not altogether dissimilar from Button.ino).

The Voltage Divider and A/D Convertor

In this section of the lab you will explore A/D analog to digital conversion with the Arduino.

First, let's measure an analog voltage with a voltmeter. Set the voltmeter for a 20V maximum DC voltage input (turn dial to the label 20V with a dashed and a solid line above it ). With nothing connected the voltage should be 0.00. Now connect a black lead from "COM" on the voltmeter using a banana jack to the test point on your board labeled "JGND" (lower left corner) with an alligator clip, and a red lead from "V·Ω·mA" to "JVCC" (lower right corner). Make sure the clips are grabbing the metal loop of the test pointand not the plastic collar. Record the voltage.

Now connect the red lead to "J_A0" which is connected to the wiper of the potentiometer on the Grove Beginner kit. Turn that potentiometer and you should see the voltage reading go from 0V to the value you measured at "JVCC."

We can convert this analog voltage to an integer number using an A/D convertor. The following code, AD_Serial.ino, reads from analog input A0.

 

Make sure you understand how the code works, and then use it to record A/D values (from serial monitor) and the corresponding input voltage (from voltmeter) using a format similar to the table below. Take about 15-20 values more-or-less evenly spaced measurements from the minimum voltage to the maximum voltage.

Voltage A/D Reading
   
   
.
.
.
.
.
.
   

 

From your data figure out how many bits of resolution the A/D convertor has.

 

Now take a look at the schematic and figure out how to change your code so that you read from the two potentiometers that are part of the joystick on the E15Shield board. Test it to make sure it works.

Pulse Width Modulation (PWM)

Run the following code, DA_keyboard.ino, enter values between 0 and 7 and observe the LED on your board. Figure out what it does (you have to add comments for the report).

 

Start with MY_DELAY set to 1000. Run the code and observe the serial monitor. Enter several different values between 0 and 7. Make sure you can explain what is happening. You can add print statements if you think it would be helpful to your understanding. The PWM cycle takes 7 seconds, so the PWM frequency is about 0.143 Hz (1 Hz = 1 cycle per second). Note: this code assumes that all computer instructions take 0 time, except for the delay.

After you (and everybody in your group) can explain to the others in your group how the code works, remove any print statements you added. Now change MY_DELAY set to 100. Run the code and enter values between 0 and 7. If the behavior of the system doesn't match your expectations, go back to the previous step, and try to make sure it makes sense. PWM frequency is 1.43 Hz .

Now change MY_DELAY set to 10. Run the code and enter values between 0 and 7. If the behavior of the system doesn't match your expectations, go back to the previous steps, and try to make sure it makes sense. PWM frequency is 14.3 Hz .

What happens if you set MY_DELAY to 1 and enter values between 0 and 7? Why?

 

Notice that the light doesn't appear to get uniformly brighter as you increase the number from 1 to 7. That is because your eye has a roughly logarithmic sensitivity to light. The graph below shows the intensity of light vs the perceived brightness. You can see that there is a much greater change in perceived brightness at low intensity (i.e., when you entered, 1, 2 or 3 into the serial monitor) than at high intensity (entering 5, 6 or 7). The reason for this is so that your eyes can respond to a much wider range of intensities; a doubling of light intensities is perceived as approximately equal changes in apparent brightness (your hearing also works this way both for pitch (octaves) and for intensity). So if you were in a cave and there was a small change in light intensity from a bear moving, you could perceive it and get out of the cave before the bear got you. Then when you got outside into the light your eyes would not be overwhelmed and you could still perceive the saber-toothed tiger trying to get you (this ignores other factors like pupil size changing and accommodations in vision that occurs over time).


https://hackaday.com/2016/08/23/rgb-leds-how-to-master-gamma-and-hue-for-perfect-brightness

Try entering the numbers 0,1, 2, 4, and 7 (each (non-zero) number is an approximate doubling of the previous) and you will perceive approximately equal increments in light intensity.

The code above implement 3 bit pulse width modulation. As you enter numbers the blue LED is on for 0/7, 1/7, 2/7 ... 7/7 of the time. The Arduino actually has a way of doing this in hardware on certain pins (so you don't have to write your own code (like I did) and the processor doesn't need to waste time. For example if you run the following code you can set the blue LED to one of 256 different levels (0/255, 1/255, 2/255, ... 255/255).

Run the code below (AD2DA.ino) that takes the 10 bit reading from a potentiometer, converts it to 8 bits, and then uses this to set the brightness of the LED. Note also that, as before, there is less change in perceived brightness as you turn the LED when the output of the A/D is high (say 800-1000) than when it is low (say 100-300). This is due to the perceived brightness effect discussed previously.

 

After you understand the code, remove the comment from the line labelled "Method 2" and comment out the line labelled "Method 1". The behavior of the code shouldn't change. Make sure you understand why. You may want to make use of this for the final step below.

Generate 24 bit RGB color

For this part of the lab "left, right, up, down" are defined with the writing on the board rightside up (in other words, the USB connector should be facing you, and the silkscreen should be in the same orientation as the image at the top of the lab).

Write code that simultaneously


You may want to do the three tasks separately (or at least add them one at a time), instead of trying to get it all to work at once.

Recall from last week:

RGB colors can be found at https://www.rapidtables.com/web/color/RGB_Color.html. Go to the page and find the table labeled "Basic colors:". Look at the rightmost column (or the one next to it if you know hexadecimal - we'll cover that soon). The intensity of the Red, Green and Blue color is given as a triplet of numbers. If R=0, the red color is off. If R=255, it is at maximum intensity, and if it is 128, the color is about half of the the maximum intensity. So for the color (255, 0, 0), Red is at maximum intensity, and Green and Blue are off, so the color is "Red" and is written in the 2nd column. At this point we can only turn the LED on or off (so intensity is either 255 or 0); soon we'll learn to modulate the intensity of each LED individually.

 

This scheme is refered to as 24 bit color, 8 bits (0→255) each for red, green, and blue. With the LED we are using you can see the individual colors (though moving further away, or looking at the reflection off a piece of paper servers to help mix the colors), and there was no attempt to calibrate the brightness levels of the LED's. However, this same principle is also used on a computer monitor as well as the neopixels (the neopixel PWM frequency is between 400 Hz and 1000 Hz, depending on the specific type of neopixel).

By adjusting the three potentiometers, you can select any one of the 224 = 167,772 possible colors. Try a few colors.

Flicker Fusion Frequency

The frequency at which the oscillating LED appears to be constantly on is called the flicker fusion frequency. Download and run the code "flicker.ino" (below). You will have to open the serial monitor to see the text displayed; you can do this by going to Tools→Serial Monitor. Make sure the baud rate (lower right corner) is set to 9600.

Note that the frequency is only sent to the serial monitor when the button is pushed. This is because the Serial.print() function takes about 1 mS to display a character (when the baud rate at 9600). Open the serial monitor and press the button, and you will see that the frequency is displayed, but the flashing of the LED on the board actually slows down; in other words the fequency is displayed when the button is pushed, but the LED only blinks at the specified frequency when the button is released. Figure out how the code works (again, make sure that everybody in the group is on board what is happening).

Now adapt the code so that when the button is pushed, the value of the potentiometer on A0 is read and is used to set the frequency between about 0.5 and 500 Hz. The exact range is not important; the lowest frequency should be slow enough that you can see the LED flashing and at the highest frequency the flashing should not be perceptible. You may want a smaller range of frequencies so you can get a more precise calculation of frequency. When the button is released, the LED will flash at the frequency selected by the potentiometer.

Have each person in the group measure their flicker fusion frequency, and record these values.

To turn in:

Formatting

For each section of code turned in you will lose one point if

Turn in a single pdf with responses to the following numbered questions.

The Serial Monitor

1) (5 pts) Run the "addOne" code from above. Enter some numbers to make sure it operates as expected. Now enter the number 32767. What is the answer that you get? Why? If you can't figure it out, research "16 bit integers".

2) (5 pts) Why is the line
       Serial.read();
necessary?

The Voltage Divider and A/D Convertor

3) (5 pts) Include your table of voltage values (Vin) and A/D readings (adVal). Add a third column for expected value which is 1023*Vin/Vref, where Vref is the actual value of the voltage supply that you measured (it should be close to 5.0 V).

4) (5 pts) Include a plot of Vin (x axis) vs adVal with discrete markers (e.g., a circle or "x") as well as a line that shows 1023*Vin/Vref.

5) (5 pts) The voltmeter uses and A/D convertor internally to measure voltage. Given that the voltage scale is -20.00 to 20.00, speculate on the number of bits of resolution the A/D convertor in the voltmeter has.

Pulse Width Modulation (PWM)

6) (10 pts) Turn in the code for DA_Keyboard.ino with comments added to demonstrate that you understand how the code works. Include a significant block comment at the top that describes how, in principle, the code works.

7) (5 pts) Explain why “Method 1” and “Method 2” in the code AD2DA.ino accomplish the same thing?

 

extra credit, (5 pts) Clearly explain why the code A2DA_exp.ino (below) gives increments in perceived brightness that are approximately equal.

 

24 bit RGB

8) (10 pts) Include your well commented code.

9) (10 pts) Fill out the table with the names of the colors generated (CW = clockwise, CCW=counterclockwise). Use color names from "Basic colors:".

A0 Potentiometer Joystick (X) JoyStick(Y)     Color Name    
fully CCW to the left to the bottom  
fully CCW to the left to the top  
fully CCW to the right to the bottom  
fully CCW to the right to the top  
fully CW to the left to the bottom  
fully CW to the left to the top  
fully CW to the right to the bottom  
fully CW to the right to the top  
midway midway midway  

Flicker Fusion Frequency

10) (15 pts) Include the well-commented code that you wrote to set the flicker frequency with the potentiometer (make sure you also include comments for calculation of the flicker frequency).

11) (5 pts) Include the flicker fusion frequency of each member of the lab group, as well as the group's average frequency.