Arduino Stepper Encoder programming question - Page 1
Forum section: electronics / general

author: bkukuk62
author_rank: Newbie
timestamp: September 18, 2019, 07:15:53 pm
content: 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 rotorconst 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 5Stepper myStepper(stepsPerRevolution, 2, 3, 4, 5);int stepCount = 0; // number of steps the motor has takenint val = 0; // variable for reading input pin 8volatile long motor_position, encoder;void setup (){//set up the various outputspinMode(motor_step, OUTPUT);pinMode(motor_direction, OUTPUT);// then the encoder inputspinMode(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/multiplyingint sensorReading = analogRead(A0); // Read the sensor value from potentiometer on pin A0int motorSpeed = map(sensorReading, 0, 1023, 0, 100); // Map sensor range from 0 to 100if (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;}}

author: ledtester
author_rank: Super Contributor
timestamp: September 18, 2019, 08:53:07 pm
content: (btw - you can use thecodetag 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) {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

author: bkukuk62
author_rank: Newbie
timestamp: September 18, 2019, 10:00:20 pm
content: 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-2019const 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 5volatile long motor_position, encoder;void setup (){//set up the various outputspinMode(motor_step, OUTPUT);pinMode(motor_direction, OUTPUT);// then the encoder inputspinMode(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/multiplyingif (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;}}

author: ledtester
author_rank: Super Contributor
timestamp: September 18, 2019, 10:08:27 pm
content: PinStartis a constant - it will always be 8.HIGHis another constant - it will always be 1. Therefore this test:Code:if (PinStart == HIGH) {will always fail.Maybe you want:Code:if (digitalRead(PinStart) == HIGH)

author: bkukuk62
author_rank: Newbie
timestamp: September 18, 2019, 10:45:24 pm
content: 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 8volatile long motor_position, encoder;void setup () {//set up the various outputspinMode(motor_step, OUTPUT);pinMode(motor_direction, OUTPUT);// then the encoder inputspinMode(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/multiplyingif (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;}}

author: ledtester
author_rank: Super Contributor
timestamp: September 18, 2019, 10:56:35 pm
content: Quote from: bkukuk62 on September 18, 2019, 10:45:24 pmGetting help from an internet forum is going to work a lot better if you test your code first.Test each individual part of it to see if it works the way you expect it to. Then you can come back and explain what you want it to do and what it is actually doing.

author: bkukuk62
author_rank: Newbie
timestamp: September 18, 2019, 11:03:48 pm
content: thanks,testing tonight.-bkukuk62

author: FreddieChopin
author_rank: Regular Contributor
timestamp: September 22, 2019, 07:14:43 am
content: You could use CppUTest library to unit test your code before trying it on actual hardware, it might be faster this way