Skip to content

Commit 466a016

Browse files
committed
Merge remote-tracking branch 'douglasbakkum/230222/touchfix'
2 parents b8d3290 + 7820c1e commit 466a016

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ customers cannot upgrade their bootloader, its changes are recorded separately.
1010
- Increased performance when signing Bitcoin transactions
1111
- Warn if the transaction fee is higher than 10% of the coins sent
1212
- ETH Testnets: add Goerli and remove deprecated Rinkeby and Ropsten
13+
- Improved touch button positional accuracy in noisy environments
1314

1415
### 9.13.1
1516
- Fix bug introduced in 9.13.0: remove double cancel confirmation in the 'Restore from recovery words' workflow

src/qtouch/qtouch.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
/*============================================================================
32
Filename : touch.c
43
Project : QTouch Modular Library
@@ -570,7 +569,7 @@ uint16_t qtouch_get_sensor_node_signal_filtered(uint16_t sensor_node)
570569
{
571570
// Filter the sensor signal.
572571
//
573-
// Smooth it out and saturate it so that values never go beyond 50.
572+
// Smooth it out and saturate it so that values never go beyond DEF_SENSOR_CEILING.
574573
// This helps to mitigate 'jumpy' channels that exist at higher sensor readings when
575574
// in noisy environments.
576575
//
@@ -592,7 +591,7 @@ uint16_t qtouch_get_sensor_node_signal_filtered(uint16_t sensor_node)
592591
X = (uint16_t)((double)X * (1 + DEF_SENSOR_EDGE_WEIGHT));
593592
}
594593
// Saturate out-of-range readings.
595-
X = (X > 50) ? 50 : X;
594+
X = (X > DEF_SENSOR_CEILING) ? DEF_SENSOR_CEILING : X;
596595

597596
// Calculate sensor readout using a moving average
598597
// The moving average wieghts previous N readings twice current reading
@@ -630,21 +629,38 @@ void qtouch_process_scroller_positions(void)
630629
uint8_t i, j;
631630
uint16_t sum = 0;
632631
uint16_t max_sensor_reading = 0;
632+
uint16_t min_sensor_reading = DEF_SENSOR_CEILING;
633633
uint16_t weighted_sum = 0;
634+
uint16_t filtered_readings[DEF_SCROLLER_NUM_CHANNELS] = {0};
634635
uint16_t sensor_location[DEF_SCROLLER_NUM_CHANNELS] = {
635636
1, // Offset by `1` because a `0` location cannot be weight-averaged
636637
DEF_SCROLLER_RESOLUTION / 3,
637638
DEF_SCROLLER_RESOLUTION / 3 * 2,
638639
DEF_SCROLLER_RESOLUTION};
639640

640-
// Read filterd data and weight by sensor physical location
641641
for (i = 0; i < DEF_SCROLLER_NUM_CHANNELS; i++) {
642-
uint16_t value;
643-
value = qtouch_get_sensor_node_signal_filtered(
642+
filtered_readings[i] = qtouch_get_sensor_node_signal_filtered(
644643
i + (scroller ? DEF_SCROLLER_OFFSET_1 : DEF_SCROLLER_OFFSET_0));
645-
sum += value;
646-
weighted_sum += value * sensor_location[i];
647-
max_sensor_reading = (value > max_sensor_reading) ? value : max_sensor_reading;
644+
min_sensor_reading = (filtered_readings[i] < min_sensor_reading) ? filtered_readings[i]
645+
: min_sensor_reading;
646+
max_sensor_reading = (filtered_readings[i] > max_sensor_reading) ? filtered_readings[i]
647+
: max_sensor_reading;
648+
}
649+
650+
// Read filterd data and weight by sensor physical location
651+
// Reduce the value by the min_sensor_reading to improve positional accuracy.
652+
// Touch position is calculated with a weighted average of the sensor readings.
653+
// If properly calibrated, sensors on the opposite end of a finger touch would
654+
// be zero and thus make no contribution to the weighted average. If the baseline
655+
// sensor readings are elevated, the sensors on the opposite edge DO contribute
656+
// to the weighted average making a positional artifact (i.e. the position is more
657+
// central than it should be in reality). This artifact is higher when the finger
658+
// is a bit distant while approaching and lower/negligible when the finger is
659+
// fully touching the device. This can cause the position to move enough to enter
660+
// "slide" mode and disable "tap" events being emitted.
661+
for (i = 0; i < DEF_SCROLLER_NUM_CHANNELS; i++) {
662+
sum += filtered_readings[i] - min_sensor_reading;
663+
weighted_sum += (filtered_readings[i] - min_sensor_reading) * sensor_location[i];
648664
}
649665

650666
// Compensate for deadband (i.e. when only a single edge button gives a reading and

src/qtouch/qtouch.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,9 @@ extern "C" {
262262
0.15 // Percent added weight to edge sensors, which are physically smaller
263263
#define DEF_SENSOR_NUM_PREV_POS \
264264
4 // Number of previous sensor positions to remember; used in a simple filter
265+
#define DEF_SENSOR_CEILING \
266+
50 // Maximum sensor reading. Mitigates 'jumpy' channels that exist at higher
267+
// sensor readings when in noisy environments.
265268

266269
#ifdef __cplusplus
267270
}

0 commit comments

Comments
 (0)