Troubleshooting Touchscreen Display (eGalax) on Linux

955 views
Skip to first unread message

aquadisco

unread,
May 12, 2014, 11:21:42 PM5/12/14
to kivy-...@googlegroups.com
How do i begin troubleshooting issues with my touchscreen controller?  I've verified the touchscreen input is working with X11 apps and have calibrated the input.  As shown below, Kivy seems to be correctly finding it (i verified it is indeed the device on event0 using evtest).  My application, i think, is step to capture all types of input events and it works when i use a mouse.

Where do i begin with this?  

Console:
[DEBUG  ] [Base        ] Create provider from mouse,disable_multitouch
[DEBUG  ] [Base        ] Create provider from probesysfs,provider=hidinput
[DEBUG  ] [ProbeSysfs  ] using probsysfs!
[DEBUG  ] [ProbeSysfs  ] found device: eGalax Inc. USB TouchController at /dev/input/event0
[INFO   ] [ProbeSysfs  ] device match: /dev/input/event0
[INFO   ] [HIDInput    ] Read event from </dev/input/event0>
[INFO   ] [Base        ] Start application main loop
[INFO   ] [HIDMotionEvent] using <eGalax Inc. USB TouchController>

Code Snippet:

class MyKivyApp (App):
    def build(self):
    
        ...   

        Window.bind(on_touch_down=self.on_touch_down)
        Window.bind(on_motion=self.on_motion)
        Window.bind(on_touch_move=self.on_touch_move)

        ...

    # Event Handlers
    def on_touch_down (self, *arg):
        print 'on_touch_down'
    def on_motion(self, *arg):
        print 'on_motion'
    def on_touch_move(self,*args):
        print 'on_touch_move'   




evtest:
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0xeef product 0x1 version 0x100
Input device name: "eGalax Inc. USB TouchController"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 330 (BTN_TOUCH)
  Event type 3 (EV_ABS)
    Event code 0 (ABS_X)
      Value    994
      Min        0
      Max     2047
    Event code 1 (ABS_Y)
      Value    846
      Min        0
      Max     2047



aquadisco

unread,
May 13, 2014, 9:11:36 PM5/13/14
to kivy-...@googlegroups.com
Update:

I've update libts to the latest as of today.  this includes various patchs supporting version 0100 of the touch screen.  Can calibrate touchscreen using ts_calibrate, test with ts_test, etc.  Still not input seen from Kivy.

Ricardo Beck

unread,
Jun 30, 2014, 5:53:21 AM6/30/14
to kivy-...@googlegroups.com
Hi,

I have a similar problem. Touchscreen "eGalax", working fine in X11 (on a raspberry pi btw). But I can't get it to work in kivy. The Kivy debug console shows the Input Device the same way as aquadisco posted before (i'm not able to paste logs at the moment...), also evtest works. As far as I unterstand this, the X11 calibration doesn't matter to kivy, because it runs in framebuffer. So there has to be an issue somewhere with the "hidinput" (tried other providers in the config.ini, to no avail). If the evtest-application can access the touchscreen, so should kivy?  Any help would be greatly appreciated.

Thanks.

Ricardo Beck

unread,
Jul 3, 2014, 7:09:01 AM7/3/14
to kivy-...@googlegroups.com
Hey!

I found a solution!

Disclaimer: I know this is a terrible hack, but it's the only way i found to get my touchscreen to work with Kivy on Raspberyy Pi. Also I don't know if this applies to Linux in general or if it's just an issue with the rpi-port of Kivy.
This is a individual solution for my use case. This breaks mouse-input and disables anything else except touchscreen. it's fine though because my embedded pi-project has no mouse connected.

This solution ignores any calibration files or tslib-drivers. You have to do the calibration manually, but it's not so hard

First step: disable all input devices in ~/.kivy/config.ini except the touchscreen (make backup)

[input]
# comment out 'probesysfs' stuff
egalax
= hidinput,/dev/input/event0   #replace event number with your own

Ok, the problem is: Kivy doesn't recognize the EV_KEY code BTN_TOUCH (330) sent by the touchscreen (verify with evtest). So I edited the kivy/input/providers/hidinput.py: (BACKUP)

In the routine process_as_mouse(), add the marked lines before the definition of "buttons". This simply converts the key-code from a touch to a left-click, so kivy recognizes it.

def process_as_mouse(...):
             
[...]
               
