Linux notes: Configuring XP-Pen drivers on Linux

When you plug in your Xp-pen graphic tablet into your Linux machine (i am running xubuntu-18.04), you will notice that the XP-Pen that you are using will be detected in the ‘Mouse and Touchpad’ settings tab:

Screenshot_2019-12-21_14-44-36

But the pen may not work! Although the device is enabled, writing on the drawing tablet using the pen does not have any effect. If you stumble upon this problem then there is a fairly simple solution that will resolve this issue:
Solution:

The solution that worked was downloading the Linux Beta driver from the xp-pen’s official website ( https://www.xp-pen.com/download-55.html )

Screenshot_2019-12-21_15-01-07(i) Make a dedicated directory *:

mkdir /home/User/Linux

(ii) Unzip all the contents of the downloaded Linux Beta driver from xp-pen’s website into ‘/home/User/Linux/’ directory

Here’s what my Linux directory looked like :

Screenshot_2019-12-21_15-05-39

(iii) Make Pentable_driver.sh as executable

cd /home/User/Linux
chmod +x Pentablet_Driver.sh

(iv) Connect your device and run Pentablet_Driver.sh

(sudo) ./Pentablet_Driver.sh

Screenshot_2019-12-21_15-09-39

The above screen should pop up and your device should work ! Open gimp to test it out.

 

** I had to make a dedicated directory titled Linux and place it under the home directory for this to work. Else I constantly  run into issues loading the xp-pen’s library files. I tested on two Xubuntu machines and both had the same issue. But this may not been a necessary step for other distros.

It is ridiculously easy to generate any audio signal using Python

Updated: May 15,2019

Now it comes as a surprise to many people when I tell them that generating an audio waveform is extremely simple.

One needs to have basic understanding on how audio signals work and basic python programming to generate any audio wave form. This post will show you exactly how.

Python packages needed: Numpy, Scipy

Screenshot_2019-05-15_11-06-02

How to play the audio the generated audio file on computer ?

1. Command line using SoX

play -t raw -r 44.1k -e signed -b 8 -c 1 test.wav

where -r = sampling rate -b = sampling precision (bits) -c = number of channels

2. Use Audacity (check video)

 

Link to code : GitHub

You can find a list of other waveforms that can be generated using SciPy here

Known Issues:

[1] This does add any headers to the audio file and therefore you cannot play it on any media player as is . Check this reddit post if you really want to have one.

[2] Adding headers to the above code seems to be making it slower. And this is a problem if you want to make larger audio files.

[3] The code generates only 8-bit audio signal. Feel free to play around with the code to change it to other formats.

[4] A lot of technical details were conveniently not included in code in order to appeal to the theme of this post. And therefore this code is not “efficient”.

Exploring /dev/input

Linux is one of those operating systems in which once you know your way around, you are unstoppable. In this post, we will explore what you can possibly do with access to /dev/input directory. Now you typically need to have superuser privileges to access this directory but there is a way around it. ( check this stackexchange )

The /dev directory

This is the directory in Linux that contains all the device files for all the devices that are on your system.

/dev/input – The input is a subdirectory that holds the device files for various input devices such as mouse, keyboard, joystick and so on.

Screenshot from 2017-04-18 22:10:46

This is a screenshot of my input directory and as you can see there is the mice/mouse0/mouse1 which are files corresponding to the touchpad/wired mouse/wireless mouse respectively. And then you have these ‘eventX’ files. Yours might look similar but depending on the nature of your device you might have more or less options available.

eventX

With so many event files, how can one possibly know which one corresponds to which ? This script is what you need:

cat /proc/bus/input/devices

This script would display relevant information about all the input devices connected to your system. Here’s a sample output for the Lid switch :

Screenshot from 2017-04-18 13:04:47

Now what we want is the event handler number for the lid switch which we can see from the information as event0. And through this one can map all the events with their corresponding devices.

Alternative method:

An alternate approach to doing this is to look at /dev/input/by-id or /dev/input/by-path, they have symbolic links to /dev/input/event<x>. But the only downside to this is that it does not display all the possible devices. We will discuss how to read from both in this post.

Let’s read the data stream !

Say you want to read the mouse file, you only need to open the file using ‘cat’ and start moving the mouse.

(sudo) cat /dev/input/event5

Screenshot from 2017-04-18 22:57:25

You would observe that as you are moving the mouse a stream of data is being dumped onto your screen. This data although seems crazy contains the information for the movement of the mouse.

Interpreting the input stream

The format for the input stream is given in the Linux documentation as follows:

struct input_event {
	struct timeval time;
	unsigned short type;
	unsigned short code;
	unsigned int value;
};

struct timeval – 16

unsigned short – 2 ( x 2 )

unsigned int – 4

Total size = 24 bytes

What this means is the first 16 bytes of data contain the system time, which in our case is not essential. The rest 8 bytes of data contain the actual relevant values. This is the output format of all eventX files.

Reading the mouse

Reading the mouse is probably the simplest to start with because one does not need to go through the trouble of accessing any eventX files. The mouse file in the /dev/input directory outputs a stream of 3/4 bytes ( Button value, x , y ).

You would get a 4 byte stream if the mouse is configured with the scroll wheel. Unfortunately in my case, even though I use a mouse with a scroll wheel, it was configured as a PS2 mouse. ( If you are in a similar situation – read this)

mouse_usb

Map of the (x, y) data with the corresponding directions

My touchpad and wireless mouse do not have any special buttons and therefore when the button values are mapped with the corresponding clicks, I got the following :

Left_Button – 9

Right_Button – 10

Scroll_Button – 12

When I was going through this stackexchange, the code seemed to suggest different values for the each of these buttons.

Python Code for reading mouse:

import struct 
f = open( "/dev/input/mice", "rb" ); 
# Open the file in the read-binary mode
while 1:
  data = f.read(3)  # Reads the 3 bytes 
  print struct.unpack('3b',data)  #Unpacks the bytes to integers

Video Demo:

Reading the keyboard

Much like the mouse, one can opt for an easier way by just reading from the /dev/input/by-id or /dev/input/by-path, but for the love of it let’s try to play around with eventX files. Let’s go about this step by step.

  1.  Find the event handler number for the keyboard ( Mine was event5 )
  2.  Reading the byte data and converting it to the format specified in the Linux Documentation using the struct module in python
  3.  Extracting the relevant information from the converted data.

 

Python code for reading keyboard:

import struct 
f = open( "/dev/input/event4", "rb" ); # Open the file in the read-binary mode
while 1:
  data = f.read(24)
  print struct.unpack('4IHHI',data)
  ###### PRINT FORMAL = ( Time Stamp_INT , 0 , Time Stamp_DEC , 0 , 
  ######   type , code ( key pressed ) , value (press/release) )

Video Demo:

Other eventX ?

What should you do if you would like to read from another eventX file ? Well, from my experience I can share with you this. : The first 16 bytes in the file are always almost the time stamp and you can read only that data by:

struct.unpack('4I',data[:16])

The rest depends on the type of output which you can find out by using the evtest program.

sudo evtest /dev/input/eventX

 

** Now in theory, using uinput one can reverse engineer to emulate events. But we are still currently working on that. If you know anything about this, please ping us at 153armstrong@gmail.com

 

Headphone jack plugged in or not ?(#1)

In an upcoming post, we will be talking in depth about the /dev/input directory in Linux and this is like a teaser to that post. This video talks about how the computer knows whether a headphone jack has been plugged in or not from a software point of view.

The series will cover in detail on what is happening in the back-end and we will also write python programs to read this data on our own without needing any external libraries.

Getting Started with the USB to TTL converter

So, I purchased one of these USB to TTL converters, It seemed like a really powerful thing  to work with. But I did not have the slightest clue on how to work with them. So, I played around a bit and was able to send and receive serial data using the converter.  Here’s what I did:

Step-1 – Finding the Serial port

There are ways to check the active serial port on Ubuntu using the command line but probably the easiest way to check is by connecting the converter and opening up the Arduino IDE.

Now if you have nothing connected to it, the Serial Port section would be greyed out.
001

But once you insert your converter onto it, then you can immediately determine the serial port that converter has been connected to. In this case (see pic) it is ttyUSB1.
002

Step-2 – Writing the client program

Now that we have our serial ports ready, we need to write a simple program in Python that to read the data that will be sent to us.

client.py 

import serial
ser = serial.Serial('/dev/ttyUSB1', 9600)

while 1:
    serial_line = ser.readline()
    print serial_line

Now our client program will print every line of serial data that is receives.

Step-3 – The server

Now that the client server is up and running, its time to set up the server. I just opened the serial port for transmission and left it at that.

Screenshot from 2017-04-15 00:09:05

The command for the transmission of serial data is write i.e

ser.write(data) 

data - Data to send 

returns the number of bytes written

Step-4 Testing

1111

Finally, the TX and RX pins of the converter are shorted by using a jumper wire. That’s about it !

Whatever is sent through the TX port will now be received through the RX port. Everything has been setup. Now we can transmit and receive data !
Video Demo: