Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Received I2C data is mangled #8390

@Merlin83b

Description

@Merlin83b

CircuitPython version

Adafruit CircuitPython 8.2.4 on 2023-08-22; TinyS3 with ESP32S3

Code/REPL

import time
import board
from adafruit_bus_device.i2c_device import I2CDevice


def read_i2c(send="123"):
    ret = "nothing"
    try:
        with board.I2C() as i2c:
            device = I2CDevice(i2c, 0x08)
            br = bytearray('yyyyyy', 'ascii')
            with device:
                print(f"sending {send}")
                device.write_then_readinto(send, br)
            ret = br
    except Exception as e:
        print(f"{type(e)}: {e}")

    return ret

send = bytearray(1)
send = "123"

while True:
    print("I2Cing in 1 second...")
    time.sleep(1)
    r = read_i2c(send)
    print(f"Sent {send}, got {r}")

    time.sleep(5)

Behavior

Posting as an issue as suggested at https://forums.adafruit.com/viewtopic.php?p=985515#p985515

The printed output should be
Sent 123, got bytearray(b'3\x00\x00\x00\x00\x00')
But instead is
bytearray(b'"\x00\x00\x00\x00\x00')

Description

No response

Additional information

I am sending some code over I2C to an ATTiny85 which is configured with a sketch to read it all in, then send back 6 bytes, the first of which is the final byte from the sent code. The idea was just to confirm that I could get I2C to work between the two chips, but CircuitPython seems to mangling the received the code.

The code running on the ATTiny is:

#include <Wire.h>

char rcvd = 0;

void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Wire.onRequest(requestEvent); // register event
}

void loop() {
  delay(100);
}

void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character
  }
  rcvd = Wire.read();    // receive byte as an integer
}

void requestEvent() {
  char buf[6] = "xxxxxx";
  sprintf(buf, "%c      ", rcvd);
  Wire.write(buf); // respond with message of 6 bytes
}

Running Arduino on the TinyS3 with a sketch to do similar to the CircuitPython behaves correctly. Here is that sketch:

#include <Wire.h>

void setup() {
  Serial.begin(9600);
  Wire.begin(7); // join i2c bus (address optional for master)
  Wire.onReceive(receiveEvent);
}

byte x = 0;

void loop() {
  Serial.println("I2Cing in 1 second...");
  delay(1000);
  Wire.beginTransmission(8); // transmit to device #8
  Wire.write("123");        // sends five bytes
  Wire.endTransmission(false);    // stop transmitting

  Wire.requestFrom(8, 6);    // request 6 bytes from slave device #8

  Serial.print("Sent 123, received ");

  while (Wire.available()) { // slave may send less than requested
    char c = Wire.read(); // receive a byte as character
    Serial.print("\\x");
    Serial.print(c, HEX);         // print the character
  }

  Wire.endTransmission();

  Serial.print("\n");

  delay(5000);
}

void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

Which gives the expected output:

Sent 123, received \x33\x20\x20\x20\x20\x20

Further, using a login analyzer on the I2C pins shows the correct data on the wire.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions