Showing posts with label touchscreen. Show all posts
Showing posts with label touchscreen. Show all posts

Sunday, January 4, 2015

Raspberry PI CarPC January 2015 updates


Hi,
Here are the updates I have recently worked on:
 - migration to KODI stable 14.0
 - Raspbian OS from 24 december 2013
 - linux kernel 3.18.1 with touchscreen drivers
 - updates to Radio and Navigation addons

You can install the build using the tutorial link on the right side of the blog. Please don't forget about the forum for any comments.

Enjoy the screenshots and Happy new Year!







Saturday, February 8, 2014

OpenCarPC

Hi!

I have worked on some new features for my CarPC. Here are the changes:
First, some videos:

The latest image can be downloaded from the Downloads link on the right of this blog(username:pi, password:a).
Note!
If you do not have any rotary encoder connected or any buttons with a resistor you need to disable the carpc-controller application. You can do this by editing the file /home/pi/StartCarPC and commenting the line which contains carpc-controller.

Hardware updates:
- added ViewHd HDMI to HDMI+audio board
- added SI4703 FM Radio module
- created an expansion board with fm radio module and three connectors(one for GPS receiver and two for rotary encoders)
- added a very cheap board to mix two output channels(RPI and radio) into a single output(which goes to the amplifier, in my case AUX input of the car player)

Software updates:
- added loading movie(created by Doru Ignat)
- added a python server responsible for controlling the radio module via i2c
- added new XBMC plugin for controlling the FM Radio(including storing up to 5 radio stations in a file)
- improved carpc-controller to support sending multiple commands for a single button press or encoder turn(e.g. turning right one rotary encoder can increase the volume in XBMC and the volume of radio at the same time)
- improved the speed in Navit clicking
- improved the Navit OSD for both day and night setup(Navit switches automatically teh setup based on the time of the system).
- added time synchronization mechanism based on GPS readings(RPI does not have a real time clock)

The expansion board.

RE1 and RE2 are rotary encoders.

The FM Radio driver and Python server.
The FM Radio module is connected using i2c communication interface(GPIO0-SDA and GPIO1-SCL of the PI).
The radio driver is contained in the si4703 python class. The Radio server is implemented in the file radio_server.py(which is automatically started at boot time). This server simply opens a socket and waits for data. After any data is received, a couple of if-else statements different radio functions are called base on the incoming data.
The available commands are:
seek_right - search for a new station in the right of the current frequency
seek_left - search for a new station in the left of the current frequency
tune_xx.x - set the current frequency to xx.x MHz
volume_xx - set the volume of the radio module to xx. xx should be between 0 and 15
toggle_mute - toggle mute
get_frequency - get the current frequency
The server reply with the current frequency for each command.

Simple test.
To understand how this radio server-client works you can make the folowing experiment:
1. Plug the gpio expansion board(or wire the radio module to the PI as in the above schematic)
2. [Server] Connect using one ssh window(I use Putty) to the PI and enter the folowing commands:
cd radio
sudo python radio_server.py
The radio server should initialize the  radio module and start the server.
3. [Client] go to the radio folder and use radio_client.py to send commands o the radio server, like in the folowing picture:
The file radio_client.py simply opens an UDP socket, puts an '_' character between arguments and send the obtained string to the server socket.

The radioFM XBMC plugin.
In order to simplify user interaction I have created a new XBMC plugin(radioFM). Its purpose is to allow interacting with the Radio Server(and with the Radio Module) using the touch screen. In order to be able to use this plugin you need to have the radio_server.py started and the FM module plugged in.
Features:
  • The current frequency is displayed at the top.
  • The left and right arrow buttons are for seeking to the next channel(left or right).
  • The bottom 5 buttons are preset channels(these are kept in a file so they are available after reboot).
  • The Set/Tune Channels button is used for changing the mode in which the bottom buttons are operating. By default they are in the 'Tune' mode, so if you presss them the radio will tune to that frequency. If you press the Set/Tune Channels button once you will enter the Set mode, which will allow you to store the current channel in which preset button you like(or in all of them... if you want) by pressing it once. You will see that the frequency will be changed.
Connecting two audio sources(RPI and Radio) to one amplifier.
In order to correctly hook up two audio sources together(putting them in parallel) for a single output you have to use one schematic from this document. I have used the last schematic. Don't forget to use at least 1% tolerance for the resistors.

The new GPIO controller.
The GPIO controller is now using the official XBMC client code from xbmcclient.h.
Now, you can call a lot more XBMC functions for any button pressed or encoder movement.

TODO List:
- update to the latest Raspberry PI firmware(today it is possible but then Navit won't be visible)
- remove the calibration file for XBMC(/usr/share/eGalax/touchscreen_axes_calib) and use the values from the Debian calibration file(/usr/share/X11/xorg.conf.d/01-input.conf)
- create an XBMC addon to allow calibrating the touch screen for both XBMC and X11 windows and also for calibrating the external encoders and button
- create a configuration page(XBMC addon) for the carpc-controller settings
- create a better audio mixer unit
- create a new page for launching different X11 applications

Saturday, August 31, 2013

OpenElec with support for eGalax touch screen

Hi!

Lately I have tested OpenElec for Raspberry PI and found out that it is very very fast, very very small and also it has some great addons(wifi, bluetooth and more).
Speed/size features on an 512MB RaspberryPI:
  - a complete boot is less than 25 seconds
  - cpu is around 30% load
  - memory used is 32%
  - total system size is less than 300MB

Edit. You can download my build from here(contains eGalax module and XBMC patches).
Username is root and password is openelec. The touch screen calibration file should be put in /storage/touchscreen_axes_calib.

Next, I will guide you through the instructions for building(cross compile) latest OpenElec  for Raspberry PI with touch screen support.
For this tutorial let's assume that you have a Linux machine where you will work.

1. Get the latest OpenElec.
git clone git://github.com/OpenELEC/OpenELEC.tv.git

2. Add kernel touch screen module support.
Open the file OpenELEC.tv/projects/RPI/linux/linux.arm.conf and search for "CONFIG_INPUT_TOUCHSCREEN". Replace the whole text line with the following lines:
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_USB_COMPOSITE=y
CONFIG_TOUCHSCREEN_USB_EGALAX=y
3. Fix ppl version in OpenElec.
Open the file OpenELEC.tv/packages/toolchain/math/ppl/meta and change PKG_VERSION from "1.1pre9" to "1.1pre10"

4. Put touch screen calibration file into the system.
Navigate to folder OpenELEC.tv/projects/RPI/ and create the file usr/share/eGalaxCalibration/touchscreen_axes_calib. This file should have the following contents:
calib_x_d=-21;calib_x_fact=0.658097686;calib_y_d=-50;calib_y_fact=0.408626561;swap_axes=0;click_confines=8
To set up these values please visit this post(at section 4).
This step is not needed any more, because you can use the calibration addon to calibrate your screen.
Get the calibration addon from my Downloads folder and put it in /storage/.xbmc/addons/

5. Put XBMC 12.3 patch.
Get my latest patches from here and put them in the folder OpenELEC.tv/packages/mediacenter/xbmc/patches/

6. Build OpenElec.
Navigate to OpenElec folder and type:
PROJECT=RPi ARCH=arm make -j3
-j3 option is to use parallel build(if you have more than one cpu's set this number as nb_cpus+1). This option will speed up the build process.
The build process will take couple of hours, but you have to come back once(in the first 10 minutes) and press ENTER for the kernel touch screen modifications to be approved.

7. Install or Update your OpenElec card.
Go to OpenElec build instructions page for RPI and follow the "Install instructions" chapter.

Have fun!

Tuesday, August 6, 2013

Car PC project(August 2013 update)

This is an update for my CarPC project.
You can download the latest image from the link on the top right corner of this blog(username:'pi', password:'a').
The main features are:
Hardware:
Software:
[Operating System]
    - Raspbian Wheezy 9.February.2013
    - Custom kernel 3.6.11
        - eGalax touch screen module
        - si470x usb radio module
        - snd-usb-audio module

[Media Center]
    - omxplayer
    - XBMC 12.2 Frodo
        - media formats supported:  listed here
        - sources with objects build on 27.July.2013
        - skin: CarPC-touch(download current version)
            - system shutdown button(safely stop xbmc and safely halt)
            - reload skin button
            - switch to camera view button
        - modified spectrum analyzer(OpenGL with no rotation)
        - eGalax touch screen calibrated
        - eGalax touch screen click&drag fix
        - black rectangle behind XBMC removed
        - patch to add getMousePosition feature to xbmcgui module(used to redirect clicks from the Navigation skin page to X11 using xdotool)

[Navigation]
    - Navit build from source
    - Zoom In, Zoom Out buttons
    - Click sent from XBMC to X11 (Navit Window)

GPS Setup
1. Connect GPS module to UART TX, UART RX, GND and 3.3V or on a usb port.
2. If you are using an UART GPS module, as I did, use this tutorial or any other to setup UART communication.
3. Connect GPS to gpsd:
sudo apt-get install gpsd
gpsd /dev/ttyAMA0

Adding maps to Navit
In order to add new maps to Navit, there is a simple process. First, go to Navit Planet Extractor and download your desired area file(this will be a .bin file).
After this, transfer the file to your Raspberry PI in the folder /home/pi/navit_export/build/navit/maps/. Here, you should also update the existing .xml file and add another entry for your new map. My .xml file is looking like this:
<map type="binfile" data="$NAVIT_SHAREDIR/maps/osm_bbox_11.3,47.9,11.7,48.2.bin" />
<map type="binfile" data="$NAVIT_SHAREDIR/maps/osm_bbox_20.3,43.5,29.9,48.4.bin" />
You can rename your .bin files for easier management

Car Modding
I had to relocate my original Radio/CD player in the trunk and keep it set on aux input source. This included buying about 60m of wires and also harness:
1. Metra 71-9003 Bmw Mini Factory Radio OEM Wire Harness
2. Scosche VW03B 2002+ Vw Audi BMW Radio Stereo Harness

 front without OEM Radio/CD player
trunk with relocated OEM Radio/CD player
Mounted Raspberry PI in the armrest
Safety:
    - The wires are 2mm in diameter with good insulation, resistant at temperature variations
    - I have added fuses(1.5A for the radio, 1A for Raspberry PI, 1A for display, 0.1A for reverse camera trigger, 0.1A for reverse camera video signal)

Bugs:
     - sound pops(will soon disappear by using this hdmi to hdmi and audio splitter)
    - Navigation is behind Video Player -> Navigation isn't visible while playing videos(this isn't a big issue)

Tuesday, February 26, 2013

Raspberry PI, Raspbian, XBMC and eGalax 7 inch touchscreen

Hello!

I have spent some time lately trying to find a solution to get my 7 inch eGalax touchscreen to work with  Raspbian(Debian Wheezy) in XBMC 12 Frodo and finally got it working as I wanted.

My Setup
  • Raspberry PI model B: ~30$
  • 7 inch display with touchscreen for car rear view camera, from eBay(touchscreen is connected to one USB port): 80$
  • HDMI male to HDMI male connector(from eBay): <2$
  • 4GB SDHC class 4 card
  • 12V(500mA) AC to DC adapter for powering the display
  • 5V(1A) microUSB AC to DC converter for powering the PI
  • USB keyboard


Edit:  Download the latest image from the top right corner of this blog(username: pi, password: a).

Here is what you need to do in order to have a system with Raspberry PI, Raspbian OS and XBMC 12 Frodo stable with eGalax touchscreen working correctly(which means axes calibrated and click working with just one tap&release action):


1. Get latest Raspbian image from here and flash it to an SD card.

2. Build your own kernel with eGalax touchscreen support, like in this post(you will only need to replace kernel.img file and /lib/modules and /lib/firmware folders on the SD card).

3. Build XBMC 12 on Raspberry PI using this tutorial.
Note: After downloading XBMC archive, get this archive and unpack it anywhere.
Apply patches to xbmc files:
cd <patches_folder>
patch -p1 <path_to_xbmc>/xbmc/input/linux/LinuxInputDevices.cpp < LinuxInputDevices_cpp.patch
patch -p1 <path_to_xbmc>/xbmc/input/MouseStat.cpp < MouseStat_cpp.patch
patch -p1 <path_to_xbmc>/xbmc/input/MouseStat.h < MouseStat_h.patch
4. Touchscreen calibration.
Create a new file /home/pi/touchscreen_axes_calib on Raspberry PI. It will contain four values for the axes calibration and one value for swapping axes.
The simplest way to swap axes is to switch the four wires cable plug's orientation which comes from the touchscreen to the touch controller.

Here is how the calibration was done.

the original behavior(no calibration)

In the picture above, we see that "touch panel values frame" differs from "touch panel physical size frame". When we are pressing the touch we are moving in the "touch panel physical size frame" but when the touch screen is not calibrated the arrow from XBMC is in another place.
  • "touch panel physical size frame" is the screen starting from (0,0) on the left top corner and going to (width, height) in the right bottom corner.
  • "touch panel values frame" is the frame which contains all the number the touch controller is giving.
We see that these frames differs a lot. Our main scope is to overlap the "touch panel values frame" to the "touch panel physical size frame".

In order to do this we need to do three steps(the third one is done in software):
a. Scale the value read from the touch driver x and y) in order to fit 0->width range and respectively 0->height range of the "touch panel physical size frame" the scale value for x axis is:
                       "touch panel physical size frame" width
