Anvil Pico W fails to run main program after reconnection

**What I’m trying to do:**I’m trying to connect to Anvil via uplink using the Anvil Pico firmware. It does connect well initially and will forward telemetry to my Anvil App. The program goes to sleep after a couple of seconds of no input. This is ok. However, when it tries to reconnect, it successfully reconnects to anvil (printing "Authenticated to app xxxxxxxx), but fails to run the main program .

What I’ve tried and what’s not working: I tried different connection options but the behavior is the same even when using the on_first_connect and on_every_connect arguments.

Code Sample:

import uasyncio as a
from machine import Pin
import utime
import ubinascii

import machine

device_id = ubinascii.hexlify(machine.unique_id()).decode()

UPLINK_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

led = Pin("LED", Pin.OUT, value=0)

sensor = Pin(16, Pin.IN, Pin.PULL_DOWN) 


def wait_pin_change(pin, stable_time=20):
  '''
    wait for pin to change value (removes debounce)
    it has to be stable for a continuous stable_time ms
  '''
  cur_value = pin.value()
  active = 0
  while active < stable_time:
    if pin.value() != cur_value:
      active += 1
    else:
      active = 0
    utime.sleep_ms(1)



@anvil.pico.callable_async
def main():
  print(f"main called from {device_id}!")
  while True:
    wait_pin_change(sensor)
    if sensor.value():
      led.toggle()
      print("motion detected!")
      await anvil.pico.call(
        "receive_telemetry",
        {
          "id": device_id,
          "value": 'True'
        }
      )
      led.toggle()
  

anvil.pico.connect(UPLINK_KEY, on_first_connect=main())

Clone link:
share a copy of your app

on_first_connection expects to receive a reference to a function. main() is not returning a reference to a function. main() returns None.

1 Like

Thanks @p.colbert for your suggestion but from the examples in the documentation, the main function called within anvil.pico.connect also returns None and still works. Moreover, as I mentioned, my code does work as it is for a while. It only fails to send telemetry upon reconnection (after waking up from sleep).

You’re both right! What’s going on here is that on_first_connect expects a reference to a function, so in your case @edmondssesay you’ll want main rather than main().

In the docs, the function being referred to is actually an async function, defined with async def, and that means it behaves slightly differently (calling it returns a generator). This is why, although the functions in the docs do return None, you call them anyway in the connect call, since that’s actually how you refer to an async function in this context.

We’ll update the docs to be extra clear on this point, and provide code samples for both async and standard functions!

4 Likes