Homemade bandsaw sawmill arduino controlled lift

Looks good for over run control. :grinning:

tried the code with the protected access

The protected access is only implemented for the forward and back moves, not the up and down.

Try using getCount() instead of direct access to count in the softStart() function. We can then see if this was truly causing any run away issues.

Actually, since the softStart() uses count values where only the lower 8 bits of an integer value are used, protected access may not be absolutely necessary, but is a preferred practice. If protected access really is related to the run away you can default to using count directly.

The analogWrite(pwm,0) did not prevent the over run in a previous test, but it can't hurt.

If there is a hardware issue, I think it is most likely with the headUp direction pin not getting driven low or with a flakey connection, to not disable the controller or the motor controller directional circuitry not responding to that input. Either way, it appears to be intermittent.

Ok. I will give that a shot, and let you know. One thing I notice, and again, all this has been done with engine off, is the servo motor (controlling throttle) jitters a little each time you hear the relay click when the motor correction (reversal) occurs.

What relay?

I thought the motor driver board was all solid state?

No, at least I am pretty sure not. I can hear them click... These are the boards that I hacked and am injecting a pwm signal to based on the roboJack video.

@cattledog, well, second try and the head ran away again when I added the getCount in place of count in the softStart()..... Here is the code and serial print, but I only changed the two variables in softStart

start...
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -241
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -160

//This has bitRead commented out and uses digitalRead.  This allows me to use uno or mega.  bitRead location in this sketch is for uno
#include <Servo.h>
Servo myServo;  // create a servo object

const byte gearSensor = 2; // external interrupt pin
const byte encoderA = 3;//INT5 external interrupt pin
const byte encoderB = 4;
const byte beginAutoSlab = 5;
const byte headUp = 6;//if this pin goes high winch will engage clockwise through transistor board
const byte headDown = 7;//if this pin goes high winch will engage counterclockwise through transistor board
const byte buttonUpQuarter = 8;
const byte pwm = 9; //can I connect this pin to both motor drivers since they should never be engaged at the same time?
const byte buttonUpManual = 10;
const byte pwm2 = 11;
const byte headForward = 12;
const byte headBackward = 13;
const byte buttonDownManual = A0;
const byte pot = A1;
const byte buttonDownQuarter = A2;
const byte throttlePot = A15;

char directionSignal;

const int countUpQuarter = 240;
const int countDownQuarter = -240;
const int countUp1inch = 320;
const int countDown1inch = -320;
const int upMaxSpeed = 255;
const int downMaxSpeed = 75;
const int upSlowSpeed = 240;
const int downSlowSpeed = 38;
const int forwardMax = 158;// Maximum Speed of head moving forward during AUTO SLAB
const int forwardSlow = 148;
const int backwardMax = 255; // Maximum Speed of head moving backward during Auto Slab
const int backwardSlow = 130;
const int headGearSensor = 318;// Gear Tooth sensor that reads the teeth as the head moves forward/backwards
const int braking = (headGearSensor);

volatile int count = 0;
volatile int countGear = 0;
volatile int targetCount = 0;
volatile boolean runFinished = false;
volatile boolean autoHeadStarted = false;
volatile boolean loopFinished = false;
volatile boolean quarterMove = false;
volatile boolean checkCount = true;

int val;
int throttleVal;
int countBeforeCorrection;
int throttleAngle;
int prevCountGear;

unsigned long prevMillis = millis();
int prevCount = count;
byte pwmValue = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println("start...");
  myServo.attach(44);
  pinMode(encoderA, INPUT_PULLUP); //external circuit pullup
  pinMode(encoderB, INPUT_PULLUP); //external circuit pullup
  pinMode(buttonUpQuarter, INPUT_PULLUP);
  pinMode(buttonDownQuarter, INPUT_PULLUP);
  pinMode(buttonUpManual, INPUT_PULLUP);
  pinMode(buttonDownManual, INPUT_PULLUP);
  pinMode(gearSensor, INPUT_PULLUP);//external circuit pullup 1K resistor
  pinMode(beginAutoSlab, INPUT_PULLUP);
  pinMode(headUp, OUTPUT); //connected to forward reverse switch of head motor driver
  pinMode(headDown, OUTPUT);//connected to forward reverse switch of head motor driver
  pinMode(pwm, OUTPUT);
  pinMode(headForward, OUTPUT); // connected to forward reverse switch of motor driver through TIP120 Transistor board 2.2K resistor
  pinMode(headBackward, OUTPUT); // connected to forward reverse switch of motor driver through TIP120 Transistor board
  pinMode(pwm2, OUTPUT);  // uncomment if there is a way to control headForward/headBackward with both pot and arduino if not pot will control speed during autoSlab and uncomment below
  pinMode(throttlePot, INPUT); // Pot for adjusting throttle 

  attachInterrupt(digitalPinToInterrupt(gearSensor), isrMove, FALLING);
  countGear = 0;

  attachInterrupt(digitalPinToInterrupt(encoderA), isrCount, CHANGE);
  EIMSK &= ~(1 << INT5);//disable interrupts until motor moves
  EIFR |= (1 << INTF5);//clear any preesisting flags
  count = 0;//clear counts
}

void loop()
{
  {
    val = analogRead(pot);
    val = map(val, 0, 1023, 0, 255);
  }

  if (val >= 10) {
    analogWrite(pwm2, val);
  }
  else {
    analogWrite(pwm2, 0);
  }

  throttleVal = analogRead(throttlePot);
  throttleVal = map(throttleVal, 0, 1023, 0, 75);//I think I need to adjust 255 to the angle needed for WOT

  throttleAngle = throttleVal;
  myServo.write(throttleAngle);

  if (digitalRead(beginAutoSlab) == LOW)
  {
    Serial.println("AutoSlab Mode has started");
    delay(1000);
    autoSlab();
  }

  if (digitalRead(buttonUpQuarter) == LOW)
  {
    Serial.println("Trigger Up");
    delay(1000);//need to rework for state change of button
    motorUpQuarter();
  }

  if (digitalRead(buttonDownQuarter) == LOW)
  {
    Serial.println("Trigger Down");
    delay(1000);//need to rework for state change of button
    motorDownQuarter();
  }
  if (digitalRead(buttonUpManual) == LOW)
  {
    motorUpUntil();
  }
  if (digitalRead(buttonDownManual) == LOW)
  {
    motorDownUntil();
  }

  if (quarterMove == true and runFinished == true)// quarterMove set true when quarterUpQuarter or QuarterDownQuarter button is pressed
  //runFinished set true in the isr once the targetCount has been reached.
{
  quarterMove = false;
  runFinished = false;

  if (directionSignal == '-')
  {
    Serial.print("hardFinish");
    Serial.print("count before motor Reversal = ");
    Serial.println (countBeforeCorrection);
    delay(150); // adjust the amount of time the reversal of motor is on
    //EIMSK &= ~(1 << INT5);//stop interrupts
    //EIFR |= (1 << INTF5);//clear any preesisting flags
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    analogWrite(pwm,0);

    delay(1000); // wait and see how much over run I get

    EIMSK &= ~(1 << INT5);//stop interrupts
    EIFR |= (1 << INTF5);//clear any preesisting flags

    Serial.print("The count after any over run = ");
    Serial.println(count);
    //runFinished = false;
  }

  if (directionSignal == '+') {
    Serial.print("Finish Up");
    Serial.print("count before motor Reversal = ");
    Serial.println (countBeforeCorrection);
    //EIMSK &= ~(1 << INT5);//stop interrupts
    //EIFR |= (1 << INTF5);//clear any preesisting flags
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    analogWrite(pwm,0);

    delay(1000); // wait and see how much over run I get

    EIMSK &= ~(1 << INT5);//stop interrupts
    EIFR |= (1 << INTF5);//clear any preesisting flags

    Serial.print("The count after any over run = ");
    Serial.println(count);
    //runFinished = false;
  }
}
  if (autoHeadStarted == true and runFinished == true)//autoHeadStarted was set True in the AutoHeadUp function and runFinished was set true once the targetCount was reached and head stopped moving
  {
    digitalWrite(headUp, LOW);//This should stop winch lift motor
    digitalWrite(headDown, LOW);//This should stop winch lift motor
    EIMSK &= ~(1 << INT5);//stop interrupts DO I need this when autoSlabbing?
    EIFR |= (1 << INTF5);//clear any preesisting flags  DO I need this when autoSlabbing?
    delay(2000);
    autoReverse();
  }

  if (loopFinished == true and runFinished == true)
  {
    digitalWrite(headUp, LOW);//This should stop winch lift motor
    digitalWrite(headDown, LOW);//This should stop winch lift motor
    EIMSK &= ~(1 << INT5);//stop interrupts DO I need this when autoSlabbing?
    EIFR |= (1 << INTF5);//clear any preesisting flags  DO I need this when autoSlabbing?
    delay(2000);
    autoSlab();
  }
}
void isrMove()
{
  countGear ++;
}

