adafruit / pxt-crickit

pxt package for crickit platform - beta
MIT License
8 stars 4 forks source link

Cap touch is not intuitive #10

Open deanm1278 opened 6 years ago

deanm1278 commented 6 years ago

Cap touch pins are intended to be read as buttons but currently the block returns an analog value, which must be combined with an extra logic >= block with a number threshold to detect a touch.

I think the touchRead block should use a default threshold (700 or so) and return true if >= threshold, or false if < threshold. An extra block can be added if the threshold for any particular cap touch pin needs to be overridden.

dhalbert commented 6 years ago

In CircuitPython, when the Touch object is first instantiated, we read the pin (we assume it is not being touched). We use that value + 100 as the touch threshold. This has worked fairly well.

deanm1278 commented 6 years ago

that's a good idea. (putting this here mainly for myself) I think the way to do it here is to instantiate lazily so the first time any CT pin is read it will record that as the ambient value.

pelikhan commented 6 years ago

users mostly access buttons via events in MakeCode so you should add an event handler that starts a background fiber that polls the state of cap touch... unless the crickit firmware is able to detect events and surface them in seesaw

pelikhan commented 6 years ago

Auto-calibration sounds great. Maybe we should apply that to the CPX apis as well.

dhalbert commented 6 years ago

The only problem with auto-calibration is if someone is touching the pads when the program starts. Perhaps that could be documented. In practice I don't remember that ever coming up as a support issue.

deanm1278 commented 6 years ago

I would also like to implement the button event. Crickit firmware could detect cap touch events and surface them, but since there is no default IRQ pin connected on the hardware a register would have to be polled by the host regardless to check for those events. Since this wouldn't eliminate the need for a poll, and would require users to update their firmware in order to use the feature I would prefer to do implement on the host.

@pelikhan Is starting a background fiber something that can be done from makecode? It seems redundant to have to rewrite and upkeep essentially the same library on two layers (makecode and codal) of the same application. Can I do something like this (copy pasted from code peli sent me one time):

control.runInBackground(() => {
   ctPin.ambient = seesaw.touchRead(ctPin.pin) //get the ambient value on thread start
   while(true) {
           //poll the value
           let val = seesaw.touchRead(ctPin.pin)
           if(val > ctPin.ambient + 100){
               f() //call the function if threshold is exceeded
           }
           pause(20) //sleep for hot min
    }
}
pelikhan commented 6 years ago

We already have a polling fiber that powers the "pauseUntil" block. You should be able to call control.__queuePollEvent(timeOut: number, condition: () => boolean, handler: () => void)

function onButtonDown(handler: () => void) {
    control.__queuePollEvent(0, seesaw.touchRead(ctPin.pin) > ctPin.ambient + 100, handler);
}

We also have a new package, "controller" in pxt-common-packages that we use for arcade.

deanm1278 commented 6 years ago

ok great I'll try that when it's time to implement.

nickine9 commented 4 years ago

when using a crickit with a microbit and makecode the cap touch pads fo not recognise multiple simultaneous touches. touching one pin is detectable but when another pad is touched the values for all pads change to their untouched values