I2C communication wrong value returned | arduino nano 33 iot & Raspberry pi 4b

I want to communicate an raspberry pi 4b(Master) and a arduino nano 33 iot (Slave).
The raspberry gets an input number from the user, then sends that number over i2c to the arduino, and the arduino only need to add 1 to it and send it back.

Everything seems to work but here is the issue, i get the same number returned without 1 being added up.

I get two adresses 0x60 and 0x6a, but i only get 0x6a to work.
I connected everything as shown in the picture below (I'm sorry that i cannot pick the right components in the schematic).
The Resistors are 1k ohm.

Already thank you if you want to help.

Schematic

CODE FOR THE ARDUINO

#include <Arduino.h>
#include <Wire.h>

#define SLAVE_ADDRESS 0x6a

int entry = 0;

void readData(int numBytes) {
 while (Wire.available()) {
   entry = Wire.read();
   Serial.print("Getal gekregen: ");
   Serial.println(entry);
   Serial.println("------------");
 }
}

void sendData() {
  Serial.print("Getal na +1: ");
  Serial.println(entry + 1);
  Serial.println("------------");
  Wire.write(entry + 1);
}

void setup() {
  Wire.begin(SLAVE_ADDRESS); // Connect met het goede i2c address
  Wire.onReceive(readData); // Functie voor wanneer data word gegeven
  Wire.onRequest(sendData); // Fucntie voor wanneer data word opgevraagd
  Serial.begin(9600); // Start Serial voor de output
  Serial.println("I2C is Ready!");
}

void loop() {
}

CODE FOR THE RASPBERRY (Pyhton)

from smbus2 import SMBus
import time


channel = 1

addr = 0x6a
i2c_reg = 0x00

bus = SMBus(channel)

print("Enter a value: ")
entry_str = input(">>>>>   ")
entry = int(entry_str)
print("Dit is er ingevoerd: ", entry)
bus.write_byte_data(addr, i2c_reg, entry)
time.sleep(0.5)

read = bus.read_byte_data(addr, 1)
time.sleep(0.5)
print("Dit word er gelezen: ", read)

The I2C bus is not a good bus to transfer data between a Arduino board and a Raspberry Pi.
If you use a USB cable to connect the Arduino board to the Raspberry Pi, then you can use the Serial communication over USB.

Why do you use 1k pullup resistors ? Do you have 10k resistors ?

The Nano 33 IoT has a security chip and a IMU.
Can you run a I2C Scanner sketch on the Nano 33 IoT ? Then you know that their I2C addresses are, so you can avoid those.
I would set the Arduino at 0x08.

Your test code is too complex. Start with something simple.
Return a byte, and increase that byte every time it is requested.

volatile byte myCounter;

void sendData() {
  Wire.write(myCounter);
  myCounter++;
}

When you want to write (binairy) data, it is often easier to print a hexadecimal number:

volatile byte entry;

void readData(int numBytes) 
{
  if (numBytes == 1)       // expecting a single byte
  {
    entry = Wire.read();
    Serial.print( "0x");
    if (entry < 0x10)
      Serial.print ("0");
    Serial.print (entry, HEX);
    Serial.print (",");
  }
  else
  {
    Serial.println( "Error, more than 1 byte");
  }
}

If that works, then you can try to send for example 'A', and try to read 'B'.
If that works, then maybe you can try to type something in the Python input.

1 Like

The I2C bus is not a good bus to transfer data between a Arduino board and a Raspberry Pi.
If you use a USB cable to connect the Arduino board to the Raspberry Pi, then you can use the Serial communication over USB.

I've read that I2C isn't the best option, but I wanted to challenge myself, so I could learn.

Why do you use 1k pullup resistors ? Do you have 10k resistors ?

Those were the biggest I had for grab, and I thought the principle would still be the same.

The Nano 33 IoT has a security chip and a IMU.
Can you run a I2C Scanner sketch on the Nano 33 IoT ? Then you know that their I2C addresses are, so you can avoid those.
I would set the Arduino at 0x08.

I runned the scanner, and here is where it went wrong, I think.

Of all the information, I've read that you need to use the address you find, as stated in the question I found, 0x60 and 0x6a.

Tried both and best result was with the 0x6a.

But that is indeed the IMU, I didn't know that for the arduino I had to choose an empty address.

I'm going to be honest, I tried my code with an free address and it worked!

Yaay!

Thank you very much, I misunderstood the address part for the arduino.

But now Iā€™m going to try some simpler things.
Again thank you!

The sink current for the I2C bus (to pull a signal low) is maximum 3 mA.
When you have 1k pullup resistors, then the sink current is 3.3V/1k = 3.3mA. That is too much, your I2C bus is no longer a I2C bus.

1 Like

I had not heard/read anything about it, so I'll dig a bit deeper in it.
Their is still a long way to go for me then.
Again thank you for all the information!

I have written a few things on Github: How to make a reliable I2C bus.

1 Like