Class 4

Key : 🔹 discussion     🔸 lecture        demo/activity      🍕 lunch 

 

 🔸 Rapid Prototyping Methods

 Arduino 201 

  • analog output and input
  • accelerometer
  • flex sensor

🍕

🔹 One-on-one discussions of final project ideas

 Start working on 1st prototype

H.W. work on 1st prototype

 

——————-

Analog Output

Analog output pins on your microcontroller make it so you can control devices with a varying output value. For example, instead of turning an LED on/off, you can fade it on and off or turn it on at a specific level of brightness.

Clip An LED onto the LilyPad making these connections:

power (+) LED –> pin 3 LilyPad

ground (-) LED –> ground (-) LilyPad

Some pins on your microcontroller are able to output a analog signal and some are not. The signal these pins output is actually called a PWM signal. This signal type is what makes your LilyPad able to output a seemingly analog signal. In order for the LED to be able to fade you need to connect it to PWM supported pins. Look up your microcontroller to see which pins those are. For example on the LilyPad USB you could connect to pins 3 – 11.

Open Sketch

In Arduino navigate to:

File > Examples > Analog > Fading

Copy and paste the example sketch in a new window and save as FadingDemo.

Change the lenPin value from 9 to 3.

Upload

Turn the board on if it isn’t already. Check your board, port and LED pin. When all looks good hit upload. The LED will start fading in and out. 

Code

There are a couple new things being implemented in this sketch. Let’s first review some things that should start to look familiar.

Create and declare a variable for the pin number the LED is clipped to.

When outputting analog values with analogWrite(), you do not need to call pinMode() like you did in your previous sketches, so nothing happens here.
For statement

Here is something new, this sketch uses a for statement. The for statement is useful for any repetitive operation, such as incrementing a value.

The for statement is made up of 3 operations: create a variable, the condition, and then increment (or decrement). The code that is between the curly brackets executes if the condition is true. Let’s take a closer look at what each of these operations do. Here is the for statement in its entirety:

Operation 1: Variable

Declare a variable called fadeValue with the value of 0.

Operation 2: Condition

Remember a variable holds a piece of data, in the first operation, you tell it to hold 0. This second operation compares the variable, which is equal to 0 now. If it’s less than or equal to 255, the code between the curly brackets and the increment gets executed. The “equal to 255” is put there so you make sure it goes all the way to 255 and doesn’t stop at 254. Once the value reaches 256 by incrementation, the condition is no longer true. The for loop is exited and the board moves on to the next block of code.

Operation 3: Increment and Execute

This is where the value gets incremented (or decremented). The combination of += is shorthand for fadeValue = fadeValue + 5. This adds 5 to the value that is being held in the fadeValue variable every time fadeValue is less than or equal to 255.

If the condition is true, the code between the for statement’s curly brackets gets executed.
The first time the for statement is executed fadeValue is set to 0. The second time it is 5, the third equals 10, fourth, 15 and so. This number correlates to the brightness of the LED which can be set 0 – 255. 0 being off and 255 being the brightest.

AnalogWrite()

AnalogWrite() is the function you call to write a PWM wave to an analog output pin. It takes two parameters (pin number, value). In this sketch it is saying, write to the pin your LED is connected to and use the value that is in our fadeValue variable (which is being incremented until it hits 255) to declare its brightness. This is how the brightness is notched up from each pass through the for statement.

The delay here is delaying the next loop through the forstatement, slowing down the fading effect. At 30 milliseconds it happens so fast the fade appears smooth.

Experiment

Cool, so now what? The code explanations may seem foreign and fuzzy so let’s change some code to see it action!

Change the increment from 5 to 10 and see what happens.

Change the 30 in the delay() function to 200 and see what happens.

Add Digital Input Challenge

Grab a switch soft or otherwise and add it to your circuit. Alter the code to read the switch and have the LED fade on and off when pressed. 

 

Analog Input

Analog input pins on a microcontroller enable you to gather data from sensors so you can read the world around you. For example, read the bend of an elbow or know how hard someone is pressing on a surface. The data you gather can then be applied to outputs triggering events like an LED fading or a note playing.

In this exercise, you will learn how to read a flex sensor, read a range of values and learn how to manipulate those values in order to control an LED.

 

The Flex Sensor

Remember the resistor used to restrict current flow in a basic LED circuit? The resistor used in that circuit has a fixed value of resistance that does not change. If current runs through a 47 ohm resistor it will always resist 47 ohms (+/- 5%).

A flex sensor is a kind of sensor where the resistance changes value. In other words, when current is running through it and you bend it the amount of current it resists changes. This gives you a range of values. When the flex sensor is connected to a microcontroller this range of values can be read and used as a way to sense that bending action.

Read Changing Resistance on Multimeter

Grab some alligator leads and connect the flex sensor to the red and black probes. The metal leads on the flex sensor are very close together so it may be tricky at first but you will get it eventually!

Turn the dial to 200k or any number larger than 20k on your multimeter. A number will pop up on the display screen and eventually settle on a number telling you the resistance of the sensor. Bend the sensor and watch the numbers go up to about 25k. The sensor is changing based on your movements.

Reading Varying Voltage with a Microcontroller

So, how do you get the range of values you see on the multimeter read by a microcontroller? A microcontroller can not read the changing resistance as easy as the multimeter, but there is a simple way to read changing voltage nicely. To translate this range of resistance to a range of voltage a simple circuit is used: a voltage divider circuit.

What is a Voltage Divider Circuit?

To have a microcontroller read a resistive sensor, like your flex sensor, you need a voltage divider circuit. The circuit consists of two resistors. These two resistors can either be two fixed, two variable or one variable and one fixed resistor.

The circuit we are building is the latter with one fixed and one variable resistor you would like to read (the flex sensor!). You run electricity through the two resistors and take a reading from the point where the two resistors meet. When the sensor changes resistance the voltage coming from the middle point, labeled “Voltage Out” in the diagram, changes. Below is the voltage divider circuit using schematic symbols. In this diagram R1 is the fixed resistor and R2 is your sensor (variable resistor).

 

 The value of the fixed resistor (R1) in the circuit is important because it will determine the range of voltage coming out from the “Voltage Out” point.

Choosing Your Fixed Resistor

When choosing a resistor for R1 there are many values to choose from. R2 represents our sensor in the above diagram.

How do we know what value resistor R1 should be? The value of R1 will determine the range of voltage that gets read by the microcontroller, so you shouldn’t choose just any value. To get the value that is best for your sensor there is a general rule of thumb to go by. This rule is easy to remember and will ensure you get a nice large range of voltage to work with.

+ Take the max resistance of your sensor and divide it by half. This is the value of your fixed resistor.

For example, the max resistance I measured my sensor at was 1.2k ohms. I divide that by 2 to get the value of the fixed resistor.

1,200 / 2 = 600 ohms

I round up from 600 so will use a 680 ohm resistor for my voltage divider circuit. Divide the max resistance you previously recorded by two and round up to the nearest resistor value you have in your kit. What did you get?

Want to know the math behind this circuit and how it works? I won’t get into it here instead, head over to Sparkfun’s Voltage Dividers page to learn more and make sure to check out their nifty voltage divider calculator.

Putting it all Together

Ok, so now we have our fixed resistor value which is R1 in the diagram and we have our sensor which is R2. What about the rest of the diagram? What gets connected to the microcontroller and where?

Below is the same diagram as above but now with our sensor and chosen fixed resistor. The “Ground” in the diagram gets connected to the ground on your LilyPad USB. The “Voltage In” will be the 3.3V coming from the power (+) pin on the LilyPad USB and the “Voltage Out” gets connected to an analog input pin so the board can read the changingvoltage. The “Voltage In” gets divided so the “Voltage Out” will always be smaller than the “Voltage In”.

Build Circuit

Let’s read the sensor’s values and add an LED as an output. This next exercise uses the sensor to fade on and off an LED. Grab your trusty alligator leads and make these connections:

flex sensor –> power (+) LilyPad

flex sensor –> resistor

resistor (same side the flex is connected to) –> pin A2 LilyPad

resistor –> ground (-) LilyPad

LED power (+) –> pin 3 LilyPad

LED ground (-) –> ground (-) LilyPad

Open Sketch

In Arduino navigate to:

File > Examples > Analog > AnalogInOutSerial

Copy, paste and save sketch as flexLED.

Upload

Change the pin numbers in the first two lines of code.

is the pin your sensor is connected to.
is the pin your LED is connected to.
Upload sketch and bend the sensor to change the LED’s brightness.

Get Max and Min

Open the serial monitor to see the sensor’s values.

Take a look at the numbers next to “sensor =”. When the sensor is resting record the number you see here. The number will change constantly so record the one you see the most and round to the nearest ten. Mine is:

780

Now, bend or press it to the maximum amount and record that number to the nearest ten. Mine is:

1020

Hang on to these numbers, you will plug them into your sketch in a next step.

 

The Code

Let’s go over what the code is doing in this sketch. Some of this may start to look familiar to you.

Declare two variables that hold the pin numbers the flex sensor and LED are attached to.

Create a variable to hold the sensor’s values coming in and one for the value that will be sent out of pin 3.

Open serial port.
AnalogRead()

Read the sensor by calling analogRead() and passing in the analogInPin variable. This function reads an analog value from an analog pin that is connected to a 10-bit analog to digital converter. This means that when you print sensor values to a serial window, the range you will see will be 0 – 1023.

Map()

The map() function maps a range of values to another range of values. This is useful for mapping sensor values to the brightness of an LED. When reading an analog value (like reading the flex sensor) the range is from 0 – 1023. When writing an analog value (like writing to an LED) the range is from 0 – 255.

The input range gets scaled to the output range using map() and the new range gets put into a variable called outputValue. The map() function has five arguments, these are the values in order: the value you are changing, old minimum, old maximum, new minimum, new maximum.

Write the newly mapped output value of 0 – 255 to the pin our LED is on.
Print the sensor value before it is mapped.
Tab over and print the phrase “output = “.
Print the newly mapped value that is the final output sent to the LED.

