Introduction: The Moral Compass

The project conducted as part of the Computational Design and Digital Fabrication seminar in the ITECH masters program and was brought to you by Vanessa Costalonga, James Hayward and Christo van der Hoven.


Have you ever doubted the choices that you make?

Have you ever looked elsewhere for wisdom and clarity only to find disappointment and vagueries?

Look no further: I would like to introduce you to the moral compass.

The moral compass is a chakra aligning, energy purifying and physiologically clarifying device. Grounding itself as a talisman with the aesthetics and vocabulary choice of the late 2010’s vaporwave movement. A movement which articulated a new era of glitch art with a strong historical appropriation of the ’90s and ’80s. Our talisman is situated alongside talismans of the modern era such as the 1950’s Magic 8-ball.

Using numerology, the study of a mythical connection to numbers and meaning we have been able to bring the pseudo back to science and to center our compass answers around an eight-pointed star, commonly associated with wisdom and knowledge.

In a nutshell, the way that it works is that you ask a deep a meaningful question, and the compass will give you a deep meaningful answer, open to interpretation...

Step 1: About the Project

In this project, we will be building a device that responds to touch (capacitive sensor) and sound (microphone) to generate a movement (stepper motor) and resulting answer. It will involve building the body of the device, connecting and mounting the hardware and electronics inside, and then uploading the code to run the device. This is a project for makers with some experience working with Arduino and some experience with machines in a workshop.

If you have not worked with these parts before, we suggest you familiarise yourself with some of the concepts through tutorials or videos. Here are some examples for capacitive sensing, the microphone and the stepper motor.

Difficulty level: Medium

Step 2: Get the Gear

