Een GPIO-handleiding voor beginners

Een GPIO-gids voor beginners Titelafbeelding

In deze blogpost leer je alles over de GPIO pinnen van de Raspberry Pi. Deze post is speciaal voor nieuwelingen in de elektronica.

Allereerst een waarschuwing:

De Raspberry Pi kan onherstelbaar beschadigd raken als de pinnen verkeerd gebruikt worden. Zorg er dus altijd voor dat je schakeling klopt en dat je voldoende weerstanden gebruikt.

Wat zijn GPIO pinnen

De GPIO pinnen zijn de 40 kleine metalen pinnen aan de bovenkant van de Raspberry Pi. De afkorting GPIO staat voor general purpose input output. Dit betekent dat de GPIO pinnen kunnen worden gebruikt als interface voor bijna elk elektronisch apparaat.

Door het grote aantal manieren om de pinnen (verkeerd) te gebruiken, kan het een beetje verwarrend zijn om aan de slag te gaan. Daarom geeft deze blogpost een aantal voorbeelden van hoe je de pinnen kunt bedienen met Bash, C en Python. Een beetje ervaring met programmeren is dus een voordeel.

Hoewel de 40 pinnen er identiek uitzien, hebben zij verschillende functies. 26 pinnen kunnen worden gebruikt voor GPIO en sommige hebben extra functies. Nog eens 4 pinnen worden gebruikt als voedingsbron (POWER, twee keer 3V3 en twee keer 5V) en 8 als negatieve pool (ook ground of GROUND). De twee resterende pinnen zijn de I2C interface voor ID EEPROM.

Pinout

Onderstaande grafiek toont de belangrijkste informatie, onder andere de pinout. De pinout is identiek voor de meeste Raspberry Pi modellen, maar er zijn verschillen. Controleer altijd de exacte pinout van uw model voordat u een apparaat aansluit. Hiervoor hoef je alleen maar een terminal op je Raspberry Pi te openen (Ctrl+Alt+t) en het volgende commando uit te voeren.

pinout

U ziet een grafiek van alle aansluitingen en de exacte pinout van uw Raspberry Pi.

Raspberry Pi Pinout

Het is u misschien opgevallen dat de GPIO nummers willekeurig zijn en niet overeenkomen met de pinnummering. Om verwarring te voorkomen, noem ik de nummering van 1 tot 40 het BOARD nummer en het nummer van 1 tot 26 het BCM of GPIO nummer.

Dus BOARD pin 1 is de 3V3 POWER connector en GPIO pin 2 is de pin ernaast met BOARD nummer 3.

Hoe sluit ik een apparaat aan op de pinnen

Er zijn verschillende alternatieven om een apparaat op de GPIO-pennen aan te sluiten. Sommige apparaten hebben een GPIO-header, zodat het apparaat rechtstreeks op de GPIO-pinnen kan worden aangesloten. In het algemeen is dit echter niet het geval, en daarom worden jumperdraden of GPIO-verlengkabels gebruikt.

Kijk op onze video over GPIO Pinnen!

In het volgende voorbeeld is een LED aangesloten op de Raspberry Pi met behulp van jumper kabels.

Het circuit

De Female to Male Jumper Wires verbindt de GPIO pin met een header of een breadboard. De pen moet dan geprogrammeerd worden om het apparaat te bedienen. Het apparaat kan een knop, een LED, een sensor, een motor of een display zijn. Het is alleen belangrijk dat het apparaat kan werken met 5 volt of minder en dat het compatibel is met de interfaces I2C, SPI of UART

Voor de bouw hebben we de volgende uitrusting nodig.

  • Raspberry Pi met Raspberry Pi OS
  • Twee mannelijke naar vrouwelijke jumperdraden
  • Een mannelijke naar mannelijke verbindingsdraad
  • 10 kilo Ohm weerstand
  • LED
  • Soldeerloze broodplank

Verbind GPIO pin 13 (BOARD nummer 33) met de + strook en de GROUND pin ernaast (BOARD nummer 34) naar de - strook van het breadboard. Steek vervolgens het ene uiteinde van de weerstand van 10 kilo Ohm (welke weerstand dan ook) in de + strook en het andere uiteinde in een van de dwarsstrips. Voor de LED is de oriëntatie van cruciaal belang. De anode is de langste van de twee armen en vaak gebogen, de kathode is de kortere arm. De anode moet altijd in de + richting, d.w.z. naar de krachtbron, en de kathode in de richting, d.w.z. naar de AARDE toe. Zet dus de langere arm in dezelfde dwarsstrip als de weerstand, zodat de kortere arm in de naastgelegen dwarsstrip zit. Gebruik tenslotte de mannelijke naar mannelijke verbindingskabel om de dwarsstrip van de kathode (kortere arm van de LED) te verbinden met de - strook.

Het volgende schema toont de assemblage, zorg ervoor dat alles correct is en dat de componenten zo ver mogelijk in de printplaat zijn gestoken, anders zullen er losse contacten zijn.

Aufbau des Schaltkreises

De volgende drie codevoorbeelden in Bash, Python en C zijn gebaseerd op deze structuur. Als u andere pennen gebruikt, moet u de code dienovereenkomstig aanpassen.

Bash

Het besturen van de GPIO pinnen via Bash is heel eenvoudig. In Linux worden de GPIO-pinnen aangestuurd door de bestanden in de /sys/class/gpio map. Om een GPIO pin te gebruiken, moet deze eerst geëxporteerd worden. Als voorbeeld gebruik ik GPIO pin 13. In het volgende zijn de bestandsnamen vet en cursief gedrukt.

Open een terminal en maak een lijst van de inhoud van de gpio-map.

cd /sys/class/gpio
ls

De map bevat de bestanden export en export, alsmede submappen voor elke geëxporteerde GPIO pin.

We exporteren de pin door het GPIO-nummer in de /sys/class/gpio/export bestand. Voer dit commando uit in de terminal.

echo 13 > /sys/class/gpio/export
ls

Nu is er een map aangemaakt met het corresponderende pinnummer gpio13. Deze map bevat nog andere mappen en bestanden. Voorlopig zijn alleen de richting en waarde bestanden van belang voor ons.

De richting bestand slaat de stand van de pin op:

in -> Pin staat in lees- of ingangsmodus

uit -> Pin staat in schrijf- of uitgangsmodus

De waarde bestand slaat de spanningstoestand van de pin op:

0 -> pin staat in LOW mode -> er wordt geen spanning op de pin gezet

1 -> Pin staat in HIGH mode -> Spanning wordt op de pin gezet

De volgende commando's zetten de modus op uit en de waarde naar 1.

echo out > /sys/class/gpio/gpio13/direction
echo 1 > /sys/class/gpio/gpio13/value

De LED brandt nu. Het is belangrijk om de pinwaarden na gebruik te resetten. De volgende commando's moeten na elk gebruik worden uitgevoerd.

echo 0 > /sys/class/gpio/gpio13/value
echo in > /sys/class/gpio/gpio13/direction
echo 13 > /sys/class/gpio/unexport

Python programma

Nu abstraheren en automatiseren we deze Bash commando's in Python.

Het volgende Python script biedt een eenvoudige GPIO_Pin klasse. Dit maakt het uiterst gemakkelijk te gebruiken. De os module staat ons toe om dezelfde bash commando's uit te voeren als hierboven vanuit Python. ook, door gebruik te maken van de __del__ methode, hoeven we de pinnen niet meer handmatig te resetten en te verwijderen.

import os
from time import sleep

class GPIO_Pin:
    def __init__(self, num, mode):
        if 0 <= num or num <= 40:
            self.num = num
        else:
            print('Invalid Pin Number -> Enter a number from 0 - 40')
        if mode == 'out' or mode == 'write':
            self.mode = 'out'
        elif mode == 'in' or mode == 'read':
            self.mode = 'in'
        else:
            print('Invalid Pin Mode -> Enter "out" or "write" for output, "in" or "read" for input')
        if self.num and self.mode:
            os.system(f'echo {str(self.num)} > /sys/class/gpio/export')
            sleep(0.05)
            os.system(f'echo {self.mode} > /sys/class/gpio/gpio{str(self.num)}/direction')

    def reset(self):
        os.system(f'echo 0 > /sys/class/gpio/gpio{str(self.num)}/value')
        os.system(f'echo in > /sys/class/gpio/gpio{str(self.num)}/direction')

    def write(self, value):
        if value == 0 or value == 'LOW':
            os.system(f'echo 0 > /sys/class/gpio/gpio{str(self.num)}/value')
        elif value == 1 or value == 'HIGH':
            os.system(f'echo 1 > /sys/class/gpio/gpio{str(self.num)}/value')
        else:
            print('Invalid value -> Enter 1 or "HIGH" for HIGH, 0 or "LOW" for LOW')

    def __del__(self):
        self.reset()
        os.system(f'echo {str(self.num)} > /sys/class/gpio/unexport')

    def set_mode(self, mode):
        self.mode = mode
        os.system(f'echo {str(self.mode)} > /sys/class/gpio/gpio{str(self.num)}/direction')

def main():
    pin = GPIO_Pin(13, 'out')
    number_of_blinks = 10
    for i in range(number_of_blinks):
        pin.write('HIGH')
        sleep(0.5)
        pin.write('LOW')
        sleep(0.5)

if __name__ == '__main__':
    main()

Met de tijdmodule kunnen we zelfs de LED laten knipperen zonder enig probleem. Het hele script kan worden uitgebreid tot een Python module voor GPIO aansturing.

C Programma

Ook in C kunnen we gemakkelijk de inhoud van de gpio-map bewerken. Met behulp van de standaard bibliotheek stdlib kunnen we bestanden openen en de inhoud veranderen.
Het volgende C-programma moet worden gecompileerd voordat het kan worden uitgevoerd. Maak een bestand gpio.c en kopieer het programma erin.
Open dan een terminal en navigeer naar de map waar de gpio.c bestand zich bevindt. Gebruik de volgende commando's om het programma te compileren en uit te voeren.

gcc -o gpio gpio.c
./gpio

Hier is het programma.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define GPIO_ROOT "/sys/class/gpio"
#define EXPORT "/sys/class/gpio/export"
#define UNEXPORT "/sys/class/gpio/export"

#define LOW 0
#define HIGH 1

int export_pin(int num) {
    FILE* export = fopen(EXPORT, "w");
    if (export == NULL) {
        printf("Failed to open the export file\n");
        exit(-1);
    }
    fprintf(export, "%d", num);
    fclose(export);
    return 0;
}

int unexport_pin(int num) {
    FILE* unexport = fopen(UNEXPORT, "w");
    if (unexport == NULL) {
        printf("Failed to open the unexport file\n");
        exit(-1);
    }
    fprintf(unexport, "%d", num);
    fclose(unexport);
    return 0;
}

int set_direction(char *mode, int num) {
    char direction_file_path[1024];
    snprintf(direction_file_path, sizeof(direction_file_path), "/sys/class/gpio/gpio%d/direction", num);
    FILE* direction = fopen(direction_file_path, "w");
    if (direction == NULL) {
        printf("Failed to open the direction file\n");
        exit(-1);
    }
    fputs(mode, direction);
    fclose(direction);
    return 0;
}

int set_value(int val, int num) {
    char value_file_path[1024];
    snprintf(value_file_path, sizeof(value_file_path), "/sys/class/gpio/gpio%d/value", num);
    FILE* value = fopen(value_file_path, "w");
    if (value == NULL) {
        printf("Failed to open the value file\n");
        exit(-1);
    }
    fprintf(value, "%d", val);
    fclose(value);
    return 0;
}

int main() {

    int rslt;
    int num;
    int num_blinks;

    num = 13;
    num_blinks = 10;

    rslt = export_pin(num);
    rslt = set_direction("out", num);
    for (int i = 0; i < num_blinks; i++) {
        rslt = set_value(HIGH, num);
        sleep(1);
        rslt = set_value(LOW, num);
        sleep(1);
    }

    rslt = set_value(LOW, num);
    rslt = set_direction("in", num);
    rslt = unexport_pin(num);

    return EXIT_SUCCESS;
}

PiCockpit - GPIO-app

De gemakkelijkste manier om de GPIO-pennen te bedienen is met behulp van de GPIO App. De PiCockpit webinterface is gratis voor maximaal 5 Raspberry Pi. Het biedt twee grote voordelen: Je hoeft geen verstand te hebben van programmeren om je GPIO pinnen aan te sturen en je kunt dit overal vandaan doen.

Installeer gewoon de PiCockpit-client op uw Raspberry Pi en maak verbinding met uw PiCockpit-account. Daarna kunt u eenvoudig de GPIO pinnen bedienen via de web interface.

Volgende stappen

Nu weet je hoe je de GPIO-pinnen kunt gebruiken met behulp van jumper wires. Natuurlijk zijn er ook externe Python-modules en C-bibliotheken om de GPIO-pinnen aan te sturen. Een goede volgende stap zou zijn om een van de codevoorbeelden uit te breiden. Bijvoorbeeld door extra LED's of een knop te gebruiken.


Veel plezier met experimenteren!

Laat een reactie achter