void isrCount()//interrupt routine for encoder
{
  byte AState = digitalRead(encoderA);
  byte BState = digitalRead(encoderB);
  if (AState == BState)
    count++;
  else
    count--;

  if (directionSignal == '-' and count <= targetCount)
  {
    //set motor to up with a value which locks the motor
    countBeforeCorrection = count;
    digitalWrite(headUp, HIGH);
    digitalWrite(headDown, LOW);
    analogWrite(pwm, 200);
    runFinished = true;
  }
  if (directionSignal == '+' and count >= targetCount)
  {
    countBeforeCorrection = count;
    //digitalWrite(headDown, HIGH);  //try using these if over run up is a problem
    //digitalWrite(headUp, LOW);
    //analogWrite(pwm, 40);//This adjust how much to pwm wanted to reverse the motor and prevent overrun
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    runFinished = true;
  }
}

void motorUpQuarter()
{
  runFinished = false;
  digitalWrite(headUp, HIGH);
  targetCount = countUpQuarter;
  directionSignal = '+';
  count = 0;
  EIFR |= (1 << INTF5);//clear any preesisting flags
  EIMSK = (1 << INT5); //enable interrupt counting
  softStart();
  quarterMove = true;
}

void motorDownQuarter()
{
  runFinished = false;
  digitalWrite(headDown, HIGH);
  targetCount = countDownQuarter;
  directionSignal = '-';
  count = 0;
  EIFR |= (1 << INTF5);//clear any preesisting flags
  EIMSK = (1 << INT5); //enable interrupt counting
  softStart();
  quarterMove = true;
}

void motorUpUntil ()
{
  digitalWrite(headUp, HIGH);
  //soft start
  for (int i = 0; i <= 255; i = i + 10)
    analogWrite(pwm, i);
  while (digitalRead(buttonUpManual) == LOW) {} //Release of Button
  analogWrite(pwm, 0);
  digitalWrite(headUp, LOW);
}
void  motorDownUntil ()
{
  digitalWrite(headDown, HIGH);
  //soft start
  for (int i = 0; i <= 255; i = i + 10)
    analogWrite(pwm, i);
  while (digitalRead(buttonDownManual) == LOW) {} //Release of Button
  analogWrite(pwm, 0);
  digitalWrite(headDown, LOW);
}

void softStart() //count should always be starting at 0
{
  if (directionSignal == '+') //was set for an up move
  {
    Serial.println("softStartUp");
    for (int i = 0; i <= 255; i = i + 1)//head should move up before 255
    {
      analogWrite(pwm, i);
      delay(10);
      if (getCount() >= 5)  //give some leeway here incase of vibration noise
      {
        i = i * 1.2;// //add 20 percent to the pwm that begins the head moving
        analogWrite(pwm, i);
        Serial.print("PWM used after being increased by 20 percent = ");
        Serial.println(i);
        break; //exit for() loop
      }
    }
  }

  if (directionSignal == '-') //was set for a down move
  {
    Serial.println("softStartDown");
    for (int i = 0; i <= 28; i = i + 1) //head should move up before 150
    {
      analogWrite(pwm, i);
      delay(10);
//The next contidional block appears to never be true
      if (getCount() <= -5)  //give some leeway here incase of vibration noise 
      {
        //  i = i ;// //add 15 percent to the pwm that begins the head moving
        // analogWrite(pwm, i);
        Serial.print("PWM used = ");
        Serial.println(i);
        break; //exit for() loop
      }
    }
  }
}
void autoSlab() //Called on from button press and completion of autoHeadDown()
{
  Serial.println("throttle increasing to WOT");
  myServo.write(65);//adjust number to be WOT Need to disable POT some how...
  delay(2000);

  Serial.println("head moving forward");
  countGear = 0;
  EIMSK |= (1 << INT4);
  digitalWrite(headForward, HIGH);
  
  while (GetCountGear() <= 250) // Start Slowing Down and prevent issue of 255/256 changeOver
  {     
    if (millis() - prevMillis > 250) // check periodically need adjust based on how fast desired tooth to pass sensor per check
    {
      if (prevCountGear == GetCountGear())
      {
        if (pwmValue < 80)
          pwmValue = pwmValue + 10; // more power to get moving at start quicker

        if (80 < pwmValue and pwmValue < 255)
          pwmValue++; // more power applied slower to make sure head continue to move
      }
      else
      {
       // noInterrupts();
        prevCountGear = GetCountGear();
       // interrupts();
      }
      
      prevMillis = millis(); // reset time for next check.
      analogWrite(pwm2, pwmValue);
    }

   if (GetCountGear() == prevCountGear + 2)
    {
      pwmValue = pwmValue--;
      analogWrite(pwm2, pwmValue);
    }
  }

  noInterrupts();
  countGear = 0;
  interrupts();

  while (GetCountGear() <= headGearSensor - 250); //  prevent issue of 255/256 change Over
  {
    if (millis() - prevMillis > 250) // check periodically need adjust based on how fast desired tooth to pass sensor per check
    {
      if (prevCountGear == GetCountGear())
      {
        if (pwmValue < 255)
          pwmValue++; // more power applied slower to make sure head continue to move
      }
      else
      {
        //noInterrupts();
        prevCountGear = GetCountGear();
        //interrupts();
      }
      prevMillis = millis(); // reset time for next check.
      analogWrite(pwm2, pwmValue);
    }
   if (GetCountGear() == prevCountGear + 2)
    {
      pwmValue = pwmValue--;
      analogWrite(pwm2, pwmValue);
    }
  }

  analogWrite(pwm2, 0);
  digitalWrite(headForward, LOW);
  loopFinished = false;
  delay (1000);
  Serial.println("throttle decreasing to IDLE");
  myServo.write(0);  // Hopefully 0 will be down to idle 
  delay(2000);
  autoHeadUp();
}

void autoHeadUp() // Called on from autoSlab
{
  Serial.print("The number of teeth counted is ");
  Serial.println(countGear);
  runFinished = false;
  digitalWrite(headUp, HIGH);
  targetCount = countUpQuarter;
  directionSignal = '+';
  count = 0;
  EIFR |= (1 << INTF5);//clear any preesisting flags
  EIMSK = (1 << INT5); //enable interrupt counting
  autoHeadStarted = true;
  softStart();
}

void autoReverse()  //Called with if statement in void loop() when runFinished = true and autoHeadStarted = true
{
  Serial.println("head moving backwards");
  countGear = 0;
  EIMSK |= (1 << INT4);//enable interrupt
  digitalWrite(headBackward, HIGH);//sets the forward reverse switch on the hacked motor driver for head forward

  for (int i = 0; i <= backwardMax; i = i + 10)
  {
    analogWrite(pwm2, i);
    delay (10);
  }
   
  while (GetCountGear() <= braking) //90 % there slow down
  {}
  
noInterrupts();
countGear = 0;
interrupts();

  for (int i = backwardMax; i >= backwardSlow; i = i - 10)
  {
    analogWrite(pwm2, i);
    delay(10);
  }
  
  while (GetCountGear() <= headGearSensor - braking);
  {}

  analogWrite(pwm2, 0);
  digitalWrite(headBackward, LOW);
  delay(2000);
  autoHeadDown();
}

