c# - 使用 Windows IOT 的 RPi 和 Arduino Uno 之间的 I2C 连接问题
问题描述
第一个 StackOverflow 问题,所以希望它是一个体面的问题。我正在使用 RPi 和 Arduino 板制作传感器网络。我过去使用 Raspbian 完成了此操作,但现在必须使用 Windows IOT 完成此操作。
Arduino Uno 板使用 I2C 通信连接到 Raspberry Pi。问题是我的 C# 代码产生了“无法识别从属地址”错误。
RPi 被配置为主机,而 Arduino 被配置为从机。没有逻辑电压转换器,但它应该在此配置中正常工作,如下所示:
当我能拿到一个双向电压转换器时,我会使用它。
我尝试了以下方法:
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 资源非常稀缺。
解决方案
@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
}
推荐阅读
- c# - 异步 API 方法
- java - Java 音频更改采样率
- python - .fit() | RuntimeError:批处理列表中的每个元素都应具有相同的大小
- c - 如何将此临时 char* 变量复制到我的结构中以进行更永久的存储?
- python - Django Forms - 该选择不是可用的选择之一
- python - 如果在 first_valid_date 之后,则从数据帧中获取布尔数据帧,否则为 false
- xml - XSLT 2.0:根据 for-each -group 的当前索引评估和修改元素值
- python - 如何在 beam.combiners.Sample.FixedSizePerKey 中设置种子
- batch-file - 是否可以在 Type | 中限制要搜索的行?查找操作
- google-cloud-platform - GCP - 根据源 IP 地址配置负载平衡器路由