Zoetrope project school. (new to arduino)

Hey sorry for interrupting all of your days. I’m currently working on a school project where we have to make a gift for someone, I chose to make a zoetrope for my little sister. I’m using a stepper motor (NEMA 17) a megatronics v3.3 and a DVR 8825 as a stepper driver. Now, I planned to let the stepper motor start turning once I press a button. Now I’ve got that to work, but now, I needed to implement my hall sensor so that it can calculate at what speed my LED’s need to blink to get 12 fps. I’m completely stuck on this part I’ve been looking at countless tutorials, and even just sites with explanations on how this works, but I just can’t get it to work. Now I’m assuming I’ll have to use blink without delay for the LEDs to not disrupt the stepper from turning? If that is not the case do please let me know. If anyone can help me out here I would greatly appreciate it.
now the code I’m supplying right now is just to make the stepper turn and make the led flash 12 times in a second when the button is held down. now I want to make it so I can turn it off and on by just pressing once. now the flashing works in a separate script but once I add the flashing to the script well then it just flashes once every time the stepper makes a full rotation. help would be very much appreciated and I’m once again very grateful for those who offer me support.
have a great day.
Kind regards O.

const long interval = 83.3333333333;
unsigned long previousMillis = 0;
int ledState = LOW;
const int ledPin =  2;
int buttonPin;
bool  fHasLooped = false;
#define dirPin 60
#define enablePin 23
#define stepPin 22
#define stepsPerRevolution 3200



void setup()
{
  buttonPin = 68; 
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(2, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(ledPin, OUTPUT);
}



void loop()
{

  
  if(digitalRead(buttonPin) == LOW) 
  {
    digitalWrite(enablePin, LOW);
    digitalWrite(dirPin, HIGH);

    unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
     
     digitalWrite(ledPin, ledState);
    }
    
    for (int i = 0; i < stepsPerRevolution; i++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(100);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(100);
    }
    
    
  }
}

sketch_nov10a.ino (1.09 KB)

Sorry for that way too complicated explanation. So basically all I need is a script that measures rpm using a hall sensor. Then convert said speed so that LED flashes 12 times in 1 rotation. I also need the script to start and stop when I press a button (I’ve only been able to make it run whenever I hold the button down). I’m using a megatronics v3.3 and a DVR 8825 as stepper driver.
I just can’t seem to get the hall sensor to work and whenever i add the blinking script to the script that also controls the stepper it just completely breaks.

I’ve tried every hall sensor rpm measuring script i could find and it just wouldn’t work. it is detecting the magnet though since i first tried by just letting it trigger a led whenever the magnet passed. i’m rlly stuck here. once again thanks for ur help.

const long interval = 83.3333333333;
unsigned long previousMillis = 0;
int ledState = LOW;
const int ledPin =  2;
int buttonPin;
bool  fHasLooped = false;
#define dirPin 60
#define enablePin 23
#define stepPin 22
#define stepsPerRevolution 3200



void setup()
{
  buttonPin = 68; 
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(2, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(ledPin, OUTPUT);
}



void loop()
{

  
  if(digitalRead(buttonPin) == LOW) 
  {
    digitalWrite(enablePin, LOW);
    digitalWrite(dirPin, HIGH);

    unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
     
     digitalWrite(ledPin, ledState);
    }
    
    for (int i = 0; i < stepsPerRevolution; i++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(100);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(100);
    }
    
    
  }
}

that is the code to just turn the stepper and make the led flash 12 times in a second but now it only flashes once the motor makes a full rotation…

If you're using a stepper and know the number of steps per revolution why do you need an external sensor to tell you angular velocity?

Or do you need the Hall sensor to act as an "index"?

Blackfin:
If you're using a stepper and know the number of steps per revolution why do you need an external sensor to tell you angular velocity?

Or do you need the Hall sensor to act as an "index"?

That's what I was thinking at first but my dad said that if it was a bit inaccurate then it won't be an animation but just a blur. The hall sensor would technically not be needed then. But I do need to use blink without delay in this case right? And how would I make it, so I can turn it on or off with just a button press and I don't have to hold it down?

And if I use it as an index how would that be used?
I'm pretty new to Arduino but I'm familiar with python, so I'm guessing it works in a similar matter

Kind regards O.

Can you clarify what it is that you are "animating"? You have a single LED. If I understand the term "zoetrope" you have something like this:

In a zeotrope, you peer through the slots as it spins and each slot "exposes" a different picture giving the illusion of animation.

How does your assemblage do "animation"? Is the LED just providing momentary illumination of a drawing or ... ?

In your example code, you have a 200uS period on the stepper rotation; with 3200 steps/rotation, that's 640mS/rotation or 1.56Hz. With 12 slots, the time between slots is 53.333mS giving a slot frequency of 18.75Hz. Does all that make sense?

Blackfin:
Can you clarify what it is that you are “animating”? You have a single LED. If I understand the term “zoetrope” you have something like this:

In a zeotrope, you peer through the slots as it spins and each slot “exposes” a different picture giving the illusion of animation.

How does your assemblage do “animation”? Is the LED just providing momentary illumination of a drawing or … ?

In your example code, you have a 200uS period on the stepper rotation; with 3200 steps/rotation, that’s 640mS/rotation or 1.56Hz. With 12 slots, the time between slots is 53.333mS giving a slot frequency of 18.75Hz. Does all that make sense?

No, the rotation was just a random number because I haven’t calculate that out yet.
So instead of the slits I’m going to use the LED as a strobe.
Now they are high power LEDs in a small ring and I’ve already tested it they can go on and off in 1ms which is more than fast enough since they need to trigger every 82ms or so.

Still have to find the formula to calculate my steps per rotation to get to said desired speed.
Kind regards O.

Blackfin:
Can you clarify what it is that you are "animating"? You have a single LED. If I understand the term "zoetrope" you have something like this:

In a zeotrope, you peer through the slots as it spins and each slot "exposes" a different picture giving the illusion of animation.

How does your assemblage do "animation"? Is the LED just providing momentary illumination of a drawing or ... ?

In your example code, you have a 200uS period on the stepper rotation; with 3200 steps/rotation, that's 640mS/rotation or 1.56Hz. With 12 slots, the time between slots is 53.333mS giving a slot frequency of 18.75Hz. Does all that make sense?

My idea is based on the PonyTrope from kellyegan it uses a 3d model instead of a drawing that spins and a strobe instead of slits. Now his code wouldn't work for me since he uses a normal DC motor and potentio meter to control the speed and thus the need for a hall sensor. But since I predetermine the speed a hall sensor would not be needed. Or from what I understand thus far. All I need to do then is figure out a way to use the blink without delay script together with my stepper motor's script because once I put the LED and stepper script together the LED only blinked once every rotation instead of every 82ms.
That's the problem I am currently facing.
If u want to take a look at Kelly's design here is the thingiverse link: PonyTrope by kellyegan - Thingiverse

Just do one step in the loop function. Use the same technique you used for the led to determine when to do it. You're going to have to use micros instead of millis though.

wildbill:
Just do one step in the loop function. Use the same technique you used for the led to determine when to do it. You're going to have to use micros instead of millis though.

alright thank you.
but how do i make the button an on off instead of a hold?
can't seem to find a tutorial for that or is that not possible?

When you see the button is pressed, flip a global boolean variable. If it's true, do your led & stepping. If it's false do nothing. You will need to debounce it too eventually, but initially, don't bother.

With that design, and using a stepper motor, the hall effect sensor is not needed.

Don't worry about using millis() to time the LED, trigger it at a specific number of steps of the stepper motor.

At 3200 steps/revolution, the LED would need to be triggered at 3200/12 = 266.67 step intervals, unfortunate because you cannot have a precisely stationary image, but using 266 or 267 would work with the horse appearing to slowly travel forward or backward.

Follow the suggestion of doing one step each time through the loop, and keep a count of the number of steps you have taken. When the desired number of steps is reached, turn the LED ON and reset the counter. Before taking the next step turn the LED back OFF, that should give you a long enough duration of the LED to strobe the image.

If you have a hardware setup, try this:

/*
 * 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 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( 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 teh 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
                        bSync = false;
                        attachInterrupt( digitalPinToInterrupt( hallPin ), isrHall, RISING );
                        
                    }//if
                    
                }//if
            
            break;

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

//
void isrHall( void )
{
    //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;

}//isrHall

david_2018:
With that design, and using a stepper motor, the hall effect sensor is not needed.

Don't worry about using millis() to time the LED, trigger it at a specific number of steps of the stepper motor.

At 3200 steps/revolution, the LED would need to be triggered at 3200/12 = 266.67 step intervals, unfortunate because you cannot have a precisely stationary image, but using 266 or 267 would work with the horse appearing to slowly travel forward or backward.

Follow the suggestion of doing one step each time through the loop, and keep a count of the number of steps you have taken. When the desired number of steps is reached, turn the LED ON and reset the counter. Before taking the next step turn the LED back OFF, that should give you a long enough duration of the LED to strobe the image.

thank you very much this was a great help. I love the forums

Blackfin:
If you have a hardware setup, try this:

/*
  • 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 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( 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 teh 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
                       bSync = false;
                       attachInterrupt( digitalPinToInterrupt( hallPin ), isrHall, RISING );
                       
                   }//if
                   
               }//if
           
           break;

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

//
void isrHall( void )
{
   //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;

}//isrHall

Holy… thank you so much I will try this tomorrow since it’s already midnight where I live and I don’t think my parents would be so happy if I started doing it right now. Thanks for the big help I was pretty stuck looking at lots of tutorials and not getting it. will have to take a look at the code to see exactly what it does but thanks a lot. Have a great day

No idea if it'll work. It compiles :slight_smile:

I'm also not sure if 6200+ steps per second is okay with that controller/motor and/or if it'd need to be accelerated to speed. Not hard to add if necessary. But you can try it as a "zero order" attempt to see if it does anything...

Blackfin:
No idea if it'll work. It compiles :slight_smile:

I'm also not sure if 6200+ steps per second is okay with that controller/motor and/or if it'd need to be accelerated to speed. Not hard to add if necessary. But you can try it as a "zero order" attempt to see if it does anything...

Alright once again thanks a lot. i've been looking at the code and at some parts i got a little confused but since i know java and python it does ring some bells 90% of the time. you have no idea how hard this saved my ass.

thenoobjoker:
Alright once again thanks a lot. i’ve been looking at the code and at some parts i got a little confused but since i know java and python it does ring some bells 90% of the time. you have no idea how hard this saved my ass.

Well, see if it works first :slight_smile:

Blackfin:
No idea if it'll work. It compiles :slight_smile:

I'm also not sure if 6200+ steps per second is okay with that controller/motor and/or if it'd need to be accelerated to speed. Not hard to add if necessary. But you can try it as a "zero order" attempt to see if it does anything...

Ok so just tested it out and the stepper works fine except that the led doesn't get triggerd. the hall sensor does detect the magnet since it has an inbuld LED when detecting a magnet and that does trigger. i'll be looking at the code for a bit to find anything regarding too that. still ur flipping amazing ty

Blackfin:
Well, see if it works first :slight_smile:

Ok so i might have found out what the problem is. You are checking in the code for the state of the LED correct?
I'm using a 12v extruder MOSFET as it's pin it might be that the board can't check the state of a mosfet? is this the case or am i just being stupid right now .

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