calib_x_fact = -------------------------------------------------
                            "touch panel values frame" width


                       "touch panel physical size frame" height
calib_y_fact = -------------------------------------------------
                            "touch panel values frame" height

"touch panel values frame" width and height are coming from your XBMC resolution(I have width=1280 and height=720).
"touch panel physical size frame" width and height are a little more trickier to find but nothing hard. In step 2 above, you have calibrated the touchscreen in XFCE. You got some values returned by xinput_calibrator, something like:
Section "InputClass"
    Identifier   "calibration"
    MatchProduct    "eGalax Inc. USB TouchController"
    Option    "Calibration"    "1977 32 1893 131"
EndSection
In my case,
"touch panel physical size frame" width is 1977 - 32 = 1945
"touch panel physical size frame" height is 1893 - 131 = 1762
Now, compute the values and put them in /home/pi/touchscreen_axes_calib file

b. Translate the "touch panel values frame" to the left and up, to match "touch panel physical size frame".
I didn't find a logical method to do this, because we don't know exactly "where is" the "touch panel values frame", so, in order to find calib_x_d and calib_y_d you have to first set them both to zero and then start XBMC. Now, put some sharp pointer on the screen and observe the distances between the cursor on the screen and your pointer's position. Try to approximate these x and y deviations(measured in pixels) and put them in the /home/pi/touchscreen_axes_calib file.

c. Revert direction of axes. This is done in the software(from patches).

5. Math behind.
To accomplish these transformations the following formula was implemented in the file
xbmc/input/linux/LinuxInputDevices.cpp
pointer.x = value_read.x * calib_x_fact + calib_x_d;
pointer.y = value_read.y * calib_y_fact + calib_y_d;

After I have successfully calibrated the touchscreen I have discovered that single click was not possible from the touchscreen, just double click. After digging through the code, I have found that this was caused by drag action which was triggered because the previous values of the touch were far(more than 5 pixels) from a new press. For example, at the start of the program, cursor is set at 0,0 coordinates; if user is trying to press a button, let's say at 100, 300, the program(XBMC) will calculate the distance between these two points and will find out that this is greater than 5.
Pythagorean theory:
(100-0)x(100-0) + (300 - 0)x(300-0) is greater than 5x5 XBMC will treat this as a drag event.
This drag issue is not caused when you double click, because the previous point in the second click action is very close to the second click point. This also works for mouses, because the previous value of the pointer is always very close to the new value of the pointer(because mouse's pointer drags on the screen and it doesn't jump - so each new value is very close to the previous one).

I have developed an algorithm to avoid this issue:
When the user is pressing the screen(x,y), the touch values are being set to (screen_width+1, screen_height+1 -> outside of the visible screen) just at the first event read(which is BTN_TOUCH PRESS).
After this event, the program will receive multiple X and Y absolute values events. The first two events, one for X and one for Y are used to set the previous X value, respectively previous Y value to the current X respective current Y values. And from now on distance is measured and this is preventing no unwanted drag action.
The user's finger/pointer will not stay at a single point, because the touchscreen's lack of precision, so it will move around 5-6 pixels in x and y directions.
I have also set the click distance to 7. You can change this by changing click_confines value in xbmc/input/MouseStat.h. Originally it was set to 5, but this is not very good for touch screens(I had to click with a sharp pointer and with my nail always, but with a value of 7 I can click with my finger with a slight touch -> really nice).

Enjoy!

Saturday, January 19, 2013

Adding 7inch display with touchscreen to Raspberry PI

Hi!

First thing I got in mind when seeing Raspberry PI was "car PC project".
The targeted display was 7 inch with touchscreen. I have found a lot of displays on Ebay.

I have got myself one for 85 dollars with free shipping(this; if it is not available any more you can search "reversing driver board hdmi" on ebay and you will find others). The display driver board has hdmi input and an on board resistive touchpanel with usb controller board.

It took less than a month to receive it(in Romania). After unpack, it worked out of the box with Ubuntu 12.10(display + touchpanel) and with Windows, but for Windows I had to install some drivers also received in the package.

I have installed latest Raspbian image on a SD_Card and tried it on my Raspberry PI model B, but the touchpanel didn't show any input. After searching a lot I have decided that I have to recompile the raspbian kernel and add support for touchpanel. This sounded very new to me but it seemed to be an easy task.

First thing, I have run lsusb to see the touch controller type(on RaspberryPI):
pi@raspberrypi ~ $ lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 1c4f:0002 SiGma Micro Keyboard TRACER Gamma Ivory
Bus 001 Device 005: ID 0eef:0001 D-WAV Scientific Co., Ltd eGalax TouchScreen
Last device is the touch controller, from eGalax.

Edit: If you don't want to build the kernel by yourself, you can download mine from here. After his, you have to replace file /boot/kernel.img and /lib/firmware and /lib/modules/ on the SD card.

Building a new kernel(in UBUNTU 12.10).
Get kernel sources.
wget https://github.com/raspberrypi/linux/archive/rpi-3.6.y.tar.gz
tar -zxvf  rpi-3.6.y.tar.gz
Install some dependencies.
sudo apt-get install git libncurses5 libncurses5-dev qt4-dev-tools build-essential
Install toolchain.
The best way to do the kernel compilation is on a Desktop/Laptop machine, which will be much more fast than on the Raspberry PI. I have did this in Ubuntu 12.10:
sudo apt-get install gcc-arm-linux-gnueabi
After download of the kernel archive has finished unpack it and then navigate with terminal to the extracted folder.
Be sure thaat the sources objects are cleaned. Type:
make mrproper
Create a folder for the generated kernel:
mkdir ../kernel
Generate the .config file:
make O=../kernel/ ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- bcmrpi_cutdown_defconfig
Configure the kernel:
make O=../kernel/ ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- xconfig
In the opened window press the | button to collapse all items. Then, navigate to Device Drivers->Input Device Support->TouchScreens and select it. Here, be sure to check also your touch screen controller if it is other than eGalax, or if it is not selected. Now press save.

