Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should uBit.logo work when switched to TouchMode::Resistive? #113

Closed
martinwork opened this issue May 29, 2021 · 10 comments
Closed

Should uBit.logo work when switched to TouchMode::Resistive? #113

martinwork opened this issue May 29, 2021 · 10 comments
Assignees
Labels
Milestone

Comments

@martinwork
Copy link
Collaborator

Does uBit.logo work only in capacitative mode or does the code below use the wrong method to switch modes?

After pressing button A to select TouchMode::Resistive, the logo is always pressed.

This example is intended to match the MakeCode code in microsoft/pxt-microbit#3724.

test-pintouch-v2.zip

#include "MicroBit.h"

MicroBit uBit;

void onButtonA(MicroBitEvent e)
{
    uBit.io.logo.isTouched( codal::TouchMode::Resistive);
}

void onButtonB(MicroBitEvent e)
{
    uBit.io.logo.isTouched( codal::TouchMode::Capacitative);
}

void display()
{
   while (true)
   {
     uBit.display.printChar( uBit.logo.isPressed() ? '1' : '0');
     uBit.sleep(100);
   }
}

int  main() {
    uBit.init();

    uBit.messageBus.listen( MICROBIT_ID_BUTTON_A,  MICROBIT_BUTTON_EVT_CLICK, onButtonA);
    uBit.messageBus.listen( MICROBIT_ID_BUTTON_B,  MICROBIT_BUTTON_EVT_CLICK, onButtonB);

    create_fiber( display);

    release_fiber();
}
@microbit-carlos
Copy link
Collaborator

microbit-carlos commented May 5, 2022

I can confirm that In this example uBit.logo.isPressed() does not work as expected.

uBit.io.logo.isTouched() does work, even when called without setting a TouchMode argument (as it is already changed when button A or B are pressed).

The same can be replicated in MakeCode, as it uses uBit.logo.isPressed(): microbit-logo-touch-change.hex.zip

image

input.onButtonPressed(Button.A, function () {
    basic.showString("r")
    pins.touchSetMode(TouchTarget.LOGO, TouchTargetMode.Resistive)
})
input.onButtonPressed(Button.B, function () {
    basic.showString("c")
    pins.touchSetMode(TouchTarget.LOGO, TouchTargetMode.Capacitive)
})
basic.forever(function () {
    if (input.logoIsPressed()) {
        basic.showIcon(IconNames.Heart)
    } else {
        basic.showIcon(IconNames.Sad)
    }
})

MakeCode C++ code:

@martinwork
Copy link
Collaborator Author

MakeCode block "set logo to touch mode %mode" uses uBit.io.logo.isTouched(mode), but I don’t think uBit.logo supports changing the uBit.io.logo touch mode.

uBit.logo is a TouchButton, whose NRF52Pin (uBit.io.logo) is initially set as output and monitored via GPIOTE events in NRF52TouchSensor (uBit.touchSensor). uBit.logo is not aware of changes to uBit.io.logo via NRF52Pin.

Changing mode with uBit.io.logo.isTouched(Resistive) creates a Button, sets the pin to input, and sets its pull mode, which presumably clashes with the ongoing uBit.logo TouchButton and NRF52TouchSensor GPIOTE code.

Changing mode with uBit.io.logo.isTouched(Capacitive) adds a second TouchButton to uBit.touchSensor, and sets the pin as output again. After that, uBit.logo.isPressed() seems to start working again, though I think it no longer has the “empty timeslot for that channel to drain all its charge before sampling it again”, and MakeCode’s “on logo pressed” block sees double events.

Do we need resistive touch for the logo?

@martinwork
Copy link
Collaborator Author

The Python program below also doesn't work after changing to resistive mode, and the logo is_touched() state always seems less stable than MakeCode, I guess because microbit_hal_pin_is_touched uses uBit.logo.buttonActive(), which misses out on the isPressed() debounced state.