When you open the serial monitor, you will see the sensor values streaming. The column on the left are the raw, unmapped values, the column on the right are the mapped values your LED is receiving.

Change Sensor Range

This is where you plug in the max and min values you recorded in the previous step. Mine were 780 and 1020. Plug your minimum where it says 0 and your maximum where it says 1023 in the map() function in the flexLED sketch.

Here is what the line of code looks like with my values.

Put your values in and upload the sketch again. The LED will now have a larger fade range because it is calibrated to your sensor. If your LED flickers it means that you should raise or lower your minimum and maximum. For example, if your sensor drops below the minimum you put in the sketch the board will give the LED full voltage and it will get very bright. You can also see this happen in the serial monitor, the values next to “output =” will become negative. If this happens lower the minimum in your sketch.

Smoothing Sensor Values

Sometimes sensor values can be a little unreliable, which can cause unreliable behavior from your output. Open the serial monitor and take a good look at the sensor values as you interact with the flex sensor. Even when it’s seemingly still the values jump anywhere within 50 values, that’s a lot! Ideally, you want to minimize the noise and narrow down that window of jumpy values.

To help with this, math can be done to average or smooth out the sensor values. A newly averaged values are the ones that go to your LED, which means a smoother LED fade too!

Arduino has a smoothing example sketch you can find by navigating to: File > Example > Analog > Smoothing. Open it and change the pin number to whatever your sensor is on: 

Hit upload and open the serial monitor to see the new, improved and smoothed values of the sensor. 

Add LED Challenge

Combine the analog in and LED example with the smoothing example so the LED is receiving the smooth values. 

 

Headers Instead of Soldering

In the hybrid lab, soldering to the delicate pins of a flex sensor or FSR aren’t a good idea. A way to make a temporary connection is be using female headers soldered to the end of two wires.

IMG_9398

two female headers ready to be soldered to wire

 

IMG_9400

soldered with heat shrink tubing ready to shrunken with the heat gun!

 

IMG_9403

IMG_9408

Plug in the flex or force sensor

 

IMG_9412

Solder two female headers to ribbon wire.

 

 

Flex Sensor Playing Note Using a Threshold

Keep the sensor hooked up to A2.

Take a speaker, connect one side to pin 2 and the other to ground.

Copy and paste this sketch in a new window and save.

If you try to upload, you will get an error that a file doesn’t exist or is missing:

pitches.h

At the very top of the sketch we tell it to reference the file, but using #include.

Click the button in the upper right corner that has a downward arrow on it. It is below the serial window button. Choose New Tab

.Screen Shot 2016-02-10 at 7.16.41 PM

Name it pitches.h

Screen Shot 2016-02-10 at 7.16.47 PM

Click the link, copy the code and paste in the new pitches.h tab.
pitches.h

Screen Shot 2016-02-10 at 7.16.53 PM

The pitches.h file assigns numbers to the name of the note that it will play. For example:

35Hz will produce the note C sharp in the 1st octave, so that is the value being assigned to that variable.
#define is another way to declare a

variable.

Upload the sketch and open the serial window to watch your sensor values.

Bend the sensor and listen for your note!

 

Changing Pitch with Flex Sensor

This next exercise changes the pitch of the note as the flex sensor is bent, instead of triggering one note with one pitch when it bends to a certain degree.

There is an example sketch that you can work from. Open Arduino and navigate to File -> Examples -> Digital -> PitchFollower

Connect sensor to A2 with a voltage divider resistor of 10K ohm.
Connect speaker to pin 9.

Change the pins in example code to reflect.

Go ahead and upload at this point, bend and listen to the behavior of the note and pitch playing out of the speaker. It may sound off or wrong. This is probably because the values need to be changed in the map () function and tuned to the high and low values of your sensor that you discovered in the previous exercise.

If you need to read them again, open the serial window and you will see your values printing out there.

Map()

map (sensor pin number, from Low, from High, to Low, to High);

The map function takes out sensor low and high value and maps them to a range of new values that translates better to the frequency of a note. Our sensor’s low and high are about 260 – 520, and the output pitch range is 120 – 1500 Hz. You want to drop the new value range in a variable, which we are calling:

So you can use the map function like this:

Adjust the pitch range as you like, 1500 Hz produces some high pitches.

Combining Threshold with Pitch Follower
Notice how as soon as you upload the sketch the note starts playing. After some time, you realize it would be nice to control when the note started playing. You can do this by adding a button and telling it to start playing when pressed, or you can use the sensor too, and use the If statement used in the threshold example.

Open up a new sketch, copy and paste the code below.

This is where you are telling it to play the note and change the pitch based on the sensor reading IF the value goes less than 450.

Notice how I didn’t mention that we needed the pitch.h file? This is because we are using the number of Hertz instead of the variables declared in the pitches.h file. So, there is no need to add it.

Tone() is a good introduction to what an Arduino board can do on its own with the available memory it has, but there are other ways to make noise with a microcontroller.

Check out some ways to do that on the Making Noise with Microcontrollers page.