Hi I am Massimo Banzi
and I like to make things
and welcome to another Arduino tutorial video.
Today we are going to build a theremin.
A theremin is a musical instrument
that produce different sounds
depending on the position of the hands
of the player around the instrument.
In this particular case
we are going to build a very simple
theremin using a light sensor
as a way to capture the position
of the hand of the player
from the Arduino.
You will be using a photoresistor
to detect the amount of light
and from the amount of light
we are going to guess the distance of
the player's hand from the sensor.
Here we have a piezo-buzzer.
The piezo-buzzer produces
sounds every time it is
turned on and off.
It is connected with a wire
to pin number 8.
While here we have a light sensor
connected to analog input zero.
The light sensor
detects the amount of light
that hits the surface of the sensor.
By moving the hand
from the sensor
we reduce or increase
he amount of light that hits the sensor
and in turn this information
goes into the Arduino
as a variation of voltage.
In our code we are going to use
the variation of voltage to
gauge the distance of the
player's hand from the sensor,
and we are going to map that
to appropriate values of sounds
and then we are going to drive
the piezo-capsule
using the "tone" function in Arduino.
Let's start building the circuit.
The first thing to do is to
connect the power bus
with the red and black wire
to the two strips
on the side of the breadboard.
Then we connect the piezo-buzzer.
Since the piezo-buzzer is a bit
tricky to mount we have to
prepare the two wires
at the right distance on the breadboard
and then plug in
he piezo in the correct lines
on the breadboard.
Now let's place the photoresistor.
Here is the photoresistor,
we placed it on the breadboard.
We connect a resistor between
this leg of the photoresistor
and ground.
We have
another wire going from
the 5v rail to the other
side of the photoresistor,
and then one wire
connects the photoresistor
and the resistor here to the
analog input zero
of the Arduino.
In this case we have set up
a sensor that reads
the amount of light
and converts that into voltage
that we can measure with Arduino
and then we have connected an actuator,
the piezo-capsule
that produces sounds
and now we are going to write
a piece of software that
ties them together.
The software that we are going to use
for this project
starts off with a
5 seconds calibration period.
During this time
you will move the hand
near the sensor like this
to let Arduino calibrate the values
that represent the minimum
and the maximum amount of light
that can hit the sensor.
After these 5 seconds,
Arduino will
start the main loop
and during the main loop
we have a very simple structure.
We read the amount of light
in terms of voltage applied
to the analog IN,
and then we convert that
to a suitable
frequency to play on the piezo speaker
and we use the "tone" function
in order to play that sound.
Let's look at the code.
We start off at the beginning
defining a few variables.
The first one is called sensorValue.
It's an integer variable
that stores the values
read from the light sensor.
After that we define to variables
called sensorLow and sensorHigh
and these are used
in the calibration phase
to determine which were the minimum
and the maximum values read
from the sensor.
So, where is the trick?
As you can see we are defining
the variables.
sensorLow starts off at 1023
and sensorHigh starts off at zero.
This is done on purpose
o make sure that if we read
a value from the sensor
it will always be less than 1023.
If we start with sensorLow at 1023
we are making sure that
the first value that we read will be
less than that and the calibration
can operate correctly.
At the same time
we are using sensorHigh
and setting it up at zero,
so that any value we will read
from the sensor will
hopefully be more than zero.
After these variables we define
the classic constant ledPin
and we assign it the value 13,
because we are going to use the LED
to signal
when the calibration phase is over.
In the setup we have pinMode(),
defining pin number 13 as an OUTPUT.
And then we
digitalWrite(ledPin, HIGH),
so that we basically turn on the LED
to signal that the calibration
phase has began.
Then here we have
an interesting piece of code.
It's a while loop
that uses the millis() function
to make sure that the calibration phase
lasts for exactly 5 seconds.
How is that done?
The millis() function
is a function that
returns the number of milliseconds
that have passed since the last time
the Arduino board was
turned on or reset.
Every time you upload code
or press the reset button,
or you plug the power,
the Arduino restarts
from zero milliseconds
and millis() will return a number
that grows as time goes by.
What we are going to do here
is that since this code
is exactly at the beginning
of the setup(),
it's happening
in the very few milliseconds
right after the board was turned on.
So, by doing while( millis() < 5000 ),
that we have here
in the while loop,
we make sure that the code
within the while loop is executed
only during the first 5 seconds
the board has been turned on or reset.
What is happening here?
We read though analogRead()
We read from input zero.
We place that into sensorValue.
Then, with a very simple algorithm,
we check if sensorValue
is more than sensorHigh,
then we make sensorHigh equal to sensorValue.
Essentially we are saying:
"is the value that I am reading
from the light sensor now
higher than the highest value
that I have read until now?"
If that's the case,
then that value becomes
the highest value
that we have read until now.
We do the same thing
for sensorValue and sensorLow.
Again, we do
we check if sensorValue is
lesser than sensorLow
then sensorLow becomes equal to sensorValue.
This code gets executed
as many times as possible
within the 5 seconds
after the board was turned on or reset.
If I move my hand over the sensor
like this during the first 5 seconds
that the program has started,
I bascially let the light sensor
experience all the possible values of
minimum and maximum light.
After that I come out of this
calibration phase with
the minimum and maximum values
stored in sensorLow and sensorHigh.
Then, as you can see here,
with digitalWrite(ledPin, LOW),
we are turning off the LED
to signal that
the calibration phase is over.
The loop is very simple.
During the loop we read
the analog input zero
and we store that into sensorValue.
Then we are going to use an interesting
function called map()
because we have
a minimum and a maximum value
that the sensor can read
in the current light conditions,
and then we have the minimum
and maximum audio frequency
that we want to play back.
Instead of having to calculate manually
the matching between those values
and the frequency values
that we want to play back on
the piezo speaker,
we are going to use this function called map().
map() is very simple to use.
We specify a value
that we want to map:
the first parameter,
that is sensorValue.
Two parameters follow sensorValue.
They determine which is
the value range that
the input value can have.
So sensorLow and sensorHigh determine
the range of values
that sensorValue can take.
The last two parameters of
the map() function determine
which is the output range
that we expect from map().
Very simply we can say:
this is a value,
this value can be between a minimum
and a maximum value and
depending on which value
I am processing
I want to produce
a value which is
within this other range.
Our aim is to very simply say:
for any value within sensorLow
and sensorHigh,
we have to produce a number between
50 and 4000,
that represents the frequency
of the audio signal that we want to produce.
The result of this calculation
goes into the "pitch" variable.
In the next line of code
you can see that tone()
is producing a sound
on the piezo-speaker connected to pin 8,
and the pitch
is the value we calculated
previously sung map(),
and 20 is the duration of this sound.
After this sound has been
produced we delay for
10 milliseconds, and then we continue.
Let's upload the code
onto the board and let's see what happens.
You can see that if you
gauge your movements
properly you can
produce a lot of different sounds.
I am sure you will find this project fun
probably for the first five minutes,
then the sound will become too annoying
and you will be prompted to do this.
Thank you for listening.
Now you have to build it,
hack it, and share it,
because remember that Arduino is you!