Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
HarrisonMcIntyre
Published © GPL3+

Control Pie Face Wirelessly with Your Phone!

I hacked a Pie Face game to give me complete control over if and when the pie is thrown.

IntermediateShowcase (no instructions)1,959

Things used in this project

Hardware components

20 kg Servo
You cannot use a micro-servo for this application. The servo has to overcome a decent amount of torque.
×1
Arduino Nano R3
Arduino Nano R3
×1
Arduino Nano Terminal Adapter
×1
HC-05 Bluetooth Module
HC-05 Bluetooth Module
×1
Limit Switch, 5 A
Limit Switch, 5 A
×1
Micro-USB to USB Cable (Generic)
Micro-USB to USB Cable (Generic)
×1
5v USB Battery Pack
×1
Jumper wires (generic)
Jumper wires (generic)
Any sufficiently strong stranded wire will suffice.
×1
Fishing Line
×1
Scrap Wood
×1
Machine Screw, M3
Machine Screw, M3
×12
Standoff, Nickel Plated
Standoff, Nickel Plated
×4
Cable Tie, Belt Ty™ In Line
Cable Tie, Belt Ty™ In Line
×2
Standard Terminal Block, Lever-Nuts
Standard Terminal Block, Lever-Nuts
×7
Servo Mounting Bracket
×1
Accessory, Screw
Accessory, Screw
×2
Eyebolt
×1
Small Washers
×7
USB-A to Mini-USB Cable
USB-A to Mini-USB Cable
×1
Pie Face
×1

Software apps and online services

Serial Bluetooth Terminal
Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free
Multitool, Screwdriver
Multitool, Screwdriver
Tape, Electrical
Tape, Electrical
Sandpaper
Jig Saw
Hot glue gun (generic)
Hot glue gun (generic)

Story

Read more

Schematics

Fritzing Wiring Schematic

Open in Fritzing to see the circuit diagram for this project.

Circuit Diagram Image

For those unable to view the Fritzing file, here is the circuit diagram view as an image.

Bread Board Schematic

For those unable to view the Fritzing file, here is the breadboard view.

Code

Hacked Pie Face Software

Arduino
This is the code that runs on the Arduino Nano. The main function of the code is to monitor the limit switch, listen for a trigger from the bluetooth module, and activate the arm by rotating the servo when a trigger is received from the bluetooth module.
#include <Wire.h>
#include <Servo.h>

// Code for debouncing of the limit switch was taken from official Arduino website:
// https://www.arduino.cc/en/tutorial/debounce

Servo arm;

int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 20;    // the debounce time; increase if the output flickers

const int buttonPin = 4;    // Indexing limit switch pin number

boolean isTriggered = false;
boolean throwPie = false;

char input = "";

int code = -1;

double totalCount = 0;
int throwIndex = -2;

// These two positions will vary depending on the tension of the fishing line
int throwPos = 155;
int standByPos = 93;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  arm.attach(3);
  Serial.begin(9600);// attaches the servo on pin 9 to the servo object
}

void loop() {

  if (Serial.available() > 0) {
    input = Serial.read();
    Serial.println(input);
  }
  
  switch (input) {
    case '1':
      code = 1;
      throwIndex = totalCount+code;
      break;
    case '2':
      code = 2;
      throwIndex = totalCount+code;
      break;
    case '3':
      code = 3;
      throwIndex = totalCount+code;
      break;
    case '4':
      code = 4;
      throwIndex = totalCount+code;
      break;
    case '5':
      code = 5;
      throwIndex = totalCount+code;
      break;
    case '6':
      code = 6;
      throwIndex = totalCount+code;
      break;
    default:
      break;
  }
  
  // read the state of the switch into a local variable:
  int reading = !digitalRead(buttonPin);
  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;
      totalCount += 0.5;
      Serial.print("\ntotalCount = ");
      Serial.println(totalCount);
      Serial.print("\nthrowIndex = ");
      Serial.println(throwIndex);
    }
  }
  
  if (totalCount-throwIndex == -1) {
    isTriggered = true;
    throwIndex = -2;
  }

  if (isTriggered == true && buttonState == HIGH) {
    throwPie = true;
    isTriggered = false;
  }

  if (throwPie) {
    arm.write(throwPos);
    Serial.println("\nIki Iki Iki Ptwang!");
    delay(500);
    arm.write(standByPos);
    throwPie = false;
  }
  
  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;  
}

Credits

HarrisonMcIntyre
1 project • 4 followers

Comments