Computing > Programming

Arduino Stepper Encoder programming question

(1/2) > >>

bkukuk62:
The code below is supposed to rotate a stepper motor to match the encoder rotation but I have an if-else if-else if statement where the code uses both a library (Stepper.h) and literal pin settings for the encoder pinout and stepper pinout.
The first part of the if statement is supposed to look for a button push and rotate the stepper 5 full rotations otherwise do the first statement on this where the stepper motor matches the encoder.

This compiles but I am not sure if what I did is the best approach.

I would like any and all comments.
thanks,
bkukuk62

// Modified code for Arduino, Quadrature Optical Encoder, Stepper Motor 9-18-2019

#include <Stepper.h>

  const int InputPinStart = 8;  //  Input pin 8 to start auto rotation of rotor

  const int stepsPerRevolution = 200;  // Number of steps per revolution for the Stepper Motor

 #define encoder_a 2    //encoder a = arduino pin 2
 #define encoder_b 3    //encoder b = arduino pin 3
 #define motor_step 4    //motor step = arduino pin 4
 #define motor_direction 5    //motor direction = arduino pin 5

Stepper myStepper(stepsPerRevolution, 2, 3, 4, 5);

int stepCount = 0; //  number of steps the motor has taken
int val = 0;  // variable for reading input pin 8

volatile long motor_position, encoder;

void setup ()
{
    //set up the various outputs
    pinMode(motor_step, OUTPUT);
    pinMode(motor_direction, OUTPUT);
    // then the encoder inputs
    pinMode(encoder_a, INPUT);
    pinMode(encoder_b, INPUT);
    digitalWrite(encoder_a, HIGH);
    digitalWrite(encoder_b, HIGH);
    // encoder pin on interrupt 0 (pin 2)
    attachInterrupt(0, encoderPinChangeA, CHANGE);
    // encoder pin on interrupt 1 (pin 3)
    attachInterrupt(1, encoderPinChangeB, CHANGE);
    encoder = 0;
    pinMode (InputPinStart, INPUT);  //  Declare pushbutton as input to start rotation
}

void encoderPinChangeA()
{
    if (digitalRead(encoder_a) == digitalRead(encoder_b))
    {
        encoder--;
    }
    else
    {
        encoder++;
    }
}

void encoderPinChangeB()
{
    if (digitalRead(encoder_a) != digitalRead(encoder_b))
    {
        encoder--;
    }
    else
    {
        encoder++;
    }
}


void loop()
{
//do stuff dependent on encoder position here
//such as move a stepper motor to match encoder position
//if you want to make it 1:1 ensure the encoder res matches the motor res by dividing/multiplying
  int sensorReading = analogRead(A0);  //  Read the sensor value from potentiometer on pin A0
  int motorSpeed = map(sensorReading, 0, 1023, 0, 100);  //  Map sensor range from 0 to 100
  if (motorSpeed > 0) {
    myStepper.setSpeed(motorSpeed);
    // step 1/100 of a revolution:
    myStepper.step(stepsPerRevolution / 100);     
  }

  val = digitalRead(InputPinStart);
  if (InputPinStart == HIGH) {
    myStepper.step(stepsPerRevolution*5);  //  Turn stepper motor 5 full rotations     
    }
   
    else if (encoder > 0) {
        digitalWrite(motor_direction, HIGH);
        digitalWrite(motor_step, HIGH);
        digitalWrite(motor_step, LOW);
        _delay_us(200);
        motor_position++;
        encoder = 0;
    }
    else if (encoder < 0) {
        digitalWrite(motor_direction, LOW);
        digitalWrite(motor_step, HIGH);
        digitalWrite(motor_step, LOW);
        _delay_us(200);
        motor_position--;
        encoder = 0;
    }
}

ledtester:
(btw - you can use the code tag to format code blocks)

Is this perhaps a typo?

