Showing posts with label calibration. Show all posts
Showing posts with label calibration. Show all posts

Sunday, April 13, 2014

Raspberry PI CarPC April 2014 updates

Hello!

I have made a lot of work on the project, with great help from Doru Ignat(idorel@gmail.com) and now the complete list of features is:

  • latest Raspberry PI firmware(which supports new models and has fixes for analog sound - no pops any more, you can use the analog out of RPI)
  • linux kernel 3.10.30 with various touch screens support and also lirc
  • reworked XBMC CarPC skin
  • XBMC 13 Gotham beta3(1080p video support, any music and picture format, support playing from archives and more)
  • reworked XBMC touch screen calibration algorithm
  • XBMC calibration plugin for touch screens(eGalax and others)
  • reworked FM Radio plugin
  • latest Navit build from source
  • fixed Navit to alllow using espeak for speech guidance
  • support for WIFI(Airplay, XBMC remotes)

The latest image can be downloaded from the right side of this blog, from the Downloads page.

Cost of the needed hardware parts: 193$
  - Raspberry PI model B: 45$
  - 7 inch display with touch screen for car reverse: 80$
  - HDMI male to HDMI male golden plated cable: 5$
  - 8GB SDHC card: 6$
  - 5V(2A) micro USB charger: 3$
  - Columbus V800 GPS module(or any other): 37$
  - SI4703 FM Radio breakout board: 13$
  - 2 rotary encoders: 4$

After installing the image on an sd card, you have to configure the system for your needs.

Calibrate the touch screen
The touch screen calibration involves two steps and you need a keyboard connected:
  1. Calibrating the touch screen for X11 applications(like Navit). Open the terminal from Desktop and type xinput_calibrator and follow the indications. After the calibration is completed you have to put the output in a file to make this permanent:
    sudo nano /usr/share/X11/xorg.conf.d/01-input.conf
Put here the output of xinput_calibrator. It will be something like:
    Section "InputClass"
        Identifier    "calibration"
        MatchProduct    "eGalax Inc. USB TouchController"
        Option    "Calibration"    "121 1917 317 1741"
        Option    "SwapAxes"    "1"
    EndSection
  2. Calibrating the touch screen for XBMC. In XBMC use the keyboard to go to Programs/Touch Screen Calibration and follow the informations on screen.
Note, that in order to make a better calibration you can move the finger on screen towards the point, before pressing enter(as can be seen on minute 0:52 in the video).
Touch each point and then press enter to go to the next one. At the end, you have to unplug the touch from usb and then plug it back(works on XBMC Gotham).
After this, he calibration is stored permanently in the file /home/pi/touchscreen_axes_calib. You can edit this file to fine tune the position of the cursor if the calibration isn't perfect.
    calib_x_d and calib_y_d - control the cursor displacement up/down/left/right
    calib_x_fact and calib_y_fact - some factors obtained in the calibration process(don't edit them)
    click_confines - defines the area that will be used for click(if the touch moves outside of this area then a drag action will occur) - this area is measured from the first touched point
    touch_mouse - if you want to use a mouse you have to set this to 0, but some touch screens behave as mouses and you have to set this to 1 in order for them to work(with single click). For the most of the touches this can be 0 if you want to also use a mouse, but if you don't want to use a mouse it doesn't mater, let it be 1.


Change the resolution
[XBMC] Using ssh you have to edit the file /home/pi/.xbmc/userdata/advancedsettings.xml and set your resolution. After this restart the whole system and XBMC should run with your new resolution.
[LXDE] Connect with ssh and type
tvservice -mDMT && tvservice -mCEA
and get the desired resolution mode
Edit /boot/config.txt and modify according to your preference, for example:
hdmi_group=2
hdmi_mode=27
CEA group is 1 and DMT 2.

Add a new map for Navit
  1. Go to Navit Planet Extractor and download a .bin file for your area.
  2. Copy the .bin file in your RPI card in /home/pi/.navit/ folder
  3. Edit the file /home/pi/navit_src/build/navit/navit.xml and search for the entry:
       <mapset enabled="yes">
           <map type="binfile" enabled="yes" data="/home/pi/.navit/Romania.bin"/>
       </mapset>
  4. Add your map name here like this:
       <mapset enabled="yes">
           <map type="binfile" enabled="yes" data="/home/pi/.navit/Romania.bin"/>
           <map type="binfile" enabled="yes" data="/home/pi/.navit/new_map.bin"/>
       </mapset>

Setup the GPS receiver
  1. For USB devices. After plugging the device into the usb port type dmesg and you should see somewhere that a new device was mapped on /dev/tty... Most probably the file name would be /dev/ttyACM0.
  2. For Serial(UART) modules. The device will have the file name as /dev/ttyAMA0.
You can test that the device is connected to a file name by calling cat/dev/ttyAMA0, for example and you should see some NMEA output.
Now, copy this file name and put it in the file /home/pi/StartCarPC in the section:
    # Start gpsd
    # /dev/ttyAMA0 - RPI serial port
    # /dev/ttyACM0 - usb port
    sudo killall gpsd
    gpsd /dev/ttyAMA0

Voice configuration for Navit
Each time a road indication has to be made, Navit will execute the file /home/pi/.navit/speech.sh with the indication text. This file will play a sound and the speak the indication, through speakers.
    aplay -r 44100 /home/pi/.navit/notification3.wav & sleep 0.7 && espeak -ven+f4 -s150 -a 150 -p 50 "$1" --stdout | aplay
    /home/pi/.navit/notification3.wav - the sound that will be played each time before an indication
    -ven+f4 - female voice number 4
    -s150 - speed 150 words per minute
    -a150 - amplitude
    -p50 - pitch
You can find more settings in the espeak manual
If you don't want the voice guidance you can press the speaker button in Navit and it will be turned off.

Configure the Controller
The controller can be easily used with Steering wheel controls or other physical controls in your car. To enable this controller, you have to edit the file /home/pi/StartCarPC and search for the entry:
    # Start the GPIO Remote
    #sudo opencarpc-controller /home/pi/gpio_description &
You have to change it to:
    # Start the GPIO Remote
    sudo opencarpc-controller /home/pi/gpio_description &
Now, you can set the configuration file like in this post

Change the car logo in the Home screen
If you want to put another car logo you have to edit the file /home/pi/.xmc/addons/skin.CarPC-touch/16x9/Home.xml and find the entry:
    <posx>580</posx>
    <posy>205</posy>
    <width>550</width>
    <height>550</height>
    <texture>bmw_logo.png</texture>

Here, you can set your new image instead of bmw_logo.png you can put a complete path of the new image.

Set up a WIFI connection
If you want to have internet connection, or airplay or control the whole system using the XBMC remotes, you have to setup a wifi hotspot with your phone and then use an USB WIFI dongle(I am using EDIMAX EW-7811UN dongle).
The system is configured to automatically connect to a wifi hotspot with the following settings:
    wpa-ssid "opencarpc"
    wpa-psk "opencarpc123"

You can find these settings in the file /etc/network/interfaces.

Some pictures with my setup:

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!

Friday, July 12, 2013

CarPC first build

Hi!

After working a lot at my CarPC project I have decided to take a break and post about it.

A short preview is here:

You can download the latest image from my Downloads page in the top right corner of this blog.
If you want to build it by yourself please follow my previous tutorials but replace the three patches with the single patch from here, which is for XBMC12.2. Also read my previous post to find how to calibrate the screen axes.

Features:
  • auto start XBMC
  • eGalax touch screen support with configurable greater area for touch event(8 pixels)
  • improved skin with larger buttons and smooth transitions(link for the skin)
  • System Power OFF button
  • usbmount enabled(so usb MSD's are plug and play)
The new calibration file contains one more entry: click_confines which defines the area for XBMC to distinguish between click and drag actions(touch moves less than 8 pixels before release than action is click, else the action is drag).

Have fun!
Andrei

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