Arduino-AirMCU icon indicating copy to clipboard operation
Arduino-AirMCU copied to clipboard

I2c作为从机,被主机用requestFrom读取时异常

Open luckycheng2017 opened this issue 2 years ago • 7 comments

描述一下这个bug / Describe the bug

手里有一个ESP32和AIR001的板子,ESP32作主机,AIR001作为从机。ESP32用requestFrom方法,不能正常触发从机AIR001的onRequest注册的方法。但是两个ESP32分别作主机和从机,主机能够正常读取从机的数据。

复现步骤 / To Reproduce

从机先复位,然后主机复位,主机能找到从机的地址,但是不能读到从机的数据。

如果正常,应该是什么样 / Expected behavior

正常ESP32主机能够读取到AIR001从机发过来的数据。

截图 / Screenshots

ESP32主机的代码 ` #include <Wire.h>

byte i = 0;

uint8_t hello[] = "hello"; uint8_t aTxBuffer[] = "你好";

void setup() { Wire.setClock(100000); Wire.begin(4, 5);

Serial.begin(9600); Serial.println("\nI2C Scanner");

byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 1; address < 127; address++ ) { Wire.beginTransmission(address); // Wire.write(aTxBuffer, sizeof(aTxBuffer)); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) { Serial.print("0"); } Serial.println(address,HEX); nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) { Serial.print("0"); } Serial.println(address,HEX); }
} if (nDevices == 0) { Serial.println("No I2C devices found\n"); } else { Serial.println("done\n"); }

}

void loop() { byte error; byte address = 0x33; int len = Wire.requestFrom((uint16_t) address, (uint8_t) 6); if (len > 0) { Serial.printf("接收长度:%d\n", len); while (Wire.available() > 1) { char c = Wire.read(); Serial.print(c); } char x = Wire.read(); Serial.println(x); } Serial.println("");

delay(2000); }

`

AIR001从机代码 `#include <Wire.h>

#define I2C_ADDR 0x33

uint8_t hello[] = "hello"; uint8_t aTxBuffer[] = "你好";

// function that executes whenever data is received from master // this function is registered as an event, see setup() void myReceive(int howMany) { while(1 < Wire.available()) // loop through all but the last { char c = Wire.read(); // receive byte as a character Serial.println(c); // print the character } int x = Wire.read(); // receive byte as an integer Serial.println(x); // print the integer }

// function that executes whenever data is requested by master // this function is registered as an event, see setup() void myRequest() { Serial.println("收到请求"); Wire.write(0x01); // respond with message of 6 bytes // as expected by master }

void setup() { Serial.begin(9600); // start serial for output

Wire.setSDA(PF_0); Wire.setSCL(PF_1); Wire.setClock(100000); Wire.begin(I2C_ADDR); // join i2c bus with address #4 Wire.onRequest(myRequest); // register event Wire.onReceive(myReceive); // register event }

void loop() { //empty loop } `

日志 / Logs

这是主机的日志 1693141197589

系统 / System

Win10

PACK包版本 / Version

0.4.5

验证

  • [x] 检查过该问题,之前没有人提过 / Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
  • [X] 提供了最小可复现工程或详细的复现步骤,确保开发者可以复现 / The provided reproduction is a minimal reproducible example of the bug.
  • [X] 已经提供了完整的报错信息、日志、截图,没有经过删减。

luckycheng2017 avatar Aug 27 '23 13:08 luckycheng2017

此问题似乎是HAL库的中断逻辑问题,待进一步排查

HalfSweet avatar Aug 29 '23 13:08 HalfSweet

遇到相同问题,air001 做为从机时,确实I2C通讯不正常。同样的程序换块主板通讯就正常了,望解决....

YFROBOTZL avatar Sep 05 '23 01:09 YFROBOTZL

这个BUG啥时候能解决,看ISSUES有人测试成功了啊,但是我AIR001做从机的时候就没正常过。

cqdadalele avatar Sep 15 '23 08:09 cqdadalele

请问官方停止维护air-duino了么,这个bug貌似一直没解决。

TiElectronic avatar Oct 24 '23 01:10 TiElectronic

虽然我没有正确的解决问题,但是我发现,真的可以读了呢! 我用了一个错误的方法!复制别人代码的时候复制错了, 本来应该是一个接收回调函数,然后一个发送回调函数。然后把发送回调函数复制成了错误回调函数。然后获取地址就正常了。因为没有注意看函数名, 我在里面添加了发送数据,然后奇迹般的主机还能获取数据。测试了几万次吧,没有死机。大概获取速度0.5ms。 当我发现我回调函数错了,我改成了发送回调。然后就一直不成功,我一度怀疑人生,实在没得办法,我点撤回到我之前成功的状态,然后他又成功了,我才发现,是错误的回调函数,导致了他正确。也就是说每次这个机器都报错了,但是在报错这里把数据发出去,是可行的。 求大佬们,搞一个正确的方法啊。 int x=1; void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) { BSP_LED_Toggle(0); aTxBuffer[0]=x>>8; aTxBuffer[1]=x&0xFF; x++; HAL_I2C_Slave_Transmit_IT(&I2cHandle, (uint8_t *)aTxBuffer, DARA_LENGTH); }

cqdadalele avatar Dec 31 '23 07:12 cqdadalele

如果使用原生sdk开发的话,见 https://github.com/openLuat/luatos-soc-air001/tree/master/ModuleDemo/I2C/Example_HAL/I2C_TwoBoard_CommunicationSlave_IT

HalfSweet avatar Dec 31 '23 07:12 HalfSweet

如果使用原生sdk开发的话,见 https://github.com/openLuat/luatos-soc-air001/tree/master/ModuleDemo/I2C/Example_HAL/I2C_TwoBoard_CommunicationSlave_IT

原生SDK的IIC例程我就没跑起来。。。

wx85105157 avatar Jan 07 '24 16:01 wx85105157