Reading ADC value at Runtime and callback functions based on voltage level

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
Post Reply
urbanspaceman
Posts: 4
Joined: Fri Jun 24, 2022 10:29 am

Reading ADC value at Runtime and callback functions based on voltage level

Post by urbanspaceman » Fri Jun 24, 2022 10:33 am

Hi, need to understand a thing
i have this piece of code

Code: Select all

set_mode = 0
def main():
    global set_mode 
    
    while True:
        adc = ADC(Pin(26, mode=Pin.IN))
        adc_voltage = adc.read_u16() * 3.3 / 65535
        
        #MODE SELECTOR
        if adc_voltage < 1:
            print("MODE 2")
            set_mode = 2
            
        elif adc_voltage > 1 and adc_voltage < 3:
            print("MODE 1")
            set_mode = 1
            
        else:
            print("MODE 0")
            set_mode = 0
            
        mode_select.mode_select(set_mode)
        
        print(adc_voltage)

main()
adv_voltage is a 3 position switch with different voltage in each position
all works fine but when the script runs, if i change the switch position, nothing change in the logs monitor (monitor print MODE 1 thousand of time)

what solution can i adopt?

Thanks!

User avatar
karfas
Posts: 193
Joined: Sat Jan 16, 2021 12:53 pm
Location: Vienna, Austria

Re: Reading ADC value at Runtime and callback functions based on voltage level

Post by karfas » Fri Jun 24, 2022 2:18 pm

It might be useful to print the value of adc_voltage so you know WHY mode X gets printed.
A few hours of debugging might save you from minutes of reading the documentation! :D
My repositories: https://github.com/karfas

Lobo-T
Posts: 36
Joined: Tue Nov 16, 2021 2:36 pm

Re: Reading ADC value at Runtime and callback functions based on voltage level

Post by Lobo-T » Fri Jun 24, 2022 2:25 pm

And maybe do the ADC initialisation outside the loop?

urbanspaceman
Posts: 4
Joined: Fri Jun 24, 2022 10:29 am

Re: Reading ADC value at Runtime and callback functions based on voltage level

Post by urbanspaceman » Fri Jun 24, 2022 2:35 pm

Ok, made some progress with multithread

in the main I have this code

Code: Select all

from machine import ADC
import utime
import _thread
import appselect_module

mode = 0

def readVoltage():
        analogValue = ADC(26)
        return analogValue.read_u16() / 65536 * 3.3
    
def main():
    global mode
    
    while True:
        if mode == 1:
            print("MODE 1")
            utime.sleep(2)
        if mode == 2:
            print("MODE 2")
            utime.sleep(2)
        if mode == 0:
            print("MODE 0")
            utime.sleep(1)
            appselect_module.appSelect(mode)
            
def mode():
    global mode
    
    while True:
        
        reading = readVoltage()

        print(reading)
        
        if reading > 1 and reading < 3:
            """
            MODE 1: App run
            """
            mode = 1
            utime.sleep(1)
        elif reading < 1:
            """
            MODE 2: Riserva
            """
            mode = 2
            utime.sleep(1)
        else:
            """
            MODE 0: App selection
            """
            mode = 0
            utime.sleep(1)

_thread.start_new_thread(mode, ())

while True:
    main()
while in the appselect_module.py I have

Code: Select all

import machine
import time
import _thread

from primitives.pushbutton import Pushbutton
import uasyncio as asyncio

import hal
import functions

prev_app = 1
next_app = 0
total_apps = 6

functions.allLedOff()
machine.Pin(hal.leds[prev_app]).low()

def appSelect():
    while True:

        def app_select():
            global prev_app 
            global next_app 
            global total_apps
          
            machine.Pin(hal.leds[prev_app]).low() #program precedente
            
            if prev_app == 0:
                machine.Pin(hal.leds[total_apps]).high()
                machine.Pin(hal.leds[0]).high()
            else:
                machine.Pin(hal.leds[prev_app]).high()
                
            next_app = prev_app + 1
            machine.Pin(hal.leds[next_app]).low()

            if next_app >= total_apps:
                prev_app = 0
            else:
                prev_app = next_app
                
        def app_confirm():
            print("confirm")
          
           

        def button():
            
            pb = Pushbutton(hal.button)
            pb.press_func(app_select, ())  # Callback on button press
            pb.long_func(app_confirm, ())  # Callback on long press
            while True:
                await asyncio.sleep(1)
                        
        try:
            asyncio.run(button())
        finally:
            asyncio.new_event_loop()       
Now, partially work
I correctly run the app_slection function
but then, when I change my switch, I need to go to MODE 1
instead I'm stuck in the app_selection (even though I see that the change of state has been read correctly)

User avatar
karfas
Posts: 193
Joined: Sat Jan 16, 2021 12:53 pm
Location: Vienna, Austria

Re: Reading ADC value at Runtime and callback functions based on voltage level

Post by karfas » Sun Jun 26, 2022 1:18 pm

This forum is not a "find-the-bugs-in-my-code-for-cheap" bot.

Please learn to debug your programs for yourself. One useful technique is to sprinkle print() statements around and confirm that the program works as you think it does.
A few hours of debugging might save you from minutes of reading the documentation! :D
My repositories: https://github.com/karfas

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Reading ADC value at Runtime and callback functions based on voltage level

Post by jimmo » Mon Jun 27, 2022 2:26 am

urbanspaceman wrote:
Fri Jun 24, 2022 2:35 pm
Ok, made some progress with multithread
I would be very careful about mixing asyncio and thread, and also any situation where you run the async event loop just for a short segment of the program is likely to cause confusion.

I don't see any parts of this program that benefit from thread -- it would be much simpler to use asyncio for the whole thing -- just use asyncio.run() at the start and run the whole program from that initial task.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Reading ADC value at Runtime and callback functions based on voltage level

Post by pythoncoder » Mon Jun 27, 2022 4:50 pm

@urbanspaceman You might be interested in this AADC class. It lets you create uasyncio tasks which pause until the ADC is within certain ranges.
Peter Hinch
Index to my micropython libraries.

Post Reply