Zoetrope project school. (new to arduino)

Blackfin:
I don't think that's it. I'm (in theory) just checking step numbers from the Hall effect "sync" pulse.

So to start debugging, can you try this code: it toggles the on-board LED on each SYNC event telling us the rising-edge interrupt from the Hall sensor is working.

/*
  • Sketch: zoetrope.ino
  • Target: Mega2560

*/
#define HALL_TO_OBJ0_DEGREES            20.0f       //deg   offset from Hall sensor rising edge to centre of first object
//
#define NUM_OBJECTS                     12          //#     number of objects
#define STEPS_PER_REV                   3200        //#     number of steps per revolution
#define DEGREES_PER_REV                 360         //#     degrees in a circle
#define LED_ON_DEGREES                  10.0f       //deg   number of degrees LED is on for each object
//
#define TIME_STEP_DIV2                  80ul        //uS    microseconds per toggle of step pin (steps/sec = 1 / (2 x E))
#define TIME_BUTTON_READ                50ul        //mS    milliseconds between button reads
//
#define ON                              HIGH        //state LED on pin state
#define OFF                             LOW         //state LED off pin state

uint16_t
   grLED_ON_Steps[NUM_OBJECTS],
   grLED_OFF_Steps[NUM_OBJECTS];

const uint8_t pinDebugLED = LED_BUILTIN;
const uint8_t ledPin =  2;
const uint8_t buttonPin = 68;
const uint8_t dirPin = 60;
const uint8_t enablePin = 23;
const uint8_t stepPin = 22;
const uint8_t hallPin = 18;

volatile uint16_t
   cntLEDSync;
volatile bool
   bSync = false;
   
uint8_t
   objNum,
   bLEDState,
   swNow,
   swLast,
   motorPinState = LOW,
   ledState = LOW;
bool      
   stateMotorPin = false,
   bEnable = false;

void setup()
{
   Serial.begin(115200);
   pinMode( buttonPin, INPUT_PULLUP );
   swLast = digitalRead( buttonPin );

pinMode( pinDebugLED, OUTPUT );
   pinMode( ledPin, OUTPUT );
   pinMode( stepPin, OUTPUT );
   pinMode( dirPin, OUTPUT );
   pinMode( enablePin, OUTPUT );
   pinMode( ledPin, OUTPUT );

//set up on and off step tables for LED
   for( uint8_t obj=0; obj<NUM_OBJECTS; obj++ )
   {
       float fNominalObjDegrees = HALL_TO_OBJ0_DEGREES + (obj * (float)DEGREES_PER_REV / (float)NUM_OBJECTS);
       float fLED_ON_Degrees = fNominalObjDegrees - (LED_ON_DEGREES / 2.0);
       float fLED_OFF_Degrees = fNominalObjDegrees + (LED_ON_DEGREES / 2.0);

grLED_ON_Steps[obj] = (uint16_t)(0.5 + (fLED_ON_Degrees * (float)STEPS_PER_REV / (float)DEGREES_PER_REV));
       grLED_OFF_Steps[obj] = (uint16_t)(0.5 + (fLED_OFF_Degrees * (float)STEPS_PER_REV / (float)DEGREES_PER_REV));
               
   }//for
/*

  • debug
  • print tables to console for check
       for( uint8_t i=0; i<NUM_OBJECTS; i++ )
       {
           Serial.print( "ON  :" ); Serial.println( grLED_ON_Steps[i] );
           Serial.print( "OFF :" ); Serial.println( grLED_OFF_Steps[i] );
           
       }//
    */

//initial state
   digitalWrite( enablePin, HIGH );        //motor driver disabled
   bLEDState = OFF;                        //LED off
   digitalWrite( ledPin, LOW );
   stateMotorPin = false;                  //step pin low
   digitalWrite( stepPin, LOW );
   digitalWrite( dirPin, HIGH );           //dir pin high (default)

}//setup

void loop()
{
   ReadButton();           //check the button for change of state
   motorStateMachine();    //process motor and LED state machine
   
}//loop

