After some days of tweaking steppers, making holes on boxes and getting your appreciated help on this forum, i finally could finish this phenakistoscope project, a christmas presents for my cousins!

info, code and scheme:

thanks everyone for your help!


+1 Impressive to mesmerizing!


I like it :)

And if you hide part of the disc the stroboscope will be eaiser.

impressive, very nice project.

If you would put dots on the outer edge of the discs you could make it auto tuning I think.

Hey, thanks for your comments! really glad you like it :-)

Yes, both hiding the LEDs from direct sight and and auto-tuning system would be certainly a very nice addon!

Like it Like !! :) very cool

Very nice project, I'm going steal it for my nieces !

If you have some funny pictures of family members and a few hours of photoshop-skills by the way.... ]:) ]:D :stuck_out_tongue_closed_eyes: :fearful:


Thanks once more, I haven’t fitted mine in a box yet, but enjoyed my first movie of ‘the happy couple’ today :).

Instead of a stepper I used a dc-motor from an old printer and an uln2803 chip. My first setup turned much to fast, but with some gears from the same printer it runs fine now. The only potentiometers I had were quite old and I’ve used buttons instead. It took me a while to read and debounce 'm without delay, but thanks to Nick Gammons pages they now are. I also have been thinking about using a light sensor, it shouldn’t be too difficult to automate the scope a bit further, but I like the idea that you need to change settings by hand. My nieces are 4 & 7 and if they have to do something besides watching and setting a speed, I hope they start wondering how it works and spark their imagination a bit.

The motor is driven using analogwrite, which still causes an annoying tone. So far I’ve only tested it using my Mega2560, intention is to use an atmega8 and I’ll tackle the noise problem when I receive one.

If anyone wants to try, here’s my code

/* Phenakistoscope, based on  LuthiersDrapaires design, but using switches and DC-motor instead of potentiometers and stepper.*/
// Button variables
const byte switchPin[] = {
byte oldSwitchState[] = {
  HIGH,HIGH,HIGH,HIGH};  // assume switch open because of pull-up resistor
byte switchState[] = {
  HIGH,HIGH,HIGH,HIGH};  // assume switch open because of pull-up resistor

const unsigned long debounceTime = 1;  // milliseconds
unsigned long switchPressTime[]= {
  0,0,0,0};  // when the switch last changed state

#define BUTTON 100 // delay used to "debounce" buttons

// global clock variables
#define DEBUG 0 // set to 1 for msgs

// Phena variables  
int flashes =56;   // starting flash-speed of my machine
int rpm=26;        //    ""    Motorspeed     ""

int Led =13;       // ledpin
int Motor=10;      // motorpin

unsigned long timeLedChanged = millis();    //variable per a calculs de temps
unsigned long period = 1000;                //variable per a periode inicial
boolean ledOn = true;                      //variable booleana de led on o off

void setup() 
  // init the button inputs
 if(DEBUG){ Serial.begin(115200);}
  pinMode(2, INPUT);
  pinMode(4, INPUT);
  pinMode(6, INPUT);
  pinMode(8, INPUT);
  pinMode(10, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(4, HIGH);       
  digitalWrite(2, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(8, HIGH);
  digitalWrite(13, HIGH);
} // end setup()  

void loop(){    
  if (flashes >= 100){
    digitalWrite(Led, LOW); 
    Pulse(Led, 1, flashes);

//Function for blinking at independant HIGH and LOW times without using delay()
void Pulse(int output, int ontime, int offtime){
  if (millis() - timeLedChanged >= period)
    ledOn = !ledOn;
    timeLedChanged = millis(); 
    digitalWrite(output, ledOn);  
    if (ledOn)
      period = ontime;
      period = offtime; 

void chkButtons(){ // checks buttons without delay()
  for (int i=0; i<=3; i++){
    switchState[i] = digitalRead (switchPin[i]);
    // has it changed since last time?
    if (switchState[i] != oldSwitchState[i])
      // debounce
      if (millis () - switchPressTime[i] >= debounceTime)
        switchPressTime[i] = millis ();  // when we closed the switch 
        oldSwitchState[i] =  switchState[i];  // remember for next time 
        if (switchState[i] == LOW)
          if(i==0 && flashes >= 10) flashes--;
          if(i==1 && flashes <= 100) flashes++;
          if(i==2 && rpm >= 1 ) rpm--;
          if(i==3 && rpm <= 254) rpm++;
            Serial.print("Button ");
            Serial.print(" pressed, flashes : ");
            Serial.print (flashes,DEC);
            Serial.print (" RPM : ");
            Serial.println (rpm,DEC);
        }  // end if switchState is LOW
          Serial.print ("Button ");
          Serial.print (i,DEC);
          Serial.println (" released.");
        }  // end if switchState is HIGH
      }  // end if debounce time up
    }  // end of state change
  }  // end for loop

Very nice job.