void autoHeadDown()  // called on from autoReverse()
{
  Serial.print("The number of teeth counted is ");
  Serial.println(GetCountGear());
  runFinished = false;
  autoHeadStarted = false;
  digitalWrite(headDown, HIGH);
  targetCount = countDownQuarter * 2; //I want it to go down twice the targetCount because it should be above the log the thickness of the board that was just cut
  directionSignal = '-';
  count = 0;
  EIFR |= (1 << INTF5);//clear any preesisting flags
  EIMSK = (1 << INT5); //enable interrupt counting
  loopFinished = true;
  softStart();
}

int GetCountGear()
{
int retval;
  //noInterrupts();
  EIMSK &= ~(1 << INT4);//disable interrupts
  retval=countGear;
  EIMSK |= (1 << INT4);//enable interrupt
  //interrupts();
return retval;
}

int getCount()
{
  int retCountVal;
  EIMSK &= ~(1 << INT5);//disable interrupts until motor moves
  //noInterrupts();
  retCountVal = count;
  //interrupts();
  EIMSK = (1 << INT5); //enable interrupt counting
  return retCountVal;
}

THanks

second try and the head ran away again when I added the getCount in place of count in the softStart().....

Yikes! :confused:

If you can turn it on and off a few more times, I'll be a believer although I still can not see how something which occurs at the start of the move can effect what happens when the move is finished sometime later.

I know you can live with the direct access of count in up and down, but I'm not so sure about with the forward and back moves. If you get trouble there, then going back to the dividing of the move into byte sized chunks will work.

Regarding the relay, I think I was confused with the driver board image you posted in your other thread about electronic noise. I guess the relay are for direction reversal. Given the importance of direction reversal to the over run solution, you may want to consider swapping the two drivers, or trying to get another one with solid state direction control.

I will do some more testing with both codes and see. I still believe it is some how tied to my hardware/wiring. I admit my wiring is a mess, and if you have read the other thread I started about the noise, I have already caught flack about it :blush: :blush:. They haven't even seen pictures yet..... :grimacing: :grimacing:

I apparently don't understand what is going on with the corrected access function. I was under the impression that each time the count increased/decreased, the getCount() had to be called and the retCountVal had to be recorded and sent back to the softStart(). However, I think maybe that is not how it happens? It actually just calls the getCount() once and waits until the retCountVal is above/below the set number in the if statement within the softStart()? I'm really not sure.

When the head runs away it is usually at around the same time as the relays turning off/and on quite quickly. I am thinking something in this sudden electrical change is causing the issue. I am guessing because the SSR is not mechanical, it may prevent this. However, I haven't seen any of these motor driver boards I am using that use SSR's. I am sure they are out there though. I am not sure if the relays could be desoldered and an SSR used in place, but that may be above my ability level any way.

I am still holding out hope something in the protective access is causing it.

I did some more testing.. The code with the protective access does cause the "runnaway" head upwards. Sometimes it may take 8-10 moves before it does it, and others times it occurs about 1 out of three times. I had some serial prints from the tests, but I apparently lost many of them, but here is one...
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -241
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -241
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -163

I uploaded the seemingly working code (I'll paste below), and made 15-20 moves and it did perfect. I decided to fire up the engine and give it a whirl) I cut up about 7-8 boards off of a log that was loaded, and it worked pretty much perfectly. Even the throttle control (servo motor) seemed to work right. I LOVE THIS FEATURE! I have never been able to control the throttle without physically turning the lever. So, the engine runs at WOT most of the time while I am cutting. This is no good for anything. Now with the turn of the pot, I can throttle down to idle for over 50 percent of the time (head moving up after cut, head moving back, head moving back down before next cut).
I have no idea why the protected access would be causing issues, but I sure hope that's what it is. I am including the serial prints below of the actual cutting that I did with the engine running and sawing lumber. It looks pretty good.... As, you will notice, after I finished cutting the log, I moved the head up and did a "fake" autoSlab run. It appeared correct until it was time for autoReverse() to be called, and it never got called. I couldn't remember what the issue was with this code for autoSlab, but I guess I will have a look later. I am going to try and load another log and see I continue to get good results.

start...
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -241
Trigger Up
softStartUp
PWM used after being increased by 20 percent = 145
Finish Upcount before motor Reversal = 240
The count after any over run = 240
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -242
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -242
Trigger Up
softStartUp
PWM used after being increased by 20 percent = 136
Finish Upcount before motor Reversal = 240
The count after any over run = 240
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -241
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -242
Trigger Up
softStartUp
PWM used after being increased by 20 percent = 140
Finish Upcount before motor Reversal = 241
The count after any over run = 241
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -240
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -242
Trigger Up
softStartUp
PWM used after being increased by 20 percent = 142
Finish Upcount before motor Reversal = 240
The count after any over run = 240
Trigger Up
softStartUp
PWM used after being increased by 20 percent = 153
Finish Upcount before motor Reversal = 240
The count after any over run = 240
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -240
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -242
Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -239
Trigger Up
softStartUp
PWM used after being increased by 20 percent = 130
Finish Upcount before motor Reversal = 240
The count after any over run = 240
AutoSlab Mode has started
throttle increasing to WOT
head moving forward
throttle decreasing to IDLE
The number of teeth counted is 55
softStartUp
PWM used after being increased by 20 percent = 139
Finish Upcount before motor Reversal = 240
The count after any over run = 240

//This has bitRead commented out and uses digitalRead.  This allows me to use uno or mega.  bitRead location in this sketch is for uno
//This has bitRead commented out and uses digitalRead.  This allows me to use uno or mega.  bitRead location in this sketch is for uno
#include <Servo.h>
Servo myServo;  // create a servo object

const byte gearSensor = 2; // external interrupt pin
const byte encoderA = 3;//INT5 external interrupt pin
const byte encoderB = 4;
const byte beginAutoSlab = 5;
const byte headUp = 6;//if this pin goes high winch will engage clockwise through transistor board
const byte headDown = 7;//if this pin goes high winch will engage counterclockwise through transistor board
const byte buttonUpQuarter = 8;
const byte pwm = 9; //can I connect this pin to both motor drivers since they should never be engaged at the same time?
const byte buttonUpManual = 10;
const byte pwm2 = 11;
const byte headForward = 12;
const byte headBackward = 13;
const byte buttonDownManual = A0;
const byte pot = A15;
const byte buttonDownQuarter = A2;
const byte throttlePot = A1;

char directionSignal;

const int countUpQuarter = 240;
const int countDownQuarter = -240;
const int countUp1inch = 320;
const int countDown1inch = -320;
const int upMaxSpeed = 255;
const int downMaxSpeed = 75;
const int upSlowSpeed = 240;
const int downSlowSpeed = 38;
const int forwardMax = 158;// Maximum Speed of head moving forward during AUTO SLAB
const int forwardSlow = 148;
const int backwardMax = 255; // Maximum Speed of head moving backward during Auto Slab
const int backwardSlow = 130;
const int headGearSensor = 298;// Gear Tooth sensor that reads the teeth as the head moves forward/backwards
const int braking = (headGearSensor);

volatile int count = 0;
volatile int countGear = 0;
volatile int targetCount = 0;
volatile boolean runFinished = false;
volatile boolean autoHeadStarted = false;
volatile boolean loopFinished = false;
volatile boolean quarterMove = false;
volatile boolean checkCount = true;

int val;
int throttleVal;
int countBeforeCorrection;
int throttleAngle;
int prevCountGear;

unsigned long prevMillis = millis();
int prevCount = count;
byte pwmValue = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println("start...");
  myServo.attach(44);
  pinMode(encoderA, INPUT_PULLUP); //external circuit pullup
  pinMode(encoderB, INPUT_PULLUP); //external circuit pullup
  pinMode(buttonUpQuarter, INPUT_PULLUP);
  pinMode(buttonDownQuarter, INPUT_PULLUP);
  pinMode(buttonUpManual, INPUT_PULLUP);
  pinMode(buttonDownManual, INPUT_PULLUP);
  pinMode(gearSensor, INPUT_PULLUP);//external circuit pullup 1K resistor
  pinMode(beginAutoSlab, INPUT_PULLUP);
  pinMode(headUp, OUTPUT); //connected to forward reverse switch of head motor driver
  pinMode(headDown, OUTPUT);//connected to forward reverse switch of head motor driver
  pinMode(pwm, OUTPUT);
  pinMode(headForward, OUTPUT); // connected to forward reverse switch of motor driver through TIP120 Transistor board 2.2K resistor
  pinMode(headBackward, OUTPUT); // connected to forward reverse switch of motor driver through TIP120 Transistor board
  pinMode(pwm2, OUTPUT);  // uncomment if there is a way to control headForward/headBackward with both pot and arduino if not pot will control speed during autoSlab and uncomment below
  pinMode(throttlePot, INPUT);
  attachInterrupt(digitalPinToInterrupt(gearSensor), isrMove, FALLING);
  countGear = 0;

  attachInterrupt(digitalPinToInterrupt(encoderA), isrCount, CHANGE);
  EIMSK &= ~(1 << INT5);//disable interrupts until motor moves
  EIFR |= (1 << INTF5);//clear any preesisting flags
  count = 0;//clear counts
}

void loop()
{
  {
    val = analogRead(pot);
    val = map(val, 0, 1023, 0, 255);
  }

  if (val >= 10) {
    analogWrite(pwm2, val);
  }
  else {
    analogWrite(pwm2, 0);
  }

  throttleVal = analogRead(throttlePot);
  throttleVal = map(throttleVal, 0, 1023, 8, 75);//I think I need to adjust 255 to the angle needed for WOT

  throttleAngle = throttleVal;
  myServo.write(throttleAngle);

  if (digitalRead(beginAutoSlab) == LOW)
  {
    Serial.println("AutoSlab Mode has started");
    delay(1000);
    autoSlab();
  }

  if (digitalRead(buttonUpQuarter) == LOW)
  {
    Serial.println("Trigger Up");
    delay(1000);//need to rework for state change of button
    motorUpQuarter();
  }

  if (digitalRead(buttonDownQuarter) == LOW)
  {
    Serial.println("Trigger Down");
    delay(1000);//need to rework for state change of button
    motorDownQuarter();
  }
  if (digitalRead(buttonUpManual) == LOW)
  {
    motorUpUntil();
  }
  if (digitalRead(buttonDownManual) == LOW)
  {
    motorDownUntil();
  }

  if (quarterMove == true and runFinished == true)// quarterMove set true when quarterUpQuarter or QuarterDownQuarter button is pressed
    //runFinished set true in the isr once the targetCount has been reached.  
  {
    if (directionSignal == '-')
    {
    Serial.print("hardFinish");
    Serial.print("count before motor Reversal = ");
    Serial.println (countBeforeCorrection);
    delay(150); // adjust the amount of time the reversal of motor is on
    EIMSK &= ~(1 << INT5);//stop interrupts
    EIFR |= (1 << INTF5);//clear any preesisting flags
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    delay(1000); // wait and see how much over run I get
    Serial.print("The count after any over run = ");
    Serial.println(count);
    runFinished = false;
    }

    if (directionSignal == '+'){
    Serial.print("Finish Up");
    Serial.print("count before motor Reversal = ");
    Serial.println (countBeforeCorrection);
    EIMSK &= ~(1 << INT5);//stop interrupts
    EIFR |= (1 << INTF5);//clear any preesisting flags
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    delay(1000); // wait and see how much over run I get
    Serial.print("The count after any over run = ");
    Serial.println(count);
    runFinished = false;
    }
  }
  if (autoHeadStarted == true and runFinished == true)//autoHeadStarted was set True in the AutoHeadUp function and runFinished was set true once the targetCount was reached and head stopped moving
   {
    if (directionSignal == '-')
    {
    Serial.print("hardFinish");
    Serial.print("count before motor Reversal = ");
    Serial.println (countBeforeCorrection);
    delay(150); // adjust the amount of time the reversal of motor is on
    EIMSK &= ~(1 << INT5);//stop interrupts
    EIFR |= (1 << INTF5);//clear any preesisting flags
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    delay(1000); // wait and see how much over run I get
    Serial.print("The count after any over run = ");
    Serial.println(count);
    runFinished = false;
    }

    if (directionSignal == '+'){
    Serial.print("Finish Up");
    Serial.print("count before motor Reversal = ");
    Serial.println (countBeforeCorrection);
    EIMSK &= ~(1 << INT5);//stop interrupts
    EIFR |= (1 << INTF5);//clear any preesisting flags
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    delay(1000); // wait and see how much over run I get
    Serial.print("The count after any over run = ");
    Serial.println(count);
    runFinished = false;
    }
    autoReverse();
  }
  if (loopFinished == true and runFinished == true)
  {
    digitalWrite(headUp, LOW);//This should stop winch lift motor
    digitalWrite(headDown, LOW);//This should stop winch lift motor
    EIMSK &= ~(1 << INT5);//stop interrupts DO I need this when autoSlabbing?
    EIFR |= (1 << INTF5);//clear any preesisting flags  DO I need this when autoSlabbing?
    delay(2000);
    autoSlab();
  }
}
void isrMove()
{
  countGear ++;
}

void isrCount()//interrupt routine for encoder
{
  byte AState = digitalRead(encoderA);
  byte BState = digitalRead(encoderB);
  if (AState == BState)
    count++;
  else
    count--;

  if (directionSignal == '-' and count <= targetCount)
  {
    //set motor to up with a value which locks the motor
    countBeforeCorrection = count;
    digitalWrite(headUp, HIGH);
    digitalWrite(headDown, LOW);
    analogWrite(pwm, 200);
    runFinished = true;
  }
  if (directionSignal == '+' and count >= targetCount)
  {
    countBeforeCorrection = count;
    //digitalWrite(headDown, HIGH);  //try using these if over run up is a problem
    //digitalWrite(headUp, LOW);
    //analogWrite(pwm, 40);//This adjust how much to pwm wanted to reverse the motor and prevent overrun
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    runFinished = true;
  }
}

void motorUpQuarter()
{
  runFinished = false;
  digitalWrite(headUp, HIGH);
  targetCount = countUpQuarter;
  directionSignal = '+';
  count = 0;
  EIFR |= (1 << INTF5);//clear any preesisting flags
  EIMSK = (1 << INT5); //enable interrupt counting
  softStart();
  quarterMove = true;
}

void motorDownQuarter()
{
  runFinished = false;
  digitalWrite(headDown, HIGH);
  targetCount = countDownQuarter;
  directionSignal = '-';
  count = 0;
  EIFR |= (1 << INTF5);//clear any preesisting flags
  EIMSK = (1 << INT5); //enable interrupt counting
  softStart();
  quarterMove = true;
}

void motorUpUntil ()
{
  digitalWrite(headUp, HIGH);
  //soft start
  for (int i = 0; i <= 255; i = i + 10)
    analogWrite(pwm, i);
  while (digitalRead(buttonUpManual) == LOW) {} //Release of Button
  analogWrite(pwm, 0);
  digitalWrite(headUp, LOW);
}
void  motorDownUntil ()
{
  digitalWrite(headDown, HIGH);
  //soft start
  for (int i = 0; i <= 255; i = i + 10)
    analogWrite(pwm, i);
  while (digitalRead(buttonDownManual) == LOW) {} //Release of Button
  analogWrite(pwm, 0);
  digitalWrite(headDown, LOW);
}

void softStart() //count should always be starting at 0
{
  if (directionSignal == '+') //was set for an up move
  {
    Serial.println("softStartUp");
    for (int i = 0; i <= 255; i = i + 1)//head should move up before 255
    {
      analogWrite(pwm, i);
      delay(10);
      if (count >= 5)  //give some leeway here incase of vibration noise
      {
        i = i * 1.2;// //add 20 percent to the pwm that begins the head moving
        analogWrite(pwm, i);
        Serial.print("PWM used after being increased by 20 percent = ");
        Serial.println(i);
        break; //exit for() loop
      }
    }
  }

  if (directionSignal == '-') //was set for a down move
  {
    Serial.println("softStartDown");
    for (int i = 0; i <= 28; i = i + 1) //head should move up before 150
    {
      analogWrite(pwm, i);
      delay(10);
      if (count <= -5)  //give some leeway here incase of vibration noise
      {
        //  i = i ;// //add 15 percent to the pwm that begins the head moving
        // analogWrite(pwm, i);
        Serial.print("PWM used = ");
        Serial.println(i);
        break; //exit for() loop
      }
    }
  }
}
void autoSlab() //Called on from button press and completion of autoHeadDown()
{
  Serial.println("throttle increasing to WOT");
  myServo.write(65);//adjust number to be WOT Need to disable POT some how...
  delay(3000);

  Serial.println("head moving forward");
  countGear = 0;
  EIMSK |= (1 << INT4);
  digitalWrite(headForward, HIGH);
  while (countGear <= 250) // Start Slowing Down and prevent issue of 255/256 changeOver
  { 
    if (millis() - prevMillis > 250) // check periodically need adjust based on how fast desired tooth to pass sensor per check
    {
      if (prevCountGear == countGear)
      {
        if (pwmValue < 80)
          pwmValue = pwmValue + 10; // more power to get moving at start quicker

        if (80 < pwmValue < 255)
          pwmValue++; // more power applied slower to make sure head continue to move
      }
      else
      {
        noInterrupts();
        prevCountGear = countGear;
        interrupts();
      }
      prevMillis = millis(); // reset time for next check.
      analogWrite(pwm2, pwmValue);
    }
  }

  noInterrupts();
  countGear = 0;
  interrupts();

  while (countGear <= headGearSensor - 250); //  prevent issue of 255/256 change Over
  {
    if (millis() - prevMillis > 250) // check periodically need adjust based on how fast desired tooth to pass sensor per check
    {
      if (prevCountGear == countGear)
      {
        if (pwmValue < 255)
          pwmValue++; // more power applied slower to make sure head continue to move
      }
      else
      {
        noInterrupts();
        prevCountGear = countGear;
        interrupts();
      }
      prevMillis = millis(); // reset time for next check.
      analogWrite(pwm2, pwmValue);
    }
  }

  analogWrite(pwm2, 0);
  digitalWrite(headForward, LOW);
  loopFinished = false;
  delay (1000);
  Serial.println("throttle decreasing to IDLE");
  myServo.write(8);//adjust number to be WOT Need to disable POT some how...
  delay(3000);
  autoHeadUp();
}
void autoHeadUp() // Called on from autoSlab
{
  Serial.print("The number of teeth counted is ");
  Serial.println(countGear);
  runFinished = false;
  digitalWrite(headUp, HIGH);
  targetCount = countUpQuarter;
  directionSignal = '+';
  count = 0;
  EIFR |= (1 << INTF5);//clear any preesisting flags
  EIMSK = (1 << INT5); //enable interrupt counting
  autoHeadStarted = true;
  softStart();
}

void autoReverse()  //Called with if statement in void loop() when runFinished = true and autoHeadStarted = true
{
  Serial.println("head moving backwards");
  countGear = 0;
  EIMSK |= (1 << INT4);//enable interrupt
  digitalWrite(headBackward, HIGH);//sets the forward reverse switch on the hacked motor driver for head forward

  for (int i = 0; i <= backwardMax; i = i + 10)
  {
    analogWrite(pwm2, i);
    delay (10);
  }
   
  while (countGear <= braking) //90 % there slow down
  {}
  
noInterrupts();
countGear = 0;
interrupts();

  for (int i = backwardMax; i >= backwardSlow; i = i - 10)
  {
    analogWrite(pwm2, i);
    delay(10);
  }
  
  while (countGear <= headGearSensor - braking);
  {}

  analogWrite(pwm2, 0);
  digitalWrite(headBackward, LOW);
  delay(2000);
  autoHeadDown();
}

void autoHeadDown()  // called on from autoReverse()
{
  Serial.print("The number of teeth counted is ");
  Serial.println(countGear);
  runFinished = false;
  autoHeadStarted = false;
  digitalWrite(headDown, HIGH);
  targetCount = countDownQuarter * 2; //I want it to go down twice the targetCount because it should be above the log the thickness of the board that was just cut
  directionSignal = '-';
  count = 0;
  EIFR |= (1 << INTF5);//clear any preesisting flags
  EIMSK = (1 << INT5); //enable interrupt counting
  loopFinished = true;
  softStart();
}

Thanks!

Good progress, especially on the throttle.

When the head runs away it is usually at around the same time as the relays turning off/and on quite quickly.

Yes. The relays control the direction of current flow which determines the motor rotation up or down. The relays are changing from the move down configuration to the move up configuration(to stop over run) and then to both off. For some unknown reason, the relay which sets the move up when closed is not releasing. Why this is interactive with the softStart() when using getCount() routine is puzzling to me.

I apparently don't understand what is going on with the corrected access function. I was under the impression that each time the count increased/decreased, the getCount() had to be called and the retCountVal had to be recorded and sent back to the softStart(). However, I think maybe that is not how it happens? It actually just calls the getCount() once and waits until the retCountVal is above/below the set number in the if statement within the softStart()? I'm really not sure.

getCount() is called every 10 ms inside a for() loop as the pwm is ramped up. The getCount() function is just turning off interrupts, getting a value, turning on interrupts and passing the value back. All this happens well before the relay contact state is being changed at the end of a run.

If the contacts were arcing and welding closed, I'm not certain that they would get back to normal like they do so the root cause of non release of the relay is confusing.

Since the relays are mounted on the board it's not known what r/c snubber arrangement is used to prevent arcing and any diodes for flyback. I'm not clear if you ever had a circuit diagram for the board you hacked. I would be concerned about the reliability of the contacts/relays given the motor reversals to control overrun. Finding a more expensive driver with solid state direction control would be an improvement, or perhaps you can figure out how to replace the relays with power IC switches.

I'm still seeing that in the softStart() in the down direction you are setting the pwm to 28 without seeing the -5 counts and getting the print from the conditional statement. This probably does not matter if the pwm value of 28 always gets the head moving, and the momentum is limited at this speed.
If you change the value to something like -2, the head may move at a lower pwm value, move slower, and place less stress on the system when reversed.

Well, I just cut up a few logs. Probably 200-300 board foot of lumber. It worked absolutely perfect! Accuracy was very good. No issues with the head running off upwards. And the throttle…. Man, I’ve got to make sure I figure out a way to keep it working. Wow, what a difference it made. Like I said before, I went from the motor running at WOT 90 percent of the time to less than 50% (only when the blade is actually engaged in cutting the log) of the time. I loved it.

I don’t know if you’re interested in any of these details, but I made a few slight adjustments to the code above but nothing major. I changed the servo from idle being “angle 0” to “8”. I noticed that when it was at 0 it “whined” and seemed under stress. But if I adjust the pot just a little, the whine would go away or be very slight. I think the servo was pushing up against its own limits and probably being very inefficient.

I think there is still some noise/interference issues, but I think they can be avoided by the user. If for some reason I adjust the servo to WOT and make a move up/downquarter, the servo jitters during this and it causes the engine to idle down slightly and then back up. But the accuracy of the move didn’t seem effected. And the blade is not engaged in the log so it doesn’t matter then either. Honestly, there really is no reason to adjust the head with the throttle at WOT any way.

I never tried autoSlab again. I need to make some adjustments in code to it. I really am starting to think something in the protected access is causing an issue. Should I even worry with trying to fix it?

Thanks!

Good results. The throttle control is nice. Auto slab looks to be next on the table.

I'm still wanting to work on the run away head up. Since I still can't see how it is related to the protected access, working on it now might solve a potentially intermittent problem.

Can you please review for me the situation with the electronics.
I believe that you have tip120 darlingtons controlling the primaries of the relays. Did you use a fly back diode? A lot of this was discussed following post 710.

Can you please provide a circuit diagram.

Perhaps the up direction Darlington is failing. Can you try replacing it?

I still think that replacing the big relays on the driver board with power MOSFETS will be a good thing since we are now relying on fast relay switching to control the over run.

I proposed setting quarterMove = false several posts ago to be patched into this section. My original suggestion was to have the two booleans set to false together before each directional section, but keeping them separate is OK. Did you forget, or did you have some reason to not do the reset.

if (quarterMove == true and runFinished == true)// quarterMove set true when quarterUpQuarter or QuarterDownQuarter button is pressed
    //runFinished set true in the isr once the targetCount has been reached.  
  {
    if (directionSignal == '-')
    {
    Serial.print("hardFinish");
    Serial.print("count before motor Reversal = ");
    Serial.println (countBeforeCorrection);
    delay(150); // adjust the amount of time the reversal of motor is on
    EIMSK &= ~(1 << INT5);//stop interrupts
    EIFR |= (1 << INTF5);//clear any preesisting flags
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    delay(1000); // wait and see how much over run I get
    Serial.print("The count after any over run = ");
    Serial.println(count);
    runFinished = false;
    quarterMove = false; //add this
    }

    if (directionSignal == '+'){
    Serial.print("Finish Up");
    Serial.print("count before motor Reversal = ");
    Serial.println (countBeforeCorrection);
    EIMSK &= ~(1 << INT5);//stop interrupts
    EIFR |= (1 << INTF5);//clear any preesisting flags
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    delay(1000); // wait and see how much over run I get
    Serial.print("The count after any over run = ");
    Serial.println(count);
    runFinished = false;
    quarterMove = false; //add this
    }
  }

I did not. I was thinking we decided it was unnecessary or optional at the time, but I don’t quite understand the concept of them. I thought they were to protect the micro controller.

Do you have an example of what you’re looking for exactly? Or program I can use to draw it? My pencil and paper skills aren’t very good :joy:

We are talking about these relays correct?

What sized MOSFETS? Not exactly sure how they would be connected.

No reason I can think of. I thought I set them both false prior to the if statements in the code that I tested. I think this is the code I posted in 1026. They are set false slightly different than they are in the most recent suggestion, but Is there a difference?

Thanks!

The last code I see posted with the successful printout is 1028 and it only sets runFinished = false
Resetting the quarterMove boolean may be important as you begin to work out the issues with autoSlab().

We are talking about these relays correct?

Yes, they are the direction control relays, and for some unknown reason due to softStart() either the Arduino pin output, the Tip120, or the relay itself is not releasing from the up direction.

As you know, I'm not a hardware guy, and replacing the relays and the tip drivers will take some research. I do know that the solid state switches will need to handle what the secondaries of the relays which I think is either 60 or 100 A
given the capacity of the driver board. They need to handle the surge current of the motor as well as the running current. Do you see writing on them which gives the capacity?

Intermittent behaviour (runaway up move when supposedly stopped) is typically not code but hardware. The code section actually works correctly given that you see this print out which shows the count changing properly with the head moving up when both pins 6 and 7 have been written LOW

digitalWrite(headUp, LOW);
digitalWrite(headDown, LOW);

Then

Trigger Down
softStartDown
hardFinishcount before motor Reversal = -240
The count after any over run = -163

Given that the code now appears to work reliably, you can decide to leave everything as it is, but the unexplained intermittent behaviour of the upward moves may come back to bite you. You can certainly work on autoSlab and throttle control as your primary tasks, but the longevity and reliability of the current hardware leaves a nagging doubt in the back of my mind.

Oh, I thought you meant added to the protected access code. I will add to the “working code” as well. I think I see where you are going with it being a problem with the autoSlab.

If quarterMove is set true with a button press and never set false, it could/will get called each time through the loop when runFinished = true. This means that autoReverse may not ever get called from this:

  if (autoHeadStarted == true and runFinished == true)

because it has already been executed because quarterMove = true virtually all the time. Being set false apparently got removed in one of the revisions...

I will check on any writing on the relays, but I am going to be honest, I don't know that I want to make a changeover from the relays to solid state just yet. Or any major hardware changes for that matter. It just worked too well yesterday. If I do my dad may kill me :blush: :blush: :rofl: :rofl:

I may do some research and see what parts may be required. Order another motor driver (they are cheap enough). Try and make the change over from mechanical to solid state outside of the mill and test. If it seems to work, then maybe I'll have a plug and play board to try. If it doesn't work, I can go back to the original.

I don't know how much time I will have to spend at the mill over the next couple of days, but a couple of things I can think of that I may to try to add: :blush: :blush: :rofl: :

If I get autoSlab working where it could truly be efficient, I am going to need away to set how far the head needs to travel down the track before making its autoReverse move. This will obviously vary depending on the length of the log being cut. Would it be possible to use one of the existing buttons (maybe the autoSlab) and hold it down while I move down the track to the end of the log then release.... During this process have the arduino track the number of teeth were counted. Use this number as the number of teeth needed to travel during the autoSlab back and forth moves. Does that make sense? Is
there a better way?

One other adjustment/addition advice. Once I finish cutting, I raise the head up 3/4" for the return. Once returned, I need to go down two moves 3/4" moves to make the next cut. Is there a simple way to make these two moves without having to wait for the first button to completely finish? Ex. holding button down for "x" second makes the double move, or If two buttons are pressed at the same time it makes a double move?

Sorry, just thinking....

Thanks!

Once returned, I need to go down two moves 3/4" moves to make the next cut. Is there a simple way to make these two moves without having to wait for the first button to completely finish?

I'm not clear on the issue here. I see that autoHeadDown() sets a targetCount of countDownQuarter *2 = -480 and then call for the head to start moving down to the target value.

Does this not do what you want?

I think that having a calibration for the auto slab travel would be easy enough. You should add another button which you held pressed to count the teeth while the head moves.

I personally like the idea of a held and released press rather than two presses--one to start and one to stop, but both are simple to code and you can use what you prefer.

Yes, in autoSlab it does exactly what I want. However, when I am manually running the controls, I press down 3/4 wait for the move to finish and the delays built in (I guess I can get rid of them for "production" mode) and then press it again so it will go down and be ready for the next cut. Its just a minor annoyance that I wondered if it would be easy enough to correct.

Ok, I may wait and give it a little more work before I go and add that. I really need a better way to physically "catch" the boards on the return before I can really make autoSlab truly automatic.

I made the changes you suggested to the autoSlab (setting quarterMove = flase). It worked! Everything seems to be working as it should.

The video below, I am slabbing up a 12’ cant. I had to up the gear tooth counter because of the length. I am still having to break it up in to two byte moves. The only problem with this is on the return, I have the braking variable to slow the head down before it stops. This keeps the momentum from changing the starting location of the next cut.

It works like a charm except. I have to set braking at less than 255 to prevent the issues of a multi byte variable and the change over from 256-0. The number of teeth needed to move the head is around 400. So, it begins braking on the return just past the half way mark. This slows down the operation. Minor I know.

I am wondering if I should try the protective access with just the gear tooth sensor and not the wheeled encoder that seems to give issues with the head movement and the run away head? The only other option I can think of is to break the return move in to a 3 part move, but this seems ugly….

Still very pleased with it!

Thanks!

1 Like

@cattledog , you asked several posts ago for a better circuit diagram. I had a little time today, and I tried to be a little neater than the past. Still not very good, but maybe its better than before.
Thanks

Sawmill Schematic with color.pdf (197.2 KB)

sawmill schematic 1 v0.pdf (28.0 KB)

Awesome :star_struck:
It's great to see it working so well.
I'll spend some time today looking at the schematics.

I am wondering if I should try the protective access with just the gear tooth sensor and not the wheeled encoder that seems to give issues with the head movement and the run away head?

Yes. I would try this. If it creates an issue, we can address the issues you have with the multi move block code in detail.

Have you noticed whether the anti stall pwm changes take place during the auto slab? I saw the laptop at the mill, and you may want to add some print outs to see what is going on during autoslab in regards to the pwm values used.

I mentioned previously (post 1003) that there is a syntax error one of your pwm adjustment statements.

if (80 < pwmValue < 255)
          pwmValue++; // more power applied slower to make sure head continue to move

I think you want to use

if (80 < pwmValue and pwmValue < 255)
          pwmValue++; // more power applied slower to make sure head continue to move

It is funny you should ask this now... As I am typing this, I am reviewing my other thread to try and adjust the code to suit the nano every. I got the 4809, I am pretty sure.... I have adjusted the pin numbers in the code I think correctly. I have to change the internal register locations for turning on/off the interrupt routines I am pretty sure. I was trying to figure out what they would be for the nano every.

EIMSK &= ~(1 << INT5);//stop interrupts
EIFR |= (1 << INTF5);//clear any preesisting flags

EIMSK |= (1 << INT4); (this is the only place in the code I can find INT4 being written too. I do not see where I am disabling it other than the using the ide functions)

noInterrupts();
prevCountGear = countGear;
interrupts();

I believe the code below is the most current code I was using with the pin numbers changed to match the pcb that is on order:

//This has bitRead commented out and uses digitalRead.  This allows me to use uno or mega.  bitRead location in this sketch is for uno
//This has bitRead commented out and uses digitalRead.  This allows me to use uno or mega.  bitRead location in this sketch is for uno
#include <Servo.h>
Servo myServo;  // create a servo object

const byte gearSensor = 2; // external interrupt pin
const byte encoderA = 3;//INT5 external interrupt pin
const byte encoderB = 4;
//D5 is servo attach
const byte headUp = 6;//if this pin goes high winch will engage clockwise through transistor board
const byte headDown = 7;//if this pin goes high winch will engage counterclockwise through transistor board
const byte buttonUpQuarter = 8;
const byte pwm = 9; //can I connect this pin to both motor drivers since they should never be engaged at the same time?
const byte pwm2 = 10;
const byte buttonUpManual = 11;
const byte headForward = 12;
const byte headBackward = 13;
const byte buttonDownManual = A3;
const byte buttonDownQuarter = A4;
const byte beginAutoSlab = A5;
const byte pot = A6;
const byte throttlePot = A7;

char directionSignal;

const int countUpQuarter = 240;
const int countDownQuarter = -240;
const int countUp1inch = 320;
const int countDown1inch = -320;
const int upMaxSpeed = 255;
const int downMaxSpeed = 75;
const int upSlowSpeed = 240;
const int downSlowSpeed = 38;
const int forwardMax = 158;// Maximum Speed of head moving forward during AUTO SLAB
const int forwardSlow = 148;
const int backwardMax = 255; // Maximum Speed of head moving backward during Auto Slab
const int backwardSlow = 130;
const int headGearSensor = 298;// Gear Tooth sensor that reads the teeth as the head moves forward/backwards
const int braking = (headGearSensor);

volatile int count = 0;
volatile int countGear = 0;
volatile int targetCount = 0;
volatile boolean runFinished = false;
volatile boolean autoHeadStarted = false;
volatile boolean loopFinished = false;
volatile boolean quarterMove = false;
volatile boolean checkCount = true;

int val;
int throttleVal;
int countBeforeCorrection;
int throttleAngle;
int prevCountGear;

unsigned long prevMillis = millis();
int prevCount = count;
byte pwmValue = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println("start...");
  myServo.attach(5);
  pinMode(encoderA, INPUT); //external circuit pullup
  pinMode(encoderB, INPUT); //external circuit pullup
  pinMode(buttonUpQuarter, INPUT);
  pinMode(buttonDownQuarter, INPUT);
  pinMode(buttonUpManual, INPUT);
  pinMode(buttonDownManual, INPUT);
  pinMode(gearSensor, INPUT);//external circuit pullup 1K resistor
  pinMode(beginAutoSlab, INPUT);
  pinMode(headUp, OUTPUT); //connected to forward reverse switch of head motor driver
  pinMode(headDown, OUTPUT);//connected to forward reverse switch of head motor driver
  pinMode(pwm, OUTPUT);
  pinMode(headForward, OUTPUT); // connected to forward reverse switch of motor driver through TIP120 Transistor board 2.2K resistor
  pinMode(headBackward, OUTPUT); // connected to forward reverse switch of motor driver through TIP120 Transistor board
  pinMode(pwm2, OUTPUT);  // uncomment if there is a way to control headForward/headBackward with both pot and arduino if not pot will control speed during autoSlab and uncomment below
  pinMode(throttlePot, INPUT);
  attachInterrupt(digitalPinToInterrupt(gearSensor), isrMove, FALLING);
  countGear = 0;

  attachInterrupt(digitalPinToInterrupt(encoderA), isrCount, CHANGE);
  EIMSK &= ~(1 << INT5);//disable interrupts until motor moves
  EIFR |= (1 << INTF5);//clear any preesisting flags
  count = 0;//clear counts
}

void loop()
{
  {
    val = analogRead(pot);
    val = map(val, 0, 1023, 0, 255);
  }

  if (val >= 10) {
    analogWrite(pwm2, val);
  }
  else {
    analogWrite(pwm2, 0);
  }

  throttleVal = analogRead(throttlePot);
  throttleVal = map(throttleVal, 0, 1023, 8, 75);//I think I need to adjust 255 to the angle needed for WOT

  throttleAngle = throttleVal;
  myServo.write(throttleAngle);

  if (digitalRead(beginAutoSlab) == LOW)
  {
    Serial.println("AutoSlab Mode has started");
    delay(1000);
    autoSlab();
  }
  
  if (digitalRead(buttonUpQuarter) == LOW)
  {
    Serial.println("Trigger Up");
    delay(1000);//need to rework for state change of button
    motorUpQuarter();
  }

  if (digitalRead(buttonDownQuarter) == LOW)
  {
    Serial.println("Trigger Down");
    delay(1000);//need to rework for state change of button
    motorDownQuarter();
  }
  if (digitalRead(buttonUpManual) == LOW)
  {
    motorUpUntil();
  }
  if (digitalRead(buttonDownManual) == LOW)
  {
    motorDownUntil();
  }

  if (quarterMove == true and runFinished == true)// quarterMove set true when quarterUpQuarter or QuarterDownQuarter button is pressed
    //runFinished set true in the isr once the targetCount has been reached.  
  {
    if (directionSignal == '-')
    {
    Serial.print("hardFinish");
    Serial.print("count before motor Reversal = ");
    Serial.println (countBeforeCorrection);
    delay(150); // adjust the amount of time the reversal of motor is on
    EIMSK &= ~(1 << INT5);//stop interrupts
    EIFR |= (1 << INTF5);//clear any preesisting flags
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    delay(1000); // wait and see how much over run I get
    Serial.print("The count after any over run = ");
    Serial.println(count);
    runFinished = false;
    }

    if (directionSignal == '+'){
    Serial.print("Finish Up");
    Serial.print("count before motor Reversal = ");
    Serial.println (countBeforeCorrection);
    EIMSK &= ~(1 << INT5);//stop interrupts
    EIFR |= (1 << INTF5);//clear any preesisting flags
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    delay(1000); // wait and see how much over run I get
    Serial.print("The count after any over run = ");
    Serial.println(count);
    runFinished = false;
    }
  }
  if (autoHeadStarted == true and runFinished == true)//autoHeadStarted was set True in the AutoHeadUp function and runFinished was set true once the targetCount was reached and head stopped moving
   {
    if (directionSignal == '-')
    {
    Serial.print("hardFinish");
    Serial.print("count before motor Reversal = ");
    Serial.println (countBeforeCorrection);
    delay(150); // adjust the amount of time the reversal of motor is on
    EIMSK &= ~(1 << INT5);//stop interrupts
    EIFR |= (1 << INTF5);//clear any preesisting flags
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    delay(1000); // wait and see how much over run I get
    Serial.print("The count after any over run = ");
    Serial.println(count);
    runFinished = false;
    }

    if (directionSignal == '+'){
    Serial.print("Finish Up");
    Serial.print("count before motor Reversal = ");
    Serial.println (countBeforeCorrection);
    EIMSK &= ~(1 << INT5);//stop interrupts
    EIFR |= (1 << INTF5);//clear any preesisting flags
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    delay(1000); // wait and see how much over run I get
    Serial.print("The count after any over run = ");
    Serial.println(count);
    runFinished = false;
    }
    autoReverse();
  }
  if (loopFinished == true and runFinished == true)
  {
    digitalWrite(headUp, LOW);//This should stop winch lift motor
    digitalWrite(headDown, LOW);//This should stop winch lift motor
    EIMSK &= ~(1 << INT5);//stop interrupts DO I need this when autoSlabbing?
    EIFR |= (1 << INTF5);//clear any preesisting flags  DO I need this when autoSlabbing?
    delay(2000);
    autoSlab();
  }
}
void isrMove()
{
  countGear ++;
}

