teaching machines

CS 491: Lecture 2 – Potentiometer

February 5, 2018 by . Filed under gamedev, lectures, spring 2018.

Dear students:

Last time we used a push button to make a game where we reversed the spin of a planet. Today we implement a crude game of Peggle. We’ll discuss potentiometers and physics. We’ll use the potentiometer to aim the cannon.

Potentiometers are rotary sensors that are useful for gathering inputs that fall into a fixed interval, like percentages, volumes, burntness, and so on. Because they spin around a central axis, using them for rotation makes sense. But only if the rotation falls within a bounded interval.

Potentiometers typically have three pins. The outer two connect to voltage and ground. The direction doesn’t matter. The inner pin gives us a reading of the potentiometer’s angle. We wire it up like so to an Arduino:

The green wire is our reading. It connects to an analog pin. In brief, analog pins give a continuous reading in the range [0, 1023]. Digital pins give either a HIGH or LOW. In the case of a potentiometer, we need lots of intermediate values, so analog is more appropriate. Later on we’ll look at ways of squeezing out continuous information from a digital signal using something called pulse-width modulation.

An Arduino program that reads the potentiometer might look like this:

#include "Arduino.h"

void setup() {
  Serial.begin(9600);
}

void loop() {
  int reading = analogRead(A4);
  Serial.write(reading);
}

Let’s only broadcast the reading when it changes by a threshold amount:

#include "Arduino.h"
#define THRESHOLD 2

int old_reading = LOW;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int reading = analogRead(A4);
  if (abs(reading - old_reading) >= THRESHOLD) {
    Serial.write(reading);
    old_reading = reading;
  }
}

We’ll find that the potentiometer doesn’t automatically span the whole interval [0, 1023]. Additionally, we’ll run into the issue that serial ports are really byte-based communication channels. It’d be really nice if we could map the potentiometer’s interval into the interval [0, 255]. Could we write a generic routine that maps one interval onto another? We sure can:

def map x, fromLow, fromHigh, toLow, toHigh
  fromSpan = fromHigh - fromLow
  toSpan = toHigh - toLow
  proportion = (x - fromLow) / fromSpan
  return proportion * toSpan + toLow

In fact, Arduino already has this function builtin:

if (abs(reading - old_reading) >= THRESHOLD) {
  int mapped = map(reading, 0, POTENTIOMETER_MAX, 0, 255);
  Serial.write(mapped);
  old_reading = reading;
}

Now, we head to Unity and start implementing Peggle. We’ll follow these steps:

Here’s your TODO list for next time:

Sincerely,

P.S. It’s time for a haiku!

Clockwise to speed up
Counterclockwise to slow down
My car’s now totaled