Getting Started with Raspberry Pi - USC 2013

Post on 30-Aug-2014

609 views 4 download

Tags:

description

The Raspberry Pi is a small credit-card sized linux computer. Developers and hobbyists around the world are creating miraculous applications and projects, and now you can join them. This year's presentation covers the first steps to using your Pi. From the basics, like burning your SD Card to creating a Weather Reporter, you will learn GPIO Basics and simple Python tools. Communication between other components using SPI or I2C will also be covered. It is recommended, but not required that you have a Raspberry Pi, some knowledge of Python and simple electronics.

Transcript of Getting Started with Raspberry Pi - USC 2013

Getting Started with Raspberry Pi

Tom Paulus

www.tompaulus.com

@tompaulus

Recommended����������� ������������������  Books

Hardware

Model B

Model A

Raspberry����������� ������������������  Pi

Text

“Take����������� ������������������  a����������� ������������������  bite!”

CPUBroadcom ARM11

SoCBroadcom ARM11

SoC

Clock Speed

Up to 1GHz ClockSpeed*

Up to 1GHz ClockSpeed*

Memory 256 MB 512 MB

USB 1 USB Port 2 USB Ports

Network None Onboard Ethernet

Model����������� ������������������  BModel����������� ������������������  A

Arduino����������� ������������������  UNO����������� ������������������  ����������� ������������������  :����������� ������������������  ����������� ������������������  Arduino����������� ������������������  MEGA����������� ������������������  ����������� ������������������  :����������� ������������������  ����������� ������������������  ����������� ������������������  Raspberry����������� ������������������  Pi����������� ������������������  

UNO MEGA DUE Pi Model A Pi Model B

Operating Voltage 5 V 5 V 3.3 V 3.3 V 3.3 V

SRAM 2 KB 8 KB 96 KB 265 MB 512 MB

FLASH-Memory 32 KB 256 KB 512 KB up to 64 MB up to 64 MB

Clock Speed 16 MHz 16 MHz 84 MHz 700 MHz* 700 MHz*

USB Host n/a n/a 1 1 2

Network n/a n/a n/a n/a10/100 wired Ethernet RJ45

Audio / Video n/a n/a n/aHDMI, Composite

Video, TRS-audio jack

HDMI, Composite Video,

TRS-audio jack

Current I/O pins 40 mA 40 mA total 130 mA 2 to 16 mA 2 to 16 mA

Digital I/O Pins 14 (6 PWM) 54 (15 PWM) 54 (12 PWM) 17 (1 PWM) 17 (1 PWM)

Analog Input Pins

6 16 12 2DAC Analog Out

0* 0*

Price $30 $59 $50 $25 $35

Initial Setup

Recommended����������� ������������������  SD����������� ������������������  Cards

•Class����������� ������������������  4����������� ������������������  Minimum����������� ������������������  

•2����������� ������������������  GB����������� ������������������  or����������� ������������������  More����������� ������������������  

•Major����������� ������������������  Brands����������� ������������������  are����������� ������������������  Better!

http://www.raspberrypi.org/downloads

1. Download and Unzip the .zip from www.raspberrypi.com 2. Format the SD Card to clear all Data 3. Drag & Drop the contents of the .zip onto the SD Card

Install Your OS

Demo

GPIO

sudo apt-get install python-dev python-pipsudo easy_install -U distribute

sudo pip install RPi.GPIO

Preparing����������� ������������������  Python

Simple����������� ������������������  Blink����������� ������������������  App

!from time import sleep import RPi.GPIO as GPIO   GPIO.setmode(GPIO.BCM) #use the common numeration, #also the one found on the Adafruit Cobbler   led = 21                    # GPIO Port to which the LED is connected delay = .5 GPIO.setup(led, GPIO.OUT)   # Set 'led' as and Output   print "Press CTRL+C to exit"   try:     while True:         GPIO.output(led, True)   # led On         sleep(delay)             # wait 'delay' seconds         GPIO.output(led, False)  # led Off         sleep(delay)             # wait another 'delay' seconds   except KeyboardInterrupt:     GPIO.output(led, False)   finally:     GPIO.cleanup()

blink.py

Hardware

Demo

Analogue����������� ������������������  Input

MCP3008 8-Channel 10-Bit ADC With SPI Interface

RaspberryPi with ADC

SPI requires four signals: clock (SCLK) master output/slave input (MOSI) master input/slave output (MISO) slave select (SS) or (CS) chip-select

RaspberryPi Serial Peripheral Interface Bus - SPI

pi@raspberrypi ~ $ cat /etc/modprobe.d/raspi-blacklist.conf!# blacklist spi and i2c by default (many users don't need them)!blacklist spi-bcm2708!blacklist i2c-bcm2708!!Loading Kernel Modules: Edit the raspi-blacklist.conf, so that the spi module gets loaded, Reboot, and confirm with lsmod that ‘spidev’ and ‘spi_bcm2708’ are now loaded and ls /dev/spi* shows two spi devices: /dev/spidev0.0 and /dev/spidev0.1 !Installing Dependencies: sudo apt-get install python-dev git-core!!Install Python bindings for Linux SPI access through spidev: cd ~!git clone git://github.com/doceme/py-spidev!cd py-spidev/!sudo python setup.py install!!... which creates /usr/local/lib/python2.7/dist-packages/spidev.so

SPI

I2C

SPI

IN =[0000 0001][1CNL ----][---- ----]!

(8+channel) <<4 OUT=[---- ----][---- -XXX][XXXX XXXX] (10bit)!

((r[1] & 3) << 8) + r[2]

IN =[0000 0001][1CNL ----][---- ----]!

(8+channel) <<4 OUT=[---- ----][---- -XXX][XXXX XXXX]!

r[0] ((r[1] & 3) << 8) + r[2]

r = spi.xfer2( [1, (8+chnnl)<<4, 0] )! return ((r[1] & 3) << 8) + r[2]

def analogRead(port, bus=0, ce=0):     """Read the given ADC port and preform the necessary shifting of bits"""     spi.open(bus, ce)      # CE port that the MCP3008 is connected to     if (port > 7) or (port < 0):         print 'analogRead -- Port Error, Must use a port between 0 and 7'         return -1     r = spi.xfer2([1, (8 + port) << 4, 0])     value = ((r[1] & 3) << 8) + r[2]     spi.close()     return value

import time import spidev import RPi.GPIO as GPIO   # This program reads an analogue value form a potentiometer attached to port 0 on the MCP3008 Chip   spi = spidev.SpiDev() pot_adc = 0 statusLED = 23          # GPIO port that our Status led is connected to   GPIO.setmode(GPIO.BCM) GPIO.setup(statusLED, GPIO.OUT)   print "Press CTRL+C to exit"   try:     while True:         GPIO.output(statusLED, True)   # Status Led On         print analogRead(pot_adc)    # Print read value         time.sleep(.125)               # Wait a little         GPIO.output(statusLED, False)  # Status Led Off         time.sleep(.175)               # Wait a bit longer   except KeyboardInterrupt:     GPIO.output(statusLED, False)   finally:     GPIO.cleanup()

ADC1.py

Hardware

But, That’s Just Ugly!

Let’s Add a Display

I2C connects the same two signal lines to all slaves. I.e. addressing is required and all devices need a unique address SDA - Serial Data SCL - Serial Clock

RaspberryPi Inter-IC Bus - I2C

pi@raspberrypi ~ $ cat /etc/modprobe.d/raspi-blacklist.conf!# blacklist spi and i2c by default (many users don't need them)!blacklist spi-bcm2708!blacklist i2c-bcm2708!!Loading Kernel Modules: - Edit the raspi-blacklist.conf, so that the i2c module gets enabled. - Add the following lines to /etc/modules 

i2c-dev i2c-bcm2708

Reboot, and confirm ls /dev/i2c* shows

/dev/i2c-0 /dev/i2c-1

!Installing Dependencies: sudo apt-get install python-smbus i2c-tools!!With i2c devices connected, run somthing like this, to discover devices addresses. sudo i2cdetect -y 0

I2C

I2C

SPI

!import time import spidev import RPi.GPIO as GPIO from lib.Char_Plate.Adafruit_CharLCDPlate import Adafruit_CharLCDPlate import smbus   GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) lcd = Adafruit_CharLCDPlate() spi = spidev.SpiDev() pot_adc = 0         # ADC l = list()          # List for Light Sensor Averaging statusLED = 23 print "Press CTRL+Z to exit" GPIO.setup(statusLED, GPIO.OUT) lcd.backlight(lcd.ON) lcd.clear() !def movavg(list, length, value):     """A function that smooths the results by averaging a list"""     list.append(value)     if length < len(list):         del list[0]     sum = 0     for x in list[:]:         sum += x     return sum / len(list)

ADC2.py

try:     while True:         # Change the Back-light based on what button has been pressed         if lcd.buttonPressed(lcd.DOWN):             lcd.backlight(lcd.ON)         if lcd.buttonPressed(lcd.UP):             lcd.backlight(lcd.OFF)         lcd.home()                                                           GPIO.output(statusLED, True)                                # Status Led On         lcd.message('Potentiometer:\n' + str(             movavg(l, 4, analogRead(pot_adc))) + '     ')           # Read analog value         sleep(.1)                                                   # Wait a little         GPIO.output(statusLED, False)                               # Status Led off         sleep(.155)                                                 # Wait a bit longer   except KeyboardInterrupt:     GPIO.output(statusLED, False)     spi.close()   finally:     lcd.clear()     lcd.backlight(lcd.OFF)     GPIO.cleanup()

ADC2.py

MORE Inputs!!

ADC3.py

def colorChange(channel):     global color     if channel == green:         if color == lcd.ON:             color = lcd.GREEN         elif color == lcd.GREEN:             color = lcd.OFF         else:             color = lcd.ON     for i in range(3):         lcd.backlight(color)         sleep(.01)     sleep(bounce/1000)

try:     GPIO.add_event_detect(green, GPIO.RISING, callback=colorChange, bouncetime=bounce)       while True:         GPIO.output(statusLED, True)                                # Status Led On         l = movavg(light_Average, 4, analogRead(light_adc))         # Read the light sensor         lcd.home()                                                          lcd.message('Pot: ' + str(analogRead(pot_adc)) + '         \nLight: ' + str(l) + '       ')           GPIO.output(statusLED, False)                               # Status Led Off         sleep(rate)                                                 # Wait a little   except KeyboardInterrupt:     GPIO.output(statusLED, False)     spi.close()   finally:     lcd.clear()     lcd.backlight(lcd.OFF)     GPIO.cleanup()

ADC3.py

Hardware

Demo

Why?

try:         # Main Program   except KeyboardInterrupt:         # On Interrupt   finally:         GPIO.cleanup()

Somewhere, there is an Arduino laughing...

Current I/O pins 40 mA

Digital I/O Pins 14 (6 PWM)

Analog Input Pins 6

Price $30

Using����������� ������������������  Outside����������� ������������������  Data

JSON

JavaScript����������� ������������������  Object����������� ������������������  Notation???JSON

??{! "firstName": "John",! "lastName": "Smith",! "age": 25,! "address": {! "streetAddress": "21 2nd Street",! "city": "New York",! "state": "NY",! "postalCode": 10021! },! "phoneNumber": [! {! "type": "home",! "number": "212 555-1234"! },! {! "type": "fax",! "number": "646 555-4567"! }! ]!}!

JSON����������� ������������������  meet����������� ������������������  JASON

{! "firstName": "John",! "lastName": "Smith",! "age": 25,! "address": {! "streetAddress": "21 2nd Street",! "city": "New York",! "state": "NY",! "postalCode": 10021! },! "phoneNumber": [! {! "type": "home",! "number": "212 555-1234"! },! {! "type": "fax",! "number": "646 555-4567"! }! ]!}

What����������� ������������������  time����������� ������������������  is����������� ������������������  it����������� ������������������  in����������� ������������������  <city>?

#! /usr/bin/python #Written By Tom Paulus, @tompaulus, www.tompaulus.com   import requests import time   timeURL = 'http://json-time.appspot.com/time.json?tz=' zone = 'America/Los_Angeles'   while True:     timeJson = requests.get(timeURL + zone).json()     hour = timeJson['hour']     minute = timeJson['minute']     second = timeJson['second']     dateTime = timeJson['datetime']     print str(hour) + ':' + str(minute) + ':' + str(second)     print dateTime     time.sleep(1)

time.py

Displaying����������� ������������������  the����������� ������������������  Data

Weather Client

while True:       if update:         lcd.clear()         lcd.message('Please Wait\nFetching Data')         json = API.getLocation(locations.get(str(location) + 's'), locations.get(str(location) + 'c'), token)         update = False         display = 0       if display == 0:         lcd.clear()         high = API.high(json, units_Temp)         low = API.low(json, units_Temp)         windSpeed = API.windSpeed(json, units_Speed)         windDir = API.winDir(json)         string1 = API.Display1(high, low, windSpeed, units_Speed, windDir, language)         lcd.message(string1)       if display == 1:         lcd.clear()         rain = API.rain(json)         humidity = API.humidity(json)         string2 = API.Display2(rain, humidity, language)         lcd.message(string2)       if display == 2:         lcd.clear()         lcd.message('More Data\nComing Soon!')

Main.py

class WebAPI:  !    def getLocation(self, state, city, token):         d = requests.get(             'http://api.wunderground.com/api/' + str(token) + '/forecast/q/' + str(state) + '/' + str(city) +'.json')         json = d.json()         return json       def high(self, json, units):         high = str(json['forecast']['simpleforecast']['forecastday'][0]['high'][units])         return high       def low(self, json, units):         low = str(json['forecast']['simpleforecast']['forecastday'][0]['low'][units])         return low       def windSpeed(self, json, units):         windSpeed = str(json['forecast']['simpleforecast']['forecastday'][0]['avewind'][units])         return windSpeed       def winDir(self, json):         windDir = str(json['forecast']['simpleforecast']['forecastday'][0]['avewind']['dir'])         return windDir

WUndergroundAPI.py

USER Data!!

NSA I have some data for you...

User Data... Main.pyapp_info_folder = '/etc/WeatherUnderground' LocationData = app_info_folder + '/locations.conf'

try:     info = open(LocationData)     data = info.readlines()     length = int(str(data).count(',')) + 1     l1 = data[0].split(',')     for x in range(0, length):         l2 = l1[x].split(':')         locations[str(x) + 's'] = l2[0]         locations[str(x) + 'c'] = l2[1]     info.close()   except IOError:     lcd.message('Welcome\nNew User!')     print 'Adding New Location...'     State = raw_input('Enter The name of the State your desired location is in, using the abbreviation -CA\n')     City = raw_input('Now, Enter the name of the City\n')     print '\nThank You!'     State = State.upper()     City = City.capitalize()     if not os.path.exists(app_info_folder):         os.makedirs(app_info_folder)     info = open(LocationData, 'w')     info.write(State + ':' + City)     locations = {'0' + 's': State, '0' + 'c': City}     info.close()

User Data... AddLocation.py

app_info_folder = '/etc/WeatherUnderground' LocationData = app_info_folder + '/locations.conf'

info = open(data)         State = raw_input('Enter The name of the State your desired location is in, using the abbreviation -CA\n')         City = raw_input('Now, Enter the name of the City\n')         print '\nThank You!'         State = State.upper()         City = City.replace(' ','_')         if raw_input("Is this Information Correct? Type 'y'\n") == 'y':             info = open(data, 'a')             info.write(',' + State + ':' + City)             info.close()

Demo

SummaryWow! We have learned a lot!!

1. Initial Setup of the Raspberry Pi2. Made a little LED blink

3. Dealt with an Analog Value and Displayed it4. The Basics of JSON

5. Got our feet wet by finding the Time in different places

6. Used our new Knowledge to find the Weather

7. Learned how to save Custom User Data

Slides:

Code Used in this Talk:

http://tompaulus.com/talks

https://github.com/tpaulus/SCC-USC2013

Email:

tom@tompaulus.com