from microbit import *

while True:
    if pin_logo.is_touched():
        display.show(Image.HAPPY)
    else:
        display.show(Image.SAD)
    if button_a.was_pressed():
        pin_logo.set_touch_mode(pin_logo.RESISTIVE)
    if button_b.was_pressed():
        pin_logo.set_touch_mode(pin_logo.CAPACITIVE)

@microbit-carlos
Copy link
Collaborator

Thanks Martin, I can confirm that with the MicroPython example pin_logo when set to resistive is always triggered as "touched".

@microbit-carlos microbit-carlos added this to the v0.2.48 milestone Jan 26, 2023
@microbit-carlos microbit-carlos modified the milestones: v0.2.48, v0.2.49 Jan 27, 2023
@microbit-carlos microbit-carlos modified the milestones: v0.2.49, v0.2.50 Feb 15, 2023
@microbit-carlos microbit-carlos modified the milestones: v0.2.50, v0.2.51 Mar 2, 2023
@microbit-carlos microbit-carlos modified the milestones: v0.2.51, v0.2.52 Mar 27, 2023
@microbit-carlos microbit-carlos modified the milestones: v0.2.52, v0.2.53 May 5, 2023
@microbit-carlos microbit-carlos modified the milestones: v0.2.56, v0.2.59 Jun 15, 2023
@microbit-carlos microbit-carlos removed this from the v0.2.59 milestone Jul 25, 2023
@microbit-carlos
Copy link
Collaborator

Quick summary:

  • uBit.logo default touch mode should be capacitive
  • uBit.io.logo default is not clear, might be either, although ideally it should be capacitive as well
  • Touch for pins default should be resistive (for V1 compatibility)
  • Changing the logo to resistive touch should work (the main problem described in this issue)

@microbit-carlos
Copy link
Collaborator

Okay, a bit more detail:

  • uBit.logo default touch mode should be capacitive

This is correct right now, no action required.

  • uBit.io.logo default is not clear, might be either, although ideally it should be capacitive as well

uBit.io.logo default is resistive, and it should be capacitive:

  • Touch for pins default should be resistive (for V1 compatibility)

This is also correct right now and no action is required.

  • Changing the logo to resistive touch should work (the main problem described in this issue)

This is the topic for this issue.

Additionally

@microbit-carlos
Copy link
Collaborator

microbit-carlos commented Mar 26, 2024

So the main reason that the code in this issue doesn't work is because TouchButton has been designed to be Capacitive only. So, when the touch mode is changed from MicroPython or MakeCode via uBit.io.logo.isTouched(TouchMode) this breaks uBit.logo (TouchButton type).

Three options to fix this issue:

  • Move to uBit.io.logo, as this pin object works for in both modes
    • This does mean that MakeCode (as MicroPython currently does) would have to explicitly call uBit.io.logo.isTouched(Capacitive) on init
  • Update TouchButton so that it can be set to resistive mode
    • This is more work for a low priority bug
  • Declare that the logo cannot be set to resistive mode and remove the functionality from MakeCode & MicroPython
    • This would count as a breaking change.

@microbit-carlos
Copy link
Collaborator

microbit-carlos commented Mar 26, 2024

Conclusion, we'll go for simplest fix:

  • MakeCode to move to uBit.io.logo
  • uBit.init() to set uBit.io.logo to capacitive mode via flag if needed
    • Document this in the appropriate place

@microbit-carlos
Copy link
Collaborator

microbit-carlos commented Mar 27, 2024

Before we can complete this we need to ensure uBit.io.logo is capacitive by default.

PR to set uBit.io.logo to capacitive by default:

MicroPython already uses this method.

Once the PR above is merged, we can submit this to MakeCode, I've tested this with pxt locally and works in resistive mode:

Issue to track in MakeCode:

@microbit-carlos
Copy link
Collaborator

Raised PR:

We can close this ticket now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants