Retour

Raspberry Pi 4 et 5 dans le navigateur — mode basique et mode Linux, étape par étape

Un Raspberry Pi dans Velxio est une carte sur le canevas qui exécute un script Python sur le circuit que vous câblez autour d’elle. Il n’y a rien à compiler. Vous écrivez le script, vous appuyez sur Run, et l’un des deux moteurs l’exécute :

Cet article construit deux projets, un par mode, et montre chaque clic en chemin. Le premier est une station d’alarme composée de modules Grove sur un Raspberry Pi 5 — un capteur de mouvement, un interrupteur à vibration et un DHT11 côté entrée, un buzzer, deux LED et un relais avec un ventilateur côté sortie. Le second est un montage de capteurs sur un Raspberry Pi 4 avec trois périphériques I2C. Les deux scripts utilisent les bibliothèques fournies avec Raspberry Pi OS, ils fonctionnent donc sans modification sur une vraie carte.

Avant de commencer, deux choses concernant l’accès. N’importe qui peut placer un Raspberry Pi sur le canevas et câbler un circuit autour. Son exécution nécessite un compte connecté — chaque compte gratuit bénéficie de trois sessions d’essai de 15 minutes sur la famille Raspberry Pi, dans l’un ou l’autre mode, et tout forfait payant supprime la limite. Les détails se trouvent dans la section Ce que cela coûte vers la fin.

Deux façons d’exécuter le même script

Mode basiqueMode Linux
Où le script s’exécuteUn interpréteur Python dans l’onglet de votre navigateurUn invité Alpine Linux sous QEMU sur les serveurs de Velxio
Temps de démarrageQuelques secondesEnviron une minute
GPIORPi.GPIO, gpiozero, Adafruit BlinkaLes mêmes, plus /dev/gpiochip0 et les outils libgpiod
I2C, SPI, UART, 1-WireLes vrais smbus2, spidev, pyserial et w1thermsensor via des fichiers de périphériques émulésLes mêmes bibliothèques via les vrais nœuds de périphériques du noyau
Un shell et un système de fichiersNonOui, dans le Serial Monitor
Paquets tiersDepuis un requirements.txtDepuis un requirements.txt, résolus hors ligne avant le démarrage de l’invité
Idéal pourPresque toutLes outils shell, les sous-processus, les fichiers et tout ce qu’un tutoriel fait depuis un terminal

Le moteur est choisi pour vous. Un script qui demande quelque chose que seul Linux peut faire, comme subprocess, est envoyé en mode Linux et une puce dans la barre d’outils vous indique pourquoi. Vous pouvez aussi forcer vous-même le mode Linux, ce que fait le second projet.

Projet 1 — une station d’alarme Grove sur un Raspberry Pi 5

Les modules Grove sont le moyen le plus rapide d’ajouter des capteurs à un Pi — chaque module possède le même connecteur à quatre broches, et dans Velxio chacun se relie au header avec trois fils, SIG, VCC et GND. Cette station surveille une pièce avec un capteur de mouvement PIR et un interrupteur à vibration, lit l’air avec un DHT11, et répond via un buzzer, une LED verte pour « tout est calme », une LED bleue pour « alarme », et un relais qui fait tourner un ventilateur quand la pièce devient chaude.

Étape 1 — démarrer un projet sur le Raspberry Pi 5

Ouvrez velxio.dev/editor. La boîte de dialogue Start a new project s’ouvre d’elle-même. Faites défiler jusqu’à la section Raspberry Pi et cliquez sur la carte Raspberry Pi 5. La carte Raspberry Pi 4B fonctionne de la même manière — les deux cartes partagent le header 40 broches et les mêmes bibliothèques, donc tout ce qui suit s’applique aux deux.

La boîte de dialogue Start a new project avec la section Raspberry Pi ; la carte Raspberry Pi 5 est mise en évidence

Étape 2 — ajouter les composants

Cliquez sur le bouton bleu Add à l’extrémité droite de la barre d’outils. Il ouvre le catalogue de composants.

La barre d'outils avec le bouton Add mis en évidence

