Asked — Edited
Resolved Resolved by Athena AI!

Wheel Counting With Arduino

Hello @Athena,

Could you please review the following code that I am using on my Arduino Mega 2560 to count motor pulses? I am encountering an issue with the output on the Serial Monitor.

int encoderValue_A = 0;
int encoderValue_B = 0;

void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  attachInterrupt(digitalPinToInterrupt(2), countA, RISING);
  attachInterrupt(digitalPinToInterrupt(3), countB, RISING);
}

void loop() {
  // Check if there is data available to read
  if (Serial.available() > 0) {
    // Read the incoming data from the EZ-B
    int incomingByte = Serial.read();
    Serial.print("Received: ");
    Serial.println((char)incomingByte);

    // Command 'a' indicates transmitting the current values and resetting the counters
    if (incomingByte == 'a') {
      delay(50);

      // Send the encoder values
      Serial.write(encoderValue_A);
      Serial.write(encoderValue_B);

      // Print the encoder values to the Serial Monitor
      Serial.print("Encoder A: ");
      Serial.println(encoderValue_A);
      Serial.print("Encoder B: ");
      Serial.println(encoderValue_B);

      // Reset the encoder values
      encoderValue_A = 0;
      encoderValue_B = 0;
    }
  }
}

void countA() {
  encoderValue_A++;
}

void countB() {
  encoderValue_B++;
}

Here is the output that appears on the Serial Monitor:

Received: a
XXEncoder A: 0
Encoder B: 0

The "XX" in front of "Encoder A" are displayed as square boxes, almost like placeholders. Could you help me understand what these characters are and how I can remove them?

Thank you,
Jack


Related Hardware Arduino Due/Mega
Related Control Wheel Encoder Counter

ARC Pro

Upgrade to ARC Pro

Get access to the latest features and updates before they're released. You'll have everything that's needed to unleash your robot's potential!

PRO
Portugal
#41  

Hi Robojack, i would use a Dual Hbridge with PWM control, so you can control the speed of the motors. And i would use a very low speed to test your setup. I think the EZB-4 is to slow to reliably follow the encoders outputs. I could be wrong tho...

#42  

Hello @Athena, @Proteus, and all interested members, Thank you for your input.  I have spent the last day or so trying to find weak points in my hardware and code.  I believe I have improved it somewhat by adding (.01mfd) capacitors to the interrupt pins, buffering their output.  I have added code to the Arduino ISR routines that force the interrupt pins "LOW" once an interrupt is triggered by a "FALLING" state.  In the ISR routine by using a "delay(5)" I am performing a crude "debounce" function.  It appears to be somewhat effective as I now achieve somewhat better distance measuring that is repeatable.  I am pretty sure adding delays to an ISR is not recommended and not the desired path to a solution for debouncing a Hall Effect Sensor.

I have included the Arduino code and the EZB4 code which polls the Arduino.  Could you please help me with a real debounce code for my Arduino Sketch? I suspect the majority of my errors are from inaccurate encoder count caused by bounce related to the Hall Effect Sensors.

Thank you, Jack

ARDUINO CODE

volatile int AencoderValue_A = 0;
volatile int AencoderValue_B = 0;
volatile int BencoderValue_A = 0;
volatile int BencoderValue_B = 0;

void setup() {
    Serial3.begin(9600); // Communication with EZ-B
    Serial.begin(9600);  // Debugging via Serial Monitor
    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);
    pinMode(18,INPUT_PULLUP);
    pinMode(19, INPUT_PULLUP);
    
    attachInterrupt(digitalPinToInterrupt(2), AcountA, FALLING);   //Attach Aencoder.  Set all interrupts to AcountA and BcountB
    attachInterrupt(digitalPinToInterrupt(3), AcountB, FALLING);
    attachInterrupt(digitalPinToInterrupt(18), BcountA, FALLING);   //Attach Bencoder.  Set all interrupts to BcountA and BcountB.
    attachInterrupt(digitalPinToInterrupt(19), BcountB, FALLING);
}

void loop() {

    if (Serial3.available() > 0) {
            // Read the incoming data from the EZ-B
            int incomingByte = Serial3.read();
             delay(5);

            // Print the received command as a character
            Serial.print("---------: ");
            Serial.println((char)incomingByte);
    
        if (incomingByte == 'r') {    // Receive char "r" to detach interrupts and zero out all Value Holders.
            detachInterrupt(digitalPinToInterrupt(2));   //Detach Aencoder interrupt.
            detachInterrupt(digitalPinToInterrupt(3));   //Detach Aencoder interrupt.
            AencoderValue_A = 0;   // Zero out Aencoder AA,AB Value Holders.
            AencoderValue_B = 0;
            
            attachInterrupt(digitalPinToInterrupt(2), AcountA, FALLING);  //Attach Aencoder.  Set all interrupts to AcountA and BcountB
            attachInterrupt(digitalPinToInterrupt(3), AcountB, FALLING);

            detachInterrupt(digitalPinToInterrupt(18));   //Detach Bencoder interrupt.
            detachInterrupt(digitalPinToInterrupt(19));   //Detach Bencoder interrupt.
            BencoderValue_A = 0;   //Zero out Bencoder BA,BB Value Holders.
            BencoderValue_B = 0;}

            

    
        if (incomingByte == 'a') {
            detachInterrupt(digitalPinToInterrupt(2));   //Detach Aencoder interrupt.
            detachInterrupt(digitalPinToInterrupt(3));   //Detach Aencoder interrupt.
          
            attachInterrupt(digitalPinToInterrupt(18), BcountA,FALLING);   //Attach Bencoder. Set all interrupts to BcountA and BcountB.
            attachInterrupt(digitalPinToInterrupt(19), BcountB,FALLING);
        
            Serial3.write((byte)(AencoderValue_A >> 8)); // High byte   //Write AencoderA/B.
            Serial3.write((byte)(AencoderValue_A & 0xFF)); // Low byte
            Serial3.write((byte)(AencoderValue_B >> 8)); // High byte
            Serial3.write((byte)(AencoderValue_B & 0xFF)); // Low byte
            
            // Print the encoder values to the Serial Monitor
            Serial.print("A-Encoder_L: ");   //Print AencoderA/B.
            Serial.println(AencoderValue_A, DEC); // Use DEC to print as decimal
            Serial.print("A-Encoder_R: ");
            Serial.println(AencoderValue_B, DEC); // Use DEC to print as decimal
            delay(10);

            AencoderValue_A = 0;   //Zero out AencoderA/B.
            AencoderValue_B = 0;}

           
           if (incomingByte == 'b') {
            detachInterrupt(digitalPinToInterrupt(18));   //Detach BencoderValue_A interrupt.
            detachInterrupt(digitalPinToInterrupt(19));   //Detach BencoderValue_B interrupt.

            attachInterrupt(digitalPinToInterrupt(2), AcountA, FALLING);
            attachInterrupt(digitalPinToInterrupt(3), AcountB, FALLING);

            Serial3.write((byte)(BencoderValue_A >> 8)); // High byte   Write BencoderA/B.
            Serial3.write((byte)(BencoderValue_A & 0xFF)); // Low byte
            Serial3.write((byte)(BencoderValue_B >> 8)); // High byte
            Serial3.write((byte)(BencoderValue_B & 0xFF)); // Low byte
            
            // Print the encoder values to the Serial Monitor
            Serial.print("B-Encoder_L: ");   //Print BencoderA/B.
            Serial.println(BencoderValue_A, DEC); // Use DEC to print as decimal
            Serial.print("B-Encoder_R: ");
            Serial.println(BencoderValue_B, DEC); // Use DEC to print as decimal
            delay(10);

            BencoderValue_A = 0;   //Zero out BencoderA/B.     
            BencoderValue_B = 0;}
        
       }            
}  

