1
-
2
1
/*============================================================================
3
2
Filename : touch.c
4
3
Project : QTouch Modular Library
@@ -570,7 +569,7 @@ uint16_t qtouch_get_sensor_node_signal_filtered(uint16_t sensor_node)
570
569
{
571
570
// Filter the sensor signal.
572
571
//
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 .
574
573
// This helps to mitigate 'jumpy' channels that exist at higher sensor readings when
575
574
// in noisy environments.
576
575
//
@@ -592,7 +591,7 @@ uint16_t qtouch_get_sensor_node_signal_filtered(uint16_t sensor_node)
592
591
X = (uint16_t )((double )X * (1 + DEF_SENSOR_EDGE_WEIGHT ));
593
592
}
594
593
// Saturate out-of-range readings.
595
- X = (X > 50 ) ? 50 : X ;
594
+ X = (X > DEF_SENSOR_CEILING ) ? DEF_SENSOR_CEILING : X ;
596
595
597
596
// Calculate sensor readout using a moving average
598
597
// The moving average wieghts previous N readings twice current reading
@@ -630,21 +629,38 @@ void qtouch_process_scroller_positions(void)
630
629
uint8_t i , j ;
631
630
uint16_t sum = 0 ;
632
631
uint16_t max_sensor_reading = 0 ;
632
+ uint16_t min_sensor_reading = DEF_SENSOR_CEILING ;
633
633
uint16_t weighted_sum = 0 ;
634
+ uint16_t filtered_readings [DEF_SCROLLER_NUM_CHANNELS ] = {0 };
634
635
uint16_t sensor_location [DEF_SCROLLER_NUM_CHANNELS ] = {
635
636
1 , // Offset by `1` because a `0` location cannot be weight-averaged
636
637
DEF_SCROLLER_RESOLUTION / 3 ,
637
638
DEF_SCROLLER_RESOLUTION / 3 * 2 ,
638
639
DEF_SCROLLER_RESOLUTION };
639
640
640
- // Read filterd data and weight by sensor physical location
641
641
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 (
644
643
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 ];
648
664
}
649
665
650
666
// Compensate for deadband (i.e. when only a single edge button gives a reading and
0 commit comments