Tapez un nom dans le champ de recherche et cliquez sur la carte pour déposer le composant sur le canevas. Les modules Grove sont tous listés sous leurs noms Seeed, donc « Grove PIR » ou « Grove relay » les trouve. Ajoutez ces huit composants, un par un :

  1. Grove - PIR Motion Sensor
  2. Grove - Vibration Sensor (SW-420)
  3. Grove - Temperature & Humidity Sensor (DHT11)
  4. Grove - Piezo Buzzer
  5. Grove - Green LED
  6. Grove - Blue LED
  7. Grove - Relay
  8. DC Motor / Fan

La boîte de dialogue Add Component avec Grove PIR tapé dans le champ de recherche et la carte du capteur de mouvement PIR mise en évidence

Les composants peuvent être glissés n’importe où sur le canevas. Laisser le Pi en bas et les modules au-dessus de son header garde les fils courts.

Étape 3 — câbler

Pour tracer un fil, cliquez sur une broche, puis cliquez sur la broche à l’autre extrémité. Les noms des broches apparaissent lorsque vous survolez un composant. Chaque module Grove prend les mêmes trois fils — SIG vers un GPIO, VCC vers 3V3, GND vers GND. Le relais fait exception côté alimentation, sa bobine veut du 5 V.

ModuleSIGVCCGND
Capteur de mouvement PIRGPIO173V3GND
Capteur de vibration (SW-420)GPIO273V3GND
DHT11GPIO43V3GND
BuzzerGPIO243V3GND
LED verteGPIO53V3GND
LED bleueGPIO63V3GND
RelaisGPIO235VGND

Le ventilateur n’a pas de fil de signal propre. Il se branche sur les contacts commutés du relais, comme une charge sur un banc — l’alimentation entre par COM et ressort par NO uniquement tant que la bobine est excitée.

DeVers
Raspberry Pi 5VRelais COM
Relais NOVentilateur +
Ventilateur -Raspberry Pi GND

La station câblée — le Raspberry Pi 5 en bas, le PIR, le capteur de vibration, le DHT11 et le buzzer alignés au-dessus de son header, les deux LED et le relais avec son ventilateur en dessous, avec des légendes sur chaque module

Étape 4 — le script

L’explorateur de fichiers à gauche contient déjà un fichier nommé script.py avec un court script de clignotement. Gardez ce nom. Le mode basique exécute le premier fichier .py qu’il trouve, mais le mode Linux exécute spécifiquement script.py, donc un projet dont le fichier principal garde ce nom fonctionne dans les deux.

L'éditeur de code avec script.py sélectionné dans l'explorateur de fichiers

Remplacez son contenu par ce script :

"""Grove alarm station on a Raspberry Pi 5.

A PIR sensor and a vibration switch watch the room, a DHT11 reads the air,
and the actuators answer: a buzzer and a blue LED for the alarm, a green LED
while all is quiet, and a relay that runs a fan when the room gets warm.
Every module hangs off the header with a Grove cable, one signal pin each.

Wiring, BCM numbers (VCC and GND of each module to 3V3 and GND):
    PIR motion sensor   SIG GPIO17   HIGH while motion is seen
    vibration SW-420    SIG GPIO27   LOW while shaking, HIGH at rest
    DHT11               SIG GPIO4
    buzzer              SIG GPIO24
    green LED GPIO5, blue LED GPIO6
    relay               SIG GPIO23, VCC on 5V; the contacts switch the fan:
                        5V to COM, NO to the fan's +, the fan's - to GND
"""
import time

import adafruit_dht
import board
from gpiozero import LED, Button, Buzzer, MotionSensor

FAN_ON_AT = 28   # degrees C
HOLD = 2.5       # seconds the alarm light stays on after the beeps

pir = MotionSensor(17)
shaker = Button(27, pull_up=True)   # the SW-420 pulls SIG low while it vibrates
dht = adafruit_dht.DHT11(board.D4, use_pulseio=False)
buzzer = Buzzer(24)
quiet_led = LED(5)
alarm_led = LED(6)
fan = LED(23)                        # the relay coil: on() closes COM to NO


def alarm(reason, beeps, beep_time):
    print(f"ALARM: {reason}")
    quiet_led.off()
    alarm_led.on()
    buzzer.beep(on_time=beep_time, off_time=0.1, n=beeps, background=False)
    time.sleep(HOLD)
    alarm_led.off()
    quiet_led.on()


