Wipy multithreading

Questions and discussion about The WiPy 1.0 board and CC3200 boards.
Target audience: Users with a WiPy 1.0 or CC3200 board.
Post Reply
Posts: 20
Joined: Fri Sep 09, 2016 7:53 am

Wipy multithreading

Post by Miguel » Wed Oct 26, 2016 7:43 pm


I would like to switch LCD backlight with a button. I tried to do it this way:

1. Setup IRQ handler that toggles value of global variable lcd_backlight between 0 and 1 everytime the button is pressed.
2. Start a separate thread, that checks the value of the lcd_backlight variable and switches the LCD backlight on or off.

Here is my ugly code (lcdbutton.py):

Code: Select all

# Example of display backlight control using a button 
import utime
import _thread
from machine import I2C, UART, Pin
from i2c_lcd import I2cLcd
import bme280
import us100

i2c = I2C(0, pins=('GP13', 'GP12'))
lcd = I2cLcd(i2c, 0x27, 4, 20)
bme = bme280.BME280(i2c=i2c)
uart = UART(0, baudrate=9600, bits=8, parity=None, stop=1)
us = us100.US100(uart=uart, bottom_distance=600)

lcd_backlight = 1 # Used to set LCD backlight on (1) or off (1)
button_last_pressed = utime.ticks_ms() # Used for button debouncing

def button_pressed(line):
    """Toggles the value of lcd_backlight variable when the button is pressed""" 
    global lcd_backlight
    global button_last_pressed
    # Button debouncing
    if utime.ticks_diff(button_last_pressed, utime.ticks_ms()) > 200:
        # Toggle lcd_backlight value
        if lcd_backlight == 1:
            lcd_backlight = 0
            lcd_backlight = 1
    button_last_pressed = utime.ticks_ms()

# Initialize button pin and IRQ handler
button = Pin('GP17', mode=Pin.IN, pull=Pin.PULL_UP)
button_irq = button.irq(trigger=Pin.IRQ_RISING, handler=button_pressed)

def backlight_control(arg):
    """Checks the lcd_backlight value and turns the backlight on or off"""
    last_state = 1
    while True:
        if lcd_backlight != last_state:
            if lcd_backlight == 1:
                last_state = 1
                last_state = 0


while True:
    lcd.putstr('Temperature: {0} C\n'.format(bme.read_temperature()//100))
    lcd.putstr('Humidity: {0} %\n'.format(bme.read_humidity()//1024))
    lcd.putstr('Pressure: {0} hPa\n'.format(bme.read_pressure()//25600))
    lcd.putstr('Water level: {0} mm'.format(us.read_liquid_level()))
It works for a while (I can switch the backlight on and off several times), but after approximately one minute it throws following error:

>>> execfile('lcdbutton.py')
Unhandled exception in thread started by <function backlight_control at 0x20034dc0>
Traceback (most recent call last):
File "lcdbutton.py", line 40, in backlight_control
NameError: name not defined

Line 40 is this one:

Code: Select all

if lcd_backlight != last_state:
I would expect wrong code to fail immediately after I try to switch the backlight. But it works in the beginning. Could somebody check my code please?


User avatar
Posts: 4242
Joined: Fri Jul 18, 2014 8:01 am
Location: UK

Re: Wipy multithreading

Post by pythoncoder » Thu Oct 27, 2016 6:18 am

I can't see anything wrong with that.

It's possible you've found a bug in the WiPy firmware - perhaps some interaction between interrupts and threading. I suggest producing a test version of the code with all the device driver stuff stripped out and the LCD displaying something simple like an incrementing count. Perhaps it could be simplified even further, with the LCD removed and the backlight being replaced by toggling a pin. If you can produce a simple test case not needing external hardware it needs reporting as a bug.

Another approach, which would test the idea of an interrupt issue, would be to remove the interrupt handler and poll the button in another thread which does the debouncing. But as far as I can see your code should work.
Peter Hinch

Posts: 20
Joined: Fri Sep 09, 2016 7:53 am

Re: Wipy multithreading

Post by Miguel » Thu Oct 27, 2016 6:38 am

Thanks a lot for checking the code! Once I get home, I will test the stripped version.


Post Reply