Raspberry Pi Hardware en I/OPs: dit is de hardware pagina, zie ook mijn algemene Raspberry Pi pagina!
Deze pagina laat wat mogelijkheden zien van I/O van de originele Raspberry, zoals de 26-pins P1 uitbreidingsconnector van de originele RaspberryPi B. Zie ook het officiële schema van de Raspberry Pi (en de errata). De latere versies van de Raspberry hebben extra pinnen; even opletten dus welke versie je hebt.
Er zijn een aantal 'general-purpose I/O' pinnen (GPIO's) die je als input of als output vrij kunt programmeren, plus een aantal pinnen met speciale functies (die je overigens ook als general purpose kunt gebruiken). De pinnen met speciale functies maken het mogelijk complexere modules aan te sturen, bijvoorbeeld via I2C: een 2-draads (plus 2 voor voeding) bus-systeem om bijvoorbeeld temperatuursensors, lcd's en zo aan te sturen. Welke versie?Er zijn verschillende revisies van de Raspberry, met verschillen in de
I/O!!! Deze pagina is voor de Raspberry Pi 1 model B, revisie 1 (van voor oktober 2012) met
maar 256 MB geheugen. Ondertussen is er ook een B+ versie met extra I/O, en zelfs al een quad-core Raspberry Pi 2B en Raspberry Pi 3B+, voor dezelfde prijs. Je kan de general-purpose I/O pinnen op de header P1 op diverse manieren benaderen, zoals vanuit C of Python, of zelfs als files vanuit bash scripts. De header P1 is te zien in de linkerbovenhoek van de foto hiernaast. Er zijn kant-en-klare printjes voor te koop om er op aan te sluiten en makkelijk te kunnen experimenteren, zoals het officiëuze GertBoard en deze goedkope prototype-bordjes, maar ik heb even zelf een printje gemaakt waarop ik de belangrijkste pinnen op aparte connectoren heb gezet (gpio, i2c, serial; zie de foto verderop). Raspberry 1B: I/O connector P1Hier als referentie de 26-polige pin-out van de P1 connector op de originele 256 MB
B-versie (zie deze eLinux pagina voor de 40-polige versie), met zowel de Broadcom
datasheet namen (BCM) als de Raspberry Pi namen. Meer details op de eLinux RPi BCM2835 GPIO pagina. Let op: hoewel er een +5 Volt
pin op de connector zit, zijn alle I/O's 3.3 Volt, en kunnen niet tegen 5 Volt!! Max stroom
per pin is blijkbaar instelbaar van 2 tot 16 mA, maar kan de details niet vinden. GPIO pinnummering
(BCM of Raspberry) is afhankelijk van je programmeertaal, zie onderstaande tabel.
(*1): I2C1_SDA/GPIO2 en I2C1_SCL/GPIO3
op revisie-2 borden! Raspberry 3: Extra pinnen
GPIO low-level aansturenGPio vanuit andere talen?Op deze RPi Low-level peripherals pagina ook voorbeelden van GPIO vanuit andere talen, zoals Perl, C, C#, Java en Ruby Ook op die pagina een hulpprogramma om vanuit bash op een meer praktische manier met de gpio om te kunnen gaan. GPIO vanaf de bash promptAls allereerste experiment: een simpel voorbeeld van GPIO aansturing vanuit bash-scripts. Ik heb hiervoor een LED op GPIO 1 aangesloten met een serie-weerstand van 680 Ohm tussen pin P1-12 (gpio-1) en P1-6 (ground). GPIO 1 (volgens de Raspberry nummering, gpio18 volgens de BCM nummering) kan ik zo hoog en laag te maken, en zo de LED aan en uit zetten. Lezen kan op een vergelijkbare manier (met b.v. cat). Let op: gebruik hierbij de pinnummering zoals Broadcom ze voor de BCM aangeeft! kees@raspberrypi ~ $ sudo -i; # niet nodig voor
nieuwere Raspberries GPIO vanuit PythonEerst éénmalig installeren van de python headers en de gpio library (download van PiPy): sudo apt-get install python-dev Dan kan je vervolgens in een python-script of vanaf de prompt de gpio aan, voorbeeld: kees@raspberrypi ~ $ sudo python I2CLet op!Er zijn twee I2C bussen op de BCM2835 chip, op een revisie-1 B-board is bus 0 de bus op de P1 connector. Op een revisie-2 bord en op de PI 2 en 3, is dit bus 1!! En: 'I2C clock stretching' is niet goed ondersteund op de BCM283x chips (dus voor alle Raspberries), zie hier en hier!!! Op de Raspberry zit (zoals op zo veel systemen) een I2C bus (vergelijkbaar met de SMB bus). Op deze 2-pins (plus ground/voeding...) bus kan je ook je eigen hardware aansluiten (tot max 128 I2C chips). Het is een ideale manier om bijvoorbeeld extra I/O pinnen te krijgen met behulp van een PCF8574A chip (8 extra I/O pinnen). Ook bijvoorbeeld LCD displays, temperatuursensors, real-time clock, A/D converters en dergelijken kunnen via I2C worden aangesloten. Plus, je kan voor speciale taken je 'eigen I2C-chips' maken voor een paar Euro's, bijvoorbeeld voor stappenmotoren aan te sturen. De (1K8) pull-up weerstanden voor I2C zitten al op de Raspberry, hoeven dus niet extern te worden aangesloten. Voor de Raspberry Pi 1: I²C aansturen is in het begin wat lastig, omdat
de I2C modules niet
standaard in Raspbian geladen zijn. De i2c-bcm2708 module is blacklisted in
Voor de Rasperry Pi 3 kan je met PCF8574 voor extra I/OIk heb het hiernaast staande schema'tje met een PCF8574A (kost zo'n € 2) op een stukje
gaatjesprint gemaakt, en met een flatcable aangesloten op de I2C-pinnen van de Raspberry. Op de
print zitten ook twee LEDs en een switch. Het was nog even lastig de PCF te 'vinden' op de bus; het
adres op de bus was een bit naar rechts verschoven t.o.v. de documentatie van de PCF8574A; dus
Standaard is de I²C-poort niet voor iedereen toegankelijk (kan hardware aansturen die de werking
van het systeem kan verstoren, zoals op een PC). Hier hebben we de I2C-bus zelf in de hand, dus om
niet steeds sudo voor een commando te moeten zetten is het handig de poort world-access te
geven: while [ "0xfe" = `i2cget -y 0 0x38 0xfe` ]; do sleep 1; i2cget -y 0 0x38 0xfd; sleep 1; done
|
Sensor |
Addr |
0 °C uitlezing |
Use |
0 |
0x48 |
0.38 °C | Test |
1 |
0x49 |
0.00 °C | Test |
2 |
0x4A |
0.25 °C | D1 |
3 |
0x4E |
0.25 °C | AZ1 |
4 |
0x49 |
0.25 °C | CV1 |
5 |
0x4D |
0.00 °C | CV2 |
6 |
0x4E |
0.12 °C | CV3 |
7 |
0x4F |
?? °C | Ext |
De PCF8574 zou controle nog eenvoudiger moeten maken... Helaas lukt het niet de driver voor de
PCF8574 te laden omdat deze niet standaard in de compiler is meegecompileerd (modprobe
pcf857x
geeft een fout). Ik kreeg van Jarno Kamminga de volgende extra informatie
hierover:
Er bestaat een kernel module genaamd gpio-pcf8574x, standaard is deze niet meegeleverd met bijvoorbeeld Raspbian wheezy en het vereist wat werk om deze te compileren, maar als deze gecompileerd is kan je hem laden met "
modprobe gpio-pcf8574x
". Zodra de driver geladen is kan je met "echo pcf8574 0x38 > /sys/class/i2c-adapter/i2c-1/new_device
" de IC toevoegen aan I2C, dit zorgt ervoor dat je vervolgens de poorten/pins kan benaderen via de sysfs interface, zoals jij toont in "GPIO vanaf de bash prompt".Zodra je het nieuwe I2C apparaat geladen hebt wordt er een nieuwe GPIO chip gecreerd (
/sys/class/gpio/gpiochip248
). Je kan nu de acht GPIO pinnen van de PCF8574 benaderen alsGPIO248
totGPIO255
. Bijvoorbeeld:kees@raspberrypi ~ $ sudo -i
root@raspberrypi ~ # echo "248" >/sys/class/gpio/export
root@raspberrypi ~ # echo "out" >/sys/class/gpio/gpio248/direction
root@raspberrypi ~ # echo "1" >/sys/class/gpio/gpio248/value; # LED gaat aan
root@raspberrypi ~ # echo "0" >/sys/class/gpio/gpio248/value; # LED gaat weer uit
root@raspberrypi ~ # echo "1" >/sys/class/gpio/gpio248/valueVoor het cross-compileren van de kernelmodule kan je terecht op deze pagina: elinux.org/RPi_Kernel_Compilation. Met rpi-update zorg je ervoor dat je de laatste versie van de kernel geinstalleerd hebt. Nadat je rpi-update hebt uitgevoerd moet je de rpi herstarten om de nieuwe kernel te laden. Je hebt dan dezelfde kernel geladen als de broncode die je uitcheckt bij git://github.com/raspberrypi/linux.git.Voer na het uitvoeren van "
oldconfig
" het volgende uit en selecteerd de kernel module voor de driver om ervoor te zorgen dat deze ook gecompileerd wordt:make ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Op de P1 connector zit ook een seriële poort, dat wil zeggen een RxD en TxD pin (receive en transmit data, respectievelijk pin 10 en pin 8). Deze pinnen zijn niet compatibel met een RS-232 seriële poort op een PC/laptop, maar zijn geïnverteerd en slechts 3.3 Volt (in plaats van de plus en min 5 .. 25 Volt van een echte RS232). Ik wilde hem toch aan de pC hangen om te testen, en had nog een FTDI serieel-naar-USB converter liggen (niet precies die, maar ok), die dat aan kan; alternatief kan je bijvoorbeeld met een MAX232 naar echte RS-232 signalen (klassieke serial port) over gaan voor oudere computers.
Door nu op de PC met bijvoorbeeld GtkTerm de verbinding op te zetten (met mijn
FTDI-oplossing, poort /dev/ttyUSB0
, baudrate 115200) krijg je een 'console'-scherm te
zien waarop je ook op de Raspberry Pi kunt inloggen (in plaats van bijvoorbeeld via Ethernet en
SSH). Ook krijg je hier bij het booten het hele boot-process te zien, handig als je
iets overhoop gehaald hebt en het systeem niet meer lijkt te starten.
Maar wat nu als je de seriële poort voor iets anders wilt gebruiken, bijvoorbeeld voor
aansturing van een serieel home control system? Hoe koppel je de poort los van de console-software?
Dit staat beschreven op "Using the Raspberry
Pi’s serial port". In het kort twee stappen, aanpassen van /boot/cmdline.txt
(verwijder console=ttyAMA0,115200
kgdboc=ttyAMA0,115200
) om tijdens
booten de poort niet te gebruiken, en aanpassen van /etc/inittab
(comment out de regel
met 2:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
) zodat de console niet wordt
herstart op de seriële poort. Dan kan je bijvoorbeeld op de Raspberry minicom installeren om de verbinding te
testen.
De basis-commando's:
^a B : scrolling back in buffer
^a Q : quit (no reset)
^a X : eXit and reset
^a Z: help
sudo apt-get install minicom ; Raspberry Pi 1, al
OK voor 3
sudo minicom -b 9600 -o -c on -D /dev/ttyAMA0
# of: sudo chmod 666 /dev/ttyAMA0; minicom -b 9600 -o -D
/dev/ttyAMA0
Met mijn serial-naar-USB converter op mijn PC aangesloten en daar GtkTerm gestart
(/dev/ttyUSB0
, baudrate 9600), werkt! (Ps: kan nodig zijn om de hardware flow control
uit te zetten als lijnen als DSR niet aangesloten zijn: start minicom met ook de
-s
parameter, ga naar 'Serial Port Setup', keuze F -> No). De poort is nu dus vrij
voor eigen applicaties. Uitleg over gebruik van de seriële poort in Linux is onder andere te vinden
op "Serial Port
Programming in Windows and Linux". En een voorbeeld van UART
programming op de Raspberry helpt ook.
Helaas is de Raspberry Pi 3 wat ingewikkelder. Dit komt omdat standaard de
ttyAMA0
UART poort voor Bluetooth BLE gebruikt wordt... In plaats daarvan is er nu een
software UART ('mini UART' ttyS0
) aan pin 8 (TxD) en 10 (RxD) geknoopt. Om de UART op
de oude manier te gebruiken moet je een 'device tree
overlay' genaamd pi3-miniuart-bt
installeren, die de UART op de ouderwetse
manier gebruikt. Op Raspberry Pi 3 UART Boot
Overlay staat dit beschreven. Let op, hangt af van welke Raspbian release je gebruikt! Als je
nu pin 8 en 10 met elkaar verbindt (jumpertje), en minicom start zoals hierboven beschreven,
moet elk karakter dat je typt ook weer op het scherm te zien zijn --> ja, lukt!
Uiteraard werkt nu Bluetooth niet meer, maar op dit moment is voor mij de seriële poort
belangrijker. De software UART heeft ook als nadeel dat bij verandering van de kloksnelheid van het
videoblok (bijvoorbeeld als de Raspberry warm wordt) de UART klok ook verandert, waarmee je dus je
verbinding kwijt raakt. Ook dit is weer te corrigeren,
bijvoorbeeld door de kloksnelheid vast te zetten (en
/lib/systemd/system/hciuart.service
bij te werken, zoek in de overlay
GitHub readme), maar dit is voor mij van later zorg.
Ps: uitschakelen van BT en/of Wifi wordt in deze post behandeld: How to disable the Pi3's WLAN & Bluetooth ?
De Raspberry heeft overigens ook een ingebouwde temperatuursensor, en ook spanningssensoren etc; uit te lezen met de VideoCore driver VCHIQ.
sudo /opt/vc/bin/vcgencmd measure_temp; # geeft b.v.:
temp=45.6'C (rust, 18°C kamer)
sudo /opt/vc/bin/vcgencmd measure_volts; # volt=1.2000V
Hier meer informatie over beschikbare vcgencmd commando's. Om dit ook als gewone gebruiker te kunnen doen moet je wat extra instellingen doen (en een reset):
sudo echo 'SUBSYSTEM=="vchiq",GROUP="video",MODE="0660"' >
/etc/udev/rules.d/10-vchiq-permissions.rules
sudo usermod -a -G video kees; # zelf toevoegen aan de groep
'video'