elif ev_type == EV_KEY:
                   
### MOD: convert the egalax BTN_TOUCH to a mouse left click
                   
if ev_code == 330: ## Add this
                        ev_code
= 272  ##Add this

                    buttons
= {
                       
272: 'left',
                       
273: 'right',
                       
274: 'middle',
                       
275: 'side',
                       
276: 'extra',
                       
277: 'forward',
                       
278: 'back',
                       
279: 'task'}

I tested everything with the touchtracer demo from the kivy examples, which is extremely helpful, because with the crosshair you see every touch even it is outside the visible screen-area

So after the modification above, you should be able to see the input from the touchscreen when you touch it. But the position is total rubbish, because we now emulate a mouse, and a mouse gives relative position values, while a touchscreen gives absolute values.

Now the calibration: use evtest to find out your min and max values for each axis and write them down. also take note if the x and y axes are swapped and if they need to be inverted (minimum-X is left, minimum-Y is bottom)

add these values to .kivy/config.ini:
[input]
# comment out 'probesysfs' stuff
egalax
= hidinput,/dev/input/event0,min_position_x=200,max_position_x=1950,min_position_y=0,max_position_y=2000,swap_axes=1,invert_y=1,invert_x=1
### insert your values

again edit hidinput.py to add the 'swap_axes' option, which is not supported initially
class HIDInputMotionEventProvider(MotionEventProvider):
    ### MOD: add 'swap_axes' to possible options
        options = ('min_position_x', 'max_position_x',
                   'min_position_y', 'max_position_y',
                   'min_pressure', 'max_pressure',
                   'invert_x', 'invert_y', 'swap_axes')

then in routine _thread_run():

        def _thread_run(self, **kwargs):

            [...]
            range_min_position_x = 0
            range_max_position_x = 2048
            range_min_position_y = 0
            range_max_position_y = 2048
            range_min_pressure = 0
            range_max_pressure = 255
            invert_x = int(bool(drs('invert_x', 0)))
            invert_y = int(bool(drs('invert_y', 0)))

          ### Add the following
            swap_axes = int(bool(drs('swap_axes',0)))
            min_position_x = int(drs('min_position_x',0))
            max_position_x = int(drs('max_position_x',0))
            min_position_y = int(drs('min_position_y',0))
            max_position_y = int(drs('max_position_y',0))

this makes the calibration values available in the program (no idea why this isn't the case in the first place...)

Last step: in routine process_as_mouse():
            def process_as_mouse(tv_sec, tv_usec, ev_type, ev_code, ev_value):

######## DELETE THIS:
elif ev_type == EV_REL:

    if ev_code == 0:
        point['x'] = \
            min(1., max(0., point['x'] + ev_value / 1000.))
    elif ev_code == 1:
        point['y'] = \
            min(1., max(0., point['y'] - ev_value / 1000.))


###### AND REPLACE WITH THIS:

elif ev_type == EV_ABS: #IMPORTANT, TS gives absolute position

    if ev_code == 0:
        if swap_axes:
            val = normalize(ev_value,
                min_position_y,
                max_position_y)
            if invert_y:
                val = 1. - val

            point['y'] = val
        else:
            val = normalize(ev_value,
                min_position_x,
                max_position_x)
            if invert_x:
                val = 1. - val

            point['x'] = val
    elif ev_code == 1:
        if swap_axes:
            val = normalize(ev_value,
                min_position_x,
                max_position_x)
            if invert_x:
                val = 1. - val
           
            point['x'] = val
        else:
            val = normalize(ev_value,
                min_position_y,
                max_position_y)
            if invert_y:
                val = 1. - val

            point['y'] = val

have a close look at the indentation and correct if necessary.(i wrote this post on windows and created the py-file on linux, so the copy&paste messed up somehow)

save and try the touchtracer demo. this should work now (at least it works for me on raspberry)

keep in mind we changed a kivy-specific file, so this will most likely be reverted, when kivy is updated.

Also excuse my grammar ;)

Hope this helps

Regards, Spritkopf

lijinqi...@163.com

unread,
Mar 1, 2015, 8:37:46 PM3/1/15
to kivy-...@googlegroups.com
hi,do you have test https://github.com/kivy/kivy/issues/2656

在 2014年5月13日星期二 UTC+8上午11:21:42,aquadisco写道:
Reply all
Reply to author
Forward
0 new messages