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

ARC Pro is your passport to a world of endless possibilities in robot programming, waiting for you to explore.

PRO
Canada
#49  

Certainly,Jack!Below is the Arduino sketch formatted for easy copying and pasting into your Arduino IDE:```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; } }

You can copy this code and paste it directly into your Arduino IDE to upload it to your Arduino Mega 2560.Feel free to reach out if you have any more questions or need further 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.
#50  

Hello @Athena, I'm sorry to say that the code keeps coming back in paragraph form.   Could you please try again to send it in copy and paste form? Thanks Jack

PRO
Canada
#51  

Certainly,Jack!Here's the Arduino sketch formatted for easy copying and pasting into your Arduino IDE:

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;
    }
}

You should be able to copy this code and paste it directly into your Arduino IDE. Let me know if you need any more help!


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.
#52  

Hello @Athena, Got it now! Thank you. Jack

PRO
Canada
#53  

You're welcome,Jack!I'm glad it worked out for you.If you have any more questions or need further assistance,feel free to reach out.Happy coding!


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.
#54  

Hello @Athena, I have tried to simplify the task for the Arduino.  I would like to:

1.  Send the " AB_EncoderTot" number from the EZB4 to the Arduino. This number will change from time to time. 2.  Start the "AencoderValue_A" and "AencoderValue_B" counting for "AB_EncoderTot". 3.  Reaching the AB_EncoderTot number, have the Arduino send via UART a "char" to the EZB4. 4.  The EZB4 continuously polling for this "char" from the Arduino. 4.  When the EZB4 receives this "char", it shuts down the PWM to the motors.

I have included a basic code for the Arduino.   Could you assist me with an Arduino Sketch and an EZB4 Script that will perform these functions listed 1-4.

Thank you again, Jack

volatile int AencoderValue_A = 0;
volatile int AencoderValue_B = 0;
volatile unsigned long AB_EncoderTot = 0;
volatile unsigned long lastDebounceTimeA = 0;
volatile unsigned long lastDebounceTimeB = 0;
const unsigned long LeftMotFwdSensDebounceDelay = 5;
const unsigned long RightMotFwdSensDebounceDelay = 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);
    attachInterrupt(digitalPinToInterrupt(2), AcountA, FALLING);
    attachInterrupt(digitalPinToInterrupt(3), AcountB, FALLING);
}

void loop() {

    AB_EncoderTot = AB_EncoderTot + ( AencoderValue_A + AencoderValue_B);
     AencoderValue_A = 0;
     AencoderValue_B = 0;
       
    
    // Check if the total count has reached the target
    if (AB_EncoderTot >= targetCount) {

     //SEND A CHARACTER ONLY TO EZB4  NO ENCODER TOTALS

        // 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
        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;
    }
}

PRO
Canada
#55  

Certainly,Jack!Let's break down the task into two parts:the Arduino sketch and the EZB4 script.

Arduino Sketch

This sketch will: 1.Receive the target count from the EZB4. 2.Count the encoder pulses. 3.Send a character to the EZB4 when the target count is reached.

volatile int AencoderValue_A = 0;
volatile int AencoderValue_B = 0;
volatile unsigned long AB_EncoderTot = 0;
volatile unsigned long lastDebounceTimeA = 0;
volatile unsigned long lastDebounceTimeB = 0;
const unsigned long LeftMotFwdSensDebounceDelay = 5;
const unsigned long RightMotFwdSensDebounceDelay = 5;
unsigned long targetCount = 1000; // Default target count

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

void loop() {
    // Check if there is data available to read from EZ-B
    if (Serial3.available() > 0) {
        targetCount = Serial3.parseInt(); // Read the target count
    }

    AB_EncoderTot += (AencoderValue_A + AencoderValue_B);
    AencoderValue_A = 0;
    AencoderValue_B = 0;

    // Check if the total count has reached the target
    if (AB_EncoderTot >= targetCount) {
        Serial3.write('T'); // Send a character to EZ-B
        Serial.print("AB_EncoderTot: ");
        Serial.println(AB_EncoderTot, DEC);
        AB_EncoderTot = 0; // Reset the encoder total
    }
}

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;
    }
}

EZB4 Script

This script will: 1.Send the target count to the Arduino. 2.Poll for the character from the Arduino. 3.Shut down the PWM to the motors when the character is received.

// Set the target count
var targetCount = 1000; // Change this value as needed

// Send the target count to Arduino
UART.sendSerialString(D0, 9600, targetCount.toString());

// Continuously poll for the character from Arduino
while (true) {
    if (UART.available(D0) > 0) {
        var receivedChar = UART.readString(D0, 1);
        if (receivedChar == 'T') {
            // Shut down the PWM to the motors
            PWM.set(D1, 0); // Set PWM to 0 on the motor control pin
            PWM.set(D2, 0); // Set PWM to 0 on the motor control pin
            break; // Exit the loop
        }
    }
    sleep(100); // Polling interval
}

Notes:

  • Ensure that the UART port and baud rate match between the Arduino and EZB4.
  • Adjust the targetCount and PWM pins as needed for your setup.
  • The Arduino sketch uses Serial3 for communication with the EZB4, so ensure the correct wiring.

Let me know if you need further 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.
#56  

Hello @Athena, Thank you for your continued support. Attached is the EZB4 script.

// Set the target count
var targetCount = 1000; // Change this value as needed

// Send the target count to Arduino
UART.sendSerialString(D0, 9600, targetCount.toString());

Digital.set(d21, false, 0);
Digital.set(d22, true, 0);
Digital.set(d20, true, 0);
Digital.set(d19, false, 0);
// Set the PWM output to a value between 0% and 100%
PWM.Set(d23, 19, 0);

// Set the PWM output to a value between 0% and 100%
PWM.Set(d18, 15, 0);

// Continuously poll for the character from Arduino
while (true) {
    if (UART.available(D0) > 0) {
        var receivedChar = UART.readString(D15, 1);
        if (receivedChar == 'T') {
            // Shut down the PWM to the motors
            PWM.set(d23, 0); // Set PWM to 0 on the motor control pin
            PWM.set(d18, 0); // Set PWM to 0 on the motor control pin
            break; // Exit the loop
        }
    }
    sleep(100); // Polling interval
}

I get the following error message:

Execution Error Line 5 Col 0 - Capability 'Transmit Uart TX on all digital ports' is not supported on this EZB device.
Done (00:00:00.0208065)

Can you please help me fix the EZB4 script? Thanks Jack