With the changes being made you can now compile the kernel:
make O=../kernel/ ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k -j3
Note: -j3 option from the end means to enable parallel build. The number should be number of cpu cores + 1(I have dual core cpu).

The build took about 20 minutes on my PC. After the build completes, you will have the new kernel in ../kernel folder, created above.

Create the kernel image:
cd ../
git clone git://github.com/raspberrypi/tools.git
Note: You need to have git installed.

Navigate to tools/mkimage and then run:
./imagetool-uncompressed.py ../../kernel/arch/arm/boot/Image
This command will generate the kernel image(kernel.img file).

Build modules:
Go back to the ../kernel/ folder.
mkdir ../modules/
make modules_install ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- INSTALL_MOD_PATH=../modules/

Replace the kernel:
Get latest firmware:
wget https://github.com/raspberrypi/firmware/archive/next.tar.gz
tar -zxvf next.tar.gz
In the small partition(/boot) do:
  • replace /boot/bootcode.bin with firmware-next/boot/bootcode.bin
  • replace /boot/kernel.img with the previously created kernel image
  • replace /boot/start.elf with firmware-next/boot/start.elf
In the big partition(/root) do:
  • replace /lib/firmware with <modules_builded_above_folder>/lib/firmware
  • replace /lib/modules with <modules_builded_above_folder>/lib/modules
  • replace /opt/vc with firmware-next/hardfp/opt/vc/
Now your card should contain the new image. Safely eject your SD card and then unplug it from the card reader and then put the card in Raspberry PI and start X(startx). Plug the touch controller in one usb and check if you can move the cursor(or you can start with he touch already plugged in).

After I have started X, my touch input was working but the axes were switched and also not calibrated.

Calibration for the touchscreen(in Raspberry PI). 
Note: The next steps are performed in the Raspberry PI's Debian Wheezy. This is a method for calibrating the touchscreen which will work just for Xserver and Xserver based applications.

Install xinput_calibrator.
Install some dependencies:
sudo apt-get install libx11-dev libxext-dev libxi-dev x11proto-input-dev
Download xinput_calibrator somewhere in the Raspberry PI's folder structure.
wget http://github.com/downloads/tias/xinput_calibrator/xinput_calibrator-0.7.5.tar.gz
Unpack it and then navigate to the unpacked folder and then install it using:
./configure
make
sudo make install
After this step you should run xinput_calibrator(from Xserver terminal console: first startx then open console and then run it).
xinput_calibrator
Follow the on screen instructions(touching some points on screen) and after calibration is complete you will receive a message like this:
Calibrating EVDEV driver for "eGalax Inc. USB TouchController" id=8
    current calibration values (from XInput): min_x=1938, max_x=114 and min_y=1745, max_y=341

Doing dynamic recalibration:
    Setting new calibration data: 121, 1917, 317, 1741


--> Making the calibration permanent <--
  copy the snippet below into '/etc/X11/xorg.conf.d/99-calibration.conf'
Section "InputClass"
    Identifier    "calibration"
    MatchProduct    "eGalax Inc. USB TouchController"
    Option    "Calibration"    "121 1917 317 1741"
    Option    "SwapAxes"    "1"
EndSection

For Raspbian you have to create a file:
sudo nano /usr/share/X11/xorg.conf.d/01-input.conf
Add in this file the content above(starting with Section "InputClass" line) and then save it(ctrl+O).

Note:
Please make sure that you don't have sections like
MatchProduct    "eGalax Inc. USB TouchController"
in other files from /usr/share/X11/xorg.conf.d/ folder(highest number files are processed last, thanks to Jasmin).

Now touchscreen should be calibrated and after reboot it will keep the settings.
Once, I had to run xinput_calibration again in order to have the pointer to the desired points. You can update the numbers given by the xinput_calibration utility in the
usr/share/X11/xorg.conf.d/01-input.conf file in order to have the best calibration at boot.

Soon I will add some pictures.

Andrei