|
H-Bridge Motor Driver L298N |
x 1 | |
|
Luxeon High Bright LED |
x 3 | |
|
Geared 6V DC Motor |
x 1 | |
|
Hall Effect Sensor |
x 1 | |
|
Neodimium Magnet |
x 1 | |
|
ARDUINO UNO REV3 |
x 1 |
Back in time! Make a Zoetrope using Arduino
I'm working on a series of animated objects for a children's play and decided to build a Zoetrope, to bring some magic to a very emotional moment in the play. I had already made a praxinoscope, using a pizza box and some acrylic mirrors. And that helped me to be a little more aware about the huge work with animation.
It was very interesting to realize that at each step of this process it is as if we were going back a few years in time. Although I didn't list them as important in the project's bill of materials, it's worth mentioning that I used several free software and online platforms for my tasks.
From Youtube to Cardboard
For the show, it was necessary to find a way to remove the characters from the paper disc and put them on their feet, as if they were other actors in the play. I didn't know if this would work, but I had a hunch it would. Before starting the hard work of frame-by-frame animation, I did some research on the internet to find out the technical feasibility of the project.
Adafruit has this example: https://learn.adafruit.com/strobe-zoetrope/build-the-zoetrope
But I found many others, including this one: https://vimeo.com/168428865
https://forum.arduino.cc/t/adustable-zoetrope-strobe/102374
https://programminginarduino.wordpress.com/2016/03/05/project-11/
https://hackaday.io/project/161254-zoetrope
https://www.youtube.com/watch?v=6kv-M7BIG5I
But the biggest job is precisely that of animation frame by frame. So I created a process to automate this task.
First of all, I needed a black and white video with two characters dancing. I found a video of Fred Astaire and Eleanor Powell, dancing "Begin the begine". https://www.youtube.com/watch?v=nZPndC-F5SE
I used the youtube-dl software to download the video to my computer and perform the next steps.
But you can also use online conversion tools like the ezgif.com platform.
For my project I'll just make an animation with fifteen frames and the ideal is that the first and last frames are with very similar movements. You can choose any number of frames for your project, ranging from 12 to 30 frames per second.
Using Shotcut, or any other video editor of your choice, select the starting and ending portion of your animation and export the resulting video at a frame rate of 15 frames per second (or the rate you want).
Then use VLC Media player to save each frame separately.
Finally, I treated each frame in isolation in GIMP, removing the background from the image and leaving the characters with the appearance of a black and white illustration. Also in this step, I created a copy of each frame keeping only the outline of the characters' silhouettes, to facilitate the laser cutting step.
For the first prototype, I cut out each character on cardboard. But for the final project, I'm going to do everything in laser cutting and adhesive paper. The process should be much faster!
Inkscape has a fantastic extension that generates the Zoetrope disk, with templates for the frames, included.
From Cardboard to Arduino
There's not much to say about this step, other than it's a lot of work! You must paste the characters one by one into the corresponding section of the disc. Originally I would put the characters on a conventional turntable, so I knew the dial rotated clockwise (thus the frame order must be reversed). But the direction of the disc can be changed later, on the Arduino.
The basic functioning of the system is as follows: the disc with the characters has a small neodymium magnet glued to it. When the disc rotates, the hall effect sensor detects the magnet and records the time the rotation took to complete. It uses this value to calculate the strobe pulses that will happen on the Luxeon LED. A 10K fader allows you to adjust the speed to get the effect (I replaced the conventional fader with a multi-turn for a more accurate adjustment).
I got this code, made by kellyegan: https://gist.github.com/kellyegan/759160b77aa87860dec1, but I have some issues with Stroboscopic effect. Probably by a poor reading of hall sensor. So, I adapt to take an average of 15 readings of hall sensor, find the correct timings of on and off for the strobe effect, and create a break routine when we turn off the system.
// Zoetrope - Adapt. by Nicolau dos Brinquedos
// of Kelly Egan's 3D Strobescopic Zoetrope (2014)
// Including a better calculation for Strobe effect
// Based in motor speed and rotation speed.
// Take an average of speed measure.
#define BUTTON_PIN 12 //Button to turn zoetrope on and off
#define POT_PIN A0 //Potentiometer used to set speed of motor
#define INDICATOR_PIN 13 //Indicator LED
#define HALL_PIN 3 //Hall effect sensor to determine motor speed
#define STROBE_PIN 6 //High-power LED used as strobe 6
#define MOTOR_PIN 5 //Motor control for spinning zoetrope
#define DIRECTION 4
#define MOTOR_MIN 10
#define MOTOR_MAX 80
#define FRAME_FACTOR 2
#define NUM_READINGS 15
//Variables used in the interrupt function should be marked volatile
volatile unsigned long rotationStartTime;
volatile unsigned long rotationDuration;
volatile unsigned long rotationReadings [NUM_READINGS];
volatile unsigned long rotations;
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
int average = 0;
volatile boolean strobeState;
int potValue;
boolean buttonState, lastButtonState; //Button state and software debounce
unsigned long lastDebounce;
boolean zoetropeOn;
unsigned long lastFrameTime;
unsigned long frameDuration;
unsigned long strobeTime;
//The Rotations per second x number of frames of animation = Frequency of the strobe or camera fps
float rpm;
float rps;
int numFrames = 15;
void setup() {
Serial.begin (115200);
delay (5);
pinMode(STROBE_PIN, OUTPUT);
pinMode(DIRECTION, OUTPUT);
pinMode(MOTOR_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(INDICATOR_PIN, OUTPUT);
pinMode(HALL_PIN, INPUT);
digitalWrite(STROBE_PIN, LOW);
digitalWrite(MOTOR_PIN, LOW);
digitalWrite(DIRECTION, digitalRead(MOTOR_PIN)); // Motor Stopped
attachInterrupt(digitalPinToInterrupt(HALL_PIN), newRotation, RISING); //Interrupt 0 is on pin 3, Hall Effect sensor
rotationStartTime = millis();
rotationDuration = 1000; // Atualiza com o sensor HALL
for (int i = 0; i < NUM_READINGS; i++) {
rotationReadings [i] = 0; // Clean my readings array
}
zoetropeOn = false;
buttonState = false;
lastButtonState = false;
Serial.println ("Zoetrope Is ON");
}
void loop() {
buttonState = digitalRead( BUTTON_PIN );
if ( buttonState != lastButtonState ) {
if ( buttonState == LOW )
zoetropeOn = !zoetropeOn;
}
lastButtonState = buttonState;
total = total - rotationReadings[readIndex];
rotationReadings[readIndex] = rotationDuration;
total = total + rotationReadings[readIndex];
readIndex = readIndex + 1;
if (readIndex >= NUM_READINGS) {
// ...wrap around to the beginning:
readIndex = 0;
}
average = total / NUM_READINGS; // Find average value of rotationSpeed
//Checks for divide by zero
rpm = (rotationDuration > 0) ? (60000 / rotationDuration) : 0;
if (rpm > 1428) {
rpm = 1428;
}
frameDuration = average / numFrames; // Take an average of rotationDuration to find FrameDuration
strobeTime = frameDuration / 15; // This number is the same number as my framenumber. // But still need more experimentation
Serial.println (strobeTime);
if ( zoetropeOn ) {
potValue = map (analogRead(POT_PIN), 0, 1023, MOTOR_MIN, MOTOR_MAX);
analogWrite( MOTOR_PIN, potValue );
digitalWrite (DIRECTION, LOW); // Clockwise HIGH to CounterClock in my motor
//If the time ellapsed since the last strobe is
//greater than the frameduraciton turn on the strobe
if ( micros() - lastFrameTime > frameDuration ) {
lastFrameTime = micros();
digitalWrite( STROBE_PIN, HIGH );
delay( strobeTime ); //In the original code, delay (1). But I can't get it work
digitalWrite( STROBE_PIN, LOW );
delay (14 * strobeTime); // Added by Nicolau dos Brinquedos
}
} else {
//If zoetrope off turn off motor
digitalWrite( STROBE_PIN, LOW );
while (potValue > 0) {
analogWrite( MOTOR_PIN, potValue );
digitalWrite (DIRECTION, LOW);
potValue --;
delay(10);
}
digitalWrite( MOTOR_PIN, HIGH );
digitalWrite (DIRECTION, HIGH); // added
}
}
// Hall Effect Interupt function
void newRotation() {
delay(1);
//Wait for first rotation before making measurement
if (rotations > 0) {
rotationDuration = millis() - rotationStartTime;
}
rotationStartTime = millis();
rotations++;
}
For the motor and led luxeon I used a L298 module. Initially I used an IRF540 module for the LEDs, but the circuit response is very slow and it was not possible to get the strobe effect.
The result is this one: https://youtu.be/kDP2CZ1zXnc
And, the final version (lasercut the characters, and increased size) - https://youtu.be/cJvl9GdjOS8
Back in time! Make a Zoetrope using Arduino
- Comments(0)
- Likes(2)
- Seçkin Cici Apr 29,2022
- (DIY) C64iSTANBUL Jul 23,2021
- 0 USER VOTES
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
More by nicolaudosbrinquedos
- Homeassistant in Beaglebone Black With Debian 11 Intro: The primary objective of my project was to give some use to the Beaglebone Black that has bee...
- The Adventures of Porting Circuitpython to Wio RP2040 I have been developing some electronic props solutions for Escape Rooms. And periodically I usually ...
- Simple Electronics to Escape Room Owners - Using a bunch of voltmeters with PCA9685 This is a preliminary study for an Escape Room game. My main goal was to add as many analog displays...
- Simple Electronics to Escape Room Owners - First Chapter I've been developing puzzles and artifacts for Escape Room since 2018 and most of the time, I've bee...
- Finally! Animated Eyes using Seed Xiao RP2040 This is another advance in my studies to enable a more economically viable version for the Monster M...
- Circuitpython on Seeed XIAO RP2040 Step 1: Unboxing... I2C Not Working?As soon as the card arrived, I installed the firmware version fo...
- Raspberry Pi Pico with GC9A01 Round Display using Arduino IDE and TFT-eSPI Library This is a work in progress for another one of the artifacts I used in Leonardo Cortez's "Strange Hou...
- Recreating an 80s TV with Raspberry Pi Recently I built a series of special effects for the scenography of the play "Strange House" by Leon...
- Talk to Me This project is part of an extensive research on the use of animatronics and interactive objects tha...
- Back in time! Make a Zoetrope using Arduino I'm working on a series of animated objects for a children's play and decided to build a Zoetrope, t...
- Alastor Moody Eye using Raspberry Pi Pico, CircuitPython and Round Display GC9A01 I am developing a series of objects for a children's play about fear and terror. And then I got insp...
- The Crazy Pots Game At some point on the internet I came across someone who had made a game like that, but unfortunately...
- Arduino Mastermind Game I created this little game as a hobby for my children during the Covid-19 quarantine. I had already ...
- Raspberry Pi Pico With I2C Oled Display and CircuitPython This is my first experience using this little board from Raspberry Pi Foundation.I preferred to inst...
- Raspberry Pi Pico and TFT ILI9341 with Circuit Python I decided to write another tutorial on the Raspberry Pi Pico, mainly because the card is very recent...
- Arduino Minesweeeper It was then that I found the works of Rachit Belwariar, on the page https://www.geeksforgeeks.org/cp...
-
-
-
kmMiniSchield MIDI I/O - IN/OUT/THROUGH MIDI extension for kmMidiMini
111 0 0 -
DIY Laser Power Meter with Arduino
162 0 2 -
-
-
Box & Bolt, 3D Printed Cardboard Crafting Tools
155 0 2 -
-
A DIY Soldering Station Perfect for Learning (Floppy Soldering Station 3.0)
555 0 2