Introduction to Physical Computing

Introduction to Physical Computing Final

Link to the Github repository:

When transforming our paper prototypes into the final version, we first tested all of our parts. Our project consisted of several different components, such as LCD screens, sliding potentiometers, rotary encoders, ultrasonic sensors, toggle switches, and arcade dome buttons, mono jacks, and mono cables. 

Testing the rotary encoder
Testing the LCD screens

When testing our components, we ran into a couple issues. We noticed that when turned very quickly, the rotary encoder does not register the change accurately. Rather than having precise compass directions from our paper prototypes, we decided that the rotary encoder should simply be spun clockwise. Initially, we faced difficulty with the LCD screens. The resistance must be changed manually with a screwdriver. The resident Anthony Bui helped us display text. We tested the neopixels, but decided not to incorporate them in our final version because they require a separate power source. We tested all of the components using an Arduino Nano with 5V power.

Soldering the LCD screen
Soldered breadboard

Soldering proved to be very time-consuming. We only soldered one breadboard. For some reason, the sliding potentiometers broke each time they were soldered. In our final version, we used alligator clips and they performed well.

Gluing the enclosures
Testing the sizes of the components
Updated paper prototypes
Finalizing the designs in Illustrator

For the fabrication, we used MDF boards. We tested out all of the components on cardboard with the laser cutter and then began the design process for the four consoles. We created more paper prototypes that resembled the final version. Once the designs were finalized, we created the circuits.

Schematic diagrams
Mounting the circuits
The circuits
Defective screens
Submission picture for the winter show

The schematic diagrams are shown above. One of the biggest hurdles we had involved the LCD screens. They worked with the Arduino Uno, but not the Arduino Nano. When they did not operate, we received two strips of white squares. In our final version, eight arduinos are connected to p5.js. The game consists of ten shared lives and a progress bar that shows how close the team is to fixing the spaceship. There are twelve rounds, each consisting of a set of instructions. When the entire team completes all of their tasks, the progress increases. Each time an incorrect interaction occurs or the team does not complete all of their tasks in time, lives are taken away. At this point, we submitted for the winter show. 

Spray painting the boxes
Final version
User playing the game
Art show presentation

At the art show, we received a lot of good feedback. We thought that a part of the fun of the game is not knowing that you need to cooperate with each other to fix the spaceship, but we decided to inform our users verbally beforehand. We had so many people who wanted to play, we decided to construct a more seamless experience. In the next version, we will not use plastic cups to cover the ultrasonic sensors. We plan to present our project at Wonderville next semester. 

Live stream
Group picture


#1 Data Reading 

We are using six different kinds of sensors to read player’s actions where the microcontrollers receive analog and digital inputs.


  • pushbuttons: 1 when pressed, 0 when released
  • flip switch: 1 when turned to ON, 0 when turned to OFF
  • mono jacks pair: 1 when connected by cable, 0 when not


  • sliding potentiometer: ranges from 0 to 1023
  • ultra sonic distance sensor: ranges from 0 to 250
  • rotary encoder: registers how many turns rotated

Mono jacks demo:

In Arduino code, we try to only keep the data-reading part and leave all the handling parts to p5. 

  • For flip switches, pushbuttons, sliding potentiometers, and jack matrices, readings are directly read and pushed.
  • Ultra sonic sensors push the distance in centimeters.
  • Rotary encoders push the counts of turns.

In p5 code, we have to build customized classes to process the readings from each sensor above. For each sensor class, they share common interace:

  • Variables:
    • Name
    • Type
    • Current Reading
    • State: helps to prevent multiple reads when reading stays the same
    • other customized variables
  • Functions
    • update: update its reading
    • listen: detects player action
    • instruct: returns an instruction that is different from the current reading
      • for example, if a switch is ON, the instruction is “turn it OFF”
    • avoidInitial: prevents detecting default state as a player action

#2 Serial Communication: P5 receives data from Arduino

Since we have 4 microcontrollers all connecting to p5, 4 different serial communication objects would be created. More importantly, since each microcontroller will send different sets of reading, customized function to parse each data set must be created. 

Console #1 data sequence

Console #1 gotData function

#3 Console class

The CONSOLE class would be the manager of all the sensor objects for each console. This class becomes the center to generate new instruction and determines whether player action achieves the instruction.


  • id
  • allButtons: stores all sensors objects
  • curIns: current instruction that needs to be done by this console
  • serialData: new updated readings from serial communication
  • LCDInfo: the text that would be pushed to the LCD screen for each console
  • lastHit: stores the latest player action 


  • getInstruction: generate a new instruction from a randomly chosen sensor object.
  • updateAll:  push the new updated readings from serial communication to each sensor object
  • listenAll: listen whether there is a player action; if there is, determine whether it is a right action or a wrong action according to the current instruction
  • determineHits: determine whether it is a right action or a wrong action; called by listenAll

#4 Control Flow

After introduction, the program will begins its round-by-round flow. When each new round begins, four new instructions would be generated:

After four instructions are generated, each of them would be pushed to a random console LCD screen. Each console would begin to listen to its sensor class to detect player actions. 

Three important variables that can affects the flow of control:

  • Group lives: each bad action would reduce this variable by 1. If this variable falls below 0, game over. Failure.
  • Progress: this variable would be updated at end of each round. If this variable goes above 100, game over. Win.
  • Timer: if this variabel goes blow 0, current round ends. Next round will start.
  • Hits: this variable keeps track of how many instructions have been done at current round. If this variable equals 4, current round ends. Next round will start.

#5 LCD screen update: P5 pushes infomation to Arduino

LCD screens show three parts:

  • Progress: updated after each round
  • Life: updated when a wrong player action happens
  • Instruction
    • new instruction updated after each round
    • “task completed” would replace the original instruction if that instruction is done by a right player action

In Win or Failure case, the LCD would update the texts according to the result too.