Bones - the Arduino Fortune Teller
by BadJer Maker in Circuits > Arduino
2145 Views, 24 Favorites, 0 Comments
Bones - the Arduino Fortune Teller
I wanted to learn more about Arduino, so I got an Arduino starter kit as a gift. In the kit there are a number of increasingly difficult projects to teach you how it works. This project combines the following (4) projects into one:
- Flashing a LED Light
- Driving a LCD Display
- Controlling a servo Motor
And... a Project I saw here on Instructables (https://www.instructables.com/id/Nixie-Jacobs-ladder-pumpkin/) about how to make a Jacob's Ladder out of a linear IN-9 Nixie tubes and an Arduino Trinket controller. Hats off to "Thereisonlyone" for the inspiration to try his project to blend Nixie tubes and Arduino! But first, here is what it does...
Meet "Bones" - The Fortune Teller. Like a magic 8 ball, you have a question that needs an answer. To get the answer out of Bones the Skeleton, you have to electrocute him to entice an answer from him. Turning on the unit, powers up the electrical panel and the Jacob's Ladder indicates that power is ready to shock Bones into submission to get your answer. Then, as you close the knife switch on the panel, the electrocution begins, causing Bones to dance as you ask the question. When you stop electrocuting Bones, and open the switch, your answer appears on the display! Now my guests play with Bones while having a good fall season visit at my house.
First, I learned to build the three project from the starter kit and really understood the code that made those work. THEN, I had to combine the three programs codes into one (copy and paste the codes together) and try to get all of them to run together in one Arduino UNO. This was a bit tricky to get the lines of code in the right spots so the LCD display and the Servo motor would work well, and ... to get the answer to stay on the display as coordinated with the knife switch. Even getting the LEDs to flash correctly to simulate the electrocution was a bit tricky. The Jacobs ladder portion is programmed on the Trinket controller since the Uno couldn't handle all the functions. See the code below:
"Bones" - the Fortune Teller
The programming code can have any number of messages you wish, just edit the appropriate lines...
The code starts below, so feel free to copy and paste it or edit it to suit your needs:
________________________________________________________________________________
// include the required libraries
#include
#include
Servo myServo; // create a servo object
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int switchPin = 6;
int switchState = 0;
int prevSwitchState = 0;
int reply;
int potVal; // variable to read the value from the analog pin
int angle; // variable to hold the angle for the servo motor
void setup() {
// put your setup code here, to run once:
// initialize digital pins 8 and 9 as the LED outputs.
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
// code for the display
pinMode(switchPin, INPUT);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
myServo.attach(13); // attaches the servo on pin 13 to the servo object
Serial.begin(9600); // open a serial connection to your computer
}
void loop() {
// put your main code here, to run repeatedly:
if (switchState == HIGH) {
//Start Servo Routine...............................
potVal = 700; // read the value of the potentiometer
angle = map(potVal, 0, 1023, 0, 179);
myServo.write(angle);
delay (25);
potVal = 100; // read the value of the potentiometer
angle = map(potVal, 0, 1023, 0, 179);
myServo.write(angle);
delay (55);
potVal = 400; // read the value of the potentiometer
angle = map(potVal, 0, 1023, 0, 179);
myServo.write(angle);
delay (25);
// End Servo Routine here........................
// code for the blinking LEDs:
digitalWrite(8, HIGH); // turn the White LED on (HIGH is the voltage level)
delay(0); // wait for a second
digitalWrite(9, LOW); // turn the Blue LED off(LOW is the voltage level)
delay(60); // wait for a second
digitalWrite(8, LOW); // turn the White LED off by making the voltage LOW
delay(1); // wait for a second
digitalWrite(9, HIGH); // turn the Blue LED on by making the voltage HIGH
delay(5); // wait for a half second
}
// here is the code for the LCD display
switchState = digitalRead(switchPin);
if (switchState != prevSwitchState) {
if (switchState == LOW) {
reply = random(30);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0,1);
switch(reply){
case 0:
lcd.print(" YES!");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 1:
lcd.setCursor(0, 0);
lcd.print(" YOU SHOULD");
lcd.setCursor(0,1);
lcd.print(" COUNT ON IT.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 2:
lcd.setCursor(0, 0);
lcd.print(" AS I SEE IT,");
lcd.setCursor(0,1);
lcd.print(" YES.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 3:
lcd.setCursor(0, 0);
lcd.print(" HELL");
lcd.setCursor(0,1);
lcd.print(" YES!");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 4:
lcd.print(" IT WILL BE.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 5:
lcd.setCursor(0, 0);
lcd.print(" YOU CAN RELY");
lcd.setCursor(0,1);
lcd.print(" ON IT!");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 6:
lcd.setCursor(0, 0);
lcd.print(" IT IS");
lcd.setCursor(0,1);
lcd.print(" CERTAIN!");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 7:
lcd.setCursor(0, 0);
lcd.print("YOU SHOULD HAVE");
lcd.setCursor(0,1);
lcd.print(" NO DOUBT!");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 8:
lcd.setCursor(0, 0);
lcd.print(" IT SEEMS");
lcd.setCursor(0,1);
lcd.print(" MOST LIKELY.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 9:
lcd.setCursor(0, 0);
lcd.print(" ALL MY SIGNS");
lcd.setCursor(0,1);
lcd.print(" INDICATE YES!");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 10:
lcd.setCursor(0, 0);
lcd.print(" THE ANSWER");
lcd.setCursor(0,1);
lcd.print(" SEEMS HAZY.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 11:
lcd.print(" ASK ME LATER.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 12:
lcd.setCursor(0, 0);
lcd.print(" I CANNOT");
lcd.setCursor(0,1);
lcd.print(" TELL YOU.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 13:
lcd.setCursor(0, 0);
lcd.print(" I CANNOT");
lcd.setCursor(0,1);
lcd.print(" PREDICT IT.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 14:
lcd.setCursor(0, 0);
lcd.print("CONCENTRATE");
lcd.setCursor(0,1);
lcd.print("AND ASK AGAIN.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 15:
lcd.setCursor(0, 0);
lcd.print(" IT IS RATHER");
lcd.setCursor(0,1);
lcd.print(" UNCLEAR.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 16:
lcd.setCursor(0, 0);
lcd.print(" DON'T COUNT");
lcd.setCursor(0,1);
lcd.print(" ON IT.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 17:
lcd.setCursor(0, 0);
lcd.print(" IT REALLY IS");
lcd.setCursor(0,1);
lcd.print(" NOT LIKELY.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 18:
lcd.setCursor(0, 0);
lcd.print(" THE SPIRITS");
lcd.setCursor(0,1);
lcd.print(" SAY NO.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 19:
lcd.setCursor(0, 0);
lcd.print(" BE CAREFUL");
lcd.setCursor(0,1);
lcd.print(" GOING FORWARD.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 20:
lcd.setCursor(0, 0);
lcd.print(" THE OUTLOOK");
lcd.setCursor(0,1);
lcd.print(" IS POOR.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 21:
lcd.setCursor(0, 0);
lcd.print(" IT IS QUITE");
lcd.setCursor(0,1);
lcd.print(" DOUBTFUL.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 22:
lcd.setCursor(0, 0);
lcd.print(" I MUST SAY");
lcd.setCursor(0,1);
lcd.print("SORRY, IT'S NO.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 23:
lcd.setCursor(0, 0);
lcd.print(" IT WILL NOT");
lcd.setCursor(0,1);
lcd.print(" BE SOON.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 24:
lcd.setCursor(0, 0);
lcd.print(" YOU CAN JUST");
lcd.setCursor(0,1);
lcd.print(" BITE ME.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 25:
lcd.setCursor(0, 0);
lcd.print(" WHY DON'T YOU");
lcd.setCursor(0,1);
lcd.print(" ASK AGAIN?");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 26:
lcd.setCursor(0, 0);
lcd.print(" YOU KNOW");
lcd.setCursor(0,1);
lcd.print(" THE ANSWER.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 27:
lcd.setCursor(0, 0);
lcd.print(" PLEASE GO");
lcd.setCursor(0,1);
lcd.print(" CAUTIOUSLY.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 28:
lcd.setCursor(0, 0);
lcd.print(" SEARCH YOUR");
lcd.setCursor(0,1);
lcd.print(" FEELINGS.");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
case 29:
lcd.print(" BEWARE...");
delay(3000);
lcd.begin(16, 2);
lcd.print("Ask Bones");
lcd.setCursor(0,1);
lcd.print("Your Question!");
break;
}
}
}
prevSwitchState = switchState;
}
Build the Control Circuit
I built each project separately on my breadboard, to really understand the code and how the Arduino worked. This is highly recommended for beginners like me. Then, I added one project at a time to the breadboard, until I had all three in one circuit. As I added each code to the Arduino, I would try running the program to ensure I could easily trouble shoot SMALL CHANGES FIRST! Making small changes and testing it is far easier to find the code or wiring issues than adding them all together and trying to sort through the entire mess. LINE positioning for each program was critical to get the leds to flash correctly. You will have to play around with the code position but the code here has it the way I wanted it.
One the breadboard is built and the code makes it work the way you want it, then build the circuit on a circuit board. and once built you will then be able to dimension the panel around the circuit board's overall size!
Build the Electrical Panels
I fabricated the electrical panels from solid copper sheeting (flashing) I had. Using simple sheet metal tools and soldering into a three dimensional object to hold the form was easier than I thought it would be. I then also soldered brass sheet metal to the rear door and for the electricution table as well to give it more of a variation in appearance.
After fabbed and soldered, I used the salt water / Liquid ammonia solution method to give the copper a blue patina. To preserve it and make it durable, I sprayed a number of coats of lacquer over the metal components.
Lastly, I filled the bas with auto putty to make a solid surface to bond the electrocution table tot he black acrylic base.
The acrylic base I sanded it to make it dull and also scribed it with a utility knife to make it look like a tiled laboratory floor.
Build the Base and Make Final Connections
The pictures show how I built the base and wired the connections to the patch cord. I find a good terminal strib is hard to beat for a clean design. Lastly I just drop the top into the base with no fasteners so I can access it easily if needed and because I didn't want visible scews from the top. The nixies are too fragile to turn the unit over to remove screws to get inside it, so I just drop in it on the wood posts as a resting /supporting stop.