quiet_led.on()
motion_seen = False
shaking = False
next_reading = 0
print("Station armed")

while True:
    if pir.motion_detected and not motion_seen:
        alarm("motion in the room", beeps=3, beep_time=0.15)
    motion_seen = pir.motion_detected

    if shaker.is_pressed and not shaking:
        alarm("vibration on the door", beeps=1, beep_time=0.6)
    shaking = shaker.is_pressed

    if time.monotonic() >= next_reading:
        next_reading = time.monotonic() + 2
        try:
            temperature, humidity = dht.temperature, dht.humidity
        except RuntimeError as err:   # a DHT11 misses a reading now and then
            print(f"DHT11: {err}")
        else:
            fan.value = temperature >= FAN_ON_AT
            print(f"{temperature:.0f} C  {humidity:.0f} %RH  fan {'on' if fan.value else 'off'}")

    time.sleep(0.1)

Trois choses méritent un coup d’œil, car elles sont identiques sur du matériel réel :

Étape 5 — exécuter

Sur la barre d’outils, cliquez sur le triangle vert pour lancer le projet. Le Serial Monitor s’ouvre en bas et rapporte ce que fait le moteur — il charge le runtime Python, installe la bibliothèque GPIO, et affiche une ligne comme [Velxio] ready in 6068 ms suivie du nom du script qu’il exécute. À partir de là, chaque print() du script atterrit là.

La barre d'outils avec le bouton Run mis en évidence

Le script affiche Station armed, puis une ligne de température et d’humidité toutes les deux secondes. Le DHT11 sur le canevas démarre à 31 C, donc le relais se ferme immédiatement et le ventilateur se met à tourner — le moteur affiche une flèche de direction et sa vitesse en tr/min, et l’indicateur propre du relais s’allume. Maintenant, interagissez avec les capteurs :

La station en cours d'exécution en mode basique — le ventilateur tourne derrière le relais, la LED bleue est allumée après un clic sur le dôme du PIR, et le Serial Monitor affiche les relevés et la ligne ALARM

Le carré rouge à côté du bouton Run arrête le script. C’est le mode basique dans son intégralité — le script s’exécute dans votre onglet, les broches atteignent le canevas directement, et toute la boucle entre Run et un circuit qui réagit prend quelques secondes.

Projet 2 — un montage de capteurs I2C sur un Raspberry Pi 4, puis le mode Linux

Le second projet place trois périphériques I2C sur le bus du connecteur et utilise le véritable smbus2 pour communiquer avec eux — un convertisseur analogique-numérique Grove ADS1115 avec deux potentiomètres, un capteur de température et d’humidité Grove SHT31, et un OLED SSD1306. Un bouton et une LED sur de simples GPIO complètent l’ensemble. Le même circuit fonctionne sur un Raspberry Pi 5 sans changer un fil ni une ligne — le connecteur est identique.

L’ADS1115 est là pour une raison qui surprend beaucoup de gens — un Raspberry Pi n’a aucune entrée analogique. Un potentiomètre câblé directement à un GPIO ne lit jamais que haut ou bas, sur la carte réelle comme dans Velxio, donc les boutons passent par le CAN.

Le circuit

Démarrez un nouveau projet sur la carte Raspberry Pi 4B et ajoutez ces composants depuis le catalogue :

Puis câblez-les. Les trois périphériques I2C partagent GPIO2 (SDA) et GPIO3 (SCL) :

Depuis (Raspberry Pi 4)Vers
GPIO2 (SDA)SDA de l’ADS1115, du SHT31 et de l’OLED
GPIO3 (SCL)SCL de l’ADS1115, du SHT31 et de l’OLED
3V3VCC de l’ADS1115, du SHT31, de l’OLED et des deux potentiomètres
GNDGND de l’ADS1115, du SHT31, de l’OLED et des deux potentiomètres
GPIO27Anode de la LED ; cathode de la LED vers 220 Ω, puis GND
GPIO22Bouton-poussoir ; l’autre côté du bouton vers GND
DepuisVers
Potentiomètre 1 SIGADS1115 A0
Potentiomètre 2 SIGADS1115 A1

Le montage de capteurs câblé — le Raspberry Pi 4 en bas, l'ADS1115 avec deux potentiomètres, l'OLED et le SHT31 au-dessus, et la LED et le bouton à droite, avec des légendes sur les broches I2C et sur chaque périphérique

Le script

Enregistrez ceci sous script.py. Il demande d’abord à chacune des trois adresses si quelqu’un répond, puis boucle — deux canaux CAN, la température et l’humidité, l’état du bouton sur la LED, et les mesures sur l’OLED via luma.oled.

"""Sensor rig check for a Raspberry Pi 4.

Probes the three I2C devices, then loops: two knobs through the ADS1115,
temperature and humidity from the SHT31, the readings on the OLED, and a
button that lights the LED. Everything here is what Raspberry Pi OS ships:
smbus2 for the bus, gpiozero for the LED and the button, luma.oled for
the display.

Wiring, on the 40-pin header:
    I2C   : ADS1115, SHT31 and OLED on GPIO2 (SDA) and GPIO3 (SCL), 3V3, GND
    ADC   : one potentiometer on ADS1115 A0, another on A1
    GPIO  : LED through 220 ohm on GPIO27, button between GPIO22 and GND
"""
import time

import smbus2
from gpiozero import LED, Button
from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1306

ADS1115, SHT31, OLED = 0x48, 0x44, 0x3C
NAMES = {ADS1115: "ADS1115", SHT31: "SHT31", OLED: "SSD1306 OLED"}

# ADS1115 config register, field by field (datasheet, table 8)
ADS_START = 0x8000       # OS: begin one conversion
ADS_MUX_SINGLE = 0x4000  # AINx against GND; the channel goes in bits 12 and 13
ADS_PGA_4V = 0x0200      # +/-4.096 V full scale
ADS_ONE_SHOT = 0x0100    # power down between conversions
ADS_128_SPS = 0x0080     # 128 samples per second
ADS_NO_COMP = 0x0003     # comparator off
ADS_LSB_VOLTS = 4.096 / 32768

bus = smbus2.SMBus(1)
led = LED(27)
button = Button(22, pull_up=True)


def present(address):
    """True when a device acknowledges its address on bus 1."""
    try:
        bus.write_quick(address)
        return True
    except OSError:
        return False


def read_ads1115(channel):
    """One single-shot conversion on AIN0..AIN3, returned in volts."""
    config = (ADS_START | ADS_MUX_SINGLE | (channel << 12)
              | ADS_PGA_4V | ADS_ONE_SHOT | ADS_128_SPS | ADS_NO_COMP)
    bus.write_i2c_block_data(ADS1115, 0x01, [config >> 8, config & 0xFF])
    time.sleep(0.01)
    hi, lo = bus.read_i2c_block_data(ADS1115, 0x00, 2)
    raw = (hi << 8) | lo
    if raw & 0x8000:
        raw -= 0x10000
    return raw * ADS_LSB_VOLTS


def read_sht31():
    """Single shot, high repeatability, no clock stretching (command 0x2400)."""
    bus.i2c_rdwr(smbus2.i2c_msg.write(SHT31, [0x24, 0x00]))
    time.sleep(0.02)
    reply = smbus2.i2c_msg.read(SHT31, 6)
    bus.i2c_rdwr(reply)
    d = list(reply)
    temperature = -45 + 175 * ((d[0] << 8) | d[1]) / 65535
    humidity = 100 * ((d[3] << 8) | d[4]) / 65535
    return temperature, humidity


print("I2C bus 1:")
for address, name in NAMES.items():
    print(f"  0x{address:02X}  {name}: {'found' if present(address) else 'missing'}")
print()

oled = ssd1306(i2c(port=1, address=OLED))

while True:
    knob_a = read_ads1115(0)
    knob_b = read_ads1115(1)
    temperature, humidity = read_sht31()
    pressed = button.is_pressed
    led.value = pressed
    print(f"A0 {knob_a:5.3f} V   A1 {knob_b:5.3f} V   {temperature:4.1f} C  {humidity:3.0f} %RH"
          + ("   button pressed" if pressed else ""))
    with canvas(oled) as draw:
        draw.text((0, 0), "Pi 4 sensor rig", fill="white")
        draw.text((0, 16), f"A0 {knob_a:.2f}V  A1 {knob_b:.2f}V", fill="white")
        draw.text((0, 32), f"{temperature:.1f} C   {humidity:.0f} %RH", fill="white")
        draw.text((0, 48), "button " + ("down" if pressed else "up"), fill="white")
    time.sleep(2)

Trois détails méritent un coup d’œil. L’ADS1115 est configuré champ par champ, comme sa fiche technique présente le registre de configuration, de sorte que chaque constante peut être vérifiée dans le tableau 8 de ce document. Le SHT31 est lu avec i2c_rdwr parce que sa commande de mesure est constituée de deux octets sans adresse de registre, ce que les appels SMBus ordinaires ne peuvent pas exprimer. Et luma.oled est la même bibliothèque d’affichage que les tutoriels Raspberry Pi installent avec pip ; ici elle est préinstallée, comme smbus2 et gpiozero.

Exécutez-le d’abord en mode basique

Appuyez sur Run. La détection trouve les trois puces, la boucle affiche les mesures, et l’OLED les montre. Tournez un potentiomètre et la tension A0 ou A1 suit ; cliquez sur le SHT31 et vous pouvez régler la température et l’humidité qu’il rapporte ; maintenez le bouton-poussoir et la LED s’allume.

Le montage de capteurs en cours d'exécution en mode basique — l'OLED affiche les deux tensions, la température et l'humidité et l'état du bouton, et le moniteur série affiche les trois périphériques trouvés et les mesures

Tout ce qui précède s’est exécuté dans le navigateur. Les étapes suivantes exécutent exactement le même projet sur une machine Linux.

Passez en mode Linux

  1. Si le moniteur série n’est pas ouvert, cliquez sur Serial dans la barre d’outils.
  2. Dans la barre de titre du moniteur série, à droite, cliquez sur Linux terminal.

La barre de titre du moniteur série avec le bouton Linux terminal mis en évidence

  1. Une boîte de dialogue intitulée Advanced Linux mode explique ce qui va se passer — le projet redémarre, le démarrage prend environ une minute, et tout s’exécute plus lentement que dans le navigateur. Cliquez sur Start Linux mode.

La boîte de dialogue Advanced Linux mode avec le bouton Start Linux mode mis en évidence

L’invité démarre dans le moniteur série, qui est devenu un véritable terminal. Pendant le démarrage, la puce à côté du sélecteur de carte dans la barre d’outils affiche Linux, et son infobulle indique que le mode Linux est activé pour ce projet.

La barre d'outils avec la puce du moteur affichant Linux mise en évidence

Quand l’invite apparaît, Velxio copie script.py dans le répertoire personnel de l’invité et le lance. Sur un serveur tranquille, l’invite s’affiche après environ 20 secondes et les premières mesures environ une minute après que vous avez cliqué sur le bouton. La sortie est la même qu’avant, et l’OLED est piloté par le même appel luma.oled, désormais depuis l’intérieur de l’invité via /dev/i2c-1 du noyau.

Le montage de capteurs en mode Linux — le terminal affiche les trois périphériques trouvés et les mesures, et l'OLED affiche les mêmes valeurs

Utilisez le shell

C’est à cela que sert le mode Linux. Cliquez dans le terminal, appuyez sur Ctrl+C pour arrêter le script, et vous êtes à une invite root sur un système Alpine Linux. Quelques lignes à essayer :

cat /etc/os-release | head -2
ls /dev/i2c* /dev/spidev* /dev/gpiochip*
gpioset gpiochip0 27=1
ls -la /home/pi

La deuxième ligne liste les bus du connecteur sous forme de nœuds de périphérique — /dev/i2c-0, /dev/i2c-1, /dev/spidev0.0, /dev/spidev0.1 et /dev/gpiochip0. Ils répondent aux mêmes appels système que sur un Raspberry Pi, donc une bibliothèque qui les ouvre elle-même, un programme C, ou votre propre code ioctl communique avec les composants sur le canevas.

