[英]ESP32 SPI/i2c/xTask interference/instability
我目前正在制作一个高带宽发射器,在 LoRa 和 NRF24 模块上传播 ADS1115 数据,但是,我遇到了很多任务调度程序问题和 i2c 的不稳定行为(用于 ADC,两个发射器都使用 SPI)。 我正在尝试在一个核心上读取和处理数据并在另一个核心上传输数据。 当 ADS1115 一起返回 -1 或 ~32k 时,这两个进程单独工作时效果很好,但一起工作时却不能一起工作,有时当一起工作时,NRF 模块会停止传输。 这是最小的工作代码:
// flag to indicate that a packet was received
volatile bool transmittedFlag = true;
void IRAM_ATTR setFlag(void) {
// packet transmission is finished, set the flag
transmittedFlag = true;
}
void AttemptTrans() {
lora.setDio0Action(setFlag);
while (true) {
if (transmittedFlag || digitalRead(DIO0)) {
int state = lora.startTransmit((uint8_t*)(&LoRaData), sizeof(Data));
if (state != ERR_NONE) {
Serial.print(F("failed, code: "));
Serial.println(state);
}
else {
data.counter++;
transmittedFlag = false;
}
}
if (nrf.txFIFOEmpty()) { //Custom function: read_register(FIFO_STATUS) & _BV(TX_EMPTY);
nrf.writeFast(&data, sizeof(Data), 0);
data.counter++;
}
}
}
int ads_counter = 0;
void ADSFunc(){
while (true) {
uint32_t input = REG_READ(GPIO_IN_REG);
if (input && 0x400000) { //Digital read on pin 22
ads.setMultiplexer(ads_counter + 4);
ADS_RAW[ads_counter] = ads.getConversion(false);
ads_counter = (ads_counter + 1) % 4;
}
}
}
任务已添加到以下代码段中:
disableCore1WDT();
xTaskCreatePinnedToCore((TaskFunction_t)ADSFunc, "ads", stackSize2, NULL, 1, &ADSHandle, 0);
xTaskCreatePinnedToCore((TaskFunction_t)AttemptTrans, "LoRaTX", stackSize, NULL, 1, &LoRaHandle, 1);
什么有效:
什么不起作用:
eTaskGetState(ADSHandle)
来检查的当前理论:SPI 和 i2c 总线之间存在资源冲突,这会锁定一个阻塞 ADS 线程的互斥体? 当您解决此问题时,i2c 总线会吐出随机值
我觉得我已经尝试了一切,所以我只是希望这是一个资源冲突,并且是一个简单的解决方法的已知问题! 任何帮助深表感谢!
ESP32 I2C 库中的任务线程和 I2C 似乎存在一些奇怪的问题。 这里提到它但没有给出解决方案。 我在通过 I2C 从不同线程读取 BME 280 温度传感器时遇到问题,即使我有一个互斥锁来避免同时读取传感器。 我发现,如果我在每个线程中连续两次读取传感器,第二次读取总是可靠的,只有线程中的第一次读取往往会给出错误的读数。 所以我现在就这样做,即使它只是一个 hack。 不确定这是否对您有帮助。
我过去遇到过同样的问题。
这很可能是由于传输期间电源线上的电压下降以及微芯片逻辑的相关故障造成的。 因此,这是一个电子问题而不是编程问题。
原因是发射器请求的电流峰值会迅速导致电源线上的电压下降。
在 GND 和 Vcc 之间焊接一个 10 µF 电容器很容易解决(注意电容器的极性)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.