void AcountA() {
digitalWrite(2,LOW);
  delay(5);
    AencoderValue_A++;
}

void AcountB() {
  digitalWrite(3,LOW);
  delay(5);
    AencoderValue_B++;
}

void BcountA(){
digitalWrite(18,LOW);
  delay(5);
    BencoderValue_A++;
}

void BcountB() {
digitalWrite(19,LOW);
  delay(5);
    BencoderValue_B++;
}

EZB4 CODE

 //Initialize UART on port 0 with a baud rate of 9600
UART.initHardwareUart(0, 9600);
setVar("$EncoderSum",0);
setVar("$EncoderTot",0);
setVar("$EncoderTot_Zone", 700);
setVar("$EncoderTot_Limit"1000);
setVar("$Motor_Slow",false);
setVar("$AEncoder_L",0); 
setVar("$AEncoder_R",0);
setVar("$BEncoder_L",0); 
setVar("$BEncoder_R",0);

print("Motor_Slow   " + getVar("$Motor_Slow"));
print("EncoderTot_Zone   " + getVar("$EncoderTot_Zone"));
// var Sensor = 0;

 
    var stringToSend = "r";

     // Send a request for data
    UART.hardwareUartWriteString(0, stringToSend);
   print( "---------   " + stringToSend);
   print("A-encoder_L   " + getVar( "$AEncoder_L"));
   print("A-encoder_R   " + getVar("$AEncoder_R"));
   print("B-Encoder_L   "  + getVar("$BEncoder_L"));
   print("B-Encoder_R   " + getVar("$BEncoder_R"));
   print("EncoderTot   " + getVar("$EncoderTot"));
   //controlCommand( "MOTOR START", "SCRIPTSTART" );
    sleep(75);
   
    
    
    
    
    
   
