Fail in the off state? GPIO Cleanup?

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
Curly Tale Games
Posts: 10
Joined: Sat May 29, 2021 5:32 am

Fail in the off state? GPIO Cleanup?

Post by Curly Tale Games » Wed Jul 14, 2021 1:16 am

I'm building a web based kiln controller, and safety is a big concern of mine.

Is there a way that I can be certain a GPIO pin that controls a relay for a heating element will always fail in the off state, or at least reset to the default state? On the Raspberry Pi you can do GPIO.cleanup() is there something equivalent to that for the ESP32/MicroPython?

I've noticed while testing in REPL that if my code errors out from me hitting CTRL+C on the keyboard the GPIO pins stay in their last state. Is there a way to catch any errors like that and run some code to turn off the pins?

I've thought about trying to make a hardware solution to this problem, but I'm not sure how to differentiate the relay being on like normal vs the relay being on because it's stuck in that state due to an error.

Any ideas?

Thanks!
-Ben

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: Fail in the off state? GPIO Cleanup?

Post by davef » Wed Jul 14, 2021 3:08 am

Would not the same thing happen on the RaspberryPi if you hit Ctrl C before you did a GPIO.cleanp()?

One reason I started looking at the ESP32 was a very infrequent input read error on my RaspberryPi 3B.

There was some recent discussion on modifying the script that processes something on either repl or webrepl. It is not immediately obvious. Are you using rshell?

Curly Tale Games
Posts: 10
Joined: Sat May 29, 2021 5:32 am

Re: Fail in the off state? GPIO Cleanup?

Post by Curly Tale Games » Wed Jul 14, 2021 4:16 am

Yeah you're right, I'm pretty sure it would behave the same way on the Raspberry Pi where it would keep the same state prior to the error. I just know that Raspberry Pi has that function built in to reset all the GPIO pins back to their default state. I've seen people put it at the end of their scripts to reset things.

I'd love it if there was some way of detecting an error and running some code. I know I can put try catches all over my code, but I was wondering if there was literally a catch all solution for any error, or even a hardware solution to this problem.

For my setup, I'm using VS Code and Pymakr to upload code and connect to my ESP32 over USB.

marcidy
Posts: 133
Joined: Sat Dec 12, 2020 11:07 pm

Re: Fail in the off state? GPIO Cleanup?

Post by marcidy » Wed Jul 14, 2021 4:49 am

Code: Select all

def main():
    # all your code is called from here
    
def cleanup():
    # do what you need to do
in main.py

Code: Select all

try:
    main()
except Exception:
    cleanup()
    # machine.reset() even.
Design your code so it has a single entrypoint, e.g. main.

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: Fail in the off state? GPIO Cleanup?

Post by davef » Wed Jul 14, 2021 5:16 am

Interesting ... can main() call other modules?

I currently use viewtopic.php?t=5517&start=10. I have it set at 70 seconds and before the machine.reset() I save a /ramdisk/logfile to flash.

If you can tolerate a few seconds of indecision you could reset the GPIO in the above, before the machine.reset() and sprinkle wdt_feed() throughout your code.

marcidy
Posts: 133
Joined: Sat Dec 12, 2020 11:07 pm

Re: Fail in the off state? GPIO Cleanup?

Post by marcidy » Wed Jul 14, 2021 5:45 am

it's a python function, it can do everything any other function can do.

Code: Select all

def main():
    import foo
    from foo.bar import baz
    ....
why wouldn't you import at the top of the file though? not sure I fully understand what your mean by calling other modules. calling functions from other modules just requires importing, and code which executes on import really should be avoided but will work where the import occurs.

you can define main elsewhere

main.py

Code: Select all

from app import main, panic

try:
    main()
except Exception:
    panic()

the pattern is to use main.py to handle global exceptions that the rest of the application didn't handle. since the application didn't handle them, make as few assumptions about the exception as possible and recover the hardware to your safe state.

main() can be its own loop, for example

Code: Select all

def main():
    while True:
        # ...
or add exception handling in main():

Code: Select all

def main():
    try:
        myapp.main()
    except Exception:
        myapp.recover()
an external wdt is certainly a good way to do it!

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: Fail in the off state? GPIO Cleanup?

Post by davef » Wed Jul 14, 2021 6:25 am

Sorry, I wasn't clear ... yes calling functions from other modules.

I will add your examples to my toolbox.

Just to clarify my understanding this approach will catch errors if code somewhere doesn't run correctly. If main() stops running because of an under-lying freeze or lock-up in the OS, filesystem corruption, etc these will not be caught, correct?

Thanks.

marcidy
Posts: 133
Joined: Sat Dec 12, 2020 11:07 pm

Re: Fail in the off state? GPIO Cleanup?

Post by marcidy » Wed Jul 14, 2021 6:51 am

right, this is only for errors which manifest as python exceptions.

There's are many c level exceptions which are raised to python exceptions, e.g. out of memory, fs space, etc, but here you are relying on the micropython devs correctly catching and propagating errors, as well as esp-idf devs correctly raising errors.

A hardware wdt is certainly good for managing all issues that can crash the system, at any level.

Curly Tale Games
Posts: 10
Joined: Sat May 29, 2021 5:32 am

Re: Fail in the off state? GPIO Cleanup?

Post by Curly Tale Games » Wed Jul 14, 2021 10:35 pm

Very cool!!!! That's exactly what I need. I don't know why I didn't think of that haha

Thanks marcidy!

Post Reply