--- Code: ---  const int InputPinStart = 8;  //  Input pin 8 to start auto rotation of rotor
  ...
  val = digitalRead(InputPinStart);
  if (InputPinStart == HIGH) {

--- End code ---

You are reading the encoder in a non-blocking fashion, so one improvement might be to make the other control code non-blocking as well. Here are some pointers:

- non-blocking ADC reading:

https://www.gammon.com.au/adc

- non-blocking stepper motor control:

https://reprage.com/post/non-blocking-control-of-stepper-motors-on-arduino

bkukuk62:
ledtester,
I think I have corrected the issues, can you review it again.  I removed the library portions.  I want the code to stop everything while the stepper is rotating 10 full rotations and resume afterward.
ledtester, thanks for helping me out on this.
-bkukuk62

// Modified code for Arduino, Quadrature Optical Encoder, Stepper Motor 9-17-2019

 const int PinStart = 8;  //  Input pin 8 to start auto rotation of rotor

 #define encoder_a 2    //encoder a = arduino pin 2
 #define encoder_b 3    //encoder b = arduino pin 3
 #define motor_step 4    //motor step = arduino pin 4
 #define motor_direction 5    //motor direction = arduino pin 5

volatile long motor_position, encoder;

void setup ()
{
    //set up the various outputs
    pinMode(motor_step, OUTPUT);
    pinMode(motor_direction, OUTPUT);
    // then the encoder inputs
    pinMode(encoder_a, INPUT);
    pinMode(encoder_b, INPUT);
    digitalWrite(encoder_a, HIGH);
    digitalWrite(encoder_b, HIGH);
    // encoder pin on interrupt 0 (pin 2)
    attachInterrupt(0, encoderPinChangeA, CHANGE);
    // encoder pin on interrupt 1 (pin 3)
    attachInterrupt(1, encoderPinChangeB, CHANGE);
    encoder = 0;
    pinMode (PinStart, OUTPUT);  //  Declare pushbutton as input to start rotation
}

void encoderPinChangeA()
{
    if (digitalRead(encoder_a) == digitalRead(encoder_b))
    {
        encoder--;
    }
    else
    {
        encoder++;
    }
}

void encoderPinChangeB()
{
    if (digitalRead(encoder_a) != digitalRead(encoder_b))
    {
        encoder--;
    }
    else
    {
        encoder++;
    }
}

void loop()
{
//if you want to make it 1:1 ensure the encoder res matches the motor res by dividing/multiplying

    if (PinStart == HIGH) {
      digitalWrite(motor_direction, HIGH);
      digitalWrite(motor_step, HIGH);
      _delay_us(200);
      digitalWrite(motor_step, LOW);
      _delay_us(200);
      for (int i = 0; i < 100; i++) {
        step(1000);
      }
   
    else (encoder > 0) {
        digitalWrite(motor_direction, HIGH);
        digitalWrite(motor_step, HIGH);
        digitalWrite(motor_step, LOW);
        _delay_us(200);
        motor_position++;
        encoder = 0;
    }

    else (encoder < 0) {
        digitalWrite(motor_direction, LOW);
        digitalWrite(motor_step, HIGH);
        digitalWrite(motor_step, LOW);
        _delay_us(200);
        motor_position--;
        encoder = 0;
    }
}

ledtester:
PinStart is a constant - it will always be 8. HIGH is another constant - it will always be 1. Therefore this test:


--- Code: ---    if (PinStart == HIGH) {

--- End code ---

will always fail.

Maybe you want:


--- Code: ---  if (digitalRead(PinStart) == HIGH)

--- End code ---


bkukuk62:
ledtester,
thanks for the review and comments.  I reworked it again and got it to compile.
Do you see anything else that I tripped up on?

--- Code: ---// Modified code for Arduino, Quadrature Optical Encoder, Stepper Motor 9-18-2019


 #define encoder_a 2    //  encoder a = arduino pin 2
 #define encoder_b 3    //  encoder b = arduino pin 3
 #define motor_step 4    //  motor step = arduino pin 4
 #define motor_direction 5    //  motor direction = arduino pin 5
 #define PinStart 8  //  button to start auto rotation of rotor = arduino pin 8

volatile long motor_position, encoder;

void setup () {
    //set up the various outputs
    pinMode(motor_step, OUTPUT);
    pinMode(motor_direction, OUTPUT);
    // then the encoder inputs
    pinMode(encoder_a, INPUT);
    pinMode(encoder_b, INPUT);
    digitalWrite(encoder_a, HIGH);
    digitalWrite(encoder_b, HIGH);
    // encoder pin on interrupt 0 (pin 2)
    attachInterrupt(0, encoderPinChangeA, CHANGE);
    // encoder pin on interrupt 1 (pin 3)
    attachInterrupt(1, encoderPinChangeB, CHANGE);
    encoder = 0;
    pinMode (PinStart, OUTPUT);  //  Declare pushbutton as input to start rotation
}

void step(long stepDelay) {
    digitalWrite(motor_step, HIGH);
    _delay_us(200);
    digitalWrite(motor_step, LOW);
    _delay_us(200);
}


void encoderPinChangeA()
{
    if (digitalRead(encoder_a) == digitalRead(encoder_b))
    {
        encoder--;
    }
    else
    {
        encoder++;
    }
}

void encoderPinChangeB()
{
    if (digitalRead(encoder_a) != digitalRead(encoder_b))
    {
        encoder--;
    }
    else
    {
        encoder++;
    }
}

void loop() {
//if you want to make it 1:1 ensure the encoder res matches the motor res by dividing/multiplying

    if (digitalRead(PinStart) == HIGH) {
      for (int i = 0; i < 100; i++) {
        step(1000);
      }
    }
   
    else if (encoder > 0) {
        digitalWrite(motor_direction, HIGH);
        digitalWrite(motor_step, HIGH);
        digitalWrite(motor_step, LOW);
        _delay_us(200);
        motor_position++;
        encoder = 0;
    }

    else if (encoder < 0) {
        digitalWrite(motor_direction, LOW);
        digitalWrite(motor_step, HIGH);
        digitalWrite(motor_step, LOW);
        _delay_us(200);
        motor_position--;
        encoder = 0;
    }
}
--- End code ---

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version