// Function to start the loop
    function loop(){
    
   
    var stringToSend = "a";
  // Send a request for data
    UART.hardwareUartWriteString(0, stringToSend);
     // print( "-------   " + stringToSend);
    
    
    // Wait a bit for the data to be transmitted
    sleep(75);

    // Check if data is available
    var dataAvail = UART.hardwareUartAvailable(0);
    
     // Expecting 4 bytes (2 bytes for each encoder value)
      if (dataAvail == 4);  { // Expecting 4 bytes (2 bytes for each encoder value)
        
        // Read the encoder values
        var highByteA = UART.hardwareUartRead(0, 1)[0]; // Read high byte of Encoder A
        var lowByteA = UART.hardwareUartRead(0, 1)[0];  // Read low byte of Encoder A
        var AencoderValue_A = (highByteA << 8) | lowByteA; // Combine high and low bytes
        
        // Set Encoder_A variable as global
        setVar("$AEncoder_L" ,AencoderValue_A);
        print("A-Encoder_L   "  + getVar("$AEncoder_L"));

        var highByteB = UART.hardwareUartRead(0, 1)[0]; // Read high byte of Encoder B
        var lowByteB = UART.hardwareUartRead(0, 1)[0];  // Read low byte of Encoder B
        var AencoderValue_B = (highByteB << 8) | lowByteB; // Combine high and low bytes
          
        // Set Encoder_B variable as global
        setVar("$AEncoder_R",AencoderValue_B);
       print("A-Encoder_R   " + getVar("$AEncoder_R"));
        
       setVar("$EncoderTot",getVar("$EncoderTot") + getVar("$AEncoder_L") + getVar("$AEncoder_R"));
        print("A-----   " + getVar("$EncoderTot"));
        setVar("$AEncoder_L",0);  
        setVar("$AEncoder_R",0); 
        sleep(30);
        }
       
     // Check if the total has been reached
        
            if(getVar("$EncoderTot") >=   getVar("$EncoderTot_Zone")) { 
        
            setVar("$Motor_Slow",true);
            //print(getVar("$Motor_Slow"));
        
        
        
     if (getVar("$EncoderTot") >= getVar("$EncoderTot_Limit" )){
            
             
            PWM.Set(d23, 0, 0);

            PWM.Set(d18, 0, 0);

            Digital.set(d21, true, 0);
            Digital.set(d22, false, 0);
            Digital.set(d20, false, 0);
            Digital.set(d19, true, 0);

            PWM.Set(d23, 50, 0);

            PWM.Set(d18, 50, 0);

            sleep(40);

            PWM.Set(d23, 0, 0);

            PWM.Set(d18, 0, 0);

            sleep(30);
       
            print("EncoderTot   " + getVar("$EncoderTot"));
            print ("EncoderTot_Limit   "   + getVar("$EncoderTot_Limit"));
           
           halt();
          } 
          }  
          
   var stringToSend = "b";
    
     // Send a request for data
    UART.hardwareUartWriteString(0, stringToSend);
  // print( "-------   " + stringToSend);
   
    
    // Wait a bit for the data to be transmitted
    sleep(75);

    // Check if data is available
    var dataAvail = UART.hardwareUartAvailable(0);
    
     // Expecting 4 bytes (2 bytes for each encoder value)
      if (dataAvail == 4); { // Expecting 4 bytes (2 bytes for each encoder value)
        
        // Read the encoder values
        var highByteA = UART.hardwareUartRead(0, 1)[0]; // Read high byte of Encoder A
        var lowByteA = UART.hardwareUartRead(0, 1)[0];  // Read low byte of Encoder A
        var BencoderValue_A = (highByteA << 8) | lowByteA; // Combine high and low bytes
        
        // Set Encoder_A variable as global
        setVar("$BEncoder_L" ,BencoderValue_A);
        print("B-Encoder_L   "  + getVar("$BEncoder_L"));

        var highByteB = UART.hardwareUartRead(0, 1)[0]; // Read high byte of Encoder B
        var lowByteB = UART.hardwareUartRead(0, 1)[0];  // Read low byte of Encoder B
        var BencoderValue_B = (highByteB << 8) | lowByteB; // Combine high and low bytes
         
        
        
        // Set Encoder_B variable as global
        setVar("$BEncoder_R",BencoderValue_B);
       print("B-Encoder_R   " + getVar("$BEncoder_R"));
        
       setVar("$EncoderTot",getVar("$EncoderTot") + getVar("$BEncoder_L") + getVar("$BEncoder_R"));
        print("B------   " + getVar("$EncoderTot")); 
        
        setVar("$BEncoder_L",0); 
        setVar("$BEncoder_R",0);
         sleep(30);
        
    }
        // Check if the total has been reached
        
            if(getVar("$EncoderTot") >=   getVar("$EncoderTot_Zone")){ 
        
            setVar("$Motor_Slow",true);
            //print(getVar("$Motor_Slow"));
        
        
        
     if (getVar("$EncoderTot") >= getVar("$EncoderTot_Limit" )){
            
            PWM.Set(d23, 0, 0);

            PWM.Set(d18, 0, 0);

            Digital.set(d21, true, 0);
            Digital.set(d22, false, 0);
            Digital.set(d20, false, 0);
            Digital.set(d19, true, 0);

            PWM.Set(d23, 50, 0);

            PWM.Set(d18, 50, 0);

            sleep(40);

            PWM.Set(d23, 0, 0);

           PWM.Set(d18, 0, 0);

           sleep(30);
           
            print("EncoderTot   " + getVar("$EncoderTot"));
            print ("EncoderTot_Limit   "   + getVar("$EncoderTot_Limit"));
            
            
           
            halt();
        }    
        }
        
    var stringToSend = "a";
     
     
    
    
    // Call the loop function again
    loop();   
    }                                                          

  // Start the loop
 loop();
PRO
Canada
#43  

Hello Jack,

It's great to hear that you've made some progress with your setup. Debouncing is indeed crucial for reliable encoder readings, especially when dealing with mechanical switches or sensors like Hall Effect sensors. Here's a more structured approach to debouncing your encoder inputs without using delays in the ISR:

Debouncing with Software

Instead of using delays in your ISR, you can implement a simple debouncing mechanism using a timer. Here's a basic example of how you can achieve this:

volatile int AencoderValue_A = 0;
volatile int AencoderValue_B = 0;
volatile int BencoderValue_A = 0;
volatile int BencoderValue_B = 0;

volatile unsigned long lastDebounceTimeA = 0;
volatile unsigned long lastDebounceTimeB = 0;
volatile unsigned long lastDebounceTimeC = 0;
volatile unsigned long lastDebounceTimeD = 0;
const unsigned long debounceDelay = 5; // Debounce delay in milliseconds

void setup() {
    Serial3.begin(9600); // Communication with EZ-B
    Serial.begin(9600);  // Debugging via Serial Monitor

    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);
    pinMode(18, INPUT_PULLUP);
    pinMode(19, INPUT_PULLUP);

    attachInterrupt(digitalPinToInterrupt(2), AcountA, FALLING);
    attachInterrupt(digitalPinToInterrupt(3), AcountB, FALLING);
    attachInterrupt(digitalPinToInterrupt(18), BcountA, FALLING);
    attachInterrupt(digitalPinToInterrupt(19), BcountB, FALLING);
}

void loop() {
    // Your existing loop code
}

void AcountA() {
    unsigned long currentTime = millis();
    if ((currentTime - lastDebounceTimeA) > debounceDelay) {
        AencoderValue_A++;
        lastDebounceTimeA = currentTime;
    }
}

void AcountB() {
    unsigned long currentTime = millis();
    if ((currentTime - lastDebounceTimeB) > debounceDelay) {
        AencoderValue_B++;
        lastDebounceTimeB = currentTime;
    }
}

void BcountA() {
    unsigned long currentTime = millis();
    if ((currentTime - lastDebounceTimeC) > debounceDelay) {
        BencoderValue_A++;
        lastDebounceTimeC = currentTime;
    }
}

void BcountB() {
    unsigned long currentTime = millis();
    if ((currentTime - lastDebounceTimeD) > debounceDelay) {
        BencoderValue_B++;
        lastDebounceTimeD = currentTime;
    }
}

Explanation:

  • Debounce Delay: The debounceDelay constant defines the minimum time between valid interrupts. Adjust this value based on your specific setup and sensor characteristics.
  • Last Debounce Time: For each encoder input, a separate lastDebounceTime variable is used to track the last time a valid interrupt was processed.
  • Millis Function: The millis() function is used to get the current time in milliseconds since the Arduino started. This allows you to check how much time has passed since the last valid interrupt.

Additional Considerations:

  • Hardware Debouncing: If possible, consider adding hardware debouncing using capacitors or Schmitt triggers to further improve reliability.
  • Signal Integrity: Ensure that your wiring and connections are solid to prevent noise and false triggers.

By implementing this debouncing mechanism, you should see improved reliability in your encoder readings. Let me know if you have any further questions or need additional assistance!

Best regards, Athena


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
#44  

Hello @Athena and all interested members, Your contribution has provided me success!  I can now run various distances and stop within 2 inches of my desired point.  Most of the time my robot stopped within 1 inch of the desired point.  I have tested out to distances of 8'.  I am very satisfied with the results.  I did tweak the code to adjust the (debounceDelay) individually for each motor and encoder.  This allowed me to capture the most ticks without picking up noise which would cause my counts to become inconsistent.   Thanks for all the help you have provided, and to @DJ for enabling you to perform this very necessary assistance. Jack

PRO
Canada
#45  

Hello Jack,

I'm thrilled to hear about your success! It's fantastic that you've achieved such precise control over your robot's movements. Adjusting the debounce delay for each motor and encoder was a smart move, allowing you to fine-tune the system for optimal performance.

If you have any more questions or need further assistance in the future, feel free to reach out. Keep up the great work with your robotics projects, and enjoy the journey of innovation and discovery!

Best regards, Athena


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
#46  

Hello @Athena,

I am trying to total my encoder counts on the Arduino first and then when they reach a certain Total number send this sum to my EZB4. Can you please look at my attached code for the Arduino and assist in rewriting it so that both encoder counts are totaled and when it reaches a predetermined number sends this number to the EZB4? Thankyou, Jack

volatile int AencoderValue_A = 0;
volatile int AencoderValue_B = 0;
volatile int BencoderValue_A = 0;
volatile int BencoderValue_B = 0;

volatile unsigned long AencoderTot = 0;
volatile unsigned long BencoderTot = 0;
volatile unsigned long AB_EncoderTot = 0;

volatile unsigned long lastDebounceTimeA = 0;
volatile unsigned long lastDebounceTimeB = 0;
volatile unsigned long lastDebounceTimeC = 0;
volatile unsigned long lastDebounceTimeD = 0;

const unsigned long LeftMotFwdSensDebounceDelay = 5; // LeftMotorFwdSens debounce delay in milliseconds 4
const unsigned long LeftMotAftSensDebounceDelay = 5; // LeftMotorAftSens debounce delay in milliseconds 4
const unsigned long RightMotFwdSensDebounceDelay = 5; // RightMotorFwdSens debounce delay in milliseconds 5
const unsigned long RightMotAftSensDebounceDelay = 5; // RightMotorAftSens debounce delay in milliseconds 5

void setup() {
    Serial3.begin(9600); // Communication with EZ-B
    Serial.begin(9600);  // Debugging via Serial Monitor

    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);
    pinMode(20, INPUT_PULLUP);
    pinMode(21, INPUT_PULLUP);

    attachInterrupt(digitalPinToInterrupt(2), AcountA, FALLING);
    attachInterrupt(digitalPinToInterrupt(3), AcountB, FALLING);
    attachInterrupt(digitalPinToInterrupt(20), BcountA, FALLING);
    attachInterrupt(digitalPinToInterrupt(21), BcountB, FALLING);
}

void loop() {
    if (Serial3.available() > 0) {
            // Read the incoming data from the EZ-B
            int incomingByte = Serial3.read();
             delay(5);

            // Print the received command as a character
            Serial.print("---------: ");
            Serial.println((char)incomingByte);
    
        if (incomingByte == 'r') {    // Receive char "r" to detach interrupts and zero out all Value Holders.
            detachInterrupt(digitalPinToInterrupt(2));   //Detach Aencoder interrupt.
            detachInterrupt(digitalPinToInterrupt(3));   //Detach Aencoder interrupt.
            AencoderValue_A = 0;   // Zero out Aencoder AA,AB Value Holders.
            AencoderValue_B = 0;
            
            attachInterrupt(digitalPinToInterrupt(2), AcountA, FALLING);  //Attach Aencoder.  Begin interrupts Left/Right Motors using Fwd Sensors
            attachInterrupt(digitalPinToInterrupt(3), AcountB, FALLING);

            detachInterrupt(digitalPinToInterrupt(20));   //Detach Bencoder interrupt.
            detachInterrupt(digitalPinToInterrupt(21));   //Detach Bencoder interrupt.
            BencoderValue_A = 0;   //Zero out Bencoder BA,BB Value Holders.
            BencoderValue_B = 0;
    
          

          void loop() {
          
            detachInterrupt(digitalPinToInterrupt(2));   //Detach Aencoder interrupt.
            detachInterrupt(digitalPinToInterrupt(3));   //Detach Aencoder interrupt.
          
            attachInterrupt(digitalPinToInterrupt(20), BcountA,FALLING);   //Attach Bencoder. Begin interrupts Left/Right Motors using Aft Sensors
            attachInterrupt(digitalPinToInterrupt(21), BcountB,FALLING);
           AencoderTot = ( AencoderValue_A +  AencoderValue_B);
            Serial.print( "AencoderTot:   ");
            Serial.println(AencoderTot, DEC);
            //Serial3.write((byte)(AencoderValue_A >> 8)); // High byte   //Write AencoderA/B.
           //Serial3.write((byte)(AencoderValue_A & 0xFF)); // Low byte
           // Serial3.write((byte)(AencoderValue_B >> 8)); // High byte
           // Serial3.write((byte)(AencoderValue_B & 0xFF)); // Low byte
            
            // Print the encoder values to the Serial Monitor
            //Serial.print("LeftMot-Encoder_Fwd: ");   //Print AencoderA/B.
            //Serial.println(AencoderValue_A, DEC); // Use DEC to print as decimal
           // Serial.print("RightMot-Encoder_Fwd: ");
            //Serial.println(AencoderValue_B, DEC); // Use DEC to print as decimal
           //delay(10);

            AencoderValue_A = 0;   //Zero out AencoderA/B.
            AencoderValue_B = 0;

           
           
            detachInterrupt(digitalPinToInterrupt(20));   //Detach BencoderValue_A interrupt.
            detachInterrupt(digitalPinToInterrupt(21));   //Detach BencoderValue_B interrupt.

            attachInterrupt(digitalPinToInterrupt(2), AcountA, FALLING);  // Attach AencoderA/B   Begin interrupts Left/Right Motors using Fwd Sensors
            attachInterrupt(digitalPinToInterrupt(3), AcountB, FALLING);
             BencoderTot = (BencoderValue_A + BencoderValue_B);
             Serial.print( "BencoderTot:   ");
            Serial.println(BencoderTot, DEC);  
            //Serial3.write((byte)(BencoderValue_A >> 8)); // High byte   Write BencoderA/B.
            //Serial3.write((byte)(BencoderValue_A & 0xFF)); // Low byte
            //Serial3.write((byte)(BencoderValue_B >> 8)); // High byte
            //Serial3.write((byte)(BencoderValue_B & 0xFF)); // Low byte
            
            // Print the encoder values to the Serial Monitor
           //Serial.print("LeftMot-Encoder_Aft: ");   //Print BencoderA/B.
            //Serial.println(BencoderValue_A, DEC); // Use DEC to print as decimal
           // Serial.print("RightMot-Encoder_Aft: ");
            //Serial.println(BencoderValue_B, DEC); // Use DEC to print as decimal
            //delay(10);

            BencoderValue_A = 0;   //Zero out BencoderA/B.     
            BencoderValue_B = 0;

             AB_EncoderTot = ( AB_EncoderTot + (AencoderTot + BencoderTot));
             if ("AB_EncoderTot" >= 1000) {
              Serial3.write((byte)(AB_EncoderTot >> 8));
              Serial3.write((byte)(AB_EncoderTot & 0xFF)); 
              Serial.print("AB_EncoderTot: ");
              Serial.println(AB_EncoderTot, DEC);
              //delay(10000);
               
         
    }
}
}
    }
}
void AcountA() {    //Left Motor Fwd Sensor  Pin2
    unsigned long currentTime = millis();
    if ((currentTime - lastDebounceTimeA) > LeftMotFwdSensDebounceDelay) {
        AencoderValue_A++;
        lastDebounceTimeA = currentTime;
    }
}

void AcountB() {    //Right Motor Fwd Sensor  Pin3
    unsigned long currentTime = millis();
    if ((currentTime - lastDebounceTimeB) > RightMotFwdSensDebounceDelay) {
        AencoderValue_B++;
        lastDebounceTimeB = currentTime;
    }
}

void BcountA() {    //Left Motor Aft Sensor  Pin20
    unsigned long currentTime = millis();
    if ((currentTime - lastDebounceTimeC) > LeftMotAftSensDebounceDelay) {
        BencoderValue_A++;
        lastDebounceTimeC = currentTime;
    }
}

void BcountB() {    //Right Motor Aft Sensor  Pin21
    unsigned long currentTime = millis();
    if ((currentTime - lastDebounceTimeD) > RightMotAftSensDebounceDelay) {
        BencoderValue_B++;
        lastDebounceTimeD = currentTime;
    }
}
PRO
Canada
#47  

Hello Jack,To achieve your goal of totaling the encoder counts and sending the sum to the EZB4 when it reaches a predetermined number,let's refine your code a bit.Here's a revised version of your Arduino code:```cpp volatile int AencoderValue_A = 0; volatile int AencoderValue_B = 0; volatile int BencoderValue_A = 0; volatile int BencoderValue_B = 0; volatile unsigned long AencoderTot = 0; volatile unsigned long BencoderTot = 0; volatile unsigned long AB_EncoderTot = 0; volatile unsigned long lastDebounceTimeA = 0; volatile unsigned long lastDebounceTimeB = 0; volatile unsigned long lastDebounceTimeC = 0; volatile unsigned long lastDebounceTimeD = 0; const unsigned long LeftMotFwdSensDebounceDelay = 5; const unsigned long LeftMotAftSensDebounceDelay = 5; const unsigned long RightMotFwdSensDebounceDelay = 5; const unsigned long RightMotAftSensDebounceDelay = 5; const unsigned long targetCount = 1000; // Set your target count here

void setup() { Serial3.begin(9600); // Communication with EZ-B Serial.begin(9600); // Debugging via Serial Monitor pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); pinMode(20, INPUT_PULLUP); pinMode(21, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(2), AcountA, FALLING); attachInterrupt(digitalPinToInterrupt(3), AcountB, FALLING); attachInterrupt(digitalPinToInterrupt(20), BcountA, FALLING); attachInterrupt(digitalPinToInterrupt(21), BcountB, FALLING); }

void loop() { // Total the encoder counts AencoderTot = AencoderValue_A + AencoderValue_B; BencoderTot = BencoderValue_A + BencoderValue_B; AB_EncoderTot = AencoderTot + BencoderTot;

// Check if the total count has reached the target
if (AB_EncoderTot >= targetCount) {
    // Send the total count to the EZB4
    Serial3.write((byte)(AB_EncoderTot >> 8)); // High byte
    Serial3.write((byte)(AB_EncoderTot & 0xFF)); // Low byte
    Serial.print("AB_EncoderTot: ");
    Serial.println(AB_EncoderTot, DEC);

    // Reset the encoder values
    AencoderValue_A = 0;
    AencoderValue_B = 0;
    BencoderValue_A = 0;
    BencoderValue_B = 0;
    AB_EncoderTot = 0;
}

}

void AcountA() { unsigned long currentTime = millis(); if ((currentTime - lastDebounceTimeA) > LeftMotFwdSensDebounceDelay) { AencoderValue_A++; lastDebounceTimeA = currentTime; } }

void AcountB() { unsigned long currentTime = millis(); if ((currentTime - lastDebounceTimeB) > RightMotFwdSensDebounceDelay) { AencoderValue_B++; lastDebounceTimeB = currentTime; } }

void BcountA() { unsigned long currentTime = millis(); if ((currentTime - lastDebounceTimeC) > LeftMotAftSensDebounceDelay) { BencoderValue_A++; lastDebounceTimeC = currentTime; } }

void BcountB() { unsigned long currentTime = millis(); if ((currentTime - lastDebounceTimeD) > RightMotAftSensDebounceDelay) { BencoderValue_B++; lastDebounceTimeD = currentTime; } }

### Key Changes:
- **Target Count:** Added a `targetCount` constant to define the threshold for sending the total count to the EZB4.
- **Total Calculation:** The total encoder counts are calculated in the `loop()` function.
- **Condition Check:** The code checks if the total count has reached the target and sends the count to the EZB4 if it has.
- **Reset:** After sending the count, the encoder values are reset to start counting again.

This code should help you achieve the desired functionality. Let me know if you have any further questions or need additional assistance!

I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
#48  

Hello @Athena, Could you please resend in sketch form so that I can "copy and paste" it to my Arduino IDE? Thanks Jack