Closed chinswain closed 6 years ago
@chinswain The ISR executes on the core that it was registered on. The ISR is registered during the first Wire.endTransmission()
or Wire.requestFrom()
.
The Bus_Busy
status is created/monitored by the hardware. The I2C hardware monitors the signal on the i/o pins, it does not know which core is accessing it. I don't see how this error could be generated by using different cores. Check your pullups.
Chuck.
Sorry chuck, didn't even think about that... I have a logic analyser and oscilloscope on the way which should help tune the pull ups.
This module has 10k pull ups built in (seem fine on their own, does having two i2c interfaces have any impact on the pull ups required or do the same rules apply to each?), I'll remove them and test with some lower ones (DIP version also ordered).
On a related note, I've managed to get i2c over 10 metres with the latest changes!
Fixed code for reference:
#include <Wire.h>
#include "Adafruit_MCP23017.h"
int rpmPin = 0;
static volatile uint16_t rpmcounter;
Adafruit_MCP23017 mcp;
TaskHandle_t Task1;
void checkRpmPins() {
static bool lastPinState;
if (mcp.digitalRead(rpmPin) != lastPinState) {
lastPinState = !lastPinState;
if (lastPinState) {
rpmcounter++;
}
}
}
void coreTask( void * parameter)
{
mcp.begin(); // use default address 0
mcp.pinMode(0, INPUT);
mcp.pullUp(0, HIGH);
while (true) {
vTaskDelay(1);
checkRpmPins();
}
}
void setup() {
Serial.begin(115200);
xTaskCreatePinnedToCore(
coreTask, /* Function to implement the task */
"coreTask", /* Name of the task */
10000, /* Stack size in words */
NULL, /* Task input parameter */
0, /* Priority of the task */
&Task1, /* Task handle. */
0); /* Core where the task should run */
delay(100);
}
void loop() {
static unsigned long lastmillis = 0;
int rpm;
if (millis() - lastmillis >= 1000) {
lastmillis = millis();
rpm = rpmcounter * 30;
rpmcounter = 0;
Serial.print("fan ");
Serial.print(": ");
Serial.print(rpm);
Serial.print("\t");
Serial.println();
}
}
@chinswain i2c was designed for usage on one board with a total bus length < 1m. With a long bus, pullup values must be calibrated to bus capacitance. They make transceivers/ bus extenders for long lines. You could be seeing crosstalk, reflection spikes, good luck.
Chuck.
@stickbreaker I'm using a pair of P82B715 break outs to boost the current. Once the oscilloscope arrives I can start some proper calibration.
Hi ! @stickbreaker I have met the same question: if i creat the task on Core (1)or run the function in the loop, i can get the right datas from the I2C bus (the sensor: MAX30102). However ,if i creat the task on Core (0),the question appears: here it the log: [E][esp32-hal-i2c.c:630] i2cDumpI2c(): i2c=0x3ffc10cc [E][esp32-hal-i2c.c:641] i2cDumpI2c(): dev=0x60013000 date=0x16042000 level=VERBOSE [E][esp32-hal-i2c.c:643] i2cDumpI2c(): lock=0x3ffd2a8c [E][esp32-hal-i2c.c:645] i2cDumpI2c(): num=0 [E][esp32-hal-i2c.c:646] i2cDumpI2c(): mode=1 [E][esp32-hal-i2c.c:647] i2cDumpI2c(): stage=3 [E][esp32-hal-i2c.c:648] i2cDumpI2c(): error=5 [E][esp32-hal-i2c.c:649] i2cDumpI2c(): event=0x3ffd2b10 bits=112 [E][esp32-hal-i2c.c:650] i2cDumpI2c(): intr_handle=0x3ffea498 [E][esp32-hal-i2c.c:651] i2cDumpI2c(): dq=0x3ffd2b40 [E][esp32-hal-i2c.c:652] i2cDumpI2c(): queueCount=1 [E][esp32-hal-i2c.c:653] i2cDumpI2c(): queuePos=0 [E][esp32-hal-i2c.c:654] i2cDumpI2c(): byteCnt=1 [E][esp32-hal-i2c.c:604] i2cDumpDqData(): [0] ae W STOP buf@=0x3ffc50aa, len=1, pos=1, eventH=0x0 bits=0 [E][esp32-hal-i2c.c:620] i2cDumpDqData(): 0x0000: . 00 [E][esp32-hal-i2c.c:968] i2cDumpInts(): 0 row count INTR TX RX [E][esp32-hal-i2c.c:971] i2cDumpInts(): [01] 0x0001 0x0202 0x0002 0x0000 0x000034b9 [E][esp32-hal-i2c.c:971] i2cDumpInts(): [02] 0x0001 0x0040 0x0000 0x0000 0x000034b9 [E][esp32-hal-i2c.c:971] i2cDumpInts(): [03] 0x0001 0x0020 0x0000 0x0000 0x000034b9 [I][esp32-hal-i2c.c:1002] i2cProcQueue(): Bus busy, reinit [E][esp32-hal-i2c.c:1246] i2cReleaseISR(): Error releasing ISR=258 [E][Wire.cpp:137] initHardware(): invalid state sda=0, scl=1
[E][Wire.cpp:155] initHardware(): Bus Invalid State, TwoWire() Can't init [E][esp32-hal-i2c.c:1193] i2cProcQueue(): Busy Timeout start=0x3532, end=0x3532, =0, max=50 error=1 [E][esp32-hal-i2c.c:630] i2cDumpI2c(): i2c=0x3ffc10cc [E][esp32-hal-i2c.c:641] i2cDumpI2c(): dev=0x60013000 date=0x16042000 level=VERBOSE [E][esp32-hal-i2c.c:643] i2cDumpI2c(): lock=0x3ffd2a8c [E][esp32-hal-i2c.c:645] i2cDumpI2c(): num=0 [E][esp32-hal-i2c.c:646] i2cDumpI2c(): mode=1 [E][esp32-hal-i2c.c:647] i2cDumpI2c(): stage=3 [E][esp32-hal-i2c.c:648] i2cDumpI2c(): error=1 [E][esp32-hal-i2c.c:649] i2cDumpI2c(): event=0x3ffd2b10 bits=110 [E][esp32-hal-i2c.c:650] i2cDumpI2c(): intr_handle=0x3ffeb18c [E][esp32-hal-i2c.c:651] i2cDumpI2c(): dq=0x3ffd2b40 [E][esp32-hal-i2c.c:652] i2cDumpI2c(): queueCount=1 [E][esp32-hal-i2c.c:653] i2cDumpI2c(): queuePos=0 [E][esp32-hal-i2c.c:654] i2cDumpI2c(): byteCnt=0 [E][esp32-hal-i2c.c:604] i2cDumpDqData(): [0] af R STOP buf@=0x3ffc5024, len=1, pos=0, eventH=0x0 bits=0 [E][esp32-hal-i2c.c:620] i2cDumpDqData(): 0x0000: . 00 [E][esp32-hal-i2c.c:968] i2cDumpInts(): 0 row count INTR TX RX [E][esp32-hal-i2c.c:971] i2cDumpInts(): [01] 0x0002 0x0002 0x0001 0x0000 0x00003532 [E][esp32-hal-i2c.c:971] i2cDumpInts(): [02] 0x0002 0x0200 0x0000 0x0000 0x00003532 [E][esp32-hal-i2c.c:1193] i2cProcQueue(): Busy Timeout start=0x359f, end=0x35d1, =50, max=50 error=1 [E][esp32-hal-i2c.c:630] i2cDumpI2c(): i2c=0x3ffc10cc [E][esp32-hal-i2c.c:641] i2cDumpI2c(): dev=0x60013000 date=0x16042000 level=VERBOSE [E][esp32-hal-i2c.c:643] i2cDumpI2c(): lock=0x3ffd2a8c [E][esp32-hal-i2c.c:645] i2cDumpI2c(): num=0 [E][esp32-hal-i2c.c:646] i2cDumpI2c(): mode=1 [E][esp32-hal-i2c.c:647] i2cDumpI2c(): stage=3 [E][esp32-hal-i2c.c:648] i2cDumpI2c(): error=1 [E][esp32-hal-i2c.c:649] i2cDumpI2c(): event=0x3ffd2b10 bits=100 [E][esp32-hal-i2c.c:650] i2cDumpI2c(): intr_handle=0x3ffeb18c [E][esp32-hal-i2c.c:651] i2cDumpI2c(): dq=0x3ffd2b40 [E][esp32-hal-i2c.c:652] i2cDumpI2c(): queueCount=1 [E][esp32-hal-i2c.c:653] i2cDumpI2c(): queuePos=0 [E][esp32-hal-i2c.c:654] i2cDumpI2c(): byteCnt=0 [E][esp32-hal-i2c.c:604] i2cDumpDqData(): [0] 5f R STOP buf@=0x3ffc5024, len=1, pos=0, eventH=0x0 bits=0 [E][esp32-hal-i2c.c:620] i2cDumpDqData(): 0x0000: . 00 [E][esp32-hal-i2c.c:968] i2cDumpInts(): 0 row count INTR TX RX [E][esp32-hal-i2c.c:971] i2cDumpInts(): [01] 0x0001 0x0002 0x0000 0x0000 0x0000359f [E][esp32-hal-i2c.c:971] i2cDumpInts(): [02] 0x0002 0x0200 0x0000 0x0000 0x0000359f [I][esp32-hal-i2c.c:1002] i2cProcQueue(): Bus busy, reinit [E][esp32-hal-i2c.c:1193] i2cProcQueue(): Busy Timeout start=0x3639, end=0x3639, =0, max=50 error=1
Strangely Thanks again
This error report show you were writing to 0x57 a byte of zero. ((0xAE is 0x57 << 1 ) | 1 )
E][esp32-hal-i2c.c:604] i2cDumpDqData(): [0] ae W STOP buf@=0x3ffc50aa, len=1, pos=1, eventH=0x0 bits=0 [E][esp32-hal-i2c.c:620] i2cDumpDqData(): 0x0000: . 00 [E][esp32-hal-i2c.c:968] i2cDumpInts(): 0 row count INTR TX RX
This line shows two bytes loaded into tx Fifo, and a transaction Start was issued. at tick 0x34b9ms
[E][esp32-hal-i2c.c:971] i2cDumpInts(): [01] 0x0001 0x0202 0x0002 0x0000 0x000034b9
This line show that the i2c Peripheral sent one character out (the i2c Address byte)
[E][esp32-hal-i2c.c:971] i2cDumpInts(): [02] 0x0001 0x0040 0x0000 0x0000 0x000034b9
This line shows that something kept SDA low, the i2c peripheral interpreted it as another master device using the bus. (Arbitration Error). This error terminated the transaction.
[E][esp32-hal-i2c.c:971] i2cDumpInts(): [03] 0x0001 0x0020 0x0000 0x0000 0x000034b9
The following errors are all a cascade of loosing control of the I2C bus. I would verify you have 2.4k or 3.3k pullups on both SDA and SCL. the Builtin WEAK pullups of the ESP32 are not strong enough to allow successful I2C communications.
The following shows a hardware problem, SDA is held low.
[I][esp32-hal-i2c.c:1002] i2cProcQueue(): Bus busy, reinit [E][esp32-hal-i2c.c:1246] i2cReleaseISR(): Error releasing ISR=258 [E][Wire.cpp:137] initHardware(): invalid state sda=0, scl=1
Part of the reset sequence releases the Interrupt, but this error ISR=258 reports the the interrupt is attached to the other core. There is an upstream (IDF) patch that fixes this cross core interrupt release issue. It will be included in the Next Arduino-ESP32 release.
This Stickbreaker ESP32 fork is stale, try using the main branch of Arduino-ESP32, (not the Release 1.0.0, the current Dev Code).
Chuck.
Thanks a lot @stickbreaker The code is based on the ble_test_repo(I get it from https://github.com/chegewara/esp32-snippets-enchancements-test). And i want to send the sensor data to my phone via the ESP32 ble. The problem is solved by creating the task on core(1). Where can i get the current Dev Code? Thanks again
Main Arduino-esp32 follow install instructions for "development repository" here
hello ! @stickbreaker
i use esp32 I2C to read the data from max30102 and send them to the app via esp32 ble. But something happened and do not how to solve it.
[D][BLEUtils.cpp:1651] dumpGattServerEvent(): GATT ServerEvent: ESP_GATTS_CONF_EVT [D][BLEUtils.cpp:1696] dumpGattServerEvent(): [status: ESP_GATT_OK, conn_id: 0x00] [D][BLEServer.cpp:176] handleGATTServerEvent(): >> handleGATTServerEvent: ESP_GATTS_CONF_EVT [D][BLECharacteristic.cpp:196] handleGATTServerEvent(): >> handleGATTServerEvent: ESP_GATTS_CONF_EVT [D][BLECharacteristic.cpp:459] handleGATTServerEvent(): << handleGATTServerEvent [D][BLEServer.cpp:315] handleGATTServerEvent(): << handleGATTServerEvent [D][esp32-hal-i2c.c:1300] i2cProcQueue(): Gross Timeout Dead start=0x85fbe, end=0x85ff0, =50, max=50 error=1 [E][esp32-hal-i2c.c:314] i2cDumpI2c(): i2c=0x3ffbedac [I][esp32-hal-i2c.c:315] i2cDumpI2c(): dev=0x60013000 date=0x16042000 [I][esp32-hal-i2c.c:317] i2cDumpI2c(): lock=0x3ffba83c [I][esp32-hal-i2c.c:319] i2cDumpI2c(): num=0 [I][esp32-hal-i2c.c:320] i2cDumpI2c(): mode=1 [I][esp32-hal-i2c.c:321] i2cDumpI2c(): stage=3 [I][esp32-hal-i2c.c:322] i2cDumpI2c(): error=1 [I][esp32-hal-i2c.c:323] i2cDumpI2c(): event=0x3ffba8c0 bits=200 [I][esp32-hal-i2c.c:324] i2cDumpI2c(): intr_handle=0x3ffbdb14 [I][esp32-hal-i2c.c:325] i2cDumpI2c(): dq=0x3ffe56c8 [I][esp32-hal-i2c.c:326] i2cDumpI2c(): queueCount=1 [I][esp32-hal-i2c.c:327] i2cDumpI2c(): queuePos=0 [I][esp32-hal-i2c.c:328] i2cDumpI2c(): errorByteCnt=0 [I][esp32-hal-i2c.c:329] i2cDumpI2c(): errorQueue=1 [I][esp32-hal-i2c.c:330] i2cDumpI2c(): debugFlags=0x00000000 [I][esp32-hal-i2c.c:349] i2cDumpInts(): Debug Buffer not Enabled [I][esp32-hal-i2c.c:1091] i2cProcQueue(): Bus busy, reinit [V][esp32-hal-i2c.c:1436] i2cInit(): num=0 sda=21 scl=22 freq=0 [V][esp32-hal-i2c.c:1621] i2cSetFrequency(): Fifo threshold=3 [W][esp32-hal-i2c.c:1363] i2cCheckLineState(): invalid state sda(21)=0, scl(22)=1 [D][esp32-hal-i2c.c:1371] i2cCheckLineState(): Recovered after 1 Cycles
Thanks again.
@wanqbabay, which version are you using?
@stickbreaker the latest [D][esp32-hal-i2c.c:1306] i2cProcQueue(): Gross Timeout Dead start=0x33db8, end=0x33dea, =50, max=50 error=1 [E][esp32-hal-i2c.c:318] i2cDumpI2c(): i2c=0x3ffbde10 [I][esp32-hal-i2c.c:319] i2cDumpI2c(): dev=0x60013000 date=0x16042000 [I][esp32-hal-i2c.c:321] i2cDumpI2c(): lock=0x3ffe17b0 [I][esp32-hal-i2c.c:323] i2cDumpI2c(): num=0 [I][esp32-hal-i2c.c:324] i2cDumpI2c(): mode=1 [I][esp32-hal-i2c.c:325] i2cDumpI2c(): stage=3 [I][esp32-hal-i2c.c:326] i2cDumpI2c(): error=1 [I][esp32-hal-i2c.c:327] i2cDumpI2c(): event=0x3ffe15a8 bits=0 [I][esp32-hal-i2c.c:328] i2cDumpI2c(): intr_handle=0x3ffe3f08 [I][esp32-hal-i2c.c:329] i2cDumpI2c(): dq=0x3ffe1924 [I][esp32-hal-i2c.c:330] i2cDumpI2c(): queueCount=1 [I][esp32-hal-i2c.c:331] i2cDumpI2c(): queuePos=0 [I][esp32-hal-i2c.c:332] i2cDumpI2c(): errorByteCnt=0 [I][esp32-hal-i2c.c:333] i2cDumpI2c(): errorQueue=1 [I][esp32-hal-i2c.c:334] i2cDumpI2c(): debugFlags=0x00000000 [I][esp32-hal-i2c.c:311] i2cDumpDqData(): Debug Buffer not Enabled [I][esp32-hal-i2c.c:354] i2cDumpInts(): Debug Buffer not Enabled [I][esp32-hal-i2c.c:1097] i2cProcQueue(): Bus busy, reinit [V][esp32-hal-i2c.c:1442] i2cInit(): num=0 sda=21 scl=22 freq=0 [V][esp32-hal-i2c.c:1643] i2cSetFrequency(): Fifo threshold=3
This stickbreaker branch or arduino-esp32 github direct or board manager v1.0.1rc1
Or v1.0.1rc2
where can i get it?
Get rc2
Follow these instructions board manager
Hardware:
Board: LOLIN32 Core Installation/update date: Main + latest stickbreaker patched i2c files IDE name: Arduino IDE Flash Frequency: 40Mhz Upload Speed: 115200
Description:
The below code works great when calling checkRpmPins(); from within the main loop, however, when calling mcp.digitalRead(0); from a second core task I get the below error. When using digitalRead(0);
I'm guessing a timing issue when using the second core? I'm not sure if anyone's tried calling from the second core for i2c? I'm counting the RPM value from 16 fans (hall effect sensors) so timing is critical which is why I'm complicating things. :)
Sketch:
Debug Messages:
Libraries used:
https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library
Digital read function: