Control XBMC from the Raspberry PI GPIO's

I have recently worked on adding external controls for my Raspberry PI CarPC project because while driving it is better to have some physical controls to rely on, rather than looking at the touch screen to find the buttons.
This post provide information on how to set up buttons or rotary encoders to control XBMC from Raspberry PI.

Rotary encoder
Rotary encoders are very cheap and very nice controls(eBay link). You can find them in car stereos for volume control. You can also use them to browse through menu items or to skip to next song etc.
They are looking very similar to a potentiometer, but there are major differences: they can be turned in both directions with infinite steps(you know just the direction of the spin), they provide digital output, a full rotation have a number of steps and they have push button also.
Connections for Raspberry PI should be done as follows:
    + pin to 3.3V
    GND pin to Raspberry PI GND
    SW to one GPIO
    CLK and DT to two GPIOs
When the push button is pressed the pin labelled SW is connected to GND. This can be set up as any push button(see below).

Push button
A push button can have two states on or off. There are two ways to hook up a button to a logical circuit(e.g Raspberry PI GPIO's):
We have to use the first setup(with pull up resistor) for the tool to work properly. So, for the push button of the rotary encoder above, we have to cable it like this:
 
The tool
I have created a tool to allow you interface rotary encoders(and also push buttons) with Raspberry PI GPIO's. Also you can set an XBMC command to be executed for click, left rotation and right rotation.
The tool can be otbained from my Google Code project(link to page).
It is very easy to use it. You just have to accomplish two steps:
    - copy rpi-xbmc-remote in a place where it can be accessed from anywhere(e.g. /usr/bin)
    - call it using sudo rpi-xbmc-remote /path/to/configuration/file

The configuration file
Example:

ip:localhost

button:7:KB:return

encoder:clk:23:KB:up:dt:24:KB:down
The configuration file can reside anywhere on the disk. It provides a way to define two kind of inputs for XBMC: regular button and rotary encoder. Lines should be less than 100 characters in length. Lines starting with # are comments and are not being processed.
 

Example of regular button definition: 
button:7:KB:return
    - 'button' means it is a regular button
    - '7' means use GPIO7 for this button
    - 'KB' means XBMC device map
        "KB" - Standard keyboard map
        "XG" - Xbox Gamepad
        "R1" - Xbox Remote
        "R2" - Xbox Universal Remote
        "LI:devicename" - valid LIRC device map where 'devicename' is the actual
name of the LIRC device
    - 'return' means XBMC button name to be called(see XBMC keymaps)

Example of rotary encoder definition:

encoder:clk:23:KB:up:dt:24:KB:down
    - 'encoder' means it is a rotary encoder
    - '23' means use GPIO23 for rotary encoder CLK
    - 'KB' means XBMC device map for rotary encoder left turn(same as above)
    - 'up' means XBMC button name to be sent for left turn of the rotary encoder
    - '24' means use GPIO24 for rotary encoder DT
    - 'KB' means XBMC device map for rotary encoder right turn(same as above)
    - 'return' means XBMC button name to be called(see XBMC keymaps)

Keep in mind!
You have to put a pull up resistor for every push button you define in the configuration file. If you don't do this then the state of the button will be variable when not pressed(it will oscillate between 0 and 1) and it will behave like it is pressed randomly.


Have fun!

Keep your linux clock synchronized with gps time

A big problem for a CarPC is that you need a real time clock to synchronize your system with.
For my CarPC, I don't have any RTC module on Raspberry PI, but I do have a gps always connected, which provide accurate date and UTC time.
I have found some tutorials on how I can set up ntp to update the system clock based on gpsd but they didn't worked with any of my gps devices:
ST22 SkyTraq GPS receiver
Columbus V-800
I have followed some links with no luck. I got:
"gpsd:WARN: can't use GGA time until after ZDA or RMC has supplied a year."
or
"gps data is no good"
or
"unrecognized ... sentence"

I have decided to make my own time synchronization based on parsing raw gps data.
You can download an archive containing the scripts from here.

How does it work?
First connect your gps module:
gpsd /dev/ttyAMA0
Then, to get the raw data I used:
gpspipe -R -n10
This command will get the first 10 lines from gps raw data. I got this:
pi@raspberrypi ~ $ gpspipe -R -n10
{"class":"VERSION","release":"3.6","rev":"3.6","proto_major":3,"proto_minor":7}
{"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/ttyAMA0","activated":"2013-10-06T09:42:18.793Z","flags":1,"driver":"Generic NMEA","native":0,"bps":9600,"parity":"N","stopbits":1,"cycle":1.00}]}
{"class":"WATCH","enable":true,"json":false,"nmea":false,"raw":2,"scaled":false,"timing":false}
$GPGGA,094220.784,4425.1141,N,02602.8254,E,1,05,1.6,96.1,M,37.0,M,,0000*6D
$GPGSA,A,3,25,05,29,31,21,,,,,,,,3.1,1.6,2.7*3A
$GPGSV,3,1,09,29,61,061,29,21,58,214,37,25,41,146,38,31,33,245,35*72
$GPGSV,3,2,09,05,25,056,30,16,14,314,,18,09,170,19,12,04,138,20*76
$GPGSV,3,3,09,06,02,278,*49
$GPRMC,094220.784,A,4425.1141,N,02602.8254,E,000.0,191.5,061013,,,A*6E
$GPVTG,191.5,T,,M,000.0,N,000.0,K,A*01
The Shell part.
To set UTC time for our unix system we have to issue a command like this:
date -u -s "2013/10/05 12:48:00"
From the raw gps output, we see that GPRMC gives all the needed information about the date and time(see here what the fields mean).
My idea was to capture just GPRMC data from this output and send it as a parameter to a C program which will parse the string and create a new string as needed to set time.
To get the GPRMC string from the raw gps output I have did the following bash command:
gpspipe -R -n10 | sed -n "/GPRMC/,/*/p"
Decomposition of the command:
gpspipe -R -n10 - this outputs the first 10 lines from the gps raw output.
sed -n "/GPRMC/,/*/p" - extracts the line starting with the string GPRMC
I have used unix pipes(| character) to pass the output from gpspipe -R -n10 to the sed command.
The output from this command will be like this:
pi@raspberrypi ~ $ gpspipe -R -n10 | sed -n "/GPRMC/,/*/p"
$GPRMC,100201.786,A,4425.1179,N,02602.8192,E,000.0,191.5,061013,,,A*61
$GPVTG,191.5,T,,M,000.0,N,000.0,K,A*01
 Now, to pass this as program arguments(assuming the program's name is set_date) we have to do the following:
./set_date 21 $(gpspipe -R -n10 | sed -n "/GPRMC/,/*/p")
The C program part.
In this example, argc will be 4 and argv will be as follows:
argv[0] - "./set_date"
argv[1] - "21"
argv[2] - "$GPRMC,100201.786,A,4425.1179,N,02602.8192,E,000.0,191.5,061013,,,A*61"
argv[3] - "$GPVTG,191.5,T,,M,000.0,N,000.0,K,A*01"

The GPRMC output gives 100201 for time and 061013 for date. This means:
UTC time is 10:02:01 and date is 06 October 2013. GPRMC does not provide the full year, so we have to provide the century as an argument to the C program to compute the correct date.

We are only interested in argv[1] and argv[2], so, in the C program we will convert argv[1] to int using atoi(argv[1]) and we will have the century and after this we have to parse argv[2] using sscanf to get the two numbers for time: 100201 and for date 061013. Let's assume we got these numbers in two uint32_t variables:
rawDate = 61013
rawTime = 100201
To get useful data from here we have to do this:
hour = timeRaw / 10000;
minute = (timeRaw % 10000) / 100;
second = (timeRaw % 10000) % 100;

century = atoi(argv[1]);
day = dateRaw / 10000;
month = (dateRaw % 10000) / 100;
year = (century - 1) * 100 + (dateRaw % 10000) % 100;
After this, to create the command we can use sprintf to put everything in an outputBuffer and then call system(outputBuffer) to execute the command.

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=m
CONFIG_TOUCHSCREEN_USB_EGALAX=y
CONFIG_TOUCHSCREEN_USB_PANJIT=y
CONFIG_TOUCHSCREEN_USB_3M=y
CONFIG_TOUCHSCREEN_USB_ITM=y
CONFIG_TOUCHSCREEN_USB_ETURBO=y
CONFIG_TOUCHSCREEN_USB_GUNZE=y
CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
CONFIG_TOUCHSCREEN_USB_GOTOP=y
CONFIG_TOUCHSCREEN_USB_JASTEC=y
CONFIG_TOUCHSCREEN_USB_ELO=y
CONFIG_TOUCHSCREEN_USB_E2I=y
CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y
CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y
CONFIG_TOUCHSCREEN_USB_NEXIO=y
CONFIG_TOUCHSCREEN_USB_EASYTOUCH=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).

5. Put XBMC 12.2 patch.
Get my latest patch from here, rename it to xbmc-300-eGalaxPatch.patch and put it in the folder OpenELEC.tv/packages/mediacenter/xbmc/patches/12.2-18397e1

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 o 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!

Car PC project(August 2013 update)

This is an update for my CarPC project.
You can download the latest image from here (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)

Clarion ADP-4000 Power Amplifier 4 Channel

Clarion ADP-4000 4 Channel Power Amplifier This 4 channel power
amplifier gives incredible power for amazing performance, Clarion
really does their best for this amp, great performance balanced output
clean and subtle sound output from this massive amplifier. This is what
clarion said about this product : The ADP4000 4 channel car audio power
amplifer offers an amazing 130W per channel from

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 my 4GB image from here
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

May Their Tribe Increase

Last 2 years, every single day I wake up, open the curtains of my bedroom window, to see them there. I can't begin my day without having a glimpse at them. They were just two last July:



Fast forward almost an year:



It is heartening to see that they could extend the family even in the extreme urban environment. After successful rainwater harvesting, this got to be the next best achievement of our apartment community. At least we didn't fail them.