toitware / public

Issue tracking for the Toit IoT platform, the Toit language, and the Toit APIs.
9 stars 0 forks source link

[BUG] triggers: gpios: -pin: triggers continuously, not on pin high #42

Closed paddyrg closed 2 years ago

paddyrg commented 2 years ago

Describe the bug Triggers: gpios: -pin: triggers continuously, not on pin high

To reproduce Steps to reproduce the behavior:

Create a yaml with the triggers triggers: gpios:

(pin 22 could be any suitable gpio, juts an example, reproducable with pins 23, 18 for instance)

Connect pin 22 high, low, floating, pulled down, whatever you like - in any case the entrypoint continuously fires once the device is powered up

Expected behavior Per the documentation, the entrypoint should only fire when pin 22 is high

Screenshots If applicable, add screenshots to help explain your problem.

SDK and console version (please complete the following information): Run toit version

Additional context Discussed with Florian who can repro going back to v1.5.0 - adding here for completeness

floitsch commented 2 years ago

Thanks for the report. This has been fixed. You will need to redeploy any application that relies on the trigger.

paddyrg commented 2 years ago

Hiya, fixed in 1.6.9 (latest available in console) or 1.6.10 (looks like latest build but not avalable for OTA deployment yet?) tyvm :)

kasperl commented 2 years ago

Hi @paddyrg! It was fixed in the cloud backend, where the gpio triggers mentioned in the .yaml file weren't sent correctly to the devices.

paddyrg commented 2 years ago

Hi Kasper, thanks for that :)

I must admit I'm still having issues, slightly different and I could see how they might be related. Now the GPIO doesn't retrigger per the documentation

gpios:

Runs the application when any of the specified GPIO pins are high. This GPIOs trigger is level-triggered, so it'll continue running the application while the GPIO pin is high.

This could be interpreted two ways, I guess. One is that the code refires continuously whilst the GPIO is high, the other is that it fires once and executes once (so a short programme would terminate and a long one terminate when GPIO went low) to refire each time the GPIO cycled low-> high. I didn't find either behaviour, so perhaps I'm misunderstanding?!

If I power cycle the ESP32 with the gpio held low, no response until it goes high (great, that's fine!) but sometimes the code is retriggered exactly once after ~6s, sometimes again after a minute or so, but certainly not predictably. Taking the pin to low again does not reset anything, still takes a hard boot.

Maybe it's just my device or something (it's a WROOM-32, though) but I provide a simplified demo below -

(yaml:)

name: gpio-responder-simple-test
entrypoint: gpio-responder-simple-test.toit

triggers:
  gpios:
    - pin: 23`

(gpio-responder-simple-test.toit)

import gpio
builtinLED := gpio.Pin 2 --output

main:
  3.repeat:
    builtinLED.set 1
    sleep --ms=200
    builtinLED.set 0
    sleep --ms=200

I just can't get predictable repeateble results except with a hard boot (v1.6.9).

Am I missing something? Can it be repro'd?

floitsch commented 2 years ago

I'm not sure I can reproduce the exact behavior, but I do get exceptions:

EXCEPTION error. 
ALREADY_IN_USE
  0: gpio_use_                 <sdk>/gpio/pin.toit:213:3
  1: Pin                       <sdk>/gpio/pin.toit:70:17
  2: Pin.in                    <sdk>/gpio/pin.toit:51:12
  3: GpioTrigger.run           system/kernel/triggers.toit:37:21
  4: GpioTrigger.start.<lambda>.<block>.<block> system/kernel/triggers.toit:25:24
  5: catch.<block>             <sdk>/core/exceptions.toit:114:10
  6: catch                     <sdk>/core/exceptions.toit:112:1
  7: catch                     <sdk>/core/exceptions.toit:63:10
  8: GpioTrigger.start.<lambda>.<block> system/kernel/triggers.toit:25:9
  9: GpioTrigger.start.<lambda> system/kernel/triggers.toit:23:17

For now I would use the trigger only to wake up from deep sleep. You can always use wait_for (maybe in a with_timeout) or get to ensure that you are in the right state.

floitsch commented 2 years ago

@kasperl : new bug or should I reopen this one?

paddyrg commented 2 years ago

The exceptions you were thrown would seem to be at least in keeping with the issues I have. I guess wait_for is the way to go for now, just I was attracted to this as an alternative to interrupts with it being handled by the firmware :)

Thanks for verification Florian!