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

Experience early access to the latest features and updates. You'll have everything that is needed to unleash your robot's potential.

PRO
Canada
#1  

Hello Jack,

The issue you're encountering with the "XX" characters appearing as square boxes in the Serial Monitor is likely due to the way you're sending the encoder values over the serial connection. The Serial.write() function sends data as raw bytes, which can result in non-printable characters being displayed as squares or other symbols in the Serial Monitor.

To resolve this, you should use Serial.print() instead of Serial.write() for sending the encoder values. This will ensure that the values are sent as human-readable text. Here's how you can modify your code:

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

Key Changes:

  • Use Serial.print() and Serial.println(): These functions are used to send data as text, which is more suitable for displaying in the Serial Monitor.
  • Check for Serial.available() > 0: This ensures that there is data available to read before attempting to read it.

By making these changes, the encoder values should be displayed correctly in the Serial Monitor without any unwanted characters. If you have any further questions or need additional assistance, feel free to ask!


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

Hello @Athena,

Thank you for helping me.  The Serial Monitor prints beautifully now.

Please look at the JavaScript below that is polling the Arduino.

// Initialize UART on port 0 with a baud rate of 9600
UART.initHardwareUart(0, 9600);

function loop() {
    // Define the string to send
    var stringToSend = "a";

    // Send a request for data to the Arduino
    UART.hardwareUartWriteString(0, stringToSend);
    print("Sent: " + stringToSend + " to Arduino");

    // Wait a bit for the data to be transmitted
    sleep(100);

    // Check if data is available
    var dataAvail = UART.hardwareUartAvailable(0);
    print("Data available: " + dataAvail);

    if (dataAvail != 2) {
        print("The Arduino didn't send us anything. Exiting");
        return; // Exit the loop
    } else {
        // Read 2 bytes of data from the UART
        var encoders = UART.hardwareUartRead(0, 2);

        // Print the encoder values
        print("Encoder A: " + encoders[0]);
        print("Encoder B: " + encoders[1]);
    }

    // Wait before the next loop iteration
    sleep(100);

    // Call the loop function again
    loop();
}

// Start the loop
loop();

When I run the script in my EZB4, it always exits and prints, "Data available  45".  "The Arduino didn't send us anything. Exiting".  All the while the Arduino Serial Monitor is printing the correct Encoder_A  and Encoder_B  values. Why won't my EZB4 script Print the Encoder_A and Encoder_B values?

Thanks  Jack

PRO
Canada
#3  

Hello Jack,

The issue you're encountering seems to be related to the way the data is being read from the UART. The UART.hardwareUartAvailable(0) function is returning a value of 45, which suggests that there is data available, but it might not be in the expected format or length. Let's go through a few steps to troubleshoot and resolve this issue:

  1. Check Data Format: Ensure that the data being sent from the Arduino is in the expected format. Since you're expecting two bytes, make sure the Arduino is sending exactly two bytes for the encoder values.

  2. Adjust Data Reading: Since the UART.hardwareUartAvailable(0) is returning 45, it indicates that there might be more data available than expected. You might want to read all available data and then parse it.

  3. Modify the JavaScript Code: Let's adjust the code to read all available data and then process it.

Here's an updated version of your JavaScript code:

// Initialize UART on port 0 with a baud rate of 9600
UART.initHardwareUart(0, 9600);

function loop() {
    // Define the string to send
    var stringToSend = "a";
    
    // Send a request for data to the Arduino
    UART.hardwareUartWriteString(0, stringToSend);
    print("Sent: " + stringToSend + " to Arduino");
    
    // Wait a bit for the data to be transmitted
    sleep(100);
    
    // Check if data is available
    var dataAvail = UART.hardwareUartAvailable(0);
    print("Data available: " + dataAvail);
    
    if (dataAvail < 2) {
        print("The Arduino didn't send us enough data. Exiting");
        return; // Exit the loop
    } else {
        // Read all available data from the UART
        var encoders = UART.hardwareUartRead(0, dataAvail);
        
        // Ensure we have at least 2 bytes
        if (encoders.length >= 2) {
            // Print the encoder values
            print("Encoder A: " + encoders[0]);
            print("Encoder B: " + encoders[1]);
        } else {
            print("Received data is not in the expected format.");
        }
    }
    
    // Wait before the next loop iteration
    sleep(100);
    
    // Call the loop function again
    loop();
}

// Start the loop
loop();

Key Changes:

  • Read All Available Data: The script now reads all available data and checks if it contains at least two bytes.
  • Check Data Length: Before accessing the encoder values, the script checks if the received data has the expected length.

By making these changes, the script should be able to handle varying amounts of data and correctly parse the encoder values. If you continue to experience issues, please ensure that the Arduino is sending the data in the expected format and that there are no additional characters being sent.

Feel free to reach out 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.
#4  

Hello @Athena,

My JavaScript code prints, " Encoder A    82"   and   "Encoder B   101". The DataAvailable prints 43.
These are not the values printed in the Arduino Serial Monitor. They are typically in the 30-50 range. I wonder if the Arduino code printed below is actually sending the correct value for Encoder_A and Encoder_B? Is Serial.println(encoderValue_A) and Serial.println(encoderValue_B) the correct commands to send over UART?

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

Thank you, Jack

PRO
Canada
#5  

Hello Jack,

The issue you're experiencing is due to the way the data is being sent from the Arduino. The Serial.print() and Serial.println() functions send data as human-readable text, which includes additional characters like the label text ("Encoder A:") and newline characters. This is not suitable for binary data transmission over UART, where you expect to receive raw byte values.

To send the encoder values as raw bytes, you should use the Serial.write() function instead. This will ensure that only the numeric values are sent without any additional formatting. Here's how you can modify your Arduino code:

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 as raw bytes
            Serial.write(encoderValue_A);
            Serial.write(encoderValue_B);

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

void countA() {
    encoderValue_A++;
}

void countB() {
    encoderValue_B++;
}

Key Changes:

  • Use Serial.write(): This function sends the encoder values as raw bytes, which is suitable for binary data transmission over UART.
  • Remove Labels: The labels ("Encoder A:" and "Encoder B:") are removed to ensure only the numeric values are sent.

By making these changes, the Arduino will send the encoder values as raw bytes, and your JavaScript code should be able to read them correctly. If you have any further questions or need additional assistance, feel free to ask!


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

Hello @Athena, The JavaScript still prints the same numbers for Encoder_A and Encoder_B.. Of course the Arduino sketch no longer prints any values for Encoder_A and Encoder_B. How can I be sure what the Ardunio is sending over UART? The Arduino code is printed below:

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 as raw bytes
            Serial.write(encoderValue_A);
            Serial.write(encoderValue_B);

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

void countA() {
    encoderValue_A++;
}

void countB() {
    encoderValue_B++;
}

Thanks, Jack

PRO
Canada
#7  

Hello Jack,

To ensure that the Arduino is sending the correct data over UART, you can take the following steps:

  1. Verify Data Transmission: Use a simple test to verify what the Arduino is sending over UART. You can temporarily modify the Arduino code to send known values and check if they are received correctly.

  2. Use a Serial Monitor: Use a serial monitor tool to directly observe the raw data being sent over UART. This can help you verify the exact bytes being transmitted.

  3. Modify the Arduino Code for Testing: Temporarily modify the Arduino code to send a known sequence of bytes. This will help you verify if the data is being sent and received correctly.

Here's a modified version of your Arduino code for testing purposes:

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 known test values for verification
            Serial.write(42);  // Test value for Encoder A
            Serial.write(84);  // Test value for Encoder B

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

void countA() {
    encoderValue_A++;
}

void countB() {
    encoderValue_B++;
}

Key Changes:

  • Test Values: The code now sends known test values (42 and 84) for Encoder A and Encoder B. This will help you verify if the data is being received correctly on the other end.

Next Steps:

  • Check the Output: Run your JavaScript code and check if it receives the test values (42 and 84). If it does, the issue might be with how the encoder values are being sent.
  • Use a Serial Monitor: Use a serial monitor tool to observe the raw data being sent over UART. This will help you verify the exact bytes being transmitted.

By following these steps, you should be able to verify what the Arduino is sending over UART and ensure that the data is being received correctly. If you have any further questions or need additional assistance, feel free to ask!


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

Hello @Athena,

The Arduino code you provided prints   "   *TReceived:    a   "  .   Instead of    "Received:   a   ".  Why is the code not printing  "Received: a "  ?

Also, the test numbers are not received over UART by the EZB4.  Can you provide an Arduino sketch that will Serial Print to the monitor just what is sent over UART?

Thanks, Jack