首页 > 解决方案 > 使用 Windows IOT 的 RPi 和 Arduino Uno 之间的 I2C 连接问题

问题描述

第一个 StackOverflow 问题,所以希望它是一个体面的问题。我正在使用 RPi 和 Arduino 板制作传感器网络。我过去使用 Raspbian 完成了此操作,但现在必须使用 Windows IOT 完成此操作。

Arduino Uno 板使用 I2C 通信连接到 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.)使用 C# 在 Windows IOT 和 Arduino Nano 之间进行 I2C 连接 2.) 检查 RPi 和 Arduino 之间的连接(SDA 到 SDA 和 SCL 到 SCL 3.) 添加 3.3V 上拉电阻 4) Raspberry pi 2 和 BMP280:Slave地址未被确认 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 操作系统相比,WIOT 资源非常稀缺。

标签: c#arduinoi2cwindowsiot

解决方案


@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
}

推荐阅读