void ReadButton( void )
{
   static uint32_t
       timeButton = 0;
   uint32_t
       timeNow = millis();

//time for a button read?
   if( (timeNow - timeButton) < TIME_BUTTON_READ )
       return;
       
   timeButton = timeNow;
   //read the pin
   swNow = digitalRead( buttonPin );
   //if not the same as the last read, state has changed
   if( swNow != swLast )
   {
       //save new value
       swLast = swNow;
       //if changed to low state...
       if( swNow == LOW )
       {
           //toggle the enable flag
           bEnable ^= true;
           //if we're now enabled...
           if( bEnable )
           {
               //enable the motor driver
               digitalWrite( enablePin, LOW );
               //force sync-up and enable the Hall sensor interrupt
               bSync = false;
               attachInterrupt( digitalPinToInterrupt( hallPin ), isrHall, RISING );                
               
           }//if
           else
           {
               //we just disabled so:
               //disable motor driver
               digitalWrite( enablePin, HIGH );
               //disconnect Hall interrupt
               detachInterrupt( digitalPinToInterrupt( hallPin ) );
               //turn off the LED
               bLEDState = OFF;
               digitalWrite( ledPin, LOW );
               //and set motor step pin low
               stateMotorPin = false;
               digitalWrite( stepPin, LOW );
               
           }//else
           
       }//if
       
   }//if
       
}//ReadButton

void motorStateMachine( void )
{
   static uint32_t
       timeMotor = 0;
   uint32_t
       timeNow = micros();

//if not enabled, just return
   if( !bEnable )    
       return;

//time for a pin toggle?
   if( (timeNow - timeMotor) < TIME_STEP_DIV2 )
       return;
       
   timeMotor = timeNow;
   //toggle the pin
   stateMotorPin ^= HIGH;
   digitalWrite( stepPin, stateMotorPin );

//if the Hall shows sync'd and the motor pin is now low...
   if( bSync && stateMotorPin == LOW )
   {
       //bump the step counter
       cntLEDSync++;
       //is the LED on or off now?
       switch( bLEDState )
       {
           case    OFF:
               //is now off; are we at the turn-on step #?
               if( cntLEDSync == grLED_ON_Steps[objNum] )
               {
                   //yes; turn on the LED
                   digitalWrite( ledPin, HIGH );
                   bLEDState = ON;
                   
               }//if
               
           break;
           
           case    ON:
           //is on now; are we at the turn-off step #?
               if( cntLEDSync == grLED_OFF_Steps[objNum] )
               {
                   //no; turn off the LED
                   digitalWrite( ledPin, LOW );
                   bLEDState = OFF;

//after an LED turns off, bump the object counter
                   objNum++;
                   //if we just turned off the last one...
                   if( objNum == NUM_OBJECTS )
                   {
                       //we can resync now by clearing the sync flag and re-enabling the Hall interrupt
                       //digitalWrite( pinDebugLED, LOW );
                       bSync = false;
                       attachInterrupt( digitalPinToInterrupt( hallPin ), isrHall, RISING );
                       
                   }//if
                   
               }//if
           
           break;

}//switch
               
   }//if
       
}//motorStateMachine

//
void isrHall( void )
{
   static bool
       bOBLEDState = false;
       
   //we we get the rising edge of the Hall sensor we're sync'd
   //first object to be lit
   objNum = 0;
   //counts to zero
   cntLEDSync = 0;
   //done with the interrupt now; disable it
   detachInterrupt( digitalPinToInterrupt( hallPin ) );
   //and show in SYNC to mainline    
   bSync = true;
   
   bOBLEDState ^= true;
   digitalWrite( pinDebugLED, bOBLEDState );

}//isrHall

The debug light just turned on permanently after i pressed the button to deactive the script and then pressed it again the led flashed correctly for a very brief time frame and now i'm getting very confused

Blackfin:
I don't think that's it. I'm (in theory) just checking step numbers from the Hall effect "sync" pulse.

So to start debugging, can you try this code: it toggles the on-board LED on each SYNC event telling us the rising-edge interrupt from the Hall sensor is working.

/*
  • Sketch: zoetrope.ino
  • Target: Mega2560

*/
#define HALL_TO_OBJ0_DEGREES            20.0f       //deg   offset from Hall sensor rising edge to centre of first object
//
#define NUM_OBJECTS                     12          //#     number of objects
#define STEPS_PER_REV                   3200        //#     number of steps per revolution
#define DEGREES_PER_REV                 360         //#     degrees in a circle
#define LED_ON_DEGREES                  10.0f       //deg   number of degrees LED is on for each object
//
#define TIME_STEP_DIV2                  80ul        //uS    microseconds per toggle of step pin (steps/sec = 1 / (2 x E))
#define TIME_BUTTON_READ                50ul        //mS    milliseconds between button reads
//
#define ON                              HIGH        //state LED on pin state
#define OFF                             LOW         //state LED off pin state

uint16_t
   grLED_ON_Steps[NUM_OBJECTS],
   grLED_OFF_Steps[NUM_OBJECTS];

const uint8_t pinDebugLED = LED_BUILTIN;
const uint8_t ledPin =  2;
const uint8_t buttonPin = 68;
const uint8_t dirPin = 60;
const uint8_t enablePin = 23;
const uint8_t stepPin = 22;
const uint8_t hallPin = 18;

volatile uint16_t
   cntLEDSync;
volatile bool
   bSync = false;
   
uint8_t
   objNum,
   bLEDState,
   swNow,
   swLast,
   motorPinState = LOW,
   ledState = LOW;
bool      
   stateMotorPin = false,
   bEnable = false;

void setup()
{
   Serial.begin(115200);
   pinMode( buttonPin, INPUT_PULLUP );
   swLast = digitalRead( buttonPin );

pinMode( pinDebugLED, OUTPUT );
   pinMode( ledPin, OUTPUT );
   pinMode( stepPin, OUTPUT );
   pinMode( dirPin, OUTPUT );
   pinMode( enablePin, OUTPUT );
   pinMode( ledPin, OUTPUT );

//set up on and off step tables for LED
   for( uint8_t obj=0; obj<NUM_OBJECTS; obj++ )
   {
       float fNominalObjDegrees = HALL_TO_OBJ0_DEGREES + (obj * (float)DEGREES_PER_REV / (float)NUM_OBJECTS);
       float fLED_ON_Degrees = fNominalObjDegrees - (LED_ON_DEGREES / 2.0);
       float fLED_OFF_Degrees = fNominalObjDegrees + (LED_ON_DEGREES / 2.0);

grLED_ON_Steps[obj] = (uint16_t)(0.5 + (fLED_ON_Degrees * (float)STEPS_PER_REV / (float)DEGREES_PER_REV));
       grLED_OFF_Steps[obj] = (uint16_t)(0.5 + (fLED_OFF_Degrees * (float)STEPS_PER_REV / (float)DEGREES_PER_REV));
               
   }//for
/*

  • debug
  • print tables to console for check
       for( uint8_t i=0; i<NUM_OBJECTS; i++ )
       {
           Serial.print( "ON  :" ); Serial.println( grLED_ON_Steps[i] );
           Serial.print( "OFF :" ); Serial.println( grLED_OFF_Steps[i] );
           
       }//
    */

//initial state
   digitalWrite( enablePin, HIGH );        //motor driver disabled
   bLEDState = OFF;                        //LED off
   digitalWrite( ledPin, LOW );
   stateMotorPin = false;                  //step pin low
   digitalWrite( stepPin, LOW );
   digitalWrite( dirPin, HIGH );           //dir pin high (default)

}//setup

void loop()
{
   ReadButton();           //check the button for change of state
   motorStateMachine();    //process motor and LED state machine
   
}//loop

void ReadButton( void )
{
   static uint32_t
       timeButton = 0;
   uint32_t
       timeNow = millis();

//time for a button read?
   if( (timeNow - timeButton) < TIME_BUTTON_READ )
       return;
       
   timeButton = timeNow;
   //read the pin
   swNow = digitalRead( buttonPin );
   //if not the same as the last read, state has changed
   if( swNow != swLast )
   {
       //save new value
       swLast = swNow;
       //if changed to low state...
       if( swNow == LOW )
       {
           //toggle the enable flag
           bEnable ^= true;
           //if we're now enabled...
           if( bEnable )
           {
               //enable the motor driver
               digitalWrite( enablePin, LOW );
               //force sync-up and enable the Hall sensor interrupt
               bSync = false;
               attachInterrupt( digitalPinToInterrupt( hallPin ), isrHall, RISING );                
               
           }//if
           else
           {
               //we just disabled so:
               //disable motor driver
               digitalWrite( enablePin, HIGH );
               //disconnect Hall interrupt
               detachInterrupt( digitalPinToInterrupt( hallPin ) );
               //turn off the LED
               bLEDState = OFF;
               digitalWrite( ledPin, LOW );
               //and set motor step pin low
               stateMotorPin = false;
               digitalWrite( stepPin, LOW );
               
           }//else
           
       }//if
       
   }//if
       
}//ReadButton

void motorStateMachine( void )
{
   static uint32_t
       timeMotor = 0;
   uint32_t
       timeNow = micros();

//if not enabled, just return
   if( !bEnable )    
       return;

//time for a pin toggle?
   if( (timeNow - timeMotor) < TIME_STEP_DIV2 )
       return;
       
   timeMotor = timeNow;
   //toggle the pin
   stateMotorPin ^= HIGH;
   digitalWrite( stepPin, stateMotorPin );

//if the Hall shows sync'd and the motor pin is now low...
   if( bSync && stateMotorPin == LOW )
   {
       //bump the step counter
       cntLEDSync++;
       //is the LED on or off now?
       switch( bLEDState )
       {
           case    OFF:
               //is now off; are we at the turn-on step #?
               if( cntLEDSync == grLED_ON_Steps[objNum] )
               {
                   //yes; turn on the LED
                   digitalWrite( ledPin, HIGH );
                   bLEDState = ON;
                   
               }//if
               
           break;
           
           case    ON:
           //is on now; are we at the turn-off step #?
               if( cntLEDSync == grLED_OFF_Steps[objNum] )
               {
                   //no; turn off the LED
                   digitalWrite( ledPin, LOW );
                   bLEDState = OFF;

//after an LED turns off, bump the object counter
                   objNum++;
                   //if we just turned off the last one...
                   if( objNum == NUM_OBJECTS )
                   {
                       //we can resync now by clearing the sync flag and re-enabling the Hall interrupt
                       //digitalWrite( pinDebugLED, LOW );
                       bSync = false;
                       attachInterrupt( digitalPinToInterrupt( hallPin ), isrHall, RISING );
                       
                   }//if
                   
               }//if
           
           break;

}//switch
               
   }//if
       
}//motorStateMachine

//
void isrHall( void )
{
   static bool
       bOBLEDState = false;
       
   //we we get the rising edge of the Hall sensor we're sync'd
   //first object to be lit
   objNum = 0;
   //counts to zero
   cntLEDSync = 0;
   //done with the interrupt now; disable it
   detachInterrupt( digitalPinToInterrupt( hallPin ) );
   //and show in SYNC to mainline    
   bSync = true;
   
   bOBLEDState ^= true;
   digitalWrite( pinDebugLED, bOBLEDState );

}//isrHall

I am such an idiot... i forgot to put my hallsensopr on pin 18 since that is the only one viable for interrupts the code works flawlessly... Ty very much

OK, cool. Good to hear.

There will be a relationship between the Hall sensor rising edge and the "nominal" position of the first object to be lit. I've expressed this in degrees in the line:

#define HALL_TO_OBJ0_DEGREES            20.0f       //deg   offset from Hall sensor rising edge to centre of first object

You can adjust/play with that so that the illumination occurs at the right time for the first object. Assuming they're all placed 30-degrees apart it should be good for the rest.

Cheers.

Blackfin:
OK, cool. Good to hear.

There will be a relationship between the Hall sensor rising edge and the "nominal" position of the first object to be lit. I've expressed this in degrees in the line:

#define HALL_TO_OBJ0_DEGREES            20.0f       //deg   offset from Hall sensor rising edge to centre of first object

You can adjust/play with that so that the illumination occurs at the right time for the first object. Assuming they're all placed 30-degrees apart it should be good for the rest.

Cheers.

Alright cheers the finial design is still printing so i'll be playing around with those numbers to find that sweet spot. u've been such a big help. and thanks for putting what everything does next to the lines of code, it helped me understand everything it does. since i'm new to arduino that is a big plus. hope i will need less and less help of the forums over time. have an amazing week.

You might google 'zoopraxtiscope' which I think is what you are making rather than a zoetrope?
A Hall sensor sounds sensible but you may be surprised how easy it is to synchronise the illumination.
If your motor runs at a reasonably constant speed, you can adjust the strobe speed until you find a stable image.
You might be over thinking this. Build your hardware & check it out.

myiot23:
You might google 'zoopraxtiscope' which I think is what you are making rather than a zoetrope?
A Hall sensor sounds sensible but you may be surprised how easy it is to synchronise the illumination.
If your motor runs at a reasonably constant speed, you can adjust the strobe speed until you find a stable image.
You might be over thinking this. Build your hardware & check it out.

well that wouldn't work for me i am aware that this is complicated but my design is not the same all the time since i'm using multiple figurines etc so the hall sensor is a safer bet.