teaching machines

Music Mouse, Part II

June 16, 2019 by . Filed under electronics, music, public.

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:

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:

$$\begin{array}{lrcrl}[& 0, && 1023 &] \\ && \downarrow && \\ [&-512, && 511 &]\end{array}$$

How do we do that with just math?
Subtract 512 (or an appropriate center for your joystick) from the analog reading.

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: