简体   繁体   中英

I2C communication Raspberry Pi 3 and Arduino

(sorry for bad English, I'm German)

Hello programmers,

I'm trying (without success) to send data from an Raspberry Pi 3(master) to an Arduino(slave):

Here's my updated Arduino Code:

#include <Wire.h>
volatile bool flag = false;
void wireHandler(int numBytes)
{
  flag = true;
}
void setup()
{
  pinMode(13, OUTPUT);
  Wire.begin(0x23);
  Wire.onReceive(wireHandler);
}
void loop()
{
  delay(100);
  digitalWrite(13, flag);
}

My Raspy code (C++, g++ main.cpp -lwiringPi):

#include <iostream>
#include <wiringPi.h>
#include <wiringPiI2C.h>
int main(void)
{
    if(wiringPiSetup() == -1)
    {
        std::cerr << "wiringPiSetup() == -1\n";
        return 1;
    }
    if(wiringPiI2CSetup(0x39) == -1) //is 0x39 correct?
    {
        std::cerr << "wiringPiI2CSetup(int) == -1\n";
        return 1;
    }
    while(true)
    {
        wiringPiI2CWrite(0x23, 0x23);
        delay(100);
    }
}

In theory this should make the Arduino Led (pin 13) blink. However the led stays dark.

I would be thankful if anyone could explain me why this program does not work and how to fix it.

And yes I2C is activated in Raspi-Config.

The Wire.onReceive() handler is called from ISR handler and therefore all other ISRs are blocked. Including the one counting millis and without it, delay() can't work as it's relying on millis .

For example some volatile variable should be updated by this event and handled in loop() , as ISR handlers must be as short as possible.

For example this one will light if received byte LSB is 1.

#include <Wire.h>

volatile byte recv = 0;

void setup() {
  Wire.begin(0x23);               // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  //Serial.begin(57600);          // start serial for output
  pinMode(13,OUTPUT);
}

void loop() {
  delay(10);
  digitalWrite(13, recv);
}

void receiveEvent(int howMany) {
  while (Wire.available()) { 
    byte c = Wire.read();
    recv = c & 1; // just last character and its LSB will be used
  }
}

On the other side is another arduino (as I just don't have RPi) sending incrementing byte sequence. One value every 500ms. This makes the first arduino blink:

#include <Wire.h>

void setup() {
  Serial.begin(57600);
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop() {
  Wire.beginTransmission(0x23); // transmit to device #8
  Wire.write(x);              // sends one byte
  byte error = Wire.endTransmission();     // stop transmitting

  Serial.print("Sent: ");
  Serial.print(x,DEC);
  Serial.print(" ");
  Serial.println(error, DEC);

  x++;
  delay(500);
}

But basically only 0 or 1 value can be sent to turn off or turn on the led.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM