Clearing encoder memory

Hi everybody,

I'm pretty new to Arduino coding but with trail and error I hope to get somewhere :slight_smile:

Currently I'm working on a project where I want to use an encoder to control the speed and position of a stepper motor.

The encoder has 2 functions: Either setting the speed or changing the max position of a bounce effect. I switch between the 2 states by pushing the encoder button.

Up until now everything works flawlessly except for when I press the button to change functions the value of the setting resets to 1 instead of the stored value I had before.

Does anybody have an idea on how to fix this issue?

Thank you very much.

#include <Encoder.h>
#include <FlexyStepper.h>
#include <Adafruit_NeoPixel.h>

//Pin assignments

#define LED_PIN 10
#define NUM_LEDS 26
const int MOTOR_STEP_PIN = 12;
const int MOTOR_DIRECTION_PIN = 11;
const int LIMIT_SWITCH_PIN = 6;
const int pushbutton = 5;
Encoder g_encoder(2, 3);

//Variable Config

int menu = 0;
int state = 0;
int oldbutton = 0;
int pos;
int motpos;
int motSpeed;
int button;



//Stepper Config

FlexyStepper stepper;
volatile bool g_has_not_homed = true;
const float maxStrokeLengthMm = 200; //Max length of movement
const float minStrokeLengthMm = 20; //Min length of movement
const float StepsPerRev = 800;


//LED Config

Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);


void setup() {
  // put your setup code here, to run once:

  pinMode(LIMIT_SWITCH_PIN, INPUT_PULLUP);
  pinMode(pushbutton, INPUT_PULLUP);
  Serial.begin(9600);


  //LED setup
  pixels.begin();
  pixels.clear();
  pixels.fill(pixels.Color(0, 0, 0),0,NUM_LEDS);
  pixels.show();

  //Stepper setup
  stepper.connectToPins(MOTOR_STEP_PIN, MOTOR_DIRECTION_PIN);
  stepper.setStepsPerMillimeter(StepsPerRev / 40);
  stepper.setSpeedInMillimetersPerSecond(0);
  stepper.setAccelerationInMillimetersPerSecondPerSecond(200);

  //Homing sequence
  delay(100);

  Serial.println("Homing Started");

  if (g_has_not_homed == true)
  {
    pixels.fill(pixels.Color(50, 0, 25),0,NUM_LEDS);
    pixels.show();
    stepper.setSpeedInMillimetersPerSecond(25);
    stepper.moveToHomeInMillimeters(1, 25, 300, LIMIT_SWITCH_PIN);

    stepper.setSpeedInMillimetersPerSecond(100);
    Serial.println("Move to Start Position");
    stepper.moveToPositionInMillimeters(-minStrokeLengthMm);
    stepper.setCurrentPositionInMillimeters(-minStrokeLengthMm);
    
    g_has_not_homed = false;
    stepper.setSpeedInMillimetersPerSecond(0);
  }
  pixels.fill(pixels.Color(0, 50, 0),0,NUM_LEDS);
  pixels.show();
  Serial.println("Ready");
}


  //Encoder Limit setup
int encLimitRead(int minVal, int maxVal){
  if(g_encoder.read()>maxVal*4)g_encoder.write(maxVal*4);
  else if(g_encoder.read()<minVal*4) g_encoder.write(minVal*4);
  return constrain(g_encoder.read()/4,minVal,maxVal);
}

void loop() {
  // put your main code here, to run repeatedly:
  
pixels.clear();

button = digitalRead(pushbutton);

if (oldbutton == 0 && button == 1){
    
    if (menu==0){
    menu = 1;
    Serial.println("");
    Serial.println("Position Menu:");
    Serial.println("");
      g_encoder.write(pos);
    }
      else{
      menu = 0;
      Serial.println("");
      Serial.println("Speed Menu:");
      Serial.println("");
        g_encoder.write(motSpeed);
     
      }

}

oldbutton = button;


if (menu == 0){

  long newSpeed = encLimitRead(0,NUM_LEDS); 
                                                             //SPEED MENU
  if (newSpeed != motSpeed) {
  motSpeed = newSpeed;
  pixels.fill(pixels.Color(50, 0, 0),0,motSpeed);
  pixels.show();
  stepper.setSpeedInMillimetersPerSecond(4*motSpeed);
  Serial.print("Speed: ");
  Serial.print(motSpeed);
  Serial.print("  Position: ");
  Serial.println(motpos);
     if (motSpeed == 0){
         pixels.fill(pixels.Color(0, 0, 0),0,0);
         pixels.show();
          }
  }

 
 } else{

  long newpos = encLimitRead(0,NUM_LEDS);
                                                             //POSITION MENU
  if (newpos != pos) {
  motpos = map(newpos, 0, NUM_LEDS, minStrokeLengthMm, maxStrokeLengthMm);
  Serial.print("Position: ");
  Serial.print(motpos);
  Serial.print("  Speed: ");
  Serial.println(motSpeed);
  pixels.fill(pixels.Color(0, 0, 50),0,newpos);
  pixels.show();
  pos = newpos;
     if (pos == 0){
         pixels.fill(pixels.Color(0, 0, 0),0,0);
         pixels.show();
          }
  }
  }


if (state == 0){
  stepper.setTargetPositionInMillimeters(-minStrokeLengthMm);
  stepper.processMovement();
} else{
  stepper.setTargetPositionInMillimeters(-(motpos));
  stepper.processMovement();
}
  

  long currentPosition = stepper.getCurrentPositionInMillimeters();
  if (currentPosition == -minStrokeLengthMm){
    state = 1;

}

  if (currentPosition == -(motpos)){
    state = 0;

}
}

Which setting are you referring to ?

motSpeed or motpos. Both switch to 1 whenever you push the button/switch state

encLimitRead returns "g_encoder.read() / 4" which is eventually stored in "motSpeed" or "pos".

When you switch to a different menu, the scaled value (g_encoder.read() / 4) is written to the encoder position with "g_encoder.write(pos);" or "g_encoder.write(motSpeed);"

Try changing "g_encoder.write(pos);" and "g_encoder.write(motSpeed);" to "g_encoder.write(pos * 4);" and "g_encoder.write(motSpeed * 4);". You will lose the bottom two bits but at least it won't be off by a factor of 4.

Thank you John that solved the issue. :grin:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.