[go: up one dir, main page]

0% found this document useful (0 votes)
7 views45 pages

RaspberryPiTutorial 2019

Uploaded by

Haozong Zeng
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views45 pages

RaspberryPiTutorial 2019

Uploaded by

Haozong Zeng
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 45

Programming Hardware with the Raspberry Pi

using Python
Frontiers in Neurophotonics Summer School 2019

Nicholas J. Michelson
Pankaj K. Gupta
Jeff LeDue
Timothy H. Murphy

Handout and code prepared by: Jamie Boyd


Raspberry Pi Specs (current model is Pi 3B+)
● A low cost, credit-card sized computer designed to enable people of
all ages to explore computing (raspberrypi.org)

1.2 GHZ quad-core ARM Cortex A53 (900MHz A7 on Pi 2)

1 GB 900 MHz SDRAM (450MHz on Pi 2)
● Runs Raspbian, a Linux-based operating System

Most of the Linux toolset supported

Programming in Python, C/C++, Java, ....
● Standard Connectivity

10/100 MBPS Ethernet • 802.11n Wireless LAN (not on Pi 2)

Bluetooth (not on Pi 2) • 4 USB Ports

HDMI video • micro SD card (no disks)

40 GPIO Pins General Purpose Input/Output
●specialized communication protocols

2
Raspberry Pi 2

3
Booting Up

Connect micro-USB power to boot
up

Watch text scroll by until log-in
prompt is presented

Login: pi

Password: raspberry

Launch GUI from the command line

Startx


Open a terminal window to get a
command line back

Raspberry menu->accessories-
>terminal (or select the picture of a
computer monitor on task bar)

4
Python Programming Language


Python (both 3.x and legacy 2.7x) is installed in Raspbian by default

Always use Python 3

Python is an interpreted language

each line of a program executed in turn by python interpreter
(slower than C)

Can be used interactively, running code as you type it

Python has great library support
import RPi.GPIO

5
Running Python in a Terminal Window

Run a python file with python interpreter, specifying python version 3


$python3 hello_world.py

print ('Hello World !')


Hello World!

Run python interpreter interactively


$python3
Python 3.53 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170124] on Linux
Type “help”, “copyright”, “credits” or “license” for more information
>>>

6
Interactive Python in Terminal Window
>>> 3 + 4 >>> for i in range (0, 10, 1):
7 ... print ('i=', i) (Python
>>> v1=17 (dynamic typing)
cares about indentation)
...
>>> v1
i= 0
17 i= 1
>>> v1 + 10 i= 2
27 i= 3
i= 4
v1 = v1 + '42' (strong typing)
i= 5
Traceback (most recent call last): i= 6
File "<stdin>", line 1, in i= 7
<module> i= 8
TypeError: unsupported operand i= 9
type(s) for +=: 'int' and 'str' >>> quit()

7
Python Integrated DeveLopment
Environment

Multi-window text editor with syntax highlighting, autocompletion, smart
indent.

Python shell

Launch from menu or from command line:

gksudo idle3 &

8
Rasberry Pi GPIO Header Pin Out

https://pinout.xyz/pinout/
9
T-Cobbler Plus and Bread-board

Pin 1
White line marks pin 1

Pin 40

10
T-Cobbler Plus and Bread-board
White line marks pin 1

Outer 2 columns
continuous vertically

3.3V power, ground

Inner rows continuous
horizontally, 5 pins/row

Not connected across
central gutter

Gutter

11
LED = Light Emiting Diode

LED has a polarity

Current only flows one way in a diode

Reverse breakdown voltage > 20V

Forward voltage = 1.5 to 3.5 V

Red < Green < Blue

max current = 20 mA. Too much current/
heat destroys LED

I/V curve is exponential. Hard to limit
Current by controlling Voltage

Use Resistor in series

Current(I) = Voltage(V)/Resistance(R)
(Ohm’s Law)
● Assume voltage drop on LED = V
F
● Current = (V – LED V )/R
F

12
Switch an LED On and Off (manually)

Left Power rail wired to Pi 3.3 V

Ground rails wired to Pi ground

560 Ohm resistor to limit current.

(3.3V - 2V)/560 Ohm= 2.3 mA

Momentary switch connects diagonals
when held down. Make it span the gutter

power->resistor->switch->LED->ground

Order of resistor, switch, LED not
important

LED has a polarity

No light, try flipping LED

short leg to ground

13
Raspberry Pi Digital Outputs

Digital output is High or Low (3.3V CMOS) GPIO 26 -> Resistor -> LED -> Ground

Set High 3.3v -> GPIO pin -> load

pin sources current, drives voltage to >= 2.4V

Set Low load -> GPIO pin -> gnd

pin sinks current, pulls voltage to <= 0.5V

How much Current can a GPIO pin sink/source
and still maintain Voltage within specification?

configurable per pin from 2 to 16 mA

Default is 8 mA

Exceed that current and voltage on pin sags

The total current from all pins must not
exceed 51mA or you may damage the pi

Higher resistance load = lower current draw

Use a transistor to drive low resistance loads
14
Turn ON/OFF LED using Python library
RPi.GPIO
sourceforge.net/p/raspberry-gpio-python/wiki/
In a terminal, enter gksudo idle3 & to open idle with root. In the python shell:
>>> import RPi.GPIO as GPIO ”as” so you can refer to it as GPIO
>>> GPIO.setmode(GPIO.BCM) Broadcom numbers, not header numbers
>>> GPIO.setup(26, GPIO.OUT) set up GPIO 26 for output
>>> GPIO.output(26, GPIO.HIGH)sets GPIO 26 to 3.3 V
>>> GPIO.output (26, GPIO.LOW) sets GPIO 26 to ground
>>> GPIO.cleanup(26) when we are done with GPIO 26

15
Blink an LED using a Python Script
From File Menu -> Open -> blink.py
From Run Menu -> Run Module

import RPi.GPIO as GPIO # import Rpi.GPIO library


from time import sleep # used for timing LED on and off periods
the_pin = 26 # declare variables
on_time = 0.5
off_time= 0.5
blinks = 10
GPIO.setwarnings(False) # warns if a GPIO pin is already in use
GPIO.setmode(GPIO.BCM) # always use Broadcom pin numbering
GPIO.setup(the_pin,GPIO.OUT) # set pin for output
for blink in range (0, blinks): # loop blinks number of times
GPIO.output(the_pin,GPIO.HIGH) #LED turns on
sleep (on_time) # sleep for LED on time
GPIO.output(the_pin,GPIO.LOW) # LED turns off
sleep (off_time) # sleep for LED off time
GPIO.cleanup () # prevents warnings from pin in use

16
Raspberry Pi Digital Inputs

Inputs are read as high if above
2 volts

Inputs are read as low if below
0.8 volts

Inputs between those levels are
undefined

Can you see a problem with
this circuit ?

Keep 0 < input < 3.3 V to
prevent damage to the Pi

The Pi GPIO pins are NOT
5V tolerant

17
Raspberry Pi Digital Inputs

Your momentary switch is Single Pole Single Throw

How can we change the circuit to get reliable inputs ?

high when switch is pushed

low when switch is not pushed
???
GPIO input 3.3 V
Single Pole Single Throw (SPST)

ground

GPIO input

3.3 V
Single Pole Double Throw (SPDT)
18
GPIO input with a pull-down Resistor

With a pull-down resistor, input is pulled down to
ground through resistor when switch is open

When switch is closed, current draw from voltage
source is 3.3 V/10 k = 0.33 mA

GPIO input

3.3 V

Could swap the 3.3V and


ground and have a pull-up
resistor to 3.3V, with switch
Hi/Low logic reversed

ground

