I2C strange characters at end of char after wire.read

I have two mega boards and want to set up a simulation but before I do that I need to ensure that the master and slave acknowledge each other and then wait. I have a test master code which sends a message but the slave shows the message with some odd characters at the end of the received message. I can't find anything by search.

Master code

#include <Wire.h>

#define I2C_SLAVE_ADDRESS 0x08

void setup() {
    Wire.begin(); // Join I2C bus as master
    Serial.begin(9600);
    Serial.println("Master device ready.");

    delay(5000); // Give some time for the slave to be ready

    sendHandshake();
}

void loop() {
    // Placeholder for logic after handshake
}

void sendHandshake() {
    Serial.println("Attempting to send HANDSHAKE to car");
    Wire.beginTransmission(I2C_SLAVE_ADDRESS);
    Wire.write("HANDSHAKE");
    Wire.endTransmission();
    Serial.println("Sent HANDSHAKE to car");

    delay(500); // Short delay to ensure the car has time to respond

    Wire.requestFrom(I2C_SLAVE_ADDRESS, 1);
    if (Wire.available()) {
        char response = Wire.read();
        Serial.print("Response from car: ");
        Serial.println(response);
        if (response == '1') {
            Serial.println("Handshake acknowledged by car");
        }
    } else {
        Serial.println("No response from car");
    }
}

slave code

#include <Wire.h>

void setup() {
    Wire.begin(0x08); // Join I2C bus as slave with address 0x08
    Wire.onReceive(receiveEvent); // Register event handler for receiving data
    Serial.begin(9600); // Start serial communication for debugging
    Serial.println("Slave device ready.");
}

void loop() {
    // Placeholder for logic after receiving the handshake
}

void receiveEvent(int howMany) {
    delay(50); // Ensure all data is received before processing
    char buffer[10];
    int i = 0;
    while (Wire.available() && i < sizeof(buffer) - 1) {
        buffer[i++] = Wire.read();
    }
   // buffer[i] = '\0'; // Null-terminate the string
// with this buffer line above all I get is a char 're' as the message. so i remmed it out for now
    Serial.print("Received message: ");
    Serial.println(buffer);

    String message = String(buffer);
    if (message == "HANDSHAKE") {
        Serial.println("Received HANDSHAKE from master");
        Wire.beginTransmission(0x08);
        Wire.write('1'); // Respond to handshake
        Wire.endTransmission();
        Serial.println("Sent HANDSHAKE response to master");
    } else {
        Serial.println("Unexpected message received.");
    }
}

Output Master:
Master device ready.

Attempting to send HANDSHAKE to car

Sent HANDSHAKE to car

Response from car: //a square block here

Output slave:
Slave device ready.

Received message: HANDSHAKE�.

Unexpected message received.

I have two pullup resistors 2.2k on the scl and sda lines using shielded rj45 cable between the two devices.

Any help would be much appreciated. Apologies if I haven't explained well enough.
Regards in advance

I think you need this. Where this returns
Wire.write("hello\n")
You should use
Wire.write("1")

You have not declared any Wire.onRequest() handler in the slave code.

In the slave code, you are not terminating the buffer with a null.

Why is the slave device trying to send a transmission to itself?

my code does this already, did I miss a point?

I am just adding your points to the code. note that I did add a comment in the slave code about the end of line null.

No, it doesn't. The receiveEvent() only receives. No Wire.write there!
The onRequest event sends.

Thank you for that advise, it was awesome.
Now the messaging is:
slave Slave device ready.
Received message: HANDSHAKE
Received HANDSHAKE from master
Sent HANDSHAKE response to master

master:
Master device ready.

Attempting to send HANDSHAKE to car

Sent HANDSHAKE to car

No response from car, retrying...

Attempting to send HANDSHAKE to car

Sent HANDSHAKE to car

No response from car, retrying...

Attempting to send HANDSHAKE to car

Sent HANDSHAKE to car

Response from car: 1

Handshake acknowledged by car

Handshake complete, ready to start traffic light sequence.

Should I now post the updated code?

Yes, post it That would be good if anyone else has the same challenge.

Here follows the updated code:

Master:

#include <Wire.h>

#define I2C_SLAVE_ADDRESS 0x08

bool handshakeComplete = false;

void setup() {
    Wire.begin(); // Join I2C bus as master
    Serial.begin(9600);
    Serial.println("Master device ready.");

    delay(5000); // Give some time for the slave to be ready

    while (!handshakeComplete) {
        sendHandshake();
        delay(2000); // Retry every two seconds until handshake is complete
    }
    Serial.println("Handshake complete, ready to start traffic light sequence.");
}

void loop() {
    // Placeholder for logic after handshake is complete
}

void sendHandshake() {
    Serial.println("Attempting to send HANDSHAKE to car");
    Wire.beginTransmission(I2C_SLAVE_ADDRESS);
    Wire.write("HANDSHAKE");
    Wire.endTransmission();
    Serial.println("Sent HANDSHAKE to car");

    delay(500); // Short delay to ensure the car has time to respond

    Wire.requestFrom(I2C_SLAVE_ADDRESS, 1);
    while (Wire.available()) {
        char response = Wire.read();
        Serial.print("Response from car: ");
        Serial.println(response);
        if (response == '1') {
            Serial.println("Handshake acknowledged by car");
            handshakeComplete = true; // Set handshakeComplete to true
            break;
        }
    }
    if (!handshakeComplete) {
        Serial.println("No response from car, retrying...");
    }
}

Slave:

#include <Wire.h>

void setup() {
    Wire.begin(0x08); // Join I2C bus as slave with address 0x08
    Wire.onReceive(receiveEvent); // Register event handler for receiving data
    Wire.onRequest(requestEvent); // Register event handler for master requests
    Serial.begin(9600); // Start serial communication for debugging
    Serial.println("Slave device ready.");
}

void loop() {
    // Placeholder for logic after receiving the handshake
}

void receiveEvent(int howMany) {
    char buffer[10];
    int i = 0;
    while (Wire.available() && i < sizeof(buffer) - 1) {
        buffer[i++] = Wire.read();
    }
    buffer[i] = '\0'; // Null-terminate the string

    Serial.print("Received message: ");
    Serial.println(buffer);

    String message = String(buffer);
    if (message == "HANDSHAKE") {
        Serial.println("Received HANDSHAKE from master");
    } else {
        Serial.println("Unexpected message received.");
    }
}

void requestEvent() {
    Wire.write('1'); // Respond to handshake
    Serial.println("Sent HANDSHAKE response to master");
}

Thank you very much for your patience and your time today.

No problem! I like to see things work.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.