• 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...):

    // 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);
    

    These are the delivered values:

    >toggle()
    =undefined
    ----- enabled
    cycle x    y      x2   y2      dx dy  (post run added comment)
    -----                           ...was tap in top left corner
    10146 1338 908 - 1345 903 d# -7 5
    10147 1340 896 - 1348 906 d# -8 -10
    ----- 
                                    ...was tap in top right corner
    10172 8569 999 - 8574 1003 d# -5 -4
    10173 8567 1006 - 8562 999 d# 5 7
    10174 8557 1003 - 8555 996 d# 2 7
    10175 8450 288 - 8323 405 d# 127 -117
    -----                           ...was top in bottom left corner
    10204 1543 8565 - 1538 8587 d# 5 -22
    10205 1533 8574 - 1528 8574 d# 5 0
    10206 1531 8555 - 1526 8560 d# 5 -5
    10207 1526 8567 - 1533 8565 d# -7 2
    -----                           ...was tab in bottom right corner
    10232 437 415 - 569 8633 d# -132 -8218
    10233 8518 8655 - 8508 8650 d# 10 5
    10234 8486 8650 - 8499 8648 d# -13 2
    10235 8499 8648 - 8504 8662 d# -5 -14
    10236 8508 8665 - 8511 8655 d# -3 10
    10237 8489 8682 - 8486 8672 d# 3 10
    -----                           ...was tap in (about) the center 
    10270 4829 4763 - 4829 4746 d# 0 17
    10271 4836 4753 - 4854 4761 d# -18 -8
    10272 4834 4756 - 4827 4753 d# 7 3
    10273 4834 4763 - 4829 4763 d# 5 0
    -----                           ...horizontal line starting in top left corner 
    10304 1448 894 - 1448 903 d# 0 -9
    10305 1638 974 - 1638 969 d# 0 5
    10306 2344 1050 - 2346 1045 d# -2 5
    10307 3274 1106 - 3274 1108 d# 0 -2
    10308 4622 1089 - 4612 1091 d# 10 -2
    10309 5684 1150 - 5686 1157 d# -2 -7
    10310 6729 1184 - 6734 1177 d# -5 7
    10311 7537 1157 - 7532 1157 d# 5 0
    10312 8113 1123 - 8125 1116 d# -12 7
    10313 8284 1138 - 8279 1226 d# 5 -88
    -----                           ...vertical line starting in top left corner
    10333 1433 1091 - 1426 1091 d# 7 0
    10334 1423 1416 - 1426 1433 d# -3 -17
    10335 1377 2512 - 1389 2522 d# -12 -10
    10336 1428 3867 - 1436 3877 d# -8 -10
    10340 1272 7954 - 1262 7947 d# 10 7
    10341 1265 8552 - 1255 8557 d# 10 -5
    -----                           ...diagonal line starting in top left corner
    10370 393 1116 - 520 1111 d# -127 5
    10371 1643 1812 - 1633 1819 d# 10 -7
    10372 2427 2874 - 2432 2881 d# -5 -7
    10373 3276 3867 - 3281 3879 d# -5 -12
    10374 4116 4795 - 4124 4788 d# -8 7
    10375 5217 5830 - 5234 5830 d# -17 0
    10376 5977 6758 - 5982 6751 d# -5 7
    10377 6912 7578 - 6914 7571 d# -2 7
    10378 7334 7952 - 7341 7947 d# -7 5
    10379 7764 8245 - 7766 8255 d# -2 -10
    10380 7857 8389 - 7839 8381 d# 18 8
    10381 7859 8589 - 7891 8587 d# -32 2
    -----                           ...diagonal line starting in bottom left corner
    10406 1382 8650 - 1382 8667 d# 0 -17
    10407 1631 8362 - 1633 8352 d# -2 10
    10408 2302 7559 - 2322 7556 d# -20 3
    10409 3355 6453 - 3359 6443 d# -4 10
    10410 4587 5125 - 4583 5134 d# 4 -9
    10411 5689 3997 - 5693 3994 d# -4 3
    10412 6697 2986 - 6692 2981 d# 5 5
    10413 7422 2200 - 7439 2205 d# -17 -5
    10414 7952 1523 - 7944 1523 d# 8 0
    10415 8338 1160 - 8347 1152 d# -9 8
    >toggle();
    =undefined
    ----- Min/Max values for x, y, and x2, y2:
    x [ 393 .. 8569  ] - y [ 288 .. 8682 ]
    x2[ 520 .. 8574 ] - y2[ 405 .. 8672 ]
    ----- disabled
    >
    

    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:

    1. 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).
    2. x and y values - as read from one edge of the sensing sheet.
    3. x2 and y2 values - as read from other edge of the sensing sheet.
    4. 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/sbaa15­5a.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

About

Avatar for allObjects @allObjects started