jacklinquan/micropython-aiobutton

Example with ADC.WIDTH_12BIT

beyonlo opened this issue · 7 comments

Hi, nice project.

Could you please to provide a example working with ADC.WIDTH_12BIT instead ADC.WIDTH_10BIT?

I tried to change the MAX_ADC to 4095 and change the button up to lambda btn: (MAX_ADC // 12) < adc_up_down.read() <= (MAX_ADC // 12 * 2) and the button down to btn_down = AIOButton(lambda btn: (MAX_ADC // 12 * 2) < adc_up_down.read())

Unfortunately is printing just DOWN is released! State:False when I press and release the button.

I'm using the ESP32-S3 and it not accept 10bit, just 12bit.

Thank you very much!

Hi @beyonlo ,

What's the adc reading when none of the buttons is pressed, and the readings when you press each button respectively?

What's the adc reading when none of the buttons is pressed, and the readings when you press each button respectively?

@jacklinquan I have just one button for press/release, so just one GPIO number. Follow the test:

>>> from machine import Pin, ADC
>>> adc_up_down = ADC(Pin(12))
>>> adc_up_down.atten(ADC.ATTN_11DB)
>>> adc_up_down.width(ADC.WIDTH_12BIT)
>>> adc_up_down.read() # Button released
4095
>>> adc_up_down.read() #Button pressed
0

Is that what do you requested?

Thank you!

Hi @beyonlo ,

The up and down buttons example is for multiple (2 or even more) buttons sharing a single GPIO of the micro using ADC function. So it saves GPIOs when the micro needs to monitor a lot of buttons.
It requires a little bit knowledge on electronic circuit. The buttons sharing the same GPIO are connected to a simple resistor network. So that when different button is pressed (only one at a time), the voltage on the GPIO is different. Thus the ADC reading is different.
In your case as per your code, when the up button is pressed, the ADC reading should be between 341 and 682, and when the down button is pressed, the ADC reading should be higher than 682. When none of them is pressed, the reading should be lower than 341.
So your hardware must support this logic.
An easier way is to configure your hardware first, and do some experiment to watch these values. Then set up these ranges accordingly.

Example schematic:
68747470733a2f2f342e62702e626c6f6773706f742e636f6d2f5f6d68757548523064786e552f5446374b65736e35676d492f4141414141414141454e672f4a6552437450326f4e4e732f73313630302f616e616c6f675f627574746f6e5f696e7075742e706e67

Hi @beyonlo ,

I read your question again, and I found I could have misunderstood your question.
Do you mean that you want to show "Pressed" when the button is pressed and show "Released" when the button is released?
If this is the case, you just need to set up both "press handler" and "release handler" for the button:

btn_down.set_press_handler(
    lambda btn: print("DOWN is pressed! State:{}".format(btn.get_debounced()))
)
btn_down.set_release_handler(
    lambda btn: print("DOWN is released! State:{}".format(btn.get_debounced()))
)

The up and down buttons example is for multiple (2 or even more) buttons sharing a single GPIO of the micro using ADC function. So it saves GPIOs when the micro needs to monitor a lot of buttons. It requires a little bit knowledge on electronic circuit. The buttons sharing the same GPIO are connected to a simple resistor network. So that when different button is pressed (only one at a time), the voltage on the GPIO is different. Thus the ADC reading is different. In your case as per your code, when the up button is pressed, the ADC reading should be between 341 and 682, and when the down button is pressed, the ADC reading should be higher than 682. When none of them is pressed, the reading should be lower than 341. So your hardware must support this logic. An easier way is to configure your hardware first, and do some experiment to watch these values. Then set up these ranges accordingly.

Example schematic: 68747470733a2f2f342e62702e626c6f6773706f742e636f6d2f5f6d68757548523064786e552f5446374b65736e35676d492f4141414141414141454e672f4a6552437450326f4e4e732f73313630302f616e616c6f675f627574746f6e5f696e7075742e706e67

Hello @jacklinquan

I understand about to use more than one button for one ADC pin, using a resistor network electronic, but why is not possible to use just one button if in the example code that there is in the README.md is about to use just one button on the ADC? The pin on the README.md is the pin number 32 - look there. I'm confuse. Maybe you can to say that if I need just one button, I do not need to use a ADC, where I can to use a normal GPIO. You are right, but I will to use more than one button in the same pin, but for now I have just one button and would like to validate your code using ADC in one button.

Well, I'm trying just to use exactly that example in the README.md, but not works for me, because adc_up_down.width(ADC.WIDTH_10BIT) (as the example in README.md) do not works, so i changed to adc_up_down.width(ADC.WIDTH_12BIT). With this change when I press and release the pin (following the README.md example) do not works very well, I mean, just the btn_down.set_release_handler() works, the btn_up.set_press_handler() do not works.

Follow my example based on the README.md example. Observe that I get out the part about he pin_enter. So for this example I have just one button to press/release.

$ cat test1.py 
from machine import Pin, ADC
import uasyncio as aio
from aiobutton import AIOButton

# Button UP and DOWN share a single ADC on pin 32.
adc_up_down = ADC(Pin(12))
adc_up_down.atten(ADC.ATTN_11DB)
adc_up_down.width(ADC.WIDTH_12BIT)
MAX_ADC = 4095

# Initialise the button with a handler that takes one argument (the button itself).
# This handler should return True when the button is pressed, or False otherwise.
# Default button check time is 10ms, debounce time 50ms and hold time 1000ms.
btn_up = AIOButton(
    lambda btn: (MAX_ADC // 12) < adc_up_down.read() <= (MAX_ADC // 12 * 2)
)
# Press handler is triggered when the button is pressed down.
btn_up.set_press_handler(
    lambda btn: print("UP is pressed! State:{}".format(btn.get_debounced()))
)

btn_down = AIOButton(lambda btn: (MAX_ADC // 12 * 2) < adc_up_down.read())
# Release handler is triggered when the button is released.
btn_down.set_release_handler(
    lambda btn: print("DOWN is released! State:{}".format(btn.get_debounced()))
)

async def main():
    task_up = aio.create_task(btn_up.coro_check())
    task_down = aio.create_task(btn_down.coro_check())
    while True:
        await aio.sleep_ms(1)

aio.run(main())
$ mpremote run test1.py 
DOWN is released! State:False
DOWN is released! State:False
DOWN is released! State:False
DOWN is released! State:False

See, just DOWN works.

Thank you very much!

Hi @beyonlo ,

I see what is the problem.
In the example, btn_up and btn_down are two different buttons. UP and DOWN are the names of the buttons.
Since you have only one button, let's say it is btn_down.
The code should be like this:

from machine import Pin, ADC
import uasyncio as aio
from aiobutton import AIOButton

# Button DOWN uses a single ADC on pin 12.
adc_down = ADC(Pin(12))
adc_down.atten(ADC.ATTN_11DB)
adc_down.width(ADC.WIDTH_12BIT)
MAX_ADC = 4095

# Initialise the button with a handler that takes one argument (the button itself).
# This handler should return True when the button is pressed, or False otherwise.
# Default button check time is 10ms, debounce time 50ms and hold time 1000ms.
btn_down = AIOButton(lambda btn: (MAX_ADC // 2) < adc_down.read())
# Press handler is triggered when the button is pressed down.
btn_down.set_press_handler(
    lambda btn: print("DOWN is pressed! State:{}".format(btn.get_debounced()))
)
# Release handler is triggered when the button is released.
btn_down.set_release_handler(
    lambda btn: print("DOWN is released! State:{}".format(btn.get_debounced()))
)

async def main():
    task_down = aio.create_task(btn_down.coro_check())
    while True:
        await aio.sleep_ms(1)

aio.run(main())

Hello @jacklinquan

I see what is the problem. In the example, btn_up and btn_down are two different buttons. UP and DOWN are the names of the buttons.

Ohh, I'm sorry, that was the names of the buttons, not up and down for the same button. Now all make sense!

Thank you to provide me a example to works with just ONE button (for press and release), it works perfect.

Thank you very much!