What do you need?


  • Arduino Uno
  • Stepper motor (28-byj-48) and driver board (uln2003)
  • Sound Sensor (LM 393 Microphone)
  • RGB Led's
  • 9v Batteries
  • 6 x 220-ohm Resistors
  • 1x 1 megaohm Resistor
  • Prototyping gear (wires, breadboards, Led's etc)


  • 2mm thick sheet material - 900mm x 300mm (we used plexiglass)
  • Copper sheet (0.3mm thick - 430mm x 40mm ) or copper adhesive tape (430mm x 40mm)
  • Spray Paint (optional)
  • Glue (depends on the material)


  • Access to a laser cutter or band saw
  • Access to a soldering iron
  • Access to a printer
  • Access to a computer with the correct software
  • Basic tools (Craft knife, steel ruler, masking tape, screwdrivers etc. )

Step 3: Assemble the Electronics

A good place to start is the assembly of the electronics.

Follow the circuit diagram and/or schematic that accompanies this step. Basically, there are three aspects to the electronics; the capacitive sensor, the stepper-motor and the microphone.

If you are confident, you can jump straight to soldering it onto some prototyping board. Alternatively, use a small breadboard that can then be placed inside the compass body.

We decided to solder the circuits onto a series of cut down proto-boards to that we can arrange the parts within the body of the compass.

One part that will require calibration is the microphone. This involves adjusting the built-in potentiometer with a small screwdriver. It is not a difficult process but can get a little frustrating. If you get stuck with this part, there are a number of tutorials that can help. Definitely calibrate the microphone before installing it on the body.

Step 4: The Code

The Arduino code for the project is not particularly complex. Essentially it comes down to three conditions:

a. It the device being held? (Or, in other words, has the capacitive sensor been enabled?)

b. Is the microphone picking up a question? (Or, is the mic reading sound?)

c. Is the question finished? (Or, has there been sound for a specified duration?)

Once all three these conditions are met the code prompts the motor to activate. This is then how the device provides an answer to the question. By this point, you have probably noticed that the device does not actually understand the question that is being asked. Instead, we are simply concerned with the duration of a sound.

For the makers that are interested in tweaking the parameters of the device have a closer look in the code. We have tried to keep the code tidy and well annotated. A nice place to start customising would be with the microphone listening durations (these have been labelled as time parameters in the code and the variables are called waitTime and cancelTime).

Once you have downloaded the code and loaded it on the Arduino, it is a good idea to test the hardware and software together. If the Led's are not flashing and the motor not turning, you may have to do some debugging. In addition to calibrating the microphone (as mentioned in the previous step), you may also have to adjust the threshold for the capacitive sensing and the threshold for the sound sensing in the code. A good way to do that is to display what these two sensors are reading by printing them and tracking the figures in the serial monitor. More specific calibrations can then be made.

Also, don't forget to load the libraries for the Stepper Motor and Capacitive Sensor.

<p>//== Libraries<br>#include 
#include </p><p>//== RGB LED  
int red_light_pin = 11;
int green_light_pin = 10;
int blue_light_pin = 9;</p><p>//== Capacitive Sensor
// pin 13 sends electrical energy
// pin 12 senses a change 
CapacitiveSensor capSensor = CapacitiveSensor(13, 12);</p><p>//== Stepper Motor
#define STEPS 2038                    // the number of steps in one revolution of the motor (28BYJ-48)
Stepper stepper(STEPS, 3, 5, 4, 6);</p><p>// Constants
int microphonePin = A1;               // microphone pin on the Arduino</p><p>// Time Parameters
const long waitTime = 4500.0;         // how long after trigger to wait before motor is activated 
const long cancelTime = 2000.0;       // during wait, how long of a lull will cancel wait</p><p>// Variables
int pickedUp = 400;                   // threshold for turning the compass on, when picked up
int threshold = 800;                  // sound threshold, 
int randOrientation;                  // variable for a random number
int randDirection;                    // variable for a random number
int orientation;                      // variable for the speed
int volume = 0;                       // variable to hold the reading from the microphone
boolean waiting = 0;                  // boolean variable for waiting loop
boolean ledBool = 0;                  // boolean variable for LED Activation
long waitStart;                       // when trigger initiated waiting
long waitDuration;                    // how long we have been waiting
long playStart;                       // when play was initiated
long playDuration;                    // how long we've been playing
long cancelStart;                     // when the last trigger was
long cancelDuration;                  // how long of a lull we've had</p><p>//== SETUP</p><p>void setup() {
  pinMode(red_light_pin, OUTPUT);
  pinMode(green_light_pin, OUTPUT);
  pinMode(blue_light_pin, OUTPUT);
  pinMode(microphonePin, INPUT); </p><p>  randomSeed(analogRead(0));          // random seed for Stepper Motor - determines the orientation of the pointer
}</p><p>//=== MAIN BODY</p><p>void loop() {
  long sensorValue = capSensor.capacitiveSensor(30);     // store the value reported by the sensor in a variable
  //Serial.println(sensorValue);                         // enable this line of code to calibrate the capacitive sensor 
  if (sensorValue > pickedUp){                           // if the value is greater than the threshold (device is picked up)
    volume = analogRead(microphonePin);                  // listening for questions
    //Serial.println (volume);                           // enable this line of code to calibrate the sound sensor
    if (!ledBool) {                                      // this statement activates the LED that signifies that compass is "listening"
      RGB_color(0, 255, 225);                            // cyan - signals Listening
      ledBool = 1;
    if (volume > threshold) {                            // when the sensor detects a signal above the threshold value, waiting LED flashes
      cancelStart = millis(); 
      if (!waiting) {
        waiting = 1;
        RGB_color(255, 0, 255);                          // magenta - signals waiting
        waitStart = millis();
    if (waiting) {
      cancelDuration = millis() - cancelStart; 
      waitDuration = millis() - waitStart;
      if (cancelDuration > cancelTime) {
        waiting = 0;
        RGB_color(0, 255, 255);                          // cyan - Signals listening
      else if (waitDuration > waitTime) {
        waiting = 0;
        randDirection = random(1,3);                     // a random number between 1 and 2
        randOrientation = random(1,9);                   // a random number between 1 and 2
        orientation = randOrientation * 255;             // orients the needle and compass face in 1/8 incements of the stepper motor
        RGB_color(255, 0, 0);                            // red - signals answering        
        if (randDirection == 1) {
          delay(2000);                                   // period of time the needle stays on the answer
          stepper.step(-1 * orientation);                // stepper motor 'homing'
        else {
          stepper.step(-1 * orientation);
          delay(2000);                                   // period of time the needle stays on the answer
          stepper.step(orientation);                     // stepper motor 'homing'
        RGB_color(0, 255, 225);                          // cyan - Signals listening
  else {                                                 // this switches the led's off
    RGB_color(0, 0, 0);                                  // off - signal the compass is not being held  
    ledBool = 0;
} </p><p>void RGB_color(int red_light_value, int green_light_value, int blue_light_value)
  analogWrite(red_light_pin, red_light_value);
  analogWrite(green_light_pin, green_light_value);
  analogWrite(blue_light_pin, blue_light_value);

Step 5: The Body

Now let's make the body. We have a diagram of all the parts and pictures for each of the steps of the process.

  1. Download, and cut the parts. The files have been formatted for laser cutting but it would also be possible to print and cut by hand.
  2. Paint. If you want to colour some of the parts, now is a good time for a spray.
  3. Assemble the top and bottom rings. Refer to the parts diagram to see which parts are assembled in which order. It is simply a matter of stacking and glueing the layers together.
  4. Attach the internal supports to the top ring with some glue. If you are getting confused with the parts, refer to the assembly diagram and pictures.
  5. Fix the copper sheet or tape. Cut the sheet or tape to size and wrap it around the internal supports. We used a copper sheet and made little tabs at the ends to temporarily hold the sheet in place.
  6. Attach the external supports. The copper sheet will now be help between the internal and external supports.
  7. Attach the bottom ring. The support should comfortably slot into position. At this stage, we have a stable frame for the body.
  8. Attach the motor and microphone. The motor, naturally, sits in the middle of the compass and the microphone is fixed to its opening. It's not a bad idea at this point to check that the electronics are still working. Depending on how important it is to you, you can also organize and fix the electronics and cables on the inside of the body.
  9. Next up is attaching the capacitance sensor. We have soldered the sensor to a small piece of copper, that was bent into a clip. Make sure this clip attaches to the side of your compass (see images for reference)
  10. Download, print and attach the compass face. Use an appropriate glue.
  11. Final touches. Attach the screen wheel and needle to the motor arm. Close the body with the clear faces on the top and bottom. And you're DONE!

Step 6: Get Some Answers

Now your project is ready to go. Ask some questions and get some answers!

Step 7: Modding and Hacking

We know that makers like to add their own twist to things and take their project a step further.

With that in mind, we have included a range of soft copies of the files in the download package. Now you can edit parts and customise the compass as it suits you.

We had a lot of fun making this project and there are a bunch of parts that we would have added if we had more time to work on it. Here are a few to spark the imagination:

a. Themed Answers: For the answers on the compass face we took some of our favourite three-word pieces of advice. You could take the answers a step further by theming them more specifically. You could make a 'morally compromised' or 'vague and ambivalent' compass.

b. Needle Jitter: If you like coding you could modify the behaviours of the needle and screen wheel. Rather sitting idly and then smoothly rotating, the device could jitter forwards and backwards. It could even pretend to be turning to a position and then change direction at the last moment. There are a lot of possibilities to program bizarre behaviours.

c. More Led's: RGB Led's are great. In our build, we simply used them to signify when the compass was activated, listening and moving. Take it a step further by linking the colour of the Led's with the type of answer the needle is moving towards. Good answers get green lights, bad answers get red. Go nuts.

We would love to hear from you if you have made the project! Please feel free to comment and post pics below.

Happy making.

V, C & J

Arduino Contest 2019

Runner Up in the
Arduino Contest 2019