Reading encoder to count steps(solved)

In my project I use a stepper motor and spindle to compress a spring.
To measure the position/displacement the spring is compressed I placed on the axle of the stepper motor an encoder disk with 300LPI resoltuion.
A full steppermotor turn is 200 steps and 2 mm displacement of compression.
I need to know the value at 1 mm displacement so I need to increment/decrement the encoder value of 1070.
So motor is turning by one step or constant rotation but my stepcounter does not increment/decrement.

I guess I am overlooking some basics after 10 hours of struckle. :slight_smile:

Any idea how simple the solution would be?

Thanks, Paco

#include <Stepper.h>

//Left = Down
//Right = Up

// Stepper has 200 revolutions for 360 degrees = 2 mm pitch we use 1 mm steps = 100 steps = 1070 pulses from the encoder
const int stepsPerRevolution = 100;  
Stepper myStepper(stepsPerRevolution, 4,5,6,7); // we use digital pins 4,5,6,7 with L298 stepper driver

boolean LeftTurnSingle = 0;
boolean RightTurnSingle = 0;
boolean LeftTurnConstant = 0;
boolean RightTurnConstant = 0;
boolean StartState = 0;
boolean RecordingState = 0;
boolean ReturnState = 0;

int incomingByte = 0;   // for incoming serial data
int StepCounter = 100;
int Analog2 = 16; // Use analog port on shield for push button to control movement and direction
int Analog3 = 17; // Use analog port on shield for push button to control movement and direction
int enablePin10= 10; //pin to enable/disable coil power
int enablePin11= 11; //pin to enable/disable coil power

///////////////////////////////
enum PinAssignments 
{
  encoderPinA = 2,   // rigth
  encoderPinB = 3,   // left
};

long encoderPos = 100000;  // a starting counterposition for the encoder
long encoderPosOld = 100000;
unsigned int lastReportedPos = 1;   // change management
static boolean rotating = false;      // debounce management


// interrupt service routine vars for encoder disk
boolean A_set = false;              
boolean B_set = false;
///////////////////////////////

void setup() 
{
  Serial.begin(9600);

  pinMode(enablePin10,OUTPUT);
  pinMode(enablePin11,OUTPUT);

  myStepper.setSpeed(400);  // set the stepperspeed at xxx rpm:

  pinMode(encoderPinA, INPUT); 
  pinMode(encoderPinB, INPUT); 

  // turn on pullup resistors for encoder
  digitalWrite(encoderPinA, HIGH);
  digitalWrite(encoderPinB, HIGH);

  // encoder pin on interrupt 0 (pin 2)
  attachInterrupt(0, doEncoderA, CHANGE);
  // encoder pin on interrupt 1 (pin 3)
  attachInterrupt(1, doEncoderB, CHANGE);
}

void loop() 
{
  LeftTurnSingle = digitalRead(Analog3);
  RightTurnSingle = digitalRead(Analog2);

  Serial.print("A,");
  Serial.println(StepCounter);
  Serial.print("B,");
  Serial.println(encoderPos,DEC);
  //Serial.print("C,");
  //Serial.println("datafromloadcell");

  if (encoderPos >= (encoderPosOld + 1070)) //if the value is 1070 higher then last known raise stepcounter by 1
  {
    StepCounter = StepCounter + 1;
  } 

  if (encoderPos <= (encoderPosOld - 1070)) //if the value is 1070 lower then last known reduce stepcounter by 1
  {
    StepCounter = StepCounter - 1;
  } 

  if (LeftTurnSingle == 1)
  {
    digitalWrite(enablePin10,HIGH);
    digitalWrite(enablePin11,HIGH);
    myStepper.step(stepsPerRevolution); // Do a left turn of 100 steps
  }

  else if (RightTurnSingle == 1)
  {
    digitalWrite(enablePin10,HIGH);
    digitalWrite(enablePin11,HIGH);
    myStepper.step(stepsPerRevolution * -1); // Do a right turn of 100 steps
  }
  else
  {
    digitalWrite(enablePin10,LOW);
    digitalWrite(enablePin11,LOW);
  }
  encoderPosOld = encoderPos;
}

// Interrupt on A changing state
void doEncoderA(){
  // debounce
  if ( rotating );  //removed the 1 us delay // wait a little until the bouncing is done
  // Test transition, did things really change? 
  if( digitalRead(encoderPinA) != A_set ) {  // debounce once more
    A_set = !A_set;
    // adjust counter + if A leads B
    if ( A_set && !B_set ) 
      encoderPos += 1;
    rotating = false;  // no more debouncing until loop() hits again
  }
}

// Interrupt on B changing state, same as A above
void doEncoderB(){
  if ( rotating ); //removed the 1 us delay
  if( digitalRead(encoderPinB) != B_set ) {
    B_set = !B_set;
    //  adjust counter - 1 if B leads A
    if( B_set && !A_set ) 
      encoderPos -= 1;
    rotating = false;
  }
}

Anything you modify in an interrupt and use elsewhere, such as encoderpos, should be declared volatile.

I'd be inclined (if you haven't already) to write something simpler to just ensure that you can read the encoders correctly before trying to debug your full sketch.

Wildbill,

I changed to volatile unsigned long encoderPos now.
originally this was a volatile unsigned int encoderPos
When I changed to long I accendentlly removed the volatile int.

Anyway after changing to "volatile unsinged long encoderPos" same problem.
Reading the encoder values is not the problem as the serialmonitor nicely shows these values when the motor steps.
It is the line

  if (encoderPos >= (encoderPosOld + 1070)) //if the value is 1070 higher then last known raise stepcounter by 1
  {
    StepCounter = StepCounter + 1;
  }

that does not in or decrement although the encoder values.

Paco

You do this unconditionally every time around loop:

  encoderPosOld = encoderPos;

So it seems unlikely that the difference will ever be anywhere near 1070. Might work better to do it only when you change StepCounter.

Oohps....
Wildbill, thanks for the pointer.
Now it works and I can fine tune further. :slight_smile:

Thanks, Paco