Using Encoder Library to Stop DC Motor

I am making an automatic chop saw to cuts wood to a specific length. The saw was working correctly with the exception of the length of the parts was varying too much. I am changing the sketch to now use the Encoder Library listed in the Arduino IDE.

The sketch is supposed to feed the wood using the 12V motor until the incremental rotary encoder reaches the pulse count, stop feeding, active the pneumatic solenoid to cut the wood, then repeat the process.

Using the sketch below, the wood is feed into the encoder, but never stops. The wood is just pushed right through.

I believe my mistake is after the "start feeding material" point. I bet I am overlooking something really simple. Please help.

/* DESCRIPTION:

   CONNECTIONS:
   Arduino D6  - Motor Driver PWM Input
   Arduino D4  - Motor Driver DIR Input
   Arduino GND - Motor Driver GND

   //Rotary Encoder Inputs
   inputCLK 2 (green)
   inputDT 3 (white)

   //solendoid Inputs
   chopPin 13 - solenoid activation of chopsaw
   loadPin 12 - solenoid activation of loader

   //IR Sensors
   homeIR A1 - IR Sensor of pusher at home, left travel limit
   yellowIR A2 - IR Sensor of material level low
   loadIR A3 - IR sensor of wood in stack, ready to load
   rightIR A5 - IR sensor of right travel limit


   redLight 8 - red light pin
   yellowLight 9 - yellow light pin
   greenLight 12 - green light pin

   7 Segment Display 7 - display
   Dump Servo 11 - dumpServo

   **15 APR 20**
   ROTARY ENCODER CALIBRATION YIELDED 16209 FOR FULL RUN FROM HOMEIR TO RIGHT IR = 63.8125"
   4-1/4" PART ENCODER OUTPUT = 1079
   ACTUAL 4.25" PART CODE SET AT 1103 TO 1106
   **25 JUN 20***
   SET LENGTH TO 1102 TO 1105
   **2JUL20**
   SET LENGTH TO 1100 AND 1103

   **REDOING VOID LOOP TO TRY AND IMPROVE TOLERANCE***
    CHANGED TO USE ENCODER LIBRARY FROM TEENSY*


 *******************************************************************************/

#include "CytronMotorDriver.h"
volatile boolean TurnDetected;  // pusher motor is turning, need voatile for Interrupts
#include <Servo.h>
Servo dumpServo;  // create servo object to control a serv

// These are the Arduino pins required to create a software serial
//  instance. We'll actually only use the TX pin.
#include <SoftwareSerial.h>
const int softwareRx = A0;
const int softwareTx = 7;
SoftwareSerial s7s(softwareRx, softwareTx);
unsigned int partcount = 0;  // This variable will count up to 65k
char tempString[10];  // Will be used with sprintf to create strings

// Configure the Pusher motor driver.
CytronMD motor(PWM_DIR, 6, 4);  // PWM = Pin 6, DIR = Pin 4

// Configure the Load motor driver.
int LoadMotorIn1 = 5;
int LoadMotorIn2 = 10;

// Rotary Encoder Connections
#include <Encoder.h>
Encoder MyEnc(2, 3);


int chopPin = 13;
int homeIR = A1;
int yellowIR = A2;
int loadIR = A3;
int rightIR = A5;
int woodIR = A4;
int redLight = 8;
int yellowLight = 9;
int greenLight = 12;
int lightDelay = 250;
int loadDelay = 500;
int unloadDelay = 2000;
int chopDelay = 1360;
int feedDelay = 1100;
int feedSpeed = 145;
int pushTime = 7000;
int retractSpeed = -255;
int cycleCount;
int oldTotalCount;
int newTotalCount;
int boxFull = 60;
int offFall = 0;
int highLimit = 1108;
int lowLimit = 1100;

unsigned long time_now = 0;
int rightval;
int homeval;
int yellowval;
int loadval;
boolean state = true;

//////////////////////////////////////////
void setup() {

  // Must begin s7s software serial at the correct baud rate.
  //  The default of the s7s is 9600.
  s7s.begin(9600);
  // Clear the display, and then turn on all segments and decimals
  clearDisplay();  // Clears display, resets cursor
  setBrightness(255);  // High brightness
  Serial.write(0x79); // Send the Move Cursor Command
  Serial.write(0x03); // Send the data byte, with value 3, cursor right most digit

  pinMode (chopPin, OUTPUT);
  pinMode(LoadMotorIn1, OUTPUT);
  pinMode(LoadMotorIn2, OUTPUT);
  digitalWrite(LoadMotorIn1, LOW);
  digitalWrite(LoadMotorIn2, LOW);

  pinMode (loadIR, INPUT);
  pinMode (rightIR, INPUT);
  pinMode (yellowIR, INPUT);
  pinMode (homeIR, INPUT);

  pinMode (redLight, OUTPUT);
  pinMode (yellowLight, OUTPUT);
  pinMode (greenLight, OUTPUT);

  digitalWrite (chopPin, LOW);

  digitalWrite (redLight, LOW);
  digitalWrite (yellowLight, LOW);
  digitalWrite (greenLight, LOW);

  dumpServo.attach(11);  // attaches the servo on pin 11 to the servo object
  dumpServo.write(42);   // tell servo to go to open position
  oldTotalCount = 0;
  newTotalCount = 0;

  long positionOld  = -999;
}

//////////////////////////////////////////
void loop() {

  sprintf(tempString, "%4d", newTotalCount);
  setDecimals(0b00001000);  // Sets digit 4 decimal on
  s7s.print(tempString);

  //control material lights
  //box full
  yellowval = digitalRead (yellowIR);
  loadval = digitalRead (loadIR);

  if (newTotalCount == boxFull) {
    digitalWrite (yellowLight, HIGH);
    digitalWrite (redLight, HIGH);
    digitalWrite (greenLight, LOW);
  }

  //material ok green light
  else if ((yellowval == 0) && (loadval == 0)) {
    digitalWrite (redLight, LOW);
    digitalWrite (yellowLight, LOW);
    digitalWrite (greenLight, HIGH);
  }
  //low material yellow light
  else if ((yellowval == 1) && (loadval == 0)) {
    digitalWrite (redLight, LOW);
    digitalWrite (yellowLight, HIGH);
    digitalWrite (greenLight, LOW);
  }
  //no material red light
  else if ((yellowval == 1) && (loadval == 1)) {
    digitalWrite (redLight, HIGH);
    digitalWrite (yellowLight, LOW);
    digitalWrite (greenLight, LOW);
  }

  // Return pusher to home
  homeval = digitalRead (homeIR);
  while (homeval == 1) {
    motor.setSpeed (retractSpeed);
    homeval = digitalRead (homeIR);
  }
  if (homeval == 0) {
    motor.setSpeed (0);
  }
  while (loadval == 1) {
    loadval = digitalRead (loadIR);
  }

  //loading wood
  if ((loadval == 0) && (homeval == 0) && (newTotalCount < boxFull)) {
    digitalWrite(LoadMotorIn1, LOW);
    analogWrite(LoadMotorIn2, 255);
    delay(722);
    analogWrite(LoadMotorIn2, LOW);
    delay(1000);
  }

  //start feeding material
  long positionOld;
  long positionNow;
  MyEnc.write(0);
  cycleCount = 0;
  oldTotalCount = newTotalCount;
  int rightval = digitalRead (rightIR);
  positionNow = MyEnc.read();
  while ((positionNow < lowLimit ) && (rightval != 0) && (newTotalCount < boxFull)) {
    motor.setSpeed(feedSpeed);  // Run forward
    positionNow = MyEnc.read();
    /*if (positionNow != positionOld) {
      positionOld = positionNow;
      }*/

    rightval = (digitalRead (rightIR));

    // Stop motor and cut
    if ((positionNow >= lowLimit) && (positionNow <= highLimit))
    {
      motor.setSpeed(0);
      digitalWrite (chopPin, HIGH);
      delay (chopDelay);
      digitalWrite (chopPin, LOW);
      delay (feedDelay);
      offFall = (positionNow);
      cycleCount = (cycleCount + 1);
      if ((offFall > 301) && (cycleCount == 3) || (cycleCount == 4)) {
        dumpServo.write(0);
      }
      if ((offFall > 0) && (offFall < 300) && (cycleCount == 3)) {
        dumpServo.write(0);
      }
      if ((offFall == 0) && (cycleCount == 3)) {
        dumpServo.write(0);
      }
      else {
        dumpServo.write(42);
      }
      if ((positionNow < lowLimit) && (rightval != 0) && (newTotalCount == boxFull))
      {
        motor.setSpeed(0);
      }
      MyEnc.write(0);
      newTotalCount = ((cycleCount - 1) + (oldTotalCount));
      sprintf(tempString, "%4d", newTotalCount);
      setDecimals(0b00001000);  // Sets digit 4 decimal on
      s7s.print(tempString);
    }
  }
}//end void loop


//////////////////////////////////////////
// Send the clear display command (0x76)
//  This will clear the display and reset the cursor
void clearDisplay()
{
  s7s.write(0x76);  // Clear display command
}
//////////////////////////////////////////
// Set the displays brightness. Should receive byte with the value
//  to set the brightness to
//  dimmest------------->brightest
//     0--------127--------255
void setBrightness(byte value)
{
  s7s.write(0x7A);  // Set brightness command byte
  s7s.write(value);  // brightness data byte
}
//////////////////////////////////////////
// Turn on any, none, or all of the decimals.
//  The six lowest bits in the decimals parameter sets a decimal
//  (or colon, or apostrophe) on or off. A 1 indicates on, 0 off.
//  [MSB] (X)(X)(Apos)(Colon)(Digit 4)(Digit 3)(Digit2)(Digit1)
void setDecimals(byte decimals)
{
  s7s.write(0x77);
  s7s.write(decimals);
}[code]

IF you believe you know where the error is, what have you done to debug that part of the program?

Paul

Use serial print to debug this. The code looks reasonable in that the encoder is read everytime
round the loop and compared to lowLimit. But is it incrementing or decrementing? If its decrementing
then the limit cannot be reached.

You also don't delay after stopping the motor before activating the solenoid - mechanical things
take time to stop moving, you don't want to slam the wood into the blade!

You hit the nail on the head MarkT!

"But is it incrementing or decrementing? If its decrementing
then the limit cannot be reached."

I just ran a sketch I have for testing the encoder and sure enough it is counting backwards. I will be testing the actual machine sketch later today.

Thanks! I was pulling whats left of my hair out and never thought of that.