La troisième ligne est la façon moderne de piloter une broche depuis le shell, avec les outils libgpiod que fournit Raspberry Pi OS Bookworm. À l’instant où vous appuyez sur Entrée, la LED sur GPIO27 s’allume sur le canevas. L’invité dispose de libgpiod version 1, donc la puce est un argument positionnel, comme écrit ci-dessus, et la syntaxe de la version 2 avec --chip n’est pas comprise.

Le shell Linux après l'interruption du script — la commande gpioset est mise en évidence et la LED sur le canevas est allumée

Pour relancer le script à la main, tapez python3 script.py. Pour revenir au moteur du navigateur, cliquez sur Exit Linux terminal dans la même barre de titre. Le choix n’est pas enregistré avec le projet — rouvrez-le demain et Run repart en mode basique.

La barre de titre du moniteur série en mode Linux avec le bouton Exit Linux terminal mis en évidence

Ce qui fonctionne dans chaque mode

Le tableau ci-dessous est la version courte de la page Raspberry Pi dans la documentation, qui a été mesurée module par module par rapport au produit en ligne.

ModuleMode basiqueMode Linux
RPi.GPIO, gpiozeroPréinstalléPréinstallé
smbus2, spidevPréinstallé, les vraies bibliothèquesPréinstallé, les vraies bibliothèques via les nœuds du noyau
serial (pyserial)Uniquement les chemins UART du PiLe vrai pyserial sur un vrai tty, /dev/serial0
adafruit_dht, Adafruit_DHTPréinstalléPréinstallé
w1thermsensor, l’arborescence sysfs 1-WirePréinstalléVia requirements.txt ; l’arborescence sysfs est présente
luma.oled, RPLCD, ST7789, Adafruit BlinkaPréinstalléPréinstallé
gpiod et les outils gpio*Pas de périphérique caractère dans le navigateurPréinstallé
cv2 (OpenCV)OuiPas de build pour l’invité
picamera2Oui, via votre webcamNon ; utilisez rpicam-jpeg et ses semblables
requests, urllibVia un proxy de sortie avec une liste d’autorisationPas de réseau à l’intérieur de l’invité
Tout le reste sur PyPIVia requirements.txtVia requirements.txt, quand PyPI dispose d’une wheel musl aarch64

Ce qu’aucun des deux modes ne fait, pour que vous ne perdiez pas une session d’essai à le découvrir :

Deux habitudes font gagner du temps. Nommez le fichier principal script.py, pour que les deux modes exécutent le même fichier. Et placez les paquets tiers dans un requirements.txt à côté : lorsqu’un script importe un paquet manquant, la console d’exécution propose la ligne et un bouton l’écrit pour vous.

Ce que cela coûte

N’importe qui peut câbler un circuit Raspberry Pi sans compte. Son exécution est soumise à conditions :

La barre d'outils telle que la voit un visiteur déconnecté, avec la puce Free trial, sign in mise en évidence

Les sessions d’essai sont identiques sur les deux moteurs, donc un script qui n’a besoin que du mode basique devrait y rester : il démarre en quelques secondes au lieu d’une minute, et l’invité Linux est là pour ce que seul Linux peut faire.

Où aller ensuite

Résumé

Deux projets, deux moteurs. La station d’alarme Grove a tourné en mode basique sur un Raspberry Pi 5, d’un canevas vide à un circuit réactif en quelques minutes, avec le code gpiozero et Adafruit DHT qu’utiliserait un tutoriel Raspberry Pi. Le montage de capteurs a d’abord tourné en mode basique sur un Raspberry Pi 4, puis en mode Linux, où le même script a communiqué avec l’ADS1115, le SHT31 et l’OLED via /dev/i2c-1 du noyau, et une commande gpioset tapée à l’invite a allumé une LED sur le canevas. Le mode basique couvre la majeure partie de ce qu’un tutoriel Raspberry Pi demande ; le mode Linux est là pour le terminal, les fichiers et les outils système, au prix d’une minute de démarrage.


Partager sur :
David Montero

Écrit par

David Montero

Creator of Velxio, the open-source circuit and Arduino simulator.

GitHub velxio.dev

Articles liés


Article suivant
Castlevania: Symphony of the Night tourne nativement sur l'ESP32-S3