Installing the python cx_Oracle extension module for connecting to Oracle databases on this Fedora 18 workstation turned out to be a bit of a faff by giving an assortment of unhelpful error messages, if you are having the same pain maybe this will help.
You will need two files from the Oracle Database Instant Client download site, the basic client package and the SDK (devel): http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html For Linux choose the correct flavour for your installed operating system: x86 or x86-64 for 64bit operating systems, you will need to register on the site to access the files. For my purposes I got the 11.2 version for x64 RPM files, install them using: $ sudo rpm -i oracle-instantclient11.2-basic-11.2.0.3.0-1.x86_64.rpm
$ sudo rpm -i oracle-instantclient11.2-devel-11.2.0.3.0-1.x86_64.rpm
You will now need to tell the system where the libraries are: $ sudo su
# echo /usr/lib/oracle/11.2/client64/lib/ > /etc/ld.so.conf.d/oracle.conf
# ldconfig
# exit
To install cx_Oracle you will need to set some environment variables otherwise you will get an “error: cannot locate an Oracle software installation” message. The easy_install program is found in python-setuptools I have included it in the recipe as a reminder if you have not installed it already. $ sudo yum install python-setuptools
$ export ORACLE_HOME=/usr/lib/oracle/11.2/client64
$ export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
$ export PATH=$ORACLE_HOME/bin:$PATH
$ sudo -E easy_install cx_Oracle
or by downloading the version from http://cx-oracle.sourceforge.net/ and installing it manually, you will still need to set the exports, as above, and do the following for installation: $ sudo -E python setup.py build
$ sudo -E python setup.py install
The -E on the sudo takes your environment variables, including the three you just set, into your sudo session.
Success: $ python
Python 2.7.3 (default, Aug 9 2012, 17:23:57)
[GCC 4.7.1 20120720 (Red Hat 4.7.1-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cx_Oracle
>>> exit()
When the the library cannot be seen, you get this error: $ python
Python 2.7.3 (default, Aug 9 2012, 17:23:57)
[GCC 4.7.1 20120720 (Red Hat 4.7.1-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cx_Oracle
Traceback (most recent call last):
File "", line 1, in
ImportError: libclntsh.so.11.1: cannot open shared object file: No such file or directory
>>> exit()
For my Spangaly Stick project, more of which later, I have been wanting to add a remote control function for the camera for a while now and with the extended winter I found I had the time. I am using an Arduino micro-controller fitted with an XBee wireless shield to respond to a keyword sent by another Arduino with a similar setup, or from a computer with an XBee on a USB port.
take a picture – board
This board had been built to work with the Canon EOS DSLR range of cameras, but should work with other makes of camera fitted with an electronic remote socket. For basic use the camera should be set in Aperture Priority (Av) mode with the lens set to manual focus and if your using a tripod switch off any image stabilization.
For this project you will need:
A Windows (XP and above) Computer
An Arduino Uno R3
Two XBee’s
An XBee USB adapter
An XBee Shield for the Arduino
A battery to power the Arduino, I use a 12v 1.3Ah Sealed Lead Acid.
A remote lead for your camera
Ability to solder, read circuit diagrams, etc..
For this remote to work, you will need to configure two XBees to talk to each other. The easy way to do this is using the X-CTU tool (unfortunately it is Windows only) and a XBee USB Adapter. The XBees come in two main types, the Series One (S1) and Series Two (S2) they will need to be of both the same series to talk to each other, I have used Series One bees here, but not the ones without the sticking out antenna as I suspect they may be a bit delicate.
While the XbeeSheid configuration is documented on the arduino site, I shall summarise here. With the XBee plugged into the USB adapter and the adapter plugged into the computer wait for it to be detected by Windows then you can configure it. In X-CTU, on the PC Settings Tab, select the USB Serial Port. By default the XBee is set to baud: 9600, flow: None, data: 8, parity: None, stop: 1. Click the Test/Query button you should see some basic XBee settings, if it says it cannot communicate, try a different baud rate. Higher baud rates are available, but whats the rush?
Now click the Modem Configuration tab, under Modem Parameter and Firmware, click Read, after a pause at the top of the list The modem indicated will be whatever model you have, in my case XB24, select the function set we will be using: XBEE 802.5.4 RS485 ADAPTER and the firmware version: 13E8. You will need to set the Networking & Security Channel (CH) and the PAN ID (ID) to the same on both, as well as check the Serial Interfacing are set correctly, Interface Data Rate (BD): 3 – 9600, Parity (NB): 0 – NONE. Click Write to save the settings to the XBee.
For testing the XBee’s, I had one plugged into the USB adapter and the other placed into the the XBee Shield, an LED fitted across Digital Output 12 and Ground, and sent the following program to the Arduino, remembering to flick the little switch on the shield to USB for programming, and Micro for XBee emissions.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// XBee Two Way Test
// echos back text recieved by the XBee from another XBee
// when return is pressed
// lights an LED connected to pin 12 when a keyword is recieved.
The circuit I made for taking photos includes the focus, this is optional but I have included it so the camera can be woken up before the picture is taken. An ILD74 opto-isolater is used to electrically separate the camera from the Arduino, it also simplified the circuit not having to use transistors. The LED’s are useful additions but are optional.
take a picture – circuit
The diagram also shows the Canon Remote connections. Most use a 2.5mm stereo jack plug, but the more expensive cameras have a proprietary Canon N3 connector, to get the lead you will need to sacrifice a wired remote, one of these can be gotten of ebay very cheaply, about £3.00. The colours for the wires can be anything, so you will need check with a continuity tester.
The program on the Arduino listens for a keyword, in this case ‘PHOTO’ which then triggers the picture taking sequence first by setting the focus to wake the camera up then taking the picture. The Indicator LED is used to show activity on the serial port.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// this listens for: PHOTO on the serial port (from the XBee)
constintCAMERA_FOCUS=12;// yellow wire
constintCAMERA_SHOOT=11;// red wire
//const int PHOTO_BUTTON = 10;
constintINDICATOR=9;
booleantrigger=false;
intix=0;
charrs[12];
Stringrecieved="";
voidtakePhoto(){
// trigger the camera,
//
// you may need to alter the delay() settings for your camera
// If you try to take a photo before the camera is ready, the camera will
// not take a photo. This also applies if the camera cannot focus.
if(trigger==false){
trigger=true;
digitalWrite(CAMERA_FOCUS,HIGH);// wake up the camera
delay(300);
digitalWrite(CAMERA_FOCUS,LOW);
delay(400);
digitalWrite(CAMERA_SHOOT,HIGH);// take photo
delay(300);
digitalWrite(CAMERA_SHOOT,LOW);
}
else{
digitalWrite(CAMERA_FOCUS,LOW);
digitalWrite(CAMERA_SHOOT,LOW);
}
trigger=false;
return;
}
booleanvalidChar(charc){
// filter to process charchetrs 0-9, A-Z, a-z, newline, space and full-stop
if(c=='\n'||c==' '||c=='.'){
returntrue;
}
if(c>='0'&&c<='9'){
returntrue;
}
if(c>='A'&&c<='Z'){
returntrue;
}
if(c>='a'&&c<='z'){
returntrue;
}
returnfalse;
}
voidsetup(){
Serial.begin(9600);
pinMode(CAMERA_FOCUS,OUTPUT);
pinMode(CAMERA_SHOOT,OUTPUT);
pinMode(INDICATOR,OUTPUT);// indicator shows activity on the serial port
The Raspberry Pi is a small computer, and as such an obvious but important question occurred to me, and despite Google, I was unable to find an answer. So using science, LEGO, a balloon, and a compressed air supply I set out to discover if the Raspberry Pi could indeed blow a raspberry.
To embark on this scientific discovery, first, I needed to be able to control a motor, for this I built a dual relay board that can be switched using a couple of the Pi’s GPIO pins: LEGO PF Motor Controller v3
Here is the circuit diagram: LEGO PF Motor Controller v3 – Circuit
And the Python source code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#! /usr/bin/python
from time import sleep
import RPi.GPIO asGPIO
GPIO.setmode(GPIO.BCM)
PARP_ON=23
PARP_OFF=24
# Set up the GPIO channels
GPIO.setup(PARP_ON,GPIO.OUT)
GPIO.setup(PARP_OFF,GPIO.OUT)
def parpON():
GPIO.output(PARP_ON,True)
sleep(0.4)
GPIO.output(PARP_ON,False)
return
def parpOFF():
GPIO.output(PARP_OFF,True)
sleep(0.4)
GPIO.output(PARP_OFF,False)
return
if__name__=="__main__":
print"The Incredible Pi Raspberry Machine";
foriinrange(0,5):
print"parp ",i
parpON()
sleep(2)
parpOFF()
sleep(0.7)
GPIO.output(PARP_ON,False)
GPIO.output(PARP_OFF,False)
To which I connected a large LEGO PF motor. This is used to switch the pneumatic valves via a clutch cog and a large cog. I used a 9v power supply for this, but a PF Battery box can be used, cut an PF extension lead in half, use the light grey side for the motor, and the dark grey end to connect to the battery box. My compressed air supply operates at 2bar / 30 psi, it was built to work with LEGO pneumatics, I found that anything much above that pressure would cause the pipes to pop off the connectors. Pi Raspberry Switch
Obviously I needed something that would make a sound. For this, a balloon (the sausage type), a small pop bottle, and some more LEGO were suffice. The air is injected into the bottle trough a couple of holes at the rear. Pi Raspberry Balloon
I would like to say thanks to the people on the Raspberry Pi forum for their advice on the electronics: http://www.raspberrypi.org/phpBB3/ and further reading about LEGO PF motors can be found here: http://www.philohome.com/pf/pf.htm, and the raspberry http://en.wikipedia.org/wiki/Blowing_a_raspberry
In one of my previous posts I mentioned setting the ownership of the /sys/class/gpio to dialout using /etc/rc.local. This worked up to a point, however entries are created in the gpio when you start using them and they retain the original root group permissions, which means you are required to run your code as root. As this is bad practice I have been looking for ways to get around this, so far setting a udev rule has proved futile.
However, I have found a tool called GPIO Admin and they have also written a Python GPIO API for it, simply install the software, add your user to the gpio group and you have access to the header without having to use root. They have written the API for Python 3, but I have found it will work in Python 2.7 (so far, with the version I downloaded on 29 June 2012, its still in development). The Flask framework has not been updated to work in Python 3. Blinking LEDs
From reading the Raspberry Pi forum, I see many are wanting to control their hardware projects from the web. Here I will show a method of integrating Python with the Apache web server, and allowing the Apache server access to the GPIO and UART ports without having to run it as root, if you have PHP already installed, both will run in the same environment. For this I am using am using Debian from here: http://www.raspberrypi.org/archives/1435, on a freshly installed SD card.
Part One: Installation, configuration and testing
As root, install the following packages:
# apt-get update
# apt-get upgrade
# apt-get install apache2 libapache2-mod-wsgi python-setuptools python-flask
edit your virtual host in /etc/apache2/sites-enabled, here I have added the wsgi components to the default host 000-default.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevelwarn
CustomLog${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Parts easily missed are setting ExecCGI on the Options and adding index.py to the DirectoryIndex. Note that I have set the wsgi to identify python by the extension .py, normally .wsgi is used, I think this is some kind of tradition, or old charter, or something.
Set permissions:
Apache on Debian runs as the user www-data, for access to the serial port and GPIO on the Raspberry Pi you will need to add that user to the relevant groups. Do not run apache as root, while this is not so important when on the Pi it is good practice to avoid.
Edit /etc/rc.local and add these two lines to the end of the file:
chgrp -R dialout /sys/class/gpio
chmod -R g+rw /sys/class/gpio
when you reboot the computer, group permissions will be set to dialout on the gpio
add www-data to the dialout group
# usermod -a -G dialout www-data
Update: the /etc/rc.local method does not work, instead I have found found a tool called GPIO Admin and they have also written a Python GPIO API for it. Currently it is under development, but once installed add apache to the gpio group: # usermod -a -G gpio www-data and the web server will have access to the gpio pins
enable the module (it may of been enabled when installed) and restart apache
# a2enmod wsgi
# /etc/init.d/apache2 restart
To test your wsgi installation place the following file into your apache root directory /var/www as myinfo.py and load it using your web browser, http://<pi’s ip address>/myinfo.py .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
##
## display environment variables in mod_wsgi - shows if wsgi, flask etc is working
Part 2: Using The Flask Framework
Here I have made a simple demonstration of how to use Flask, it consists of a wrapper, demo.py, the actual program coreDemo.py and some html to process, demo.html. It does not show how to use the GPIO or UART. The wrapper is used to capture error messages and conveniently display them in the web browser. Again save these files into your apache root directory, /var/www and load it using your web browser, http://<pi’s ip address>/demo.py
demo.py:
demo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
##
## filename: demo.py
##
## this is a wrapper for your main program, its primary purpose is to
## manage error messages and output your HTML, XML or JSON as required
Now all you have to do is open the port 80 forwarding on your router, and everyone in the world can make your little buzzer project make noises at two in the morning.
Using the latest distribution of Debian for the Raspberry Pi, I wanted add myself as a user and connect to a network share. Here are the steps I took:
install a couple of programs:
# apt-get update
# apt-get upgrade
# apt-get install minicom joe
set default shell to bash, add new user with groups, and set that users password:
# useradd -D -s /bin/bash
# useradd -m -G adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input <username>
# passwd <username>
created a directory to be shared, and add the samba share to /etc/fstab:
# mkdir /home/raspberry
# nano /etc/fstab
and added this to the end:
//<ip address>/<share> /home/raspberry cifs username=<username>,password=<password>,_netdev,uid=<username> 0 0