280 likes | 476 Views
Lecture 9: GPIO on the Raspberry Pi Teaching resources are at www.eej.ulst.ac.uk My office 5B18, telephone 028 90 366364 My email IJ.McCrum@ulster.ac.uk. EEE305 Microcontroller Systems. Background. The following website was accessed on 25/4/13
E N D
Lecture 9: GPIO on the Raspberry Pi Teaching resources are at www.eej.ulst.ac.uk My office 5B18, telephone 028 90 366364 My email IJ.McCrum@ulster.ac.uk EEE305 Microcontroller Systems
Background The following website was accessed on 25/4/13 http://codeandlife.com/2012/07/03/benchmarking-raspberry-pi-gpio-speed/ This compares the speed of doing GPIO in a variety of ways, at least for simple output – the examples show how to generate a square wave by outputting ‘1’s and ‘0’s. The site concludes Hence either the BCM2835 or wiringPI libraries look good!
Summary of methods for GPIO from http://codeandlife.comThe details are in the raspberry Pi Wiki athttp://elinux.org/RPi_Low-level_peripherals Some more examples at https://sites.google.com/site/semilleroadt/raspberry-pi-tutorials/gpio Using /sys/class/gpio “files” is a useful convenient but slow method of access from ANY language, there is also pseudo files in /proc/sys that can be used in a similar way. Another alternative for Python are the wiringPi Python bindings.
C: Maximum performance The Raspberry Pi Wiki gives a nice C code example for true hardware-level access to the GPIO. The interfacing is slightly more difficult, but code isn’t too bad. …[he] took the example program and simplified the main method after setup_io() to this: Note you do not need to use the << operator, use 0x10 instead With a performance of 14MHz this is the fastest; but the code is complex, there is simpler ways of doing GPIO in C, at “reasonable speed” I think I favour the wiringPi library, but the BCM2835 library is good too. Time will tell which is “best” In 12 months time use the one getting more use and with a more vibrant user forum
BCM2835 C library by Mike McCauleyhttp://www.airspayce.com/mikem/bcm2835/index.html It provides functions for reading digital inputs and setting digital outputs, using SPI and I2C, and for accessing the system timers. Pin event detection is supported by polling (interrupts are not supported). There is support at https://groups.google.com/forum/?fromgroups#!forum/bcm2835 Installation Note that you need to add the option –l bcm2835 when compiling your own code.
Notes on using BCM2835 Physical Addresses: Functionsbcm2835_peri_read(), bcm2835_peri_write() and bcm2835_peri_set_bits() are low level peripheral register access functions. They are designed to use physical addresses. The library can use other boards as well as the Pi. In the Pi the base address of the various peripheral registers are available with the following externals: • bcm2835_gpio • bcm2835_pwm • bcm2835_clk • bcm2835_pads • bcm2835_spio0 • bcm2835_st • bcm2835_bsc0 • bcm2835_bsc1
Pin Numbering • The GPIO pin numbering as used by RPi is different to and inconsistent with the underlying BCM 2835 chip pin numbering. • RPi has a 26 pin IDE header that provides access to some of the GPIO pins on the BCM 2835, as well as power and ground pins. Not all GPIO pins on the BCM 2835 are available on the IDE header. • RPi Version 2 also has a P5 connector with 4 GPIO pins, 5V, 3.3V and Gnd. • The functions in this library are designed to be passed the BCM 2835 GPIO pin number and not the RPi pin number. There are symbolic definitions for each of the available pins that you should use for convenience. See RPiGPIOPin. (http://www.airspayce.com/mikem/bcm2835/group__constants.html#ga63c029bd6500167152db4e57736d0939 ) • I will not talk about SPI or I2C here, see the original article at http://www.airspayce.com/mikem/bcm2835/index.html
Benchmarking the BCM code from the codeandspace website Compiling the code is done with the -l bcm2835 compiler flag to include the library. Benchmark code looked like this (note that in Broadcom numbering, GPIO 4 is P1_07):
bcm2835 documentation on the previous code+ other functions int bcm2835_init(void);// returns 1 if successful else 0 Initialise the library by opening /dev/mem and getting pointers to the internal memory for BCM 2835 device registers. You must call this (successfully) before calling any other functions in this library. If bcm2835_init() fails by returning 0, calling any other function may result in crashes or other failures. Prints messages to stderr in case of errors. Nb call bcm2835_close at the end of your program, it is has an end! See OHP 11 for PIN assignments, e.g#define PIN RPI_GPIO_P1_07 void bcm2835_gpio_fsel(uint8_t pin,uint8_t mode);// mode can be BCM2835_GPIO_FSEL_INPT or BCM2835_GPIO_FSEL_OUTP or others… void bcm2835_gpio_write(uint8_t pin, uint8_t on);// use HIGH or LOW for on uint8_t bcm2835_gpio_lev(uint8_t pin);// reads level on PIN, returns HIGH/LOW void bcm2835_delay(unsigned intmillis); // uses the nanosleep system call – RTFM void bcm2835_delayMicrosecs(uint64_t micros); // delays are approx for both of these The functions above are enough to use simple i/o on the rPi – I list some miscellaneous snippets on the overheads following to give you the flavour of the full library
Some notes on the hardwaresee http://elinux.org/RPi_Low-level_peripherals GPIO voltage levels are 3.3 V and are not 5 V tolerant. All the GPIO pins can be reconfigured to provide alternate functions, SPI, PWM, I²C and so. At reset only pins GPIO 14 & 15 are assigned to the alternate function UART, these two can be switched back to GPIO to provide a total of 17 GPIO pins[3]. You must not drive a 3.3V GPIO input from a 5 Volt chip output. You can drive a 5 volt chip with a 3.3 Volt output from the GPIO. Use level shifter ICs, or potential dividers or open collector transistors. Rev.2 boards (>sept ‘12) have an extra connector with 4 more GPIO and some changes to P1 (pins 3,5 become the second I2C, pin 13 chnages from GPIO21 to GPIO27)
WiringPI: (writted to be easy for arduino programmers)see https://projects.drogon.net/raspberry-pi/wiringpi/ Pin numbering • WiringPi supports both an Arduino style pin numbering scheme which numbers the pins sequentially from 0 upwards, as well as the Raspberry Pi’s native BCM_GPIO pin numbering scheme. • Note that when using the BCM_GPIO numbering scheme, you must take into account the board revision! Some pins changed their meaning and numbers from revision 1 to revision 2. • So Arduino pin 7 is actually GPIO 4, see the next slide. • Different Arduino boards use different AVR chips with differently named PORTS and I/O pins. But the PCB connectors are kept the same and the language uses the PCB numbers not the PORT and PIN numbers
The following tables give the mapping of the Raspberry Pi GPIO Pins to the GPIO connector in relation to the pin numbers and the physical location on the connector. This is a representation of the GPIO connector as viewed looking at the board from above, with the USB power at the top and the GPIO to the top-right of the board. If using the connector pin numbering, then note that Pin 1 on the connector is the 3.3v supply. Pin 2 is the 5V supply, and pin 26 is marked CE1 below. Rev 1 boards are marked R1 (3 pins differ on Rev 2 boards)
WiringPi functions https://projects.drogon.net/raspberry-pi/wiringpi/functions/ Before using the WiringPi library, you need to include its header file: #include <wiringPi.h> You may also need to add -I/usr/local/include -L/usr/local/lib -lwiringPi to the compile line of your program depending on the environment you are using. The important one is -lwiringPi Setup Functions there are three ways to initialise wiringPi. intwiringPiSetup (void) ; intwiringPiSetupGpio (void) ; or intwiringPiSetupSys (void) ; I will describe wiringPiSetup(void) ; This initialises the wiringPi system and assumes that the calling program is going to be using thewiringPi pin numbering scheme. This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. See the pins page for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector. This function needs to be called with root privileges.
General wiring functions void pinMode(int pin, int mode) ; This sets the mode of a pin to either INPUT, OUTPUT, or PWM_OUTPUT. Note that onlywiringPi pin 1 (BCM_GPIO 18) supports PWM output. The pin number is the number obtained from the pins table.(intp void digitalWrite (int pin, int value) ;Writes the value HIGH or LOW (1 or 0) to the given pin which must have been previously set as an output. intdigitalRead (int pin) ;This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0) depending on the logic level at the pin. There are also functions to write bytes and setup pwm values as well as controlling activation of pullup or pull down resistors on individual pins. There are some useful timing functions as well; void delay(unsigned int milliseconds) and void delayMicroseconds(unsigned int micros) do what you would expect. The function unsigned intmillis(void) returns the number of milliseconds since you called Setup
Simple installationhttps://projects.drogon.net/raspberry-pi/wiringpi/download-and-install/ Click on the word snapshot on the righthand side of the page: https://git.drogon.net/?p=wiringPi;a=summary This downloads a tar.gz file with a name like wiringPi-98bcb20.tar.gz. Note that the numbers and letters after wiringPi (98bcb20 in this case) will probably be different – they’re a unique identifier for each release. You then need to do this to install: tar xfz wiringPi-98bcb20.tar.gz cd wiringPi-98bcb20 ./build Remember the actual filename will be different – you will have to check the name and adjust accordingly. Test wiringPi’s installation run the gpio command to check the installation: (you need to be root to do this) gpio -v gpioreadall That should give you some confidence that it’s working OK.
The GPIO utility You can use the gpio command from the command line once you install the wiringPi library. – it supports thePiFACE interface board as well as the GPIO pins. Run man gpioto see the options, gpio –v gives the version number Using –g as an argument allows pin numbers to be interpreted as BCM_GPIO rather than wiringPI numbers gpio [-g] mode <pin> in/out/pwm/up/down/tri This sets the mode of a pin to be input, output or pwm and additionally can set the internal pull-up/down resistors to pull-up, pull-down or none. gpio[-g] write <pin> 0/1 This sets an output pin to high (1) or low (0) gpio [-g] read <pin> Reads and prints the logic value of the given pin. It will print 0 (low) or 1 (high).
Examples of command line gpio gpio mode 0 out gpiowrite 0 1 This uses the wiringPi pin numbers to set pin 0 as an output and then sets the pin to a logic 1. gpio -g mode 0 in gpio-g read 0 This uses the BCM_GPIO pin numbering scheme and reads pin 0 (SDA0 on a Rev. 1 Raspberry Pi)
PiFaceCommands (if you have a board!) • The PiFace is somewhat limited in that it has 8 inputs pins and 8 output pins and these are fixed in the hardware, so only the write and read commands are implemented: gpio -p write <pin> 0/1 • Writes the value 0 (off) or 1 (on) to the output pin on the PiFace gpio -p read <pin> • Reads and prints the value on the given input pin. gpio -p mode <pin> up/tri • This enables (up) or disables (tri) the internal pull-up resistor on the given input pin. You need to enable the pull-up if you want to read any of the on-board switches on the PiFace board.
The PiFACE: http://piface.openlx.org.uk/ PiFace Digital communicates to the Raspberry Pi using the SPI interface. The SPI interface driver is included in the later Raspbian distributions but is not enabled by default. You can always enable the SPI driver, or you can load it by hand when required. Always enabling SPI To always enable the SPI driver: After logging in, edit /etc/modprobe.d/raspi-blacklist.conf sudonanoetc/modprobe.d/raspi-blacklist.conf Insert a # at the start of the line containing blacklist spi-bcm2708 #blacklist spi-bcm2708
Alternatively, to load the SPI driver by hand (will not be loaded on reboot): • Type in a terminal: • sudomodprobe spi-bcm2708 • Next, you we need to install the PiFace Digital libraries and change the permissions of the SPI interface. The following script automates this into one command. To install and setup the software, ensure your Pi can access the Internet and type: • sudo apt-get update • wget -O - http://pi.cs.man.ac.uk/download/install.txt | bash • The software will complete installing in a few minutes. • Reboot your Pi by typing: • sudoreboot
Testing use GPIO or After installing the software and restarting, login and startx. Start the PiFace emulator by typing in a terminal: piface/scripts/piface-emulator
http://piface.openlx.org.uk/ see also https://www.modmypi.com/piface-digital-raspberry-pi-expansion-board
Suggested experiments (without PiFace) • Wire up an LED to a couple of GPIO pins (and 3.3V thru a 120 Ohm resistor. Get it blinking! • Wire up a 7 segment display and get it displaying, you’ll need 7 series resistors. • Wire up a keypad, 4 lines for output and 4 lines for input. You will need series resistors on the output and pulldownson the inputs (in case you hit two keys and short outputs together) • Write code that inputs a 4 digit number and then displays it, decrementing at once per second.
The series resistors Are in case you hit two keys at once (in the same column) That would short two outputs together. R1-R4 can be 330 Ohms to limit the current to 10mA. The pulldowns can be any value higher than a k (so that the potential divider being formed still causes a ‘1’ to be read)