简体   繁体   中英

I2C Connection Issue between RPi and Arduino Uno using Windows IOT

first StackOverflow question so hopefully its a decent one. I'm in the process of making a sensor network using RPi's and Arduino boards. I have done this in the past using Raspbian but now have to do it using Windows IOT.

The Arduino Uno boards are connected to the Raspberry Pi using I2C communication. The problem is that my C# code produces a "Slave address is not recognized" error.

The RPi is configured as a master and the Arduino as a slave. There is no logic voltage converter, but it should work fine in this configuration as per:

https://create.arduino.cc/projecthub/phantom_override/arduino-i2c-ommunication-with-raspi-2-wiot-63d599?ref=user&ref_id=11763&offset=0

Will use a bidirectional voltage converter when I can get my hands on one.

I have tried the following:

1.) I2C connection between Windows IOT and Arduino Nano using C# 2.) Checking the connections between the RPi and the Arduino (SDA to SDA and SCL to SCL 3.) Adding 3.3V pullup resistors 4) Raspberry pi 2 and BMP280 : Slave address was not acknowledged 5.) Changing the slave address of the Arduino 6.) Swapping the both the Arduino and RPi out in case the pins were blown 7.) Digitally writing the Arduino pins low in case they were interfering with the i2c commmunication

Here is the corresponding Arduino Code:

//**********************Libraries**********************
#include <Wire.h>

//*********************Definitions*********************
 #define SERIAL Serial
#define SLAVE_ADDRESS 0x40 

//********************Global Variables*******************
float humidity, temperature, temp, motion;

byte      ReceivedData[4];
byte      Response[4]; 
bool      DataReceived;


//Analoge Pin setup 
int clockFrequency = 100000;

//***********************************Setup******************************

void setup(){
      //digitalWrite(SCL, 0);
      //digitalWrite(SDA, 0);

      //i2c communication setup

      Wire.begin(SLAVE_ADDRESS);
      Wire.onReceive(receiveData);
      Wire.onRequest(sendData);
      //Wire.setClock(clockFrequency);

      //Baud rate
      Serial.begin(9600);

      dht.begin();  
}



//*********************************Loop*********************************
void loop()
{

  getSensors();  
  delay(100);

}

void getSensors() 
{

     //sensors data retrieved 

      Response[0]=(byte)humidity;
      Response[1]=(byte)temperature;
      Response[2]=(byte)proximity;
      Response[3]=(byte)motion;

}  

void sendData()
{

      Wire.beginTransmission(SLAVE_ADDRESS);

      //Loop to iterate i2c transmissions

      for (int i = 0; i <= 3; i++) { 
      Wire.write((uint8_t *)Response[i], sizeof(Response));
      }  

      Wire.endTransmission();
}

And here is the corresponding C# methods for the RPi

private async Task InitI2C()
        {
            var settings = new I2cConnectionSettings(0x40); // Arduino address
            settings.BusSpeed = I2cBusSpeed.StandardMode;
            string aqs = I2cDevice.GetDeviceSelector("I2C1");
            var dis = await DeviceInformation.FindAllAsync(aqs);
            _device = await I2cDevice.FromIdAsync(dis[0].Id, settings);

        } 

 private async Task GetArduino()
        {
            try
            {
                byte[] ReadBuf = new byte[32];
                _device.Read(ReadBuf);

                //convert buffer into floats here

            }

Any help would be greatly appreciated as WIOT resources are quite scarce compared to other IOT OS's.

@MichaelXu-MSFT and @jdweng Thank you for your help. I worked out the problem. The Arduino code had unnecessary wire.beginTransmission and wire.endTransmission statements, which seem to be for sending data from master to slave on i2c, whereas I had a configuration of the master device requesting data from the slave. Just using the wire.write(data, length) length function in the sendData() ISR did the trick. I highly recommend http://www.gammon.com.au/i2c , as he has excellent i2c resources on his site.

The correction is as follows:

void sendData()
{

      //Wire.beginTransmission(SLAVE_ADDRESS); remove this statement

      Wire.write(Response, sizeof(Response));

      //Wire.endTransmission(); remove this statement as well
}

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