Closed Manuauto closed 6 years ago
@Manuauto
a couple of changes, you need to tell the compiler to always have the ISR in RAM. This processor ESP32 loads program from FLASH into RAM where it executes it. It only has 128Kbytes of RAM for ICACHE (instruction cache) so it switches out unused code on the fly. When an interrupt is triggered it bypasses the Cache load operation and jumps right to the specified code (ISR) location. If that ISR is not in RAM it panics.
void IRAM_ATTR hall_interrupt() {
hall_millis_current = millis(); //Current time for Reference
// this if() will cause integer rollover problems, if millis_last + 100 in at or
// near maximum int value, and millis() has already rolled over it will miss.
// and never trigger until aproximately 49 days later! (millis() 32bit millisecond rollover)
// if (hall_millis_current > hall_millis_last + 100) {
// change it to this order, the integer rollover will be correctly handled
if(hall_millis_current - hall_millis_last >100){
time_for_rotation = hall_millis_current - hall_millis_last; //Calculate Time of Rotation
kmph = (56.8 * float(circumference)) / float(time_for_rotation);
kmph = kmph * 1.60934; //Convert to km/h
hall_millis_last = hall_millis_current; //(Re)Set reference Point
}
}
Chuck.
@stickbreaker Thanks for taking the time and going over my code! Many thanks for an actual explanation of what I did wrong / what caused the issue. This was really helpful!
I have implemented the changes and the issue seems to be gone!
Today I went on a test ride and the issue seems to be still there.
In order to decode the debug output I tried to compile the code with the Arduino IDE. This does not work with the changes suggested by @stickbreaker.
'hall_interrupt' was not declared in this scope
Previously I used VisualMicro to compile which worked fine for some reason.
Now I used Visual Micro to compile (with apparent fix) and uploaded it. i reproduced the error and decoded it with the Arduino IDE (Here I compiled the code Without the Fix, otherwise it would not compile) The Output is as follows:
Decoding 4 results 0x40080ed6: analogInit at E:\Documents\Arduino\hardware\espressif\esp32\cores\esp32/esp32-hal-adc.c line 98 0x400812e9: pinMode at E:\Documents\Arduino\hardware\espressif\esp32\cores\esp32/esp32-hal-gpio.c line 115 0x40082b35: _xt_medint3 at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/./xtensa_vectors.S line 1256 0x400ea783: esp_event_process_default at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/esp32/./event_default_handlers.c line 136
Might my pin-selection be unfortunate?
Hi, I just wanted to say that I had a similar problem where an external interrupt (generated every second by a DS3231 RTC) was causing OTA updates to fail. I added IRAM_ATTR to the ISR as suggested by stickbreaker and it seems that it solved the issue :)
I had a lots of problems with OTA as well. What I learned to get OTA working is stop all
in ArduinoOTA.onStart()
@Manuauto Can we close this issue?
Yes, I'll close it. The reason for crashes even after adding IRAM_ATTR was that I did "a lot" of relatively complicated calculations in the ISR. By offloading those to the main loop() I resolved this issue completely. Thanks for the help.
If hall_millis_current == hall_millis_current then you get a divide by zero error! I think this is the problem. Test time_for_rotation !=0 and do the computation only if it is true !
time_for_rotation = hall_millis_current - hall_millis_last; //Calculate Time of Rotation if (time_for_rotation != 0) kmph = (56.8 * float(circumference)) / float(time_for_rotation);
Or use micros() insted of millis(). A miilisecond is a long time ;)
Hardware:
Board: DOIT ESP32 Devkit v1 Core Installation/update date: 10. Dec. 2017 IDE name: Arduino IDE 1.8.5 / Visual Micro Flash Frequency: 80Mhz Upload Speed: 921600
Description:
I am using an external hall effect sensor in order do measure the rotation of a wheel. To get the most accurate results, I am using an interrupt which triggers on the falling edge of the hall-sensor input.
In most cases the measurement goes just fine and I get reasonable results. In some cases, which cannot be distinguished by an obvious factor by myself, the ESP32 crashes. (Maybe and only maybe multiple interrupts happens in a very short period of time and this causes the issue? But why?)
For testing I have replaced the hall sensor with a simple push button, the pin is pulled high by an external resistor (and an internal one too, initially I only used the internal one; same problem).
I have implemented a Screen-Lock in software. The device can be unlocked via RFID. If an interrupt occurs while the device is locked, it instantly crashes.
Sketch:
(the whole sketch is attached too)
All variables accessed by the interrupt function are declared as volatile.
Debug Messages: