0

I am trying to send data sent from my Arduino Uno to my Raspberry Pi 4 by way of I2C. I seem to be able to send data without issue from the Uno, BUT the data is not being read in on the Raspberry Pi 4. I have done different permutations of the below code, nothing seems to be working.

In the code below, I set the slave process to 0x08. I know the RPi can see it,

i2cdetect -y 1 # returns 08

Many different websites suggest using gpio and WiringPi, but these are no longer available?

Here is the code for the Arduino:

#include <Wire.h>

byte val = 0;

void setup() {
  Serial.begin(9600);
  Serial.print(" Starting slave ");
  Wire.begin();
}

void loop() {
  Wire.beginTransmission(0x08);
  Wire.write(val++);
  Serial.print("sent: "); Serial.println(val-1);
  Wire.write(val++);
  Serial.print("sent: "); Serial.println(val-1);
  Wire.write(val++);
  Wire.endTransmission();

  delay(500);
}

and here is my C++ code for the Raspberry Pi 4:

#include <unistd.h> //Needed for I2C port
#include <fcntl.h> //Needed for I2C port
#include <sys/ioctl.h> //Needed for I2C port
#include <linux/i2c-dev.h> //Needed for I2C port

#include <cstring>
#include <cstdio>
#include <iostream>

using namespace std;


int main() {
    int file_i2c;
    int length;
    unsigned char buffer[60] = {0};

    //----- OPEN THE I2C BUS -----
    char *filename = (char*) "/dev/i2c-1";

    cout << "Starting the program \n";
    if ((file_i2c = open(filename, O_RDWR)) < 0) {
        cerr << "Failed to open the i2c bus\n";
        return -1;
    }

    int addr = 0x08; //<<<<<The I2C address of the slave
    if (ioctl(file_i2c, I2C_SLAVE, addr) < 0) {
        cerr << "Failed to acquire buss access and / or talk to slave.\n";
        return -1;
    }

    //----- READ BYTES -----
    while (true) {
        length = 24; //<<< Number of bytes to read
        if (read(file_i2c, buffer, length) != length) {
            //ERROR HANDLING: i2c transaction failed
            cerr << "Failed to read from the i2c bus\n";
        }
        else {
            if (strlen((char*)buffer))
                printf("Data read: %s -> %d\n", buffer, strlen((char*)buffer));
        }
    }
}

Thanks for your help!

1 Answer 1

0

This is not how I2C works.

In UART communication you have two more-or-less equal devices that communicate with each other, and they can both send whenever they want to (barring flow control and so on).

This is NOT the case in I2C. In I2C you have one master and a number of slaves (or whatever terminology you want to use), and all communication have to be initiated by the master. You are trying to make a RPi master read from an Arduion master write - that will never work.

On the bright side, then the Arduino Wire library actually seems to support setting the Arduino up as a slave device by using the onReceive() and onRequest() to register callback functions.

Read here: https://docs.arduino.cc/learn/communication/wire and look at the Controller Reader and Controller Writer examples. In both examples you want to look at the Peripheral sketch part.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.