You may wonder whether the edge matters where the sensing sheet is connected. It does not (really). Why: the resistance of the coating from the touch point to the edge is (practically) negligible compared to the ADC pin's input impedance (inner resistance) and therefore practically no power (amperes) flows compared to the power that flows in the powered sheet's resistive coating, which is the voltage divider with the division point at the touch point. In other words, it is as if the pin would connect right there where the touch point is. It's all about Ohm's Law.
And last but not least: your soft, fat finger creates anyway a bit a fuzzy touch area with 'a lot of (electrical) noise'. But because it is fat - compared to the location sensitivity of the touch screen (or pad), there have anyway to be multiple measuring and algorithm that find kind of the center of gravity of the touch point. But to that later.
There are chips out there - touch controllers - that handle all the cases and corner cases, create an interrupt, and deliver (more then less) clean numbers through a simple connection interface (see http://www.espruino.com/ADS7843 - ADS7843 TOUCHSCREEN).
But I want to explore how Espruino can do that, I connect Espruino directly to the edges of the sheets. The mentioned color TFT LCD is (or has) a (transparent) resistive touch screen (on top of the display) and the carrier/breakout board makes the 4 edges available (sequence as on the boards bottom connector from left to right, pins counted from 1...):
// touch2X.js [1v70] [1v99] // updated 20180925
//
// Pin Touch Connected to: Connected to left/right /top/bottom edge
// on LCD Screen Espruino Board of top/bottom sheet... (TBFO)
// Carrier Edges ADC Pin (|||| = touch screen connectors at bottom
// Board Label var Orig Pico left of TFT LCD display)
// 1. 11: +Y pYp C3 B1 '...... sheet' .... edge
// 2. 12: +X pXp C1 A6 '...... sheet' .... edge
// 3. 13: -Y pYn C2 A7 '.......sheet' .... edge
// 4. 14: -X pXn C0 A5 '.......sheet' .... edge
// Uncomment line w/ pin assignments to be used:
//var pXn=C0, pXp=C1, pYn=C2, pYp=C3; // pin assignments Original
var pXn=A6, pXp=B1, pYn=A7, pYp=A5; // pin assignments Pico
var enabled = false; // for start and stop
var minMaxDisplayed = true; // ...and 1st time reads determination
var cnt,cnt0; // for 'new' tap (touch) detection
var x ,xMin ,xMax;
var y ,yMin ,yMax;
var x2,xMin2,xMax2;
var y2,yMin2,yMax2;
var toggle = function() { enabled = !enabled; };
var logXY = function() {
readXY(function(xy) {
if (enabled) {
if (minMaxDisplayed) {
minMaxDisplayed = false;
xMin = 99999; xMax = -9999;
yMin = 99999; yMax = -9999;
xMin2 = 99999; xMax2 = -9999;
yMin2 = 99999; yMax2 = -9999;
cnt = 10000; cnt0 = cnt;
console.log("----- enabled");
console.log("cycle","x ","y "," ","x2 ","y2 "," ","dx dy");
}
cnt++;
x = Math.round(xy.x * 10000) ; y = Math.round(xy.y * 10000);
x2 = Math.round(xy.x2 * 10000) ; y2 = Math.round(xy.y2 * 10000);
if ((x > 1000) || (y > 1000) || (x2 > 1000) || (y2 > 1000)) {
if (cnt > cnt0 + 4) { // tap gap detection - 5[Hz] - 200[ms]
console.log("-----");
}
cnt0 = cnt;
xMin = (x < xMin ) ? x : xMin ;
xMax = (x > xMax ) ? x : xMax ;
yMin = (y < yMin ) ? y : yMin ;
yMax = (y > yMax ) ? y : yMax ;
xMin2 = (x2 < xMin2) ? x2 : xMin2;
xMax2 = (x2 > xMax2) ? x2 : xMax2;
yMin2 = (y2 < yMin2) ? y2 : yMin2;
yMax2 = (y2 > yMax2) ? y2 : yMax2;
console.log(cnt,x,y,"-",x2,y2,"d#",(x-x2),(y-y2));
}
} else {
if (!minMaxDisplayed) {
minMaxDisplayed = true;
console.log("----- Min/Max values for x, y, and x2, y2:");
console.log("x [",xMin ,"..",xMax," ] - y [",yMin ,"..",yMax ,"]");
console.log("x2[",xMin2,"..",xMax2,"] - y2[",yMin2,"..",yMax2,"]");
console.log("----- disabled");
}
}
});
setTimeout("logXY();",50); // 20[Hz] sample rate - 50[ms]
};
var readXY = function(callback) {
var xy = {};
pXn.set();
pXp.reset();
analogRead(pYn);
analogRead(pYp);
setTimeout(function(){
xy.x = analogRead(pYn);
xy.x2 = analogRead(pYp);
pYn.set();
pYp.reset();
analogRead(pXn);
analogRead(pXp);
setTimeout(function(){
xy.y = analogRead(pXn);
xy.y2 = analogRead(pXp);
callback(xy);
},1);
},1);
};
function onInit() {
enabled = true;
logXY();
}
setTimeout(onInit,1000);
After sending to the board, the code immediately starts running. With a frequency of 20Hz - twenty times per second / in 50[ms] intervals - it invokes the self explanatory logXY() function. Since the code is initialized with var enabled = false, the main part of the function body is skipped. At the end of the method, the method sets a timeout - of 50[ms] - for self-invocation.
After enabling with command toggle(); in command pane, the code initializes some control values and various minimum and maximum variables, and prints a header in the console pane for the values to be logged (lines 27..36). Furthermore, the code starts to count in cnt variable - from 10000 upwards for aligned column oriented output - the cycles - 20 per second - as defined by the setTimeout (line 65) and invokes the reading of x and y (voltage) values. Since the reading needs some setup and settling time, the statistics / calculation and logging is passed as a callback to the readXY() function. More about that readXY() function a bit later.
The callback code will detect when a touch happens by the fact that any of the x or y values are beyond a certain threshold: 1000 (line 40). The threshold's value was determined by some code tinkering and is touch screen dependent. The initial value ranging from 0.0000 to 1 is multiplied by 10000 and rounded to an integer (line 38) to trigger the set threshold, and to ease the - optical - tracking of value changes and detecting value and value change patterns. When the threshold is overstepped, the current cnt counter is checked against the past cnt2 counter and if there is a difference of more than 4 (missed cycles - 200[ms], line 41), the touch (tap) is considered a new one. past cnt2 is updated to current cnt as long as the touch keeps going (line 44).
Lines 45 thru 52 do statistics to keep track of the minimum and maximum values.
Finally, line 53 prints the following values:
Cycle as counted by cnt variable. It is consecutive for each touch or tap including related moving/draggin on the touch screen. A new touch (or tap) related value sequence is separated from the previous one by a line of five (5) dashes (with posthume added comment about the touch/drag action).
x and y values - as read from one edge of the sensing sheet.
x2 and y2 values - as read from other edge of the sensing sheet.
the differences between x and x2 and y and y2.
As you can see, the difference of the values from both edges are very small compared to the read values (with a few exceptions). This proofs, that is sufficient to read just from one edge of the sensing sheet. Codes touch2.js (as shown above) and touch3.js (reading from one edge of the sensing sheet only) are attached as files at the very bottom of this post.
The reading algorithm with its settings of the pins and stabilization times is in lines 68 thru 87 - implemented as readXY() function.
@Gordon, could you please comment on optimal pin setting and reading including timing and provide advice? = From what I understood from other implementations is that it is crucial for clean measuring that no output conflicts are there and powering of the to-power sheet has to stabilize, as well as the sensing ADC pin has to be ready and eventual capacitive energy has been discharged before measurements are taken. Most applications take multiple measurements and increase the accuracy of the (virtual) touch point coordinates.
If the same effects can be achieved with less statements the better. Because when integrated into any other apps, every spared (cpu) cycle will be welcome to not just detect a touch or swipe, but more so to process it and its related biz or tech process.
So much for now. Next steps will be to get some basic algorithm for increasing accuracy of mapping of read value to actual coordinate on screen. For that, some material is there done as part of designing dedicated touch controllers (see http://www.ti.com/lit/an/sbaa036/sbaa036.pdf, http://www.ti.com/lit/an/slyt277/slyt277.pdf, and most helpful http://www.ti.com/lit/an/sbaa155a/sbaa155a.pdf - Reducing Analog Input Noise in Touch Screen Systems). After that a module will be sketched that includes also some basic calibration support - Do you remember when you had to tap with your stylus X-es in the corners and center of the screen?
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
But there is also some good news:
You may wonder whether the edge matters where the sensing sheet is connected. It does not (really). Why: the resistance of the coating from the touch point to the edge is (practically) negligible compared to the ADC pin's input impedance (inner resistance) and therefore practically no power (amperes) flows compared to the power that flows in the powered sheet's resistive coating, which is the voltage divider with the division point at the touch point. In other words, it is as if the pin would connect right there where the touch point is. It's all about Ohm's Law.
And last but not least: your soft, fat finger creates anyway a bit a fuzzy touch area with 'a lot of (electrical) noise'. But because it is fat - compared to the location sensitivity of the touch screen (or pad), there have anyway to be multiple measuring and algorithm that find kind of the center of gravity of the touch point. But to that later.
There are chips out there - touch controllers - that handle all the cases and corner cases, create an interrupt, and deliver (more then less) clean numbers through a simple connection interface (see http://www.espruino.com/ADS7843 - ADS7843 TOUCHSCREEN).
But I want to explore how Espruino can do that, I connect Espruino directly to the edges of the sheets. The mentioned color TFT LCD is (or has) a (transparent) resistive touch screen (on top of the display) and the carrier/breakout board makes the 4 edges available (sequence as on the boards bottom connector from left to right, pins counted from 1...):
These are the delivered values:
After sending to the board, the code immediately starts running. With a frequency of 20Hz - twenty times per second / in 50[ms] intervals - it invokes the self explanatory logXY() function. Since the code is initialized with var enabled = false, the main part of the function body is skipped. At the end of the method, the method sets a timeout - of 50[ms] - for self-invocation.
After enabling with command toggle(); in command pane, the code initializes some control values and various minimum and maximum variables, and prints a header in the console pane for the values to be logged (lines 27..36). Furthermore, the code starts to count in cnt variable - from 10000 upwards for aligned column oriented output - the cycles - 20 per second - as defined by the setTimeout (line 65) and invokes the reading of x and y (voltage) values. Since the reading needs some setup and settling time, the statistics / calculation and logging is passed as a callback to the readXY() function. More about that readXY() function a bit later.
The callback code will detect when a touch happens by the fact that any of the x or y values are beyond a certain threshold: 1000 (line 40). The threshold's value was determined by some code tinkering and is touch screen dependent. The initial value ranging from 0.0000 to 1 is multiplied by 10000 and rounded to an integer (line 38) to trigger the set threshold, and to ease the - optical - tracking of value changes and detecting value and value change patterns. When the threshold is overstepped, the current cnt counter is checked against the past cnt2 counter and if there is a difference of more than 4 (missed cycles - 200[ms], line 41), the touch (tap) is considered a new one. past cnt2 is updated to current cnt as long as the touch keeps going (line 44).
Lines 45 thru 52 do statistics to keep track of the minimum and maximum values.
Finally, line 53 prints the following values:
As you can see, the difference of the values from both edges are very small compared to the read values (with a few exceptions). This proofs, that is sufficient to read just from one edge of the sensing sheet. Codes touch2.js (as shown above) and touch3.js (reading from one edge of the sensing sheet only) are attached as files at the very bottom of this post.
The reading algorithm with its settings of the pins and stabilization times is in lines 68 thru 87 - implemented as readXY() function.
@Gordon, could you please comment on optimal pin setting and reading including timing and provide advice? = From what I understood from other implementations is that it is crucial for clean measuring that no output conflicts are there and powering of the to-power sheet has to stabilize, as well as the sensing ADC pin has to be ready and eventual capacitive energy has been discharged before measurements are taken. Most applications take multiple measurements and increase the accuracy of the (virtual) touch point coordinates.
If the same effects can be achieved with less statements the better. Because when integrated into any other apps, every spared (cpu) cycle will be welcome to not just detect a touch or swipe, but more so to process it and its related biz or tech process.
So much for now. Next steps will be to get some basic algorithm for increasing accuracy of mapping of read value to actual coordinate on screen. For that, some material is there done as part of designing dedicated touch controllers (see http://www.ti.com/lit/an/sbaa036/sbaa036.pdf, http://www.ti.com/lit/an/slyt277/slyt277.pdf, and most helpful http://www.ti.com/lit/an/sbaa155a/sbaa155a.pdf - Reducing Analog Input Noise in Touch Screen Systems). After that a module will be sketched that includes also some basic calibration support - Do you remember when you had to tap with your stylus X-es in the corners and center of the screen?
Codes attached as files touch2X.js:
1 Attachment