void isrCount()//interrupt routine for encoder
{
  byte AState = digitalRead(encoderA);
  byte BState = digitalRead(encoderB);
  if (AState == BState)
    count++;
  else
    count--;

  if (directionSignal == '-' and count <= targetCount)
  {
    //set motor to up with a value which locks the motor
    countBeforeCorrection = count;
    digitalWrite(headUp, HIGH);
    digitalWrite(headDown, LOW);
    analogWrite(pwm, 200);
    runFinished = true;
  }
  if (directionSignal == '+' and count >= targetCount)
  {
    countBeforeCorrection = count;
    //digitalWrite(headDown, HIGH);  //try using these if over run up is a problem
    //digitalWrite(headUp, LOW);
    //analogWrite(pwm, 40);//This adjust how much to pwm wanted to reverse the motor and prevent overrun
    digitalWrite(headUp, LOW);
    digitalWrite(headDown, LOW);
    runFinished = true;
  }
}

void motorUpQuarter()
{
  runFinished = false;
  digitalWrite(headUp, HIGH);
  targetCount = countUpQuarter;
  directionSignal = '+';
  count = 0;
  EIFR |= (1 << INTF5);//clear any preesisting flags
  EIMSK = (1 << INT5); //enable interrupt counting
  softStart();
  quarterMove = true;
}

void motorDownQuarter()
{
  runFinished = false;
  digitalWrite(headDown, HIGH);
  targetCount = countDownQuarter;
  directionSignal = '-';
  count = 0;
  EIFR |= (1 << INTF5);//clear any preesisting flags
  EIMSK = (1 << INT5); //enable interrupt counting
  softStart();
  quarterMove = true;
}

void motorUpUntil ()
{
  digitalWrite(headUp, HIGH);
  //soft start
  for (int i = 0; i <= 255; i = i + 10)
    analogWrite(pwm, i);
  while (digitalRead(buttonUpManual) == LOW) {} //Release of Button
  analogWrite(pwm, 0);
  digitalWrite(headUp, LOW);
}
void  motorDownUntil ()
{
  digitalWrite(headDown, HIGH);
  //soft start
  for (int i = 0; i <= 255; i = i + 10)
    analogWrite(pwm, i);
  while (digitalRead(buttonDownManual) == LOW) {} //Release of Button
  analogWrite(pwm, 0);
  digitalWrite(headDown, LOW);
}

void softStart() //count should always be starting at 0
{
  if (directionSignal == '+') //was set for an up move
  {
    Serial.println("softStartUp");
    for (int i = 0; i <= 255; i = i + 1)//head should move up before 255
    {
      analogWrite(pwm, i);
      delay(10);
      if (count >= 5)  //give some leeway here incase of vibration noise
      {
        i = i * 1.2;// //add 20 percent to the pwm that begins the head moving
        analogWrite(pwm, i);
        Serial.print("PWM used after being increased by 20 percent = ");
        Serial.println(i);
        break; //exit for() loop
      }
    }
  }

  if (directionSignal == '-') //was set for a down move
  {
    Serial.println("softStartDown");
    for (int i = 0; i <= 28; i = i + 1) //head should move up before 150
    {
      analogWrite(pwm, i);
      delay(10);
      if (count <= -5)  //give some leeway here incase of vibration noise
      {
        //  i = i ;// //add 15 percent to the pwm that begins the head moving
        // analogWrite(pwm, i);
        Serial.print("PWM used = ");
        Serial.println(i);
        break; //exit for() loop
      }
    }
  }
}
void autoSlab() //Called on from button press and completion of autoHeadDown()
{
  Serial.println("throttle increasing to WOT");
  myServo.write(65);//adjust number to be WOT Need to disable POT some how...
  delay(3000);

  Serial.println("head moving forward");
  countGear = 0;
  EIMSK |= (1 << INT4);
  digitalWrite(headForward, HIGH);
  while (countGear <= 250) // Start Slowing Down and prevent issue of 255/256 changeOver
  { 
    if (millis() - prevMillis > 250) // check periodically need adjust based on how fast desired tooth to pass sensor per check
    {
      if (prevCountGear == countGear)
      {
        if (pwmValue < 80)
          pwmValue = pwmValue + 10; // more power to get moving at start quicker

        if (80 < pwmValue < 255)
          pwmValue++; // more power applied slower to make sure head continue to move
      }
      else
      {
        noInterrupts();
        prevCountGear = countGear;
        interrupts();
      }
      prevMillis = millis(); // reset time for next check.
      analogWrite(pwm2, pwmValue);
    }
  }

  noInterrupts();
  countGear = 0;
  interrupts();

  while (countGear <= headGearSensor - 250); //  prevent issue of 255/256 change Over
  {
    if (millis() - prevMillis > 250) // check periodically need adjust based on how fast desired tooth to pass sensor per check
    {
      if (prevCountGear == countGear)
      {
        if (pwmValue < 255)
          pwmValue++; // more power applied slower to make sure head continue to move
      }
      else
      {
        noInterrupts();
        prevCountGear = countGear;
        interrupts();
      }
      prevMillis = millis(); // reset time for next check.
      analogWrite(pwm2, pwmValue);
    }
  }

  analogWrite(pwm2, 0);
  digitalWrite(headForward, LOW);
  loopFinished = false;
  delay (1000);
  Serial.println("throttle decreasing to IDLE");
  myServo.write(8);//adjust number to be WOT Need to disable POT some how...
  delay(3000);
  autoHeadUp();
}
void autoHeadUp() // Called on from autoSlab
{
  Serial.print("The number of teeth counted is ");
  Serial.println(countGear);
  runFinished = false;
  digitalWrite(headUp, HIGH);
  targetCount = countUpQuarter;
  directionSignal = '+';
  count = 0;
  EIFR |= (1 << INTF5);//clear any preesisting flags
  EIMSK = (1 << INT5); //enable interrupt counting
  autoHeadStarted = true;
  softStart();
}

void autoReverse()  //Called with if statement in void loop() when runFinished = true and autoHeadStarted = true
{
  Serial.println("head moving backwards");
  countGear = 0;
  EIMSK |= (1 << INT4);//enable interrupt
  digitalWrite(headBackward, HIGH);//sets the forward reverse switch on the hacked motor driver for head forward

  for (int i = 0; i <= backwardMax; i = i + 10)
  {
    analogWrite(pwm2, i);
    delay (10);
  }
   
  while (countGear <= braking) //90 % there slow down
  {}
  
noInterrupts();
countGear = 0;
interrupts();

  for (int i = backwardMax; i >= backwardSlow; i = i - 10)
  {
    analogWrite(pwm2, i);
    delay(10);
  }
  
  while (countGear <= headGearSensor - braking);
  {}

  analogWrite(pwm2, 0);
  digitalWrite(headBackward, LOW);
  delay(2000);
  autoHeadDown();
}

void autoHeadDown()  // called on from autoReverse()
{
  Serial.print("The number of teeth counted is ");
  Serial.println(countGear);
  runFinished = false;
  autoHeadStarted = false;
  digitalWrite(headDown, HIGH);
  targetCount = countDownQuarter * 2; //I want it to go down twice the targetCount because it should be above the log the thickness of the board that was just cut
  directionSignal = '-';
  count = 0;
  EIFR |= (1 << INTF5);//clear any preesisting flags
  EIMSK = (1 << INT5); //enable interrupt counting
  loopFinished = true;
  softStart();
}

Thanks!