This is the datasheet of the stepper we use:
This is the encoder we use.
This is the code:
#include <Bounce2.h>
#include <Stepper.h>
/*
DESCRIPTION
====================
Reads the 2 switches in an encoder,
determines direction,
updates counter.
No interrupts.
Switches debounced, didn't test first, just did it anyway.
*/
const byte ENCODER_PINA= 2;
//const byte LED_PINA= 12;
const byte ENCODER_PINB= 3;
//const byte LED_PINB= 11;
const int stepsPerRevolution = 64;
Stepper myStepper(stepsPerRevolution, 7, 4, 5, 6);
int valueA; //debounced encoder switch reads
int valueB;
bool motionDetected = false;
int grossCounter = 0; // total steps
int nettCounter = 0; // cw-ccw
int fullRevolutions = 0;
int surplusSteps = 0; //part revs
bool CW;
byte cyclesPerRev =20; //check encoder datasheet
// Instantiate 2 Bounce object
Bounce debouncerA = Bounce();
Bounce debouncerB = Bounce();
// setup ********************************************
void setup() {
Serial.begin(115200);
Serial.println("Setup");
// Setup the buttons
pinMode(ENCODER_PINA,INPUT_PULLUP);
pinMode(ENCODER_PINB,INPUT_PULLUP);
// After setting up the button, setup debouncer
debouncerA.attach(ENCODER_PINA);
debouncerA.interval(5);
debouncerB.attach(ENCODER_PINB);
debouncerB.interval(5);
myStepper.setSpeed(300);
Serial.println("Setup done");
}
// loop *****************************************
void loop() {
// Update the debouncers
doDebounce();
// Read the encoder switches
doEncoderRead();
//determine direction and update counter
updateCounter();
} //loop
// my functions **************************************************
void doDebounce()
{
debouncerA.update();
debouncerB.update();
} //doDebounce
void doEncoderRead()
{
valueA = debouncerA.read();
valueB = debouncerB.read();
} //doEncoderRead
void updateCounter()
{
/*
the possibilites are:
AB: in a detent
if just arrived, update counter, clear motiondetected
otherwise do nothing
Ab: start of CW or end of CCW
if start, set CW bool and set motionDetected
if at end (know becasue motionDetected already set), do nothing
aB: start of CCW or end of CW
if start, clear CW bool and set motionDetected
if at end (know becasue motionDetected already set), do nothing
ab: in middle of either CW or CCW, do nothing
*/
if (valueA && valueB && motionDetected ) //in a detent and just arrived
{
if (CW)
{
grossCounter= grossCounter + 1;
nettCounter= nettCounter + 1;
myStepper.step(80);
}
else //CCW
{
grossCounter= grossCounter + 1;
nettCounter= nettCounter - 1;
myStepper.step(-80);
}
motionDetected = false;
Serial.print("grossCounter: ");
Serial.println(grossCounter);
Serial.print("nettCounter: ");
Serial.println(nettCounter);
fullRevolutions = nettCounter / cyclesPerRev;
surplusSteps = nettCounter % cyclesPerRev;
Serial.print("Nett position: ");
Serial.print(fullRevolutions);
Serial.print(" + ");
Serial.println(surplusSteps);
Serial.println(" ");
}
if (valueA && !valueB && !motionDetected ) // just started CW
{
CW= true;
motionDetected=true;
Serial.println("CW");
}
if (!valueA && valueB && !motionDetected ) //just started CCW
{
CW= false;
motionDetected=true;
Serial.println("CCW");
}
} //updateCounter
Our code works perfectly for our purposes when we use myStepper.step(1);.
The problem is in the myStepper.step(80);, because when we use that, the serial monitor (and the stepper) mess up clockwise and counterclockwise. For example, when we use step(1) the output would be:
cw
cw
cw
cw
cw
cw
but with step(80) and doing the same, the output is e.g.
cw
cw
ccw
cw
ccw
ccw
cw
We think that is because when the stepper is turning 80 steps, that takes time and in that time the code misses pulses from the encoder.
We want 80 steps at once because that corresponds with the amount of degrees when you turn the encoder one step.
We think we could solve that by using interrupts, because that would 'interrupt' the code to read out the encoder, and we wanted to try that but didn't know where to start.
We have some example codes for the encoder that work with interrupts, but when we tried to implement the code for the stepper in those, well, we don't really know what we're doing anyway.