No announcement yet.

Multi-Touch with Gen4-uLCD-70DCT-CLB, Diablo16, 4DGL and FT5x36 ( capacitive Touch)?

  • Filter
  • Time
  • Show
Clear All
new posts

  • Multi-Touch with Gen4-uLCD-70DCT-CLB, Diablo16, 4DGL and FT5x36 ( capacitive Touch)?

    I use a Gen4-uLCD-70DCT-CLB smart display with capacitive touch to replace a very old LCD display with mechanical buttons. The display is connected with a serial channel to an embedded system.
    For compatibility reasons, I had to use an old protocol on the serial channel, which is implemented with 4DGL on the Diablo16. The GUI was made with the Workshop IDE. The Touch-Events for GUI-Elements are working as expected, but...

    To stay compatible, I have to detect two simultaneously pressed GUI-Buttons. (I tried to search the forum for „Multi Touch“ but I could not find any hint...)

    Are there library functions to get more than one touch point?

    I already know, that the hardware (Focaltech FT5x36/FT5x46?) can detect at least 5 touch points, but how can I use touch_Get(), img_Touched(), touch_TestArea() and friends to detect two simultaneously pressed GUI-Elements?

    As long as the first Button is pressed I don‘t see the second touch.
    Any hint is welcome.

  • #2
    You can't do it using the functions you've listed as they cannot be effectively used for multitouch.

    You can, however, disable touch and read the registers yourself.

    I've attached a program that demonstrates how to do this.
    Attached Files


    • #3
      Thanks for the sample program. It's working and I have to change my own project accordingly.

      I know how to change touch_Get(TOUCH_GETX) and touch_Get(TOUCH_GETY), but what about touch_Get(TOUCH_STATUS), which returns TOUCH_PRESSED, TOUCH_RELEASED and TOUCH_MOVING.

      How do I have to replace img_Touched(hndl, -1)?
      Does this function internally call touch_Get(TOUCH_GETX) and touch_Get(TOUCH_GETY) or is there a possibility to pass the position to test from external?
      pokeW(TOUCH_RAW_X) for example?

      Is there sample code available for these function to implement multi touch behaviour?

      Thanks a lot so far.
      Best regards,


      • #4
        Whilst you can pokeW(TOUCH_RAW_X), these are not the Touch values you think the are. They are 'RAW' values used and generated by internal touch. They are not set or used by capacative touch.

        A lot more happens inside the touch routines that is important to correct operation, but not immediately apparent.

        I was thinking you could 'simply' disable touch at the point where you need the two touches and use an adaption of the supplied code at that point. But it's not that simple, as if you don't take all current touch values 'as a whole' you can miss things important to the integrity of the whole.

        You also need to allow for the fact that the positions of TP1 and TP2 can flip to be TP2 and TP1 at any time, you will see that occasionally in the demo.

        Then I got to thinking about using the 'RAW' values that are not used by CT and whether they could be populated and used as the second second touch value.

        Try the attached sample, you will need the driver included in the zip before this can work. Also note the comments at the top. You may be able to simplify this code for your use if you don't need the 'up' and 'down' button actions. It will become more complex if you need to handle sliding off the buttons.

        Let me know how you go.
        Attached Files


        • #5
          I think the problem with flipping positions in the 1st sample program can be solved, if you use the TouchID associated with the Touch-Position,
          that is reported by the FT5x36 instead of the index within the report.

          I changed the following lines in your 1st sample to get consistent colors for the remaining touch points, even if you lift one finger:
          tid := ((gCTPData[3+i*6] & 0xf0) >> 4); // Associated TouchID
          gfx_PutPixel(y,x,cols[tid]) ; // x and y swapped! Use TouchID from report instead of index to select color of pixel

          I attached an adapted version of your 1st sample program.

          Attached Files


          • #6
            I tried to use your 2nd sample program. I extended the function check_other(), to use it as a simplified replacement for img_Touched().
            (Please correct me, if scanning the object list is wrong.)

            func MyImg_Touched(var *pH, var x, var y)
            var result := -1, o;
            var *pB;
            for (o:=0; o<pH[IMG_COUNT]; o++)
            pB := pH + pH[IMG_ENTRYLEN] * o + 8; // address xywh directly in handle for entry to test
            if (gfx_PointWithinBox(x,y, pB))
            result := o; // Hit!
            return result ;

            What is still causing headache is how to properly detect all Press- Release- and Move-Events.
            I guess the following table does not yet contain all situations?
            touch_Get(TOUCH_STATUS) peekW(TOUCH_RAW_X) Description
            NOTOUCH -1 No Touch at all
            TOUCH_PRESSED -1 SingleTouch Pressed-Event
            TOUCH_MOVING -1 SingleTouch Moving-Event
            TOUCH_RELEASED -1 SingleTouch Released-Event
            NOTOUCH 2ndTouch?? Doesn't make sense? Not allowed or might occur spuriously?
            TOUCH_PRESSED 2ndTouch TwoTouch Pressed-Event
            What happens, if 2ndTouch is released first.
            TOUCH_MOVING 2ndTouch Detection of two moving points can be left for future extensions...
            TOUCH_RELEASED 2ndTouch?? I assume, that 2ndTouch will be reported by touch_get() in the next cycle.

            If there is a 2ndTouch, I would like to call my handler two times. The first time with
            x_p := touch_Get(TOUCH_GETX);
            y_p := touch_Get(TOUCH_GETY);
            n:= MyImg_Touched(hndl,x_p, y_p);

            and the 2nd time with
            x_p := peekW(TOUCH_RAW_X); // get 2nd touch x + y
            y_p := peekW(TOUCH_RAW_Y);
            other := MyImg_Touched(hndl,x_p, y_p);

            For the 1st run the Event can be determined by touch_Get(TOUCH_STATUS).
            I think for the 2nd run
            the value of TOUCH_RAW_X has to be tracked to get the same information.
            -1 --> 2ndTouchPosition TOUCH2_PRESSED
            2ndTouchPosition1 --> 2ndTouchPosition2 TOUCH2_MOVING
            2ndTouchPosition --> -1 TOUCH2_RELEASED

            Duplicating the handler for the 2ndTouch is unluckily no option, bcause it would exhaust the remaining space.

            Thanks for your help. All hints are welcome...


            • #7
              The way I see it the only thing that is missing is the detection of touch moving for the second touch, but any attempt to calculate this is made almost impossible as the touches might swap. You suggest this can be solved using TID, but really, just how 'accurate' is this if both touches are very close together.

              NOTOUCH - 2ndTouch?? - Not possible
              TOUCH_RELEASED - 2ndTouch?? - will be the release of the second touch, the first release will appear as a 'jumped' (assuming the two touches are a fair way apart) touch moving.

              I thought you were just trying to detect a 'dual' touch type situation. It would appear that what is there now is sufficient to do that?


              • #8
                The topic ca be marked as solved for two simultaneously pressed buttons.
                Some additional work on the application side was necessary to track the state of the 2nd Touch to get it working as expected.
                It‘s not yet very comfortable, but at least doable.
                Thanks for your help.