Hello forum. This is my first post, so there's that.
As many others, I am new to Arduino and programming, so you can tear into my code all you want, as long as it's helpful
I've ripped a inkjet apart and connected to the encoder and motor, so I should be able to control its position from the serial monitor.
For reference I've followed this video on how to handle the interrupts How to use linear encoders with Arduino. hardware, code, and demo. - YouTube
Now, when I enter a position in the serial monitor all is well and the carrier moves as it should, but SOMETIMES it goes haywire and moves waaaay further than it is supposed to and slams into the end of the rails.
If I leave it with the motor whining, it ends with this (see code for reference):
forward
stop
(forward) New absolute position: 32744
Enter new absolute position and press Enter
Does anyone know what is going on? Do I need to post anything else for debugging?
Thanks you in advance!
Regards
int encoderI = 2; //interrupt
int encoderQ = 3; //interrupt
int dir1PinA = 5;
int dir2PinA = 6;
int spdCtrl = 9; //motor speed ctrl
int Stop = 0;
volatile int count = 0;
int newPos = 0;
int newPosTemp = 0;
//int temp = 0;
void setup() {
 // put your setup code here, to run once:
 Serial.begin(115200);
 pinMode(encoderI, INPUT);
 pinMode(encoderQ, INPUT);
 attachInterrupt(0, handleEncoder, CHANGE);
 pinMode(dir1PinA, OUTPUT);
 pinMode(dir2PinA, OUTPUT);
 pinMode(spdCtrl, OUTPUT);
 Serial.println("Enter new absolute position"); //prompt for first position
}
void loop() {
 if (Serial.available()) {
  byte incomingByte = Serial.read(); //read serial
  while (incomingByte != '\n') { //run 'while' as long as 'enter' hasn't been sent
//Â Â Â while(newPos == newPosTemp && temp == 0){
//Â Â Â Â if(temp == 0){
//Â Â Â Â Â Serial.println("Enter new absolute position");
//Â Â Â Â Â }
//Â Â Â Â Â temp = 1;
//Â Â Â Â Â }
   if (incomingByte >= '0' && incomingByte <= '9') //restrict to 0-9
   newPosTemp = newPosTemp * 10 + (incomingByte - '0'); //convert to int
   incomingByte = Serial.read();
  }
  if (newPosTemp >= 0 && newPosTemp <= 4001) { //restrict to 0-4000 so we don't slam in to end of carrier
   newPos = newPosTemp;
   //Serial.println(newPos);
   //Serial.println(newPosTemp);
   newPosTemp = 0; //reset
   Stop = 0; //ensure motor has a green light
  }
  else
  { Serial.println("Choose a position less than 4000");
  }
 }
 if (count != newPos) { //compare current pos. to requested pos.
  if (newPos >= count) {
   forward();
  }
  else
  { back();
  }
 }
}
//Functions
void handleEncoder() {
 if (digitalRead(encoderI) == digitalRead(encoderQ)) // linear encoder https://www.youtube.com/watch?v=0QLZCfqUeg4
 {
  count++;
 }
 else
 {
  count--;
 }
}
void forward() {
 while (count <= newPos && Stop == 0) { // as long as count is less or equal to newPos or we have a red light from the motor
  Serial.println("forward");
  analogWrite(spdCtrl, 150);
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, HIGH);
  if(newPos <= count){ //once we reach count = newPos OR pass it due to reaction time of Arduino / lack of active brake on motor
   StopMotor();
   Serial.print("(forward) New absolute position: ");
   Serial.println(count);
   Serial.println("Enter new absolute position and press Enter");
 }
}
}
void back() {
 while (count >= newPos && Stop == 0) {
  Serial.println("back");
  analogWrite(spdCtrl, 150);
  digitalWrite(dir1PinA, HIGH);
  digitalWrite(dir2PinA, LOW);
  if(newPos >= count){
   StopMotor();
   Serial.print("(backwards) New absolute position: ");
   Serial.println(count);
   Serial.println("Enter new absolute position and press Enter");
 }
}
}
void StopMotor(){ //turn off motor, set Stop to 1 (red light)
 Serial.println("stop");
 Stop = 1;
 analogWrite(spdCtrl, 0);
//Â digitalWrite(dir1PinA, HIGH);
//Â digitalWrite(dir2PinA, HIGH);
 digitalWrite(dir1PinA, LOW);
 digitalWrite(dir2PinA, LOW);
}