va3wam / TWIPi

Next generation of inverted pendulum Robot by Doug and Andrew
5 stars 0 forks source link

Inconsistent variable behavior #14

Closed va3wam closed 5 years ago

va3wam commented 5 years ago

The t0_per_sec variable sometimes has an invalid value of 0 and other times has a valid value of ~50K. Further investigation shows that if the I2C bus definitions come first in setup() then the timer moves to priority 0 on core0 and never runs. If the timer is defined first then the second I2C bus generates a HAL 261 error and is unusable.

va3wam commented 5 years ago

I believe I have isolated the issue. It appears as if Timer0 conflicts with the second I2C bus used to communicate with the MPU6050. Note that simply defining the second bus causes the issue so it does not appear to be work load related. I tried abandoning the use of TwoWire() library in favour of the Wire() library but I see the exact same issue. Further investigation into the nature of the conflict and what option will best eliminate it is ongoing.

nerdoug commented 5 years ago

I don't understand the conflict, but I notice that the examples I see on the net use a variety of pins for the second I2C bus, but I can't find anyone using the same ones we do. Maybe we should try some of these other pin assignments?

---From our code:

define SDA1 23

define SCL1 22

define SDA2 4

define SCL2 5

TwoWire I2Cone = TwoWire(0); TwoWire I2Ctwo = TwoWire(1);

--- from https://github.com/espressif/arduino-esp32/issues/977 1)

TwoWire I2Cone = TwoWire(0); TwoWire I2Ctwo = TwoWire(1); void setup() { I2Cone.begin(21,22,100000); // SDA pin 21, SCL pin 22, 100kHz frequency I2Ctwo.begin(16,17,400000); // SDA pin 16, SCL pin 17, 400kHz frequency

2)

include

include //for esp32

define SDA1 21

define SCL1 22

define SDA2 5

define SCL2 4

TwoWire I2Cone = TwoWire(0); TwoWire I2Ctwo = TwoWire(1);

---from https://github.com/espressif/arduino-esp32/issues/1438

The actual configuration will require one port to be a master and one port to be a slave.

And thoughts or insights? Sketch:

include

include

include //for esp32

define SDA1 21

define SCL1 22

//#define SDA1 19 //#define SCL1 23

define SDA2 19

define SCL2 23

TwoWire1 I2Cone = TwoWire1(0); TwoWire2 I2Ctwo = TwoWire2(1);

--- from https://randomnerdtutorials.com/esp32-esp8266-i2c-lcd-arduino-ide/

Wire your LCD to the ESP32 by following the next schematic diagram.

We’re using the ESP32 default I2C pins (GPIO 21 and GPIO 22).

(on a different ESP32 board: ESP32 DOIT DEVKIT V1 Board https://makeradvisor.com/tools/esp32-dev-board-wi-fi-bluetooth/ )

[image: image.png]

delliott@nds.com

I'm going to see if I can find some Expressif documentation that suggests particular pins.

Cheers, Doug Elliott VA3DAE cell & text: 519-630-8925 email: canoe.eh@gmail.com web: http://nerdpit.ca

On Sun, Nov 25, 2018 at 8:49 PM va3wam notifications@github.com wrote:

I believe I have isolated the issue. It appears as if Timer0 conflicts with the second I2C bus used to communicate with the MPU6050. Note that simply defining the second bus causes the issue so it does not appear to be work load related. I tried abandoning the use of TwoWire() library in favour of the Wire() library but I see the exact same issue. Further investigation into the nature of the conflict and what option will best eliminate it is ongoing.

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/va3wam/TWIPi/issues/14#issuecomment-441495821, or mute the thread https://github.com/notifications/unsubscribe-auth/AJ2U4pW0Ve_-B2LS1SsI8Tj7kp-Jr9rwks5uy0iYgaJpZM4YuPuB .

va3wam commented 5 years ago

Behavior: We have refined the behavior to this: If the I2C bus definitions come first then the timer moves to priority 0 on core0 and never runs. If the timer is defined first then the second I2C bus generates a HAL 261 error.

Cause: In summary the issue is that using a hardware timer plus two I2C buses causes resource challenges. In detail, this issues appears to be tied to a known issue with the i2c HAL. A fix has been submitted (see https://github.com/espressif/arduino-esp32/pull/1877). This fix was submitted on September 21, 2018 and our PlatformIO ESP32 bundle does not include the fix. We know this because when you look at the affected file on Andrew's hard drive (/Users/andrewmitchell/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-i2c.c) we see this chunk of code:

if(!i2c->intr_handle) { // create ISR for either peripheral
    // log_i("create ISR %d",i2c->num);
    uint32_t ret = 0;
    uint32_t flags = ESP_INTR_FLAG_EDGE |  //< Edge-triggered interrupt
      ESP_INTR_FLAG_IRAM |  //< ISR can be called if cache is disabled
      ESP_INTR_FLAG_LOWMED;   //< Low and medium prio interrupts. These can be handled in C.

which should be changed to if(!i2c->intr_handle) { // create ISR for either peripheral // log_i("create ISR %d",i2c->num); uint32_t ret = 0; uint32_t flags = ESP_INTR_FLAG_IRAM | //< ISR can be called if cache is disabled ESP_INTR_FLAG_LOWMED | //< Low and medium prio interrupts. These can be handled in C. ESP_INTR_FLAG_SHARED; //< Reduce resource requirements, Share interrupts

Fix: We need to use this updated ESP32 image so we need to figure out how to do that until PlatformIO updates to the latest image.

va3wam commented 5 years ago

Changed /Users/andrewmitchell/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-i2c.c code from

if(!i2c->intr_handle) { // create ISR for either peripheral
// log_i("create ISR %d",i2c->num);
uint32_t ret = 0;
uint32_t flags = ESP_INTR_FLAG_EDGE |  //< Edge-triggered interrupt
  ESP_INTR_FLAG_IRAM |  //< ISR can be called if cache is disabled
  ESP_INTR_FLAG_LOWMED;   //< Low and medium prio interrupts. These can be handled in C.

to if(!i2c->intr_handle) { // create ISR for either peripheral // log_i("create ISR %d",i2c->num); uint32_t ret = 0; uint32_t flags = ESP_INTR_FLAG_IRAM | //< ISR can be called if cache is disabled ESP_INTR_FLAG_LOWMED | //< Low and medium prio interrupts. These can be handled in C. ESP_INTR_FLAG_SHARED; //< Reduce resource requirements, Share interrupts as documented here: (see espressif/arduino-esp32#1877). We now must track these changes until the stable branch of ESP-IDF includes them.