使用Windows IOT的RPi和Arduino Uno之间的I2C连接问题

时间:2019-12-07 13:40:51

标签: c# arduino i2c windowsiot

第一个StackOverflow问题,希望它是一个不错的问题。 我正在使用RPi和Arduino开发板建立传感器网络。我过去使用Raspbian做到了这一点,但现在必须使用Windows IOT做到这一点。

使用I2C通信将Arduino Uno开发板连接到Raspberry Pi。问题是我的C#代码产生“无法识别从站地址”错误。

RPi被配置为主设备,而Arduino被配置为从设备。没有逻辑电压转换器,但是按照以下配置,它应该可以正常工作:

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

当我可以使用双向电压转换器时,将使用它。

我尝试了以下方法:

1。)I2C connection between Windows IOT and Arduino Nano using C# 2.)检查RPi和Arduino之间的连接(从SDA到SDA和SCL到SCL 3.)添加3.3V上拉电阻 4)Raspberry pi 2 and BMP280 : Slave address was not acknowledged 5.)更改Arduino的从站地址 6.)换掉Arduino和RPi,以防引脚被烧断 7.)以数字方式将Arduino引脚写为低电平,以防它们干扰i2c通信

这是相应的Arduino代码:

//**********************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();
}

这是RPi的相应C#方法

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

            }

任何帮助将不胜感激,因为与其他IOT OS相比,WIOT资源非常稀缺。

1 个答案:

答案 0 :(得分:0)

@ MichaelXu-MSFT和@jdweng谢谢您的帮助。我解决了这个问题。 Arduino代码具有不必要的wire.beginTransmission和wire.endTransmission语句,这似乎是用于在i2c上将数据从主设备发送到从设备,而我却配置了主设备来从从设备请求数据。仅在sendData()ISR中使用wire.write(data,length)length函数就可以了。我强烈推荐http://www.gammon.com.au/i2c,因为他在自己的网站上拥有出色的i2c资源。

更正如下:

void sendData()
{

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

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

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