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
Canada
#9  

Hello Jack,

To ensure that the Arduino is sending the correct data over UART and to verify what is being sent, you can modify the Arduino sketch to print both the data being sent and the data being received. This will help you debug the issue and understand what is happening.

Here's a modified version of your Arduino code that prints the data being sent over UART to 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 known test values for verification
            int testValueA = 42; // Test value for Encoder A
            int testValueB = 84; // Test value for Encoder B

            Serial.write(testValueA);
            Serial.write(testValueB);

            // Print the test values to the Serial Monitor
            Serial.print("Sent Encoder A: ");
            Serial.println(testValueA);
            Serial.print("Sent Encoder B: ");
            Serial.println(testValueB);

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

void countA() {
    encoderValue_A++;
}

void countB() {
    encoderValue_B++;
}

Key Changes:

  • Print Sent Values: The code now prints the test values being sent over UART to the Serial Monitor. This will help you verify what is being transmitted.
  • Corrected Print Statements: Ensure that the Serial.print() and Serial.println() functions are used correctly to print the received and sent data.

Next Steps:

  • Check the Serial Monitor: Run the Arduino sketch and observe the Serial Monitor. It should display the received command and the test values being sent.
  • Verify UART Communication: Ensure that the EZ-B is correctly set up to receive data over UART. Double-check the connections and settings.

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.
PRO
Synthiam
#10  

It looks like you’re trying to use the serial0 as both communication and debugging. If your ardunio has more than one uart, you’ll need to use one for debugging output to the monitor and another for communication to an ezb.

if you’re not wanting to use an ezb, you’ll need to figure out how to have two connections to the pc from the arduino - if you still want to debug.

but the script is very simple and the misunderstanding is two fold I think

  1. write the correct number of bits over serial from arduino for the size of the data type
  2. read the correct number of bits in ARC JavaScript from serial and reassemble to the correct data type

@athena can explain more.

PRO
Canada
#11  

Hello Jack,

DJ_Sures has pointed out a crucial aspect of using UART for both debugging and communication. Let's address the two main points:

1. Use Separate UARTs for Debugging and Communication

If your Arduino has multiple UARTs (like the Arduino Mega), you can use one for communication with the EZ-B and another for debugging with the Serial Monitor. Here's how you can set it up:

  • Serial0: Use this for communication with the EZ-B.
  • Serial1: Use this for debugging output to the Serial Monitor.

2. Correctly Handle Data Types Over Serial

When sending data over serial, it's important to ensure that the correct number of bits are written and read. Here's how you can modify your code to handle this:

Arduino Code

int encoderValue_A = 0;
int encoderValue_B = 0;

void setup() {
    Serial.begin(9600); // Communication with EZ-B
    Serial1.begin(9600); // Debugging with Serial Monitor
    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();
        Serial1.print("Received: ");
        Serial1.println((char)incomingByte);

        // Command 'a' indicates transmitting the current values and resetting the counters
        if (incomingByte == 'a') {
            delay(50);
            // Send the encoder values as two bytes each
            Serial.write((byte)(encoderValue_A >> 8)); // High byte
            Serial.write((byte)(encoderValue_A & 0xFF)); // Low byte
            Serial.write((byte)(encoderValue_B >> 8)); // High byte
            Serial.write((byte)(encoderValue_B & 0xFF)); // Low byte

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

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

void countA() {
    encoderValue_A++;
}

void countB() {
    encoderValue_B++;
}

JavaScript in ARC

When reading the data in ARC, you need to reassemble the bytes into integers:

var highByteA = UART.readByte(0); // Read high byte of Encoder A
var lowByteA = UART.readByte(0);  // Read low byte of Encoder A
var encoderValue_A = (highByteA << 8) | lowByteA; // Combine bytes

var highByteB = UART.readByte(0); // Read high byte of Encoder B
var lowByteB = UART.readByte(0);  // Read low byte of Encoder B
var encoderValue_B = (highByteB << 8) | lowByteB; // Combine bytes

print("Encoder A: " + encoderValue_A);
print("Encoder B: " + encoderValue_B);

Key Points:

  • Separate UARTs: Use different UARTs for communication and debugging.
  • Data Handling: Ensure that you send and receive the correct number of bytes for your data type.

By following these steps, you should be able to debug and communicate effectively with your Arduino and EZ-B. 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.
#12  

Hello @Athena,

Thank you very much for your help.  Thank you, DJ, for framing the question more clearly.  It seems between printing to the Serial Monitor and Writing to the EZB4 on the same UART path, a collision of sorts was scrambling the data.

I have been unsuccessful in pasting the ARC code you provided to my current ARC code as printed below:

// 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();

@Athena could you incorporate your recommended ARC code into the above EZB4 script?  Many thanks, Jack

PRO
Canada
#13  

Hello Jack,Let's integrate the recommended ARC code into your existing script to ensure it works seamlessly with your Arduino setup. Here's how you can modify your ARC script:

// 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 >= 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 encoderValue_A = (highByteA << 8) | lowByteA; // Combine bytes
        
        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 encoderValue_B = (highByteB << 8) | lowByteB; // Combine bytes
        
        // Print the encoder values
        print("Encoder A: " + encoderValue_A);
        print("Encoder B: " + encoderValue_B);
    } 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:

  • Data Availability Check: Ensure that at least 4 bytes are available before reading, as each encoder value consists of 2 bytes.
  • Reading Bytes: Use UART.hardwareUartRead(0, 1)[0] to read each byte individually and combine them to form the encoder values.

Next Steps:

  • Run the Script: Load this script into ARC and run it to see if it correctly reads and prints the encoder values.
  • Verify Connections: Ensure that the Arduino and EZ-B are properly connected and configured for UART communication.

By following these steps, you should be able to successfully read and print the encoder values from your Arduino. If you encounter any issues or need further 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.
#14  

Hello @Athena, Thanks again for your help.  The ARC script successfully polls the Arduino and Prints the Encoder_A  and Encoder_B values.  That is super!

However, the Serial Monitor prints gibberish in one line.  No Encoder values at all.   Could you look at the following Arduino code and help me figure out why no Encoder values are printing to the Serial Monitor?

int encoderValue_A = 0;
int encoderValue_B = 0;

void setup() {
    Serial.begin(9600); // Communication with EZ-B
    Serial1.begin(9600); // Debugging with Serial Monitor
    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();
        Serial1.print("Received: ");
        Serial1.println((char)incomingByte);

        // Command 'a' indicates transmitting the current values and resetting the counters
        if (incomingByte == 'a') {
            delay(50);
            // Send the encoder values as two bytes each
            Serial.write((byte)(encoderValue_A >> 8)); // High byte
            Serial.write((byte)(encoderValue_A & 0xFF)); // Low byte
            Serial.write((byte)(encoderValue_B >> 8)); // High byte
            Serial.write((byte)(encoderValue_B & 0xFF)); // Low byte

            delay(50);

            // Print the encoder values to the Serial Monitor
            Serial1.print("Sent Encoder A: ");
            Serial1.println(encoderValue_A);
            Serial1.print("Sent Encoder B: ");
            Serial1.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
#15  

Hello Jack,It seems like the issue might be related to how the data is being sent to the Serial Monitor.Lets make sure that the data is being printed correctly to Serial1 for debugging.Here are a few things to check and modify in your Arduino code:### 1. Ensure Correct Data Type for Serial1 Printing When printing to the Serial Monitor,ensure that the data is being sent as a string or a format that the Serial Monitor can interpret correctly.### 2. Modify the Arduino Code Heres an updated version of your Arduino code with some adjustments to ensure proper printing to the Serial Monitor:cpp int encoderValue_A = 0;int encoderValue_B = 0;void setup(){ Serial.begin(9600);// Communication with EZ-B Serial1.begin(9600);// Debugging with Serial Monitor 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();Serial1.print(Received:);Serial1.println((char)incomingByte);// Command a indicates transmitting the current values and resetting the counters if(incomingByte == a){ delay(50);// Send the encoder values as two bytes each Serial.write((byte)(encoderValue_A 8));// High byte Serial.write((byte)(encoderValue_A 0xFF));// Low byte Serial.write((byte)(encoderValue_B 8));// High byte Serial.write((byte)(encoderValue_B 0xFF));// Low byte delay(50);// Print the encoder values to the Serial Monitor Serial1.print(Sent Encoder A:);Serial1.println(encoderValue_A,DEC);// Use DEC to print as decimal Serial1.print(Sent Encoder B:);Serial1.println(encoderValue_B,DEC);// Use DEC to print as decimal // Reset the encoder values encoderValue_A = 0;encoderValue_B = 0;} } } void countA(){ encoderValue_A++;} void countB(){ encoderValue_B++;}### Key Changes:- Use DEC in Serial1.println():This ensures that the encoder values are printed as decimal numbers,which should be readable in the Serial Monitor.### Next Steps:- Upload the modified code to your Arduino.- Open the Serial Monitor and ensure that the baud rate is set to 9600 to match the Serial1.begin(9600); setting.- Check the Serial Monitor for the printed encoder values.By following these steps,you should be able to see the encoder values printed correctly in the Serial Monitor.If you continue to experience issues,please let me know!


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

Hello @Athena,

Can you please resend the last post and separate the code for copy and paste? Thanks, Jack