DXARTS 490: Embedded Systems report.
http://wiki.roberttwomey.com/Raspberry_Pi
1) Audio Routing
A really easy way to switch audio output routes while logged into pi@raspberrypi is to run a
sudo amixer cset numid=3 1
#where 0 is automatic
#1 is 3.5mm jack
#2 is HDMI
2) Load VNCserver on boot/reboot
establish VNCserver connection automatically on boot so that you can run VNCViewer immediately:
(instructions from http://www.penguintutor.com/linux/tightvnc)
#first download text file from this address and move it into the proper ‘init.d’ folder
wget http://www.penguintutor.com/otherfiles/tightvncserver-init.txt
sudo mv tightvncserver-init.txt /etc/init.d/tightvncserver
#chmod execute 7-read write execute for use, 5 read execute for group, 5-read execute for world. this executes the file name /etc/init.d/tightvncserver
sudo chmod 755 /etc/init.d/tightvncserver
#add the script to default run levels with this command
sudo update-rc.d tightvncserver defaults
3) Load any file on boot/reboot
#enter text edit with nano command (alter ‘testfile’ as you wish)
sudo nano /etc/init.d/testfile
#enter text here; example runs a pd patch entitled “testpatch” on boot, alter script and name of file accordingly, exit, save and now you have a file created in the /etc/init.d/ folder:
- #!/bin/sh
- ### BEGIN INIT INFO
- # Provides: runs PD patch ‘testpatch’ on startup
- # Required-Start: $local_fs
- # Required-Stop: $local_fs
- # Default-Start: 2 3 4 5
- # Default-Stop: 0 1 6
- # Short-Description: Start/stop a sample puredata patch
- ### END INIT INFO
- # Set the USER variable to the name of the user to start pd under
- export USER=’Pi’
- ### End customization required
- eval cd ~$USER
- case “$1” in
- start)
- su $USER -c ‘pd -nogui -noadc -alsa testPatch.pd’
- echo “Starting testPatch for $USER “
- ;;
- stop)
- ps kill-9 ‘pd -nogui -noadc -alsa testPatch.pd’
- echo “testPatch stopped”
- ;;
- *)
- echo “Usage: /etc/init.d/testpatch {start|stop}”
- exit 1
- ;;
- esac
- exit 0
#make your script executable
sudo chmod 755 /etc/init.d/testfile
#test running script
sudo /etc/init.d/testfile start
sudo /etc/init.d/testfile stop
#register to make it run
sudo update-rc.d testfile defaults
#TO REMOVE SCRIPT
sudo update-rc.d -f testfile remove
#TO KILL THE RUN OF ANY SCRIPT
$ ps ux
$ kill-9 ‘4 digit PID number’
4) Working with I2C
for this example the sensor used is a digital luminosity sensor TSL2561 from Adafruit.
The TSL2561 takes measurements of luminosity across IR spectrums and visible light spectrums to optimize ambient light data harvest. It can be used to monitor ambient light conditions for use in responsive LCD/LED monitors, More information can be found here: http://www.adafruit.com/products/439
there is also a tutorial for use with Arduino, and a tutorial that will allow you to get Lux readings out of the box. But for our purposes here’s a quick introduction to get the TS2561 working with the Raspberry/Python to get ambient light sensor readings
- Follow the instructions for configuring GPIO and I2C on the Raspberry
http://learn.adafruit.com/adafruits-raspberry-pi-lesson-4-gpio-setup/configuring-i2c - Connect the hardware.
TSL2561: VCC —> 3.3V: RPi
TSL2561: SDA –> 2 SDA: RPi
TSL2561 SCL –> 3 SCL: RPi
TSL2561 GND –> GND: RPi
#note: the ADDR pin can be connected to GND to add a new address 0x29 for lining another TSL2561 :
http://learn.adafruit.com/tsl2561/wiring - check to see if the sensor is in place with
$ sudo i2cdetect -y 1
If one TSL2561 is connected, it should show up in the 0X39 address - Open a python editor (i used Komodo Edit 8) **editors minimize problems with scripting
- Enter this code (adapted from http://forums.adafruit.com/viewtopic.php?f=8&t=34922):
- #!/usr/bin/python
- import sys
- import smbus
- import time
- from Adafruit_I2C import Adafruit_I2C
- from time import sleep
- #this code has been adapted for Python 2 that converts the raw values from the TSL2561 to Lux units.
- #Math and code adapted from discussions on http://forums.adafruit.com/viewtopic.php?f=8&t=34922
- class Luxmeter:
- i2c = None
- def __init__(self, address=0x39, debug=0, pause=0.8):
- self.i2c = Adafruit_I2C(address)
- self.address = address
- self.pause = pause
- self.debug = debug
- self.gain = 0 # no gain preselected
- self.i2c.write8(0x80, 0x03) # enable the device
- def setGain(self,gain=1):
- “”” Set the gain “””
- if (gain != self.gain):
- if (gain==1):
- self.i2c.write8(0x81, 0x02) # set gain = 1X and timing = 402 mSec
- if (self.debug):
- print “Setting low gain”
- else:
- self.i2c.write8(0x81, 0x12) # set gain = 16X and timing = 402 mSec
- if (self.debug):
- print “Setting high gain”
- self.gain=gain; # safe gain for calculation
- time.sleep(self.pause) # pause for integration (self.pause must be bigger than integration time)
- def readWord(self, reg):
- “””Reads a word from the I2C device”””
- try:
- wordval = self.i2c.readU16(reg)
- newval = self.i2c.reverseByteOrder(wordval)
- if (self.debug):
- print(“I2C: Device 0x%02X returned 0x%04X from reg 0x%02X” % (self.address, wordval & 0xFFFF, reg))
- return newval
- except IOError:
- print(“Error accessing 0x%02X: Check your I2C address” % self.address)
- return -1
- def readFull(self, reg=0x8C):
- “””Reads visible+IR diode from the I2C device”””
- return self.readWord(reg);
- def readIR(self, reg=0x8E):
- “””Reads IR only diode from the I2C device”””
- return self.readWord(reg);
- def getLux(self, gain = 0):
- “””Grabs a lux reading either with autoranging (gain=0) or with a specified gain (1, 16)”””
- if (gain == 1 or gain == 16):
- self.setGain(gain) # low/highGain
- ambient = self.readFull()
- IR = self.readIR()
- elif (gain==0): # auto gain
- self.setGain(16) # first try highGain
- ambient = self.readFull()
- if (ambient < 65535):
- IR = self.readIR()
- if (ambient >= 65535 or IR >= 65535): # value(s) exeed(s) datarange
- self.setGain(1) # set lowGain
- ambient = self.readFull()
- IR = self.readIR()
- if (self.gain==1):
- ambient *= 16 # scale 1x to 16x
- IR *= 16 # scale 1x to 16x
- ratio = (IR / float(ambient)) # changed to make it run under python 2
- if (self.debug):
- print “IR Result”, IR
- print “Ambient Result”, ambient
- if ((ratio >= 0) & (ratio <= 0.52)):
- lux = (0.0315 * ambient) – (0.0593 * ambient * (ratio**1.4))
- elif (ratio <= 0.65):
- lux = (0.0229 * ambient) – (0.0291 * IR)
- elif (ratio <= 0.80):
- lux = (0.0157 * ambient) – (0.018 * IR)
- elif (ratio <= 1.3):
- lux = (0.00338 * ambient) – (0.0026 * IR)
- elif (ratio > 1.3):
- lux = 0
- return lux
- oLuxmeter=Luxmeter()
- while(true):
- print “LUX HIGH GAIN “, oLuxmeter.getLux(16),
- print “LUX LOW GAIN “, oLuxmeter.getLux(1),
- print “LUX AUTO GAIN “, oLuxmeter.getLux(), #!/usr/bin/env python
- sleep(3);
- #take 3 recordings at 3 second intervals
- save (luxsensor.py) and use the scp command to move to folder on the Raspberry Pi
- ideally save this with the rest of the Adafruit tutorials, but if not, you will need to create a shortcut to the file Adafruit_I2C in the same folder as the luxsensor.py file
- on the Raspberry IDE, open root terminal and type
sudo idle
#this opens python 2 on your machine as a root user to allow you to change I2C/GPIO settings - Open luxsensor.py and run – you should begin getting lux sensor recordings (3 values) every 3 seconds at address 0x39
From here, you can adapt code to draw graphs, add to an online repository (Xively.com) or control other responsive systems and appendages.
Created: Jun 8 2013