Pico W send and receive

I made an application to send a message to an LCD screen 16x2. I succeeded to send the message. each message has a unique number. So I send this number (nr) and 2 lines of text (l1 and l2). The function is called message(nr, l1,l2)
I have also a button that I can push to clear the LCD, stop blinking a led, and send a response back that the message is read. It sends back with anvil.pico.call(“msgback”, oldnr, resp) and updates the database

Everything is working, but I want to separate the message sending and the response back, while as it is written now, the client side of the app is continuously busy until the button is pressed.

Code Sample:

# this is a formatted code snippet.
# paste your code between ``` 

import anvil.pico
import uasyncio as a
from machine import I2C, Pin
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd
import utime

I2C_ADDR     = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16

i2c = I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)

UPLINK_KEY = "***************************************************"


# We use the LED to indicate server calls and responses.
led = Pin("LED", Pin.OUT, value=1)
ledal = Pin(15,Pin.OUT,value=0)  # message led toggles on and off
btnstop = Pin(18,Pin.IN,Pin.PULL_DOWN) # button pressed to send response message read

lcd.clear()
lcd.backlight_off()
pressed = False
oldnr = 0
resp = False

 # interrupt request with the button
def int_handler(pin): 
 global pressed
 btnstop.irq(handler=None)
 pressed = True
 print(f"pressed = {pressed}, button pressed")
 utime.sleep(0.5)
 btnstop.irq(handler=int_handler)
 
    
btnstop.irq(trigger=machine.Pin.IRQ_RISING, handler=int_handler)

# main program
@anvil.pico.callable(is_async=True)
async def message(nr,l1,l2):
  # Output will go to the Pico W serial port
  global pressed, oldnr, resp
  print(f"send message nr:{nr} {l1} {l2}")
  print(f"prev old = {oldnr}, new = {nr}")
  nrstr = str(nr)
  l1 = str(l1)
  l2 = str(l2)
  lcd.backlight_on()
  lcd.clear()
  lcd.move_to(0, 0)
  lcd.putstr(nrstr+" "+l1)
  lcd.move_to(0, 1)
  lcd.putstr(l2)
  resp = False
  pressed = False
  a.sleep(0.2)  
  # new message is send and shown on LCD screen
  while pressed == False: #as long as the button is not pressed toggle the led
      ledal.toggle()
      utime.sleep(0.5)
      if pressed == True: # now button is pressed send response back, clear LCD and stop blinking the led
         oldnr = nr
         print(f"old = {oldnr}, new = {nr}")
         resp = True
         await anvil.pico.call("msgback", oldnr, resp)
         await a.sleep(0.5)
         ledal.value(0)
         lcd.clear()
         lcd.backlight_off()
         a.sleep(0.2)

  
  
# Connect the Anvil Uplink. In MicroPython, this call will block forever.

anvil.pico.connect(UPLINK_KEY)


##CLIENT CODE##########################################
# sending to pico in client code
anvil.server.call('message',nr,l1,l2)

##SERVERMODULE########################################

#to save new message in database
@anvil.server.callable
def msgadd(nr,l1,l2):
app_tables.msg.add_row(msgback=False,msgl1=l1,msgl2=l2,msgnr=nr,msgsend=True,msgsendtime=datetime.now(tz))
  
# from pico
@anvil.server.callable
def msgback(oldnr, resp):
  if resp == True:
    row = app_tables.msg.get(msgnr=oldnr)
    row.update(msgback=True,msgbacktime=datetime.now(tz))
    print(oldnr)

Clone link:
share a copy of your app

1 Like

My first thought is that instead of calling the blocking function on the pico from your front end Anvil client code, when the user enters a new message in the Anvil front end, save the message, its unique ID, and a flag showing its unread status to the database.

In each iteration of the while loop on your pico, call an Anvil server function to grab any unread message from the database, and in that server function, change the unread message status in the database, once its been delivered to the pico.

That way, the while loop can run endlessly on the pico, and it simply calls an Anvil function which returns and never blocks in the Anvil app.

Ok thanks for the tip, I will try