teaching machines

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. Initialize them to your favorite MIDI numbers.

Setup

In setup, prepare pins A0, A1, and 5 for INPUT. Initialize the serial port.

Centering

In loop, read and print just pin A0. (We’ll add the others later. For now, we want simplicity.) This pin controls the x-position. Also add a short delay. 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?
    0
  • 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:

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

How do we do that with just math?
Subtract 512 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.

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 of your other 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
  x = x + dx
  old_dx = dx
  print x

Upload your code and test that it wanders along the x-axis.

Non-zero Only

When dx is 0, we don’t really change x in anyway. So let’s revise our code a bit to not do anything when dx is 0:

if old_dx and dx are different
  if dx isn't 0
    x = x + dx
    print x
  old_dx = dx

Upload your code and make sure it still works as expected.

Challenges

After you get the horizontal movement working, answer the following questions on a piece of scratch paper:

  • Investigate the assignment operators in C++. How else can you write x = x + dx?
  • Currently x changes by 1 with each joystick action. How could we make x change by 5 with every action?

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *