Go Down

Topic: activating stepper motor with IR fork light sensor (Read 582 times) previous topic - next topic

MitchStraub

Hi,

for a school project i am making a chewing gum dispenser. For this dispenser I am using an Arduino uno R3, a 28BYJ-48 stepper motor and an IR fork light barrier.
The goal of the setup is that a coin rolls through the fork light barrier which in turn triggers te stepper motor to complete a number of steps.

The problem I'm bumping into is that the code i have now only allows the stepper motor to rotate when something stays in between the fork light barrier instead of passing through it.

I was wondering if somebody would be willing to help me adjust my code to solve this problem.

Thank you,
Mitch

Code: [Select]

/*
   BYJ48 Stepper motor code
   Connect :
   IN1 >> D8
   IN2 >> D9
   IN3 >> D10
   IN4 >> D11
   VCC ... 5V Prefer to use external 5V Source
   Gnd
   written By :Mohannad Rawashdeh
  https://www.instructables.com/member/Mohannad+Rawashdeh/
     28/9/2013
  */

#define IN1  8
#define IN2  9
#define IN3  10
#define IN4  11

int Steps = 0;
boolean Direction = true;// gre
unsigned long last_time;
unsigned long currentMillis ;
int steps_left=17786;
long time;
int isObstaclePin = 7;
int isObstacle = LOW;

void setup()
{
Serial.begin(115200);
pinMode(isObstaclePin, INPUT);     
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
// delay(1000);

}

void loop()
{

  while(steps_left>0){
  currentMillis = micros();
  if(currentMillis-last_time>=1000){
  stepper(1);
  time=time+micros()-last_time;
  last_time=micros();
  steps_left--;
  }
 
 
  }
   Serial.println(time);
  Serial.println("Wait...!");
  delay(2000);
  Direction=!Direction;
  steps_left=0;


}
void stepper(int xw){   
  for (int x=0;x<xw;x++){
switch(Steps){
   case 0:
     digitalWrite(IN1, LOW);
     digitalWrite(IN2, LOW);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, HIGH);
   break;
   case 1:
     digitalWrite(IN1, LOW);
     digitalWrite(IN2, LOW);
     digitalWrite(IN3, HIGH);
     digitalWrite(IN4, HIGH);
   break;
   case 2:
     digitalWrite(IN1, LOW);
     digitalWrite(IN2, LOW);
     digitalWrite(IN3, HIGH);
     digitalWrite(IN4, LOW);
   break;
   case 3:
     digitalWrite(IN1, LOW);
     digitalWrite(IN2, HIGH);
     digitalWrite(IN3, HIGH);
     digitalWrite(IN4, LOW);
   break;
   case 4:
     digitalWrite(IN1, LOW);
     digitalWrite(IN2, HIGH);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, LOW);
   break;
   case 5:
     digitalWrite(IN1, HIGH);
     digitalWrite(IN2, HIGH);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, LOW);
   break;
     case 6:
     digitalWrite(IN1, HIGH);
     digitalWrite(IN2, LOW);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, LOW);
   break;
   case 7:
     digitalWrite(IN1, HIGH);
     digitalWrite(IN2, LOW);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, HIGH);
   break;
   default:
     digitalWrite(IN1, LOW);
     digitalWrite(IN2, LOW);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, LOW);
   break;

 
 
 
  } 
SetDirection();
}
}
void SetDirection(){
 isObstacle = digitalRead(isObstaclePin);
if (isObstacle == HIGH) {
if(Direction==1){ Steps++;}
if(Direction==0){ Steps--; }
if(Steps>7){Steps=0;}
if(Steps<0){Steps=7; }
}
}



UKHeliBob

Quote
The problem I'm bumping into is that the code i have now only allows the stepper motor to rotate when something stays in between the fork light barrier instead of passing through it.
You need to detect when the light becomes interrupted rather than when it is interrupted.

Look at the StateChangeDetection example in the IDE
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

MitchStraub

Thank you for replying Bob,

I understand the StateChangeDetection example in IDE, but I don't understand how to implement it into my own code..


DKWatson

Declare a byte variable as a flag.

When the IR interrupts, set the flag to one.

Execute your stepper routine.

When your stepper routine finishes, clear the flag.
=======
Use the flag to trigger the stepper routine rather than the event.
Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

DKWatson

If you like, I use a lot of flags for all kinds of tests and control.

My approach:

Code: [Select]

typedef struct
{
    bool    bit_0: 1;
    bool    bit_1: 1;
    bool    bit_2: 1;
    bool    bit_3: 1;
    bool    bit_4: 1;
    bool    bit_5: 1;
    bool    bit_6: 1;
    bool    bit_7: 1;
} bits;

bits flag1;
//bits flag2;
// .
// .
// .
//bits flagn;

#define your_flag_name_here flag1.bit_0
//#define flag_name_1 flag1.bit_1
//#define flag_name_1 flag1.bit_2
//#define flag_name_1 flag1.bit_3
//#define flag_name_1 flag1.bit_4
//#define flag_name_1 flag1.bit_5
//#define flag_name_1 flag1.bit_6
//#define flag_name_1 flag1.bit_7


You get 8 single bit flags per byte and you can make as many as you need with little penalty.

As a single bit it will either be 1 or 0.

Add 2 macros,

#define Set(x)    x=1
#define Clear(x)  x=0

and you're away to the races.

Easy to test also,

if(your_flag_name)
{
}
else
{
}

or use the ternary function,

(your_flag_name)?action_if_true:action_if_false;

The world is now your oyster.
Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

DKWatson

For completeness I must add that the individual flags can be referenced as flag1.bit_0 and so on as well.

Penalty for using bitfields:

if(byte) takes 16 clock cycles
if(byte.bitfield) takes 18 clock cycles
Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

Go Up