Bounce, responsiveRead and velocity for touchRead()

joshnishikawa

Active member
[Originally posted in the wrong thread. Sorry!]

I thought there should be something like the Bounce library for touchRead() inputs. So I adapted all those functions: risingEdge(), fallingEdge(), duration(), rebounce() etc. and added a few other features like the auto detection of the usable touchRead() range (as it varies depending on your setup and circumstances). There's also an option to make an input latchable.

I thought there should be a simple way to get quieter variable input too. So I included the "TouchVariable" class for that. And I remembered someone asking about the possibility of velocity sensitivity using touchRead() and I haven't been able to let go of that idea. So there's a "TouchVelocity" class for that.

See the video
https://youtu.be/q51Z1SEb8Cw

or the code.
https://github.com/joshnishikawa/Flicker
 
That looks Very Cool! Useful extension of touch and well played on the drum line/stick/bar ...

What is in the drum bar for sensors?
 
That looks Very Cool! Useful extension of touch and well played on the drum line/stick/bar ...

What is in the drum bar for sensors?

Thank you! The controller is literally just 5 pieces cut from a biscuit tin and sandwiched between a strip of sponge tape and a strip of duct tape.

IMG_5214.jpgIMG_5219.jpg

Next time I won't run the wires under the pads though. You can probably imagine that there's a lot of interference. But, if done right, it could be the makings of very inexpensive velocity-sensitive controllers. It even works on a banana!


Caveat: I've only gotten this to work under a very specific set of circumstances (laptop on battery power, Teensy stuck directly into the banana). And even then, the responsiveness doesn't stay consistent. But the first step was proving it could be done.
 
I've been playing around with the Flicker library a little bit. It initially worked great, but then I added a couple extra touch switches and I seem to have broken the debounce function. Am I initializing the touch switches properly in the setup void?

Code:
  myPowerSwitch.setThreshold();
  myPowerVariable.setInputRange();

  myInputSwitch.setThreshold();
  myInputVariable.setInputRange();

  myOutputSwitch.setThreshold();
  myOutputVariable.setInputRange();
 
Yes, that looks fine. There was a known issue that caused the quiescent touchRead() value to go above the offThreshold when using the ADC. This meant that the input would never go off. Two questions...

Is that what you are experiencing?
Do you happen to be using analogRead() anywhere in your code?

I went ahead and pushed a version of the library with improved setInputRange() and setThreshold() functions to address this. I'm still fine tuning them but please update your library and see if that fixes it.
 
I'm trying to put together software to control an integrated amplifier. On initial power up there seems to be a 50/50 shot that the power button and input selector will work perfectly but within a few seconds they start to malfunction. Touching the power button will cause the supply to rattle off and on about 6 times. Input selection will scroll through 5 or 6 inputs. Output selection flies through the outputs too.

I'm not using analogRead for anything, but I am talking to port expanders and temperature sensors with the wire library and using a couple interrupts for DC detection of the output and overcurrent. The touch switches are a few inches from a switch mode supply but there's a steel shield between them and the supply, possibly this may be affecting the threshold as well?

I'll try out the updated library later this evening and let you know how it works.
 
I've done a little more testing this morning. What I've been finding is on initial power up the touch functions work great. After a short time (a couple seconds) the debounce function is gone on all of the touch switches. If I apply power and don't touch any buttons for a few seconds, the debounce function doesn't work at the first button touch. To me it seems like a timing value is overflowing like an "int" was declared where a long should have been used. On line 75 of the Touch_Velicity.cpp I see the following.

" newValue = map(int(timer), 9000, MAX_VELOCITY, outHi/2, outHi);"

Could int(timer) be where my issue is coming from? (Just trying to learn here, I'm a newby to the Arduino world)
 
To me it seems like a timing value is overflowing like an "int" was declared where a long should have been used

No, that 'timer' is an elapsedMillis so it should be fine. I don't think you're using the TouchVelocity class anyway (you only had functions for TouchSwitch and TouchVariable). You can use those functions with specific values too.

myPowerSwitch.setThreshold(int threshold);
myPowerVariable.setInputRange(int min, int max);

Just throw a touchRead() for the power switch pin and a Serial.println() for that value at the bottom of your code. Wait until myPowerSwitch stops working and then take note of the reading you get in the Serail Monitor when you lightly touch it. Replace 'threshold' with that number. Repeat for the other objects.

Meanwhile I'll mess around with Wire and go bug hunting.
 
Last edited:
Hi

Is there a reason for a fixed onThresHold/ offThreshold ratio?

onThreshold = qval * 1.2; // Threshold for rising edge
offThreshold = qval * 1.1; // Slightly lower for falling edge

Depending on the front panel I find 20% a bit high.
 
Is there a reason for a fixed onThresHold/ offThreshold ratio?

The only reason they're fixed values is for the sake of simplicity. You can instantiate with a specific value as a threshold but a specific percentage would be pretty complicated to implement.

As for why it's 1.2 and 1.1, also mainly for simplicity but also for stability. Touch readings can get pretty jumpy but, yeah, 20% may be overkill. As long as there's no overlap between an untouched reading, a reading near the offThreshold and a reading near the onThreshold, I'm open to suggestions for better numbers to use.
 
The only reason they're fixed values is for the sake of simplicity. You can instantiate with a specific value as a threshold but a specific percentage would be pretty complicated to implement.

As for why it's 1.2 and 1.1, also mainly for simplicity but also for stability. Touch readings can get pretty jumpy but, yeah, 20% may be overkill. As long as there's no overlap between an untouched reading, a reading near the offThreshold and a reading near the onThreshold, I'm open to suggestions for better numbers to use.
I'll play with it some time. And try some different sensor layout's (distance, adding ground traces between sensors etc...)

Did I read the code correct that after detecting a falling edge the duration is placed at zero?
So that it's a bit complicated to measure the "on" time?

(same for rising edge)
 
...after detecting a falling edge the duration is placed at zero?
So that it's a bit complicated to measure the "on" time?

Good point! The (newer) Bounce2 library has a previousDuration() function that provides that info. I'll work on implementing that in this library.
 
Version 1.1.4 of the Flicker library is now available either from the Arduino Library Manager or https://github.com/joshnishikawa/Flicker/releases/tag/1.1.4.

This update includes a previousDuration() method that will give you the duration (in milliseconds) of the previous state. As AlainD pointed out, this could be useful within fallingEdge() or risingEdge() to tell you how long the input was touched or not (respectively). Incidentally, you can also use the more concise rose() and fell() now.
 
New version works like a charm.

One remark.
I use a custom touchRead that also does a pulldown after reading.

I do a manual read off all the pins before the setThreshold() call's to get them "pulled down" before calculating the Threshold. Maybe just calling setThreshoold() twice is better.


pinMode(pin, INPUT_PULLDOWN);
 
Back
Top