Music Mouse, Part II
This post is part of a series of notes and exercises for a summer camp on making musical instruments with Arduino and Pure Data.
We’ll complete the Music Mouse in stages. In this stage, let’s get the joystick behaving like a mouse. We’ll start at a position and allow the joystick to move us around the musical terrain.
Globals
Create two global int
variables to hold our x- and y-positions in this 2D musical grid. Initialize them to the MIDI numbers of your favorite notes. To avoid later suffering, give them meaningful names, like x
and y
.
Centering
In loop
, read and print just pin A0 for the moment. This pin will be indirectly applied to move the musician along the x-axis. (It isn’t used to set x
directly, as you’ll in a moment.) Upload and run the program. Inspect the values you see and answer these questions:
- What value do you see when the joystick is pushed all the way left?Something near 0. Hardware imperfections might keep it from reaching 0 exactly.
- What value do you see when the joystick is pushed all the way right?~1023
- What value do you see when the joystick is idle, not pushed at all?Around 511.
It’d be nice if pushing left made the number go negative, idle was 0, and pushing right made the number go positive. Let’s make that happen. We want to turn a number in the top range into a number in the bottom range:
Center the reading and test that it works.
Sign Zones
For our purposes, we really only care if the joystick is pushed left, right, or not at all. But we currently have a spectrum of 1024 different possible joystick positions. Let’s simplify the positions into three “sign zones”: -1, 0, and 1.
Add a new function with this shape:
int sign(int value) {
}
The function returns an int
. Inside this function, write if
statements to return -1 if value
is less than -10, 1 if value
is greater than 10, and 0 otherwise. We allow [-10, 10] to count as idling to handle the electronic noise that makes analog signals jump around. If your joystick gives particularly wild readings, you may need to increase the size of this window.
Back in loop
, turn the centered reading into its sign zone. Store the result in a variable named dx
—short for delta x.
Print dx
. Upload your code and test that it behaves as you expect. If it does, get rid of all your print statements. They will start to drown us in information.
Change Only
As with our other instruments, we only want to act on changes to the sensor. Declare a global variable named old_dx
and assign it 0.
Add C++ code to loop
equivalent to this pseudocode:
if old_dx and dx are different increase x-position by dx print x-position old_dx = dx
Upload your code and test that it wanders along the x-axis.
Non-zero Only
When the musician is idling, we don’t really change the x-position in anyway, so let’s add a conditional statement to not do anything when in the idle state:
if old_dx and dx are different if we're not idling increase x-position by dx print x-position old_dx = dx
Upload your code and make sure prints nothing while idling.
Challenges
After you get the horizontal movement working, answer the following questions on a piece of scratch paper:
- Currently the x-position changes by 1 with each joystick action. How could we make it change by 5 with every action?