19
Read Digital Inputs using RPi.GPIO
>>> GPIO.setup(21, GPIO.IN) # set up GPIO 21 for input
>>> GPIO.input (21) # returns 1 if GPIO pin is High, 0 if pin is Low
From File Menu -> Open -> check_input.py From Run Menu -> Run Module
import RPi.GPIO as GPIO # gksudo idle for root access
from time import sleep
in_pin = 21
GPIO.setmode(GPIO.BCM)
# enable built in pull-down resistor on GPIO Pin (also PUD_UP)
GPIO.setup(in_pin,GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
while True: # infinite loop
try: # exceptions try-catch
if GPIO.input(in_pin) is GPIO.HIGH:
print ('GPIO pin ' + str (in_pin) + ' is high')
else:
print ('GPIO pin ' + str (in_pin) + ' is low')
sleep (0.1) # 1/0.1 sec = 10Hz rate
except KeyboardInterrupt: # ctrl-c triggers interrupt
GPIO.cleanup()
break # breaks out of infinite loop

20
GPIO Input: Edge Detection

An edge is the change in state of an electrical signal from LOW to HIGH
(rising edge) or from HIGH to LOW (falling edge).

Edge changes are events, as opposed to states (high and low)

We are often more interested in events than states

Checking GPIO input level repeatedly in a loop is called polling.

Processor intensive to poll at a high frequency

Easy to miss events polling at too low a frequency
From File Menu -> Open -> check_input_edge.py
From Run Menu -> Run Module

while GPIO.input(in_pin) is GPIO.LOW:#polling for low-to-high edge


sleep (sleep_time) # replace with pass for best performance
print ('GPIO pin ' + str (in_pin) + ' went HIGH')

21
Edge Detection: Switch Debounce

Mechanical switches bounce
when switched, rapidly making
and breaking contact until they
settle (1 ms or more depending
on switch).

Bounces give rise to phantom
events 3V

Software debounce or filter with
capacitor

1 ms

22
Rpi.GPIO functions for Edge Detection
GPIO.wait_for_edge (GPIO pin, event,[bouncetime, timeout])

event can be GPIO.RISING, GPIO.FALLING or GPIO.BOTH

bouncetime in milliseconds

transitions are ignored unless a constant state is maintained for this many
milliseconds (to mitigate physical switch bounce)

Too short a bounce time gives extra events

Too long a bounce time may ignore real events

Timeout in milliseconds

Returns GPIO pin number if an event has occurred before the timeout, returns
None (a special Python object) if there is a timeout.

Function returns after the timeout expires, even if an event has not occurred

Doesn’t miss the event, use less processor time while waiting

Your program is blocked while waiting for event or timeout
23
GPIO input: wait_for_edge.py
# Set up a pin for input as usual
GPIO.setup (in_pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

# each time through loop, call wait for edge


result = GPIO.wait_for_edge(in_pin, GPIO.BOTH, bouncetime= bounce_time_ms,
timeout=time_out_ms)

# check for timeout


if result is None:
print ('No button press on GPIO pin ' + str (in_pin) + ' for ' + str
(time_out_ms/1000) + ' seconds.')

# As we waited for both rising and falling, check level


if GPIO.input (in_pin) is GPIO.HIGH:
print ('GPIO pin ' + str (in_pin) + ' went HIGH')
else:
print ('GPIO pin ' + str (in_pin) + ' went LOW')

24
GPIO input: edge_detected.py
GPIO.add_event_detect(pin, edge,[callback, bouncetime])
GPIO.event_detected(pin)

Designed to be used in a loop where you want to do other things without constantly
checking for an event.
●Your program is not blocked, and not constantly polling
● event_detected has a memory, but only for the most recent event
●If more than one event since last check, previous events will be lost
# Set up a pin for input as usual, then add event to detect
GPIO.setup (in_pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.add_event_detect(in_pin, GPIO.BOTH, bouncetime = bounce_time_ms)

# in the loop, do some work, then check if an event happened


sleep (processing_time) # simulates doing other processing
result = GPIO.event_detected(in_pin) # if True, an event

25
GPIO input: edge_counter.py

Callback functions are threaded (threads run concurrently with data shared)

A callback function runs at the same time as your main program, in immediate response to
an edge. my_callback (pin)

Global variables share information with callback and main program
rising_edges =0 #define globals outside of any functions
falling_edges =0
# to share a global variable between two threads, you need two
functions. we define a main function
def main ():
# body of main function goes here

# tell Python to run main() when file is opened


if __name__ == '__main__':
main()

26
GPIO input: edge_counter.py
The callback function that runs in a separate thread when an edge is detected
It increments global variable rising_edges if a low-to-high transition, or
falling_edges if a high-to-low transition

def counter_callback(channel):
global rising_edges #global, same variable in main
global falling_edges
if GPIO.input (channel) is GPIO.HIGH:
rising_edges +=1 #increment rising_edges
else:
falling_edges +=1 #increment falling_edges

27
GPIO input: edge_counter.py
In main(), we occasionally check how many events have occurred. We only read global
variables in main (), never write to them as the callback runs concurrently
global rising_edges #the global tells Python these variables
global falling_edges #are declared outside of the function

sleep (processing_time) # simulates doing other processing

#rising_edges – last_rising = rising edges in processing_time


print ('GPIO pin ' + str (in_pin) + ' went HIGH ' +
str (rising_edges - last_rising) + ' times in the last ' + str
(processing_time) + ' seconds')

last_rising = rising_edges # keep track of values before


last_falling = falling_edges # next period of sleeping.

print ('GPIO pin ' + str (in_pin) + ' went HIGH a total of ' + str
(rising_edges) + ' times') # at ctrl-c, print totals

28
GPIO: a Challenge

How you would write a program that waits for a button press
and blinks an LED after button is pressed?
Combine whichever of the GPIO input and output functions that
you like. There’s more than one way to do this.
Yes, you can light an LED from a switch without using a Raspberry
Pi, but keep in mind that:
GPIO output to more “interesting” devices is the same as GPIO
output for lighting an LED
GPIO input from a more “interesting” device is the same as
processing input from a button press

29
PiCamera module v2.1
The PiCamera camera module has specs similar to a cell phone camera
●Sony IMX219 silicon CMOS back-lit sensor
● 8 megapixel (3280 × 2464 pixels)
●400 to 700 nm spectral response (also a NoIR version)
●ISO settings between 100 and 800 in steps of 100, or auto gain
●exposure times between 9 μs and 6 s (Rolling Shutter)
●24 bit RGB output
●Movies:


up to 15 frames per second (fps) full-frame imaging video

up to 30 fps in 1080p - faster, more reliable, with reduced image size

Frames will be dropped if Pi is taxed (pre-allocate an array ?)

30
Proper PiCamera Cable Insertion

Biggest cause of problems is reversed cable insertion

On both the Pi and the camera

Avoid kinks in the cable

31
PiCamera Python Interface
picamera.readthedocs.io/en/release-1.13/
import picamera
camera = picamera.PiCamera() # constructor for PiCamera object
camera.resolution = (640, 480) # horizontal size, vertical size
camera.framerate = 30
camera.preview_fullscreen = False
camera.preview_window = (20, 40, 680, 500) # left, top, right, bottom
camera.start_preview()#draws directly to the screen
camera.capture ('test.jpg') #takes a single image
camera.start_recording(name.h264)#extension sets filetype

many more settings than shown here (gain, white balance, ISO)
but defaults are o.k.
32
camera_test.py
Preview running at this point
Sleep the cpu, wait for keyboard interrupt
while True:
try:
time.sleep(0.1)
#Press CTRL+C to stop the preview and take picture
except KeyboardInterrupt:
camera.capture ('test.jpg') #take single image
camera.stop_preview()
camera.close()
break

33
camera_on_button.py
from time import time, sleep
from datetime import datetime

time() returns seconds since 1970/01/01 - use this to grab time stamps

datetime is for human readable date/time formats. A datetime object has fields for
year, month, day, hour, minutes, seconds, microseconds
datetime.fromtimestamp (time()).isoformat (' ')

fromtimestamp returns a datetime object from number of seconds since 1970/01/01
.isoformat (' ') returns a string with formatted date, parameter is separator
character, a space in this case
>>> now = time()
>>> dt = datetime.fromtimestamp(now)
>>> dt.isoformat(‘ ‘)

34
camera_on_button.py

result = GPIO.wait_for_edge(in_pin, GPIO.FALLING,


bouncetime= bounce_time_ms, timeout = 1000)
if result is None:
continue # continues at top of loop (ctrl-c)
camera.start_recording(base_name + str(trial_num) +
'.h264') # h264 is a video format, with compression
startSecs= time()
camera.start_preview()
isRecording = True
print ('Started recording ' + base_name + str(trial_num) +
'.h264 at ' + datetime.fromtimestamp
(int(startSecs)).isoformat (' '))

35
camera_on_button.py
timed_out = not GPIO.wait_for_edge(in_pin, GPIO.FALLING,
bouncetime= bounce_time_ms, timeout=max_movie_time)
camera.stop_recording()
endSecs = time()
camera.stop_preview()
isRecording = False
if timed_out:
print ('movie ' + base_name + str(trial_num) + '.h264 stopped
because of time out after ' + str( endSecs -startSecs) + '
seconds')
else:
print ('movie ' + base_name + str(trial_num) + '.h264 stopped
because of button up after ' + str( endSecs -startSecs) + '
seconds')
$ omxplayer trial_1.h264

36
Care and Feeding of a Raspberry Pi
Frontiers in Neurophotonics Summer School 2019
Nicholas J. Michelson
Jeff LeDue
Pankaj K. Gupta
Timothy H. Murphy

Handout and code prepared by: Jamie Boyd


Setting up an SD Card


Some cards come with Rasbian (or other) OS installed

Otherwise, you can install your own

Start at https://www.raspberrypi.org/downloads/
●Download a disk image
●Copy the disk image to the SD card
●Etcher is a graphical SD card writing tool that works on Mac OS,
Linux and Windows https://etcher.io/

Raspbian versions named after Toy Story characters
●wheezy->jessie->stretch

●Latest Pi needs latest OS, but latest OS will work with oldest Pi

39
sudo raspi-config

Change default user password for security

Set time zone, locale, and WiFi country code.
●Alloptions on these menus default to British or GB until you
change them.

Change keyboard layout

40
apt-get is for software package management
Command What it Does
apt-get update updates list of packages available from repositories
apt-get upgrade Upgrades all installed packages to latest versions
apt-get dist-upgrade Also updates dependent packages
apt-get install pkg downloads and installs a software package pkg
apt-get remove --purge pkg removes the package pkg
apt-get -y autoremove removes packages that are no longer required
apt-get install synaptic installs a GUI package manager front-end

All if these need sudo

41
Sudo: super user-level security privileges


sudo allows users to run commands or launch programs with super
user-level security privileges

gksudo also sets HOME=/root, and copies .Xauthority to a tmp
directory. This prevents files in your home directory becoming
owned by root. May be better when launching applications with
windowed (GUI) interfaces

gksudo python3 myprogram.py
runs myprogram.py with python interpreter permissions elevated to
use GPIO library for hardware access

gksudo idle3
launches idle for Python 3, the python shell has elevated permissions

42
Sharing Data with PCs


Why does this USB drive not work on my pi?
●Linux native file system format is ext3 or ext4
●Windows native file system is NTFS
●Macintosh native file system is APFS, replaced HFS+

How can I make them all share a drive?
●For small thumb drives, format the drive as FAT32 (4 GiB file limit)
●Install NTFS support for Raspbian with apt-get install ntfs-3g
●Consider exFAT, since Windows and Mac support it natively

apt-get install fuse-exfat

https://en.wikipedia.org/wiki/Comparison_of_file_systems

43
Controlling the Pi over a Network

Login remotely with ssh


ssh pi@142.103.107.xxx
pi@142.103.107.xxx's password:

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent


permitted by applicable law.
Last login: Sun May 6 04:17:06 2018
pi@raspberrypi:~ $

44
Copying/Sending Data over a Network

scp copies files over a secure, encrypted network connection

From a remote computer to the local computer

scp pi@192.168.0.102:RemotePath/RemoteFileName LocalPath

From the local computer to a remote computer

scp LocalPath/LocalFileName pi@192.168.0.102:RemotePath

Recursively for all files in a directory (can also use wild cards *)

scp -r pi@192.168.0.102:RemotePath LocalPath

For GUI version for Windows or Mac:

FileZilla, Cyberduck, WinSCP

45
Use git/github for Sharing Code

git clone https://github.com/jamieboyd/neurophoto2018

46

You might also like