Introduction: Spooky Mona Lisa Painting
This project was inspired by Harry Potter movies which show moving painting in Hogwarts. I have made this project long time ago and today I decided to post it on Instructables.The idea for this project is pretty simple, the Mona Lisa painting moves the eyes at random time intervals in a selected period of time, lets say after midnight and before sunrise. The time settings can all be configured in code. so without further to do lets get started.
Tools:
- Soldering iron
- Solder wire
- Access to computer
- Drill bit (depend on bolt size)
- Screw driver (I used hex)
- Hot glue
- Box cutter
- Circuit Holder (unnecessary)
- Access to 3D printer (I used online service for printing, this project can be completed without one)
Materials:
- 1 x Arduino Nano
- 2 x stepper motors + drivers
- 1 x prototyping board
- 1 x DS3231Clock Module
- 1 x mini USB type B female (optional)
- 1 x wires
- 1 x Toggle switch
- 1 x LED
- 1 x 180 ohm resistor for the LED
- 1 x power supply-enough to run everything
- 2 x 3mm, 75mm Steel rods
- 1 x Set of plastic gears
- 1 x Set of PCB standoff
- 1 x Classic picture frame
- 1 x Set of M2 scews and nuts.
- 1 x printed 3D frame for motors (more on this later)
Step 1: Getting Moving Eyes Mechanism Ready
This step will require access to a 3D printer which would make things easier for any build. I will attach the 3D STL models to this post, so you can download and print your own frame. The nice thing about the 3D models is that they can be scaled easily to any size you need. I understand many tinkerers do not own a 3D printer or do not have access to one. Actually I do not own one myself. I have used an online service to print and ship those parts to me. It is important to note that you do not have to use a 3D printer, you could use any material for the frame.
Assuming you are using the supplied 3D printer frame it pretty easy to put together.
- insert the metal rod through the bottom frame
- place the middle piece on top of the bottom of the frame and let the rods through it.
- place the top frame on top of the rods
- assemble left and right frames with M2 screws
- screw male-female PCB standoffs.
- assemble stepper motors as you see in the pictures
Step 2: Prepare Stepper Motor Driver Circuits
The stepper motor driver circuit that I own have pins which could be used to solder more flexible wires. I decided to remove them completely. So I started desoldering those pins. Then, I soldered 4 signal wires (colorful, see the picture) and 2 wires for power (black & white). Then, I added PCB standoffs to cluster 2 drivers together.
Step 3: Wire Modules to Arduino
So at this point you should wire everything to the Arduino. To make things easier, we are going to connect everything in a prototyping board and have one power input to everything. Here is a list of things that we need to connect to the Arduino:
- DS3231 module
- 2 Stepper motor drives
- mini USB B as power supply input (this is needed because Arduino cannot supply enough power to the stepper motors)
- Switch to reset stepper motors position
- LED indicator
Wire DS3231 module
- VCC and GND are pretty straightforward. VCC to Arduino 5V and GND to Arduino GND.
- SDA to A4 (analog pin) in Arduino Nano
- SCL to A5
- ignore SQW and 32K
Stepper motor drivers:
- Connect the +/- of the drivers to the +/- of mini USB B, respectively
- Connect the vertical motor driver to Arduino pins
- input 1==>d5 (digital pin)
- input 2==>d4
input 3==>d3
- input 4==>d2
Connect the other horizontal driver to Arduino using pins:
input 1==>d12
input 2==>d11
input 3==>d10
input 4==>d9
Switch
- Connect one end of the switch to GND
- Connect the other to pin d7.
LED
- Connect to GND through 180 ohm resistor.
- Connect other end to pin d6
here is the code I used for the Arduino. It is important to note that you might need to download libraries to compile the provided code. I build this project long time ago and since then I have cleaned the Arduino libraries I have for compatibility issues. Hopefully you can search for the #include "*something*" and the appropriate library should be there.
// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include #include "RTClib.h" #include "StepperMotorT.h"
RTC_DS3231 rtc;
// Time Interval int interval = 0; // wait time between motions in seconds int intervalMax = 10; // maximum wait time between motions long previousTime = -1; // Time from last motion, initial -1 int delayTime = 5000; // Delay time when stepper motion reaches maximum value long prevMillis = 0;
// motion int motionType = -1; // -1 stopped, 0 left/right, 1 up/down, 2 combination. int leftMaxMotion = 2; // the maximum factor for left motion
// Motors StepperMotorT motor1(12, 11, 10, 9, 4); // Horizential Motor (pin1, pin2, pin3, pin4, motionFactor) StepperMotorT motor2(2, 3, 4, 5, 32 ); // Vertical Motor
// LED lock mechanism int lockLED = 6; int lockInput = 7; bool lock = false;
void setup() {
Serial.begin(9600); delay(3000); // wait for console opening
if (! rtc.begin()) { Serial.println("Couldn't find RTC"); while (1); }
if (rtc.lostPower()) { Serial.println("RTC lost power, lets set the time!"); // following line sets the RTC to the date & time this sketch was compiled rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); }
// Initialize motors motor1.Initalize(); motor1.SetIdleWait(delayTime);
motor2.Initalize(); motor2.SetIdleWait(delayTime);
// Get first wait time randomSeed(analogRead(0)); interval = random(1, intervalMax+ 1);
// Setup Lock mechanism pinMode(lockLED, OUTPUT); digitalWrite(lockLED, LOW); pinMode(lockInput, INPUT_PULLUP); lock = false; }
void loop() {
// Check lock first - pulled up state means reversed logic open is HIGH and closed is LOW if(digitalRead(lockInput) == HIGH && false == lock) { // Turn on lock led digitalWrite(lockLED, HIGH); lock = true; } else if(!motor2.IsMoving() && !motor1.IsMoving() && true == lock && digitalRead(lockInput) == HIGH) { // Turn off lock led digitalWrite(lockLED, LOW); lock = false; }
DateTime now = rtc.now(); if(now.unixtime() >= previousTime + interval || -1 == previousTime) { // reset previous time previousTime = now.unixtime();
// randomize new interval interval = random(5, intervalMax + 1) + delayTime/1000;
// randomize a motion motionType = 0;//random(0, 3); if(!motor1.IsMoving() && false == lock) { motor1.Move(); }
if(!motor2.IsMoving() && false == lock) { motor2.Move(); } }
long currMills = millis(); motor1.Update(currMills - prevMillis); motor2.Update(currMills - prevMillis); prevMillis = currMills;
}
Attachments
Step 4: Prepare Frame & Painting Picture
This is a simple task. Just make a rectangular hole in the picture frame to support the moving mechanism. And make holes for M2 scews to secure the moving mechanism with the frame. In addition, prepare the Mona Lisa picture by cutting the eyes and sticking them with hot glue to a piece of paper to be used later.
Step 5: Assemble Everything
There you go. Enjoy!