Add Adafuit Macropad serial connection article
This commit is contained in:
parent
4345e877fa
commit
eff6e3b6e5
7 changed files with 627 additions and 0 deletions
|
@ -0,0 +1,47 @@
|
|||
from adafruit_macropad import MacroPad
|
||||
import usb_cdc
|
||||
import time
|
||||
|
||||
macropad = MacroPad()
|
||||
serial = usb_cdc.data
|
||||
|
||||
def exec_command (data):
|
||||
global timer
|
||||
try:
|
||||
command,option = data.split()
|
||||
except:
|
||||
command = ""
|
||||
option = ""
|
||||
print("cmd: {} | opt: {}".format(command, option))
|
||||
if command == 'time':
|
||||
timer = float(option)
|
||||
print("new timer: {}".format(timer))
|
||||
response = "nouveau timer : {}\r\n".format(option)
|
||||
buffer = bytearray(response)
|
||||
serial.write(buffer)
|
||||
|
||||
def blink(led, light):
|
||||
print('light: {}'.format(light))
|
||||
if light:
|
||||
macropad.pixels[led] = (33, 45, 230)
|
||||
else:
|
||||
macropad.pixels[led] = (0, 0, 0)
|
||||
print('c: {}'.format(macropad.pixels[led]))
|
||||
return False if light else True
|
||||
|
||||
timer=2
|
||||
light=False
|
||||
in_data=bytearray()
|
||||
|
||||
while True:
|
||||
light = blink(1, light)
|
||||
time.sleep(timer)
|
||||
|
||||
if serial.in_waiting > 0:
|
||||
while(serial.in_waiting>0):
|
||||
byte = serial.read(1)
|
||||
if byte == b'\r':
|
||||
exec_command(in_data.decode("utf-8"))
|
||||
in_data = bytearray()
|
||||
else:
|
||||
in_data += byte
|
|
@ -0,0 +1,5 @@
|
|||
import usb_cdc
|
||||
try:
|
||||
usb_cdc.enable(console=True, data=True) # Enable console and data# Write your code here :-)
|
||||
except Exception as e:
|
||||
print(e)
|
|
@ -0,0 +1,44 @@
|
|||
from adafruit_macropad import MacroPad
|
||||
import usb_cdc
|
||||
import time
|
||||
|
||||
macropad = MacroPad()
|
||||
serial = usb_cdc.data
|
||||
|
||||
def exec_command (data):
|
||||
global timer
|
||||
try:
|
||||
command,option = data.split()
|
||||
except:
|
||||
command = ""
|
||||
option = ""
|
||||
print("cmd: {} | opt: {}".format(command, option))
|
||||
if command == 'time':
|
||||
timer = float(option)
|
||||
print("new timer: {}".format(timer))
|
||||
|
||||
def blink(led, light):
|
||||
print('light: {}'.format(light))
|
||||
if light:
|
||||
macropad.pixels[led] = (33, 45, 230)
|
||||
else:
|
||||
macropad.pixels[led] = (0, 0, 0)
|
||||
print('c: {}'.format(macropad.pixels[led]))
|
||||
return False if light else True
|
||||
|
||||
timer=2
|
||||
light=False
|
||||
in_data=bytearray()
|
||||
|
||||
while True:
|
||||
light = blink(1, light)
|
||||
time.sleep(timer)
|
||||
|
||||
if serial.in_waiting > 0:
|
||||
while(serial.in_waiting>0):
|
||||
byte = serial.read(1)
|
||||
if byte == b'\r':
|
||||
exec_command(in_data.decode("utf-8"))
|
||||
in_data = bytearray()
|
||||
else:
|
||||
in_data += byte
|
|
@ -0,0 +1,45 @@
|
|||
from adafruit_macropad import MacroPad
|
||||
import usb_cdc
|
||||
import time
|
||||
|
||||
macropad = MacroPad()
|
||||
serial = usb_cdc.data
|
||||
|
||||
def exec_command (data):
|
||||
global muted
|
||||
try:
|
||||
print(data)
|
||||
command,option = data.split()
|
||||
except:
|
||||
command = ""
|
||||
option = ""
|
||||
print("cmd: {} | opt: {}".format(command, option))
|
||||
if command == 'mute':
|
||||
muted = True if option == 'yes' else False
|
||||
print('muted: {}'.format(muted))
|
||||
|
||||
timer=2
|
||||
in_data=bytearray()
|
||||
muted=False
|
||||
|
||||
while True:
|
||||
key_event = macropad.keys.events.get()
|
||||
if muted:
|
||||
macropad.pixels[1] = (255,0,0)
|
||||
else:
|
||||
macropad.pixels[1] = (0,255,0)
|
||||
|
||||
if key_event:
|
||||
if key_event.pressed:
|
||||
if key_event.key_number == 1:
|
||||
print('get key 1')
|
||||
serial.write(bytearray('mute\r\n'))
|
||||
|
||||
if serial.in_waiting > 0:
|
||||
while(serial.in_waiting > 0):
|
||||
byte = serial.read(1)
|
||||
if byte == b'\r':
|
||||
exec_command(in_data.decode("utf-8"))
|
||||
in_data = bytearray()
|
||||
else:
|
||||
in_data += byte
|
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env python
|
||||
import serial
|
||||
import subprocess
|
||||
|
||||
ser = serial.Serial(port='/dev/ttyACM1')
|
||||
|
||||
ser.flushInput()
|
||||
print('Begin loop')
|
||||
while True:
|
||||
line = ser.readline()
|
||||
try:
|
||||
command = (line.decode()).split()
|
||||
print('command received: {}'.format(command[0]))
|
||||
except:
|
||||
print('no valid command received')
|
||||
command = ""
|
||||
|
||||
try:
|
||||
if command[0] == "mute":
|
||||
# First subprocess for toggle mote the microphone
|
||||
subprocess.run(
|
||||
['pactl', 'set-source-mute', '@DEFAULT_SOURCE@', 'toggle'],
|
||||
)
|
||||
|
||||
# Second one for check the states of microphone
|
||||
result = subprocess.run(
|
||||
['pactl', 'get-source-mute', '@DEFAULT_SOURCE@'],
|
||||
capture_output=True
|
||||
)
|
||||
message = "mute {}\r".format(result.stdout.split()[1].decode())
|
||||
ser.write(message.encode())
|
||||
print('command sent: {}'.format(message))
|
||||
except Error as e:
|
||||
print('Error in command: {}'.format(e))
|
Binary file not shown.
After Width: | Height: | Size: 169 KiB |
452
content/articles/2023/adafruit_macropad_conn_serie/index.md
Normal file
452
content/articles/2023/adafruit_macropad_conn_serie/index.md
Normal file
|
@ -0,0 +1,452 @@
|
|||
Title: Jouer avec le Macropad Adafruit! mais en série
|
||||
Category: linux
|
||||
Tags: Adafruit, CircuitPython, Python
|
||||
Date: 2023-02-26 18:10
|
||||
status: hidden
|
||||
|
||||
Le Macropad Adafruit est un petit clavier de 12 touches rétroéclairées avec un
|
||||
écran OLED et un sélecteur. Il est motorisé par un Raspberry Pi RP2040.
|
||||
|
||||
Dans cet article, nous allons voir comment utiliser ce clavier et communiquer
|
||||
avec via l'utilisation du port série.
|
||||
|
||||
## Circuitpython
|
||||
|
||||
Comme beaucoup de carte électronique à base de micro controlleurs, ce clavier
|
||||
est compatible avec l'écosystème Arduino, il est donc possible de le programmer
|
||||
en C. Il existe aussi un firmware embarqant [CircuitPython][l_circuitp], couplé
|
||||
aux diférentes bibliothèques [fournies par Adafuit][l_circuitp_ada], il est
|
||||
possible d'utiliser *Python* pour le programmer. C'est **ce que nous allons
|
||||
utiliser ici**.
|
||||
|
||||
La documentation sur l'installation du firmware *CyrcuitPython* pour le Macropad
|
||||
est disponible sur le site [d'Adafuit][l_ada_macropad]
|
||||
|
||||
[l_circuitp]:https://circuitpython.org/
|
||||
[l_circuitp_ada]:https://github.com/adafruit/Adafruit_CircuitPython_MacroPad
|
||||
[l_ada_macropad]:https://learn.adafruit.com/adafruit-macropad-rp2040/circuitpython
|
||||
|
||||
## Préparer l'environnement
|
||||
|
||||
Sur notre ordinateur nous allons préparer un *environnement virtuel Python* pour
|
||||
y installer `circup`, module Python permettant d'installer le nécessaire **sur
|
||||
le Macropad**:
|
||||
|
||||
```
|
||||
python -m venv ~/venv_circup
|
||||
source ~/venv_circup/bin/activate
|
||||
```
|
||||
|
||||
Puis après avoir branché le Macropad et monté l'espace de stockage :
|
||||
|
||||
```
|
||||
circup install adafruit_macropad
|
||||
```
|
||||
|
||||
## Installer minicom
|
||||
|
||||
Nous allons maintenant prépare notre système pour tester la connexion série .
|
||||
Tout d'abord installons un logiciel pour communiquer via le port série pour
|
||||
Interagir avec le Macropad. Personnellement j'ai choisi [*minicom*][l_minicom]
|
||||
disponible dans les dépôts Debian, Archlinux et sûrement d'autres distributions:
|
||||
|
||||
```
|
||||
pacman -S minicom
|
||||
```
|
||||
|
||||
Il est aussi nécessaire d'ajouter votre utilisateur dans le groupe `uucp` en
|
||||
utilisant la commande suivante (avec `root` ou `sudo`):
|
||||
|
||||
```
|
||||
gpasswd -a ephase uucp
|
||||
```
|
||||
|
||||
[l_minicom]:https://salsa.debian.org/minicom-team/minicom
|
||||
|
||||
## Initialiser un périphérique série sur la Macropad
|
||||
|
||||
Afin d'initialiser un périphérique série sur le Macropad, il est nécessaire de
|
||||
créer un fichier `boot.py` à la racine de votre lecteur CIRCUITPY et d'y ajouter
|
||||
le code suivant:
|
||||
|
||||
```python
|
||||
import usb_cdc
|
||||
try:
|
||||
"""
|
||||
Initialisation du port série pour la console REPL mais
|
||||
aussi pour un périphérique série, Sous Linux il sera
|
||||
disponible dans /dev/ttyACM
|
||||
"""
|
||||
usb_cdc.enable(console=True, data=True)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
```
|
||||
|
||||
Lors de l'enregistrement du fichier, le Macropad devrait se relancer et prendre
|
||||
en compte les modifications. Plus besoin de toucher à ce fichier, on le laissera
|
||||
tranquille tout au long de cet article. Nous modifierons maintenant le fichier
|
||||
`code.py` toujours à la racine de notre lecteur `CIRCUITPY`.
|
||||
|
||||
## Premier script, faire clignoter une DEL
|
||||
|
||||
Nous allons maintenant tester notre premier code. Celui-ci va simplement faire
|
||||
clignoter une DEL sous une touche de notre clavier. Nous **pourrons changer la
|
||||
fréquence en envoyant la commande `time` via une connexion série**. Voici le
|
||||
code en question:
|
||||
|
||||
```python
|
||||
from adafruit_macropad import MacroPad
|
||||
import usb_cdc
|
||||
import time
|
||||
|
||||
macropad = MacroPad()
|
||||
serial = usb_cdc.data
|
||||
|
||||
def exec_command (data):
|
||||
global timer
|
||||
command,option = data.split()
|
||||
print("cmd: {} | opt: {}".format(command, option))
|
||||
if command == 'time':
|
||||
timer = float(option)
|
||||
print("new timer: {}".format(timer))
|
||||
|
||||
def blink(led, light):
|
||||
print('light: {}'.format(light))
|
||||
if light:
|
||||
macropad.pixels[led] = (33, 45, 230)
|
||||
else:
|
||||
macropad.pixels[led] = (0, 0, 0)
|
||||
print('c: {}'.format(macropad.pixels[led]))
|
||||
return False if light else True
|
||||
|
||||
timer=2
|
||||
light=False
|
||||
in_data=bytearray()
|
||||
|
||||
while True:
|
||||
light = blink(1, light)
|
||||
time.sleep(timer)
|
||||
|
||||
if serial.in_waiting > 0:
|
||||
while(serial.in_waiting>0):
|
||||
byte = serial.read(1)
|
||||
if byte == b'\r':
|
||||
exec_command(in_data.decode("utf-8"))
|
||||
in_data = bytearray()
|
||||
else:
|
||||
in_data += byte
|
||||
```
|
||||
|
||||
Le code est plutôt simple, nous initialisons notre Macropad et la connexion
|
||||
série avec le début de notre fichier:
|
||||
|
||||
```python
|
||||
from adafruit_macropad import MacroPad
|
||||
import usb_cdc
|
||||
import time
|
||||
|
||||
macropad = MacroPad()
|
||||
serial = usb_cdc.data
|
||||
```
|
||||
|
||||
Ensuite nous définissons notre fonction `exec_command` chargée d'interpréter les
|
||||
commandes envoyées depuis la connexion série puis notre fonction `blink` changer
|
||||
de faire clignoter notre DEL.
|
||||
|
||||
Après avoir initialiser les variables `timer` `light` et `in_data` -- cette
|
||||
dernière recevra les données de la connexion série le programme commence. La
|
||||
partie la plus intéressante démarre avec `if serial.is_wainting`.
|
||||
|
||||
À ce moment, si des données sont en attente sur le port série, alors nous les
|
||||
ajoutons à notre variable `in_data`. Lors de la réception d'un retour chariot
|
||||
`\r`, alors nous passons les données reçues à notre fonction `exec_command`.
|
||||
|
||||
### Test de notre code
|
||||
|
||||
Le Test démarre une fois le fichier `code.py` écrit sur notre Macropad.
|
||||
Vous devriez voir la DEL sous la touche 2 clignoter toute les deux secondes.
|
||||
L'écran du Macropad affiche aussi les informations données par les instructions
|
||||
`print` de notre code.
|
||||
|
||||
À partir de de moment nous allons pouvoir utiliser `minicon` pour se connecter à
|
||||
la partie REPL du Macropad et ainsi visualiser aussi les `print`. Ici la console
|
||||
REPL est accessible sous le périphérique `/dev/ttyACM0` :
|
||||
|
||||
```shell
|
||||
$ minicom -D /dev/ttyACM0
|
||||
Welcome to minicom 2.8
|
||||
|
||||
OPTIONS: I18n
|
||||
Compiled on Jan 9 2021, 12:42:45.
|
||||
Port /dev/ttyACM0, 18:28:08
|
||||
|
||||
Press CTRL-A Z for help on special keys
|
||||
|
||||
light: False
|
||||
c: (0, 0, 0)
|
||||
light: True
|
||||
c: (33, 45, 230)
|
||||
```
|
||||
|
||||
La connexion série initiée par notre code est disponible sur le périphérique
|
||||
`/dev/ttyACM1`. Pour modifier le timer, alors nous pouvons entrer la commande
|
||||
suivante depuis un autre terminal:
|
||||
|
||||
```shell
|
||||
printf "time 10\r" > /dev/ttyACM1
|
||||
```
|
||||
|
||||
Sur notre terminal de contrôle avec `minicom`, vous voyons apparaitre alors:
|
||||
|
||||
```
|
||||
light: True
|
||||
c: (33, 45, 230)
|
||||
cmd: time | opt: 10
|
||||
new timer: 10.0
|
||||
light: False
|
||||
c: (0, 0, 0)
|
||||
```
|
||||
|
||||
Notre timer est bien pris en compte et le clignotement se fait maintenant toutes
|
||||
les dix secondes.
|
||||
|
||||
Ce code est bien rudimentaire : il n'y a aucun contrôle et un rien -- comme
|
||||
juste envoyer `time toto` avec notre `printf` -- le fait planter. Pas de panique
|
||||
: le Macropad redémarrera alors tout seul.
|
||||
|
||||
Autre problème, il faut attendre que notre instruction `time.sleep(timer)` soit
|
||||
finie avant que la modification de notre `timer` soit prise en compte. Il est
|
||||
possible d'utiliser la librairie `asyncio` pour contourner ce problème, mais
|
||||
nous ne traiterons pas de ce cas dans cet article.
|
||||
|
||||
## Envoyer des données depuis le Macroad
|
||||
|
||||
Maintenant que nous avons réussi à envoyer des données depuis notre ordinateur
|
||||
vers le Macropad, nous allons en envoyer en sens inverse. Nous allons modifier
|
||||
le fichier `code.py`, plus précisément la fonction `exec_command` comme
|
||||
ci-dessous:
|
||||
|
||||
```python
|
||||
# [...]
|
||||
def exec_command (data):
|
||||
global timer
|
||||
try:
|
||||
command,option = data.split()
|
||||
except:
|
||||
command = ""
|
||||
option = ""
|
||||
print("cmd: {} | opt: {}".format(command, option))
|
||||
if command == 'time':
|
||||
timer = float(option)
|
||||
print("new timer: {}".format(timer))
|
||||
response = "nouveau timer : {}\r\n".format(option)
|
||||
buffer = bytearray(response)
|
||||
serial.write(buffer)
|
||||
# [...]
|
||||
```
|
||||
|
||||
La modification est relativement simple et tient en 3 instructions. Pour tester
|
||||
son fonctionnement, nous allons ouvrir deux terminaux avec `minicom` :
|
||||
|
||||
1. sur notre périphérique `/dev/ttyACM0` afin d'avoir un accès à la console du
|
||||
Macropad;
|
||||
2. sur `/dev/ttyACM1` afin d'interagir avec notre programme dans le Macropad;
|
||||
|
||||
Sur cette dernière fenêtre de terminal, nous allons lancer *minicom* avec la
|
||||
commande `minicom -D /dev/ttyACM1 -c on` puis une fois lancé nous allons
|
||||
activer l'affichage des commandes que l'on saisit avec `Ctrl + X` puis `E`. Cette
|
||||
étape est facultative mais *il est plus agréable de voir ce que nous saisissons*.
|
||||
|
||||
À partir de là nous pouvons changer la fréquence de clignotement avec la
|
||||
commande `time` saisie directement dans *minicom*, notre Macropad nous répond
|
||||
alors directement en envoyant la confirmation via la connexion série:
|
||||
|
||||
```
|
||||
Welcome to minicom 2.8
|
||||
|
||||
OPTIONS: I18n
|
||||
Compiled on Jan 9 2021, 12:42:45
|
||||
Port /dev/ttyACM1, 17:16:49
|
||||
|
||||
Press CTRL-A Z for help on special keys
|
||||
|
||||
|
||||
time 1
|
||||
nouveau timer : 1
|
||||
time 2
|
||||
nouveau timer : 2
|
||||
time 4
|
||||
nouveau timer : 4
|
||||
time 1
|
||||
nouveau timer : 1
|
||||
```
|
||||
|
||||

|
||||
|
||||
Vous devriez obtenir un fonctionnement similaire à ce que montre la capture
|
||||
d'écran ci-dessus.
|
||||
|
||||
Nous avons maintenant obtenu une **communication série bidirectionnelle** entre
|
||||
notre Macropad et notre ordinateur. Mais cet exemple est plutôt succinct, que
|
||||
pouvons nous en faire **concrètement**?
|
||||
|
||||
## Un (début) d'exemple "réel"
|
||||
|
||||
Nous allons utiliser ce que nous avons vu jusqu'ici pour mettre en place un
|
||||
bouton du clavier pour mettre en sourdine le microphone de notre ordinateur.
|
||||
|
||||
Nous allons programmer le bouton N°1 du Macropad pur envoyer une instruction
|
||||
*mute*. Sa DEL sera rouge si le microphone est coupé et verte s'il est actif. Un
|
||||
script *Python* sur notre ordinateur se chargera de recevoir les ordres les
|
||||
exécutera et enverra l'état du microphone en retour.
|
||||
|
||||
### Sur le Macripad
|
||||
|
||||
Voici le code à mettre dans `code.py`:
|
||||
|
||||
```python
|
||||
from adafruit_macropad import MacroPad
|
||||
import usb_cdc
|
||||
import time
|
||||
|
||||
macropad = MacroPad()
|
||||
serial = usb_cdc.data
|
||||
|
||||
def exec_command (data):
|
||||
global muted
|
||||
try:
|
||||
command,option = data.split()
|
||||
except:
|
||||
command = ""
|
||||
option = ""
|
||||
print("cmd: {} | opt: {}".format(command, option))
|
||||
if command == 'mute':
|
||||
muted = True if option == 'yes' else False
|
||||
|
||||
timer=2
|
||||
in_data=bytearray()
|
||||
muted=False
|
||||
|
||||
while True:
|
||||
# Define muted button color
|
||||
if muted:
|
||||
macropad.pixels[1] = (255,0,0)
|
||||
else:
|
||||
macropad.pixels[1] = (0,255,0)
|
||||
|
||||
# Get key event
|
||||
key_event = macropad.keys.events.get()
|
||||
if key_event:
|
||||
if key_event.pressed:
|
||||
if key_event.key_number == 1:
|
||||
serial.write(bytearray('mute\r\n'))
|
||||
|
||||
# Receive serial data
|
||||
if serial.in_waiting > 0:
|
||||
while(serial.in_waiting > 0):
|
||||
byte = serial.read(1)
|
||||
if byte == b'\r':
|
||||
exec_command(in_data.decode("utf-8"))
|
||||
in_data = bytearray()
|
||||
else:
|
||||
in_data += byte
|
||||
```
|
||||
|
||||
Comme vous pouvez le constater nous utilisons largement le code présent dans les
|
||||
deux premières parties.
|
||||
|
||||
### Le script Python sur notre ordinateur
|
||||
|
||||
Il utilise `pactl` pour piloter le micro et obtenir son état. Voici le code à
|
||||
mettre dans le fichier `serial_daemon.py`:
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python
|
||||
import serial
|
||||
import subprocess
|
||||
|
||||
ser = serial.Serial(port='/dev/ttyACM1')
|
||||
|
||||
ser.flushInput()
|
||||
print('Begin loop')
|
||||
while True:
|
||||
line = ser.readline()
|
||||
try:
|
||||
command = (line.decode()).split()
|
||||
print('command received: {}'.format(command[0]))
|
||||
except:
|
||||
print('no valid command received')
|
||||
command = ""
|
||||
|
||||
try:
|
||||
if command[0] == "mute":
|
||||
# First subprocess for toggle mote the microphone
|
||||
subprocess.run(
|
||||
['pactl', 'set-source-mute', '@DEFAULT_SOURCE@', 'toggle'],
|
||||
)
|
||||
|
||||
# Second one for check the states of microphone
|
||||
result = subprocess.run(
|
||||
['pactl', 'get-source-mute', '@DEFAULT_SOURCE@'],
|
||||
capture_output=True
|
||||
)
|
||||
message = "mute {}\r".format(result.stdout.split()[1].decode())
|
||||
ser.write(message.encode())
|
||||
print('command sent: {}'.format(message))
|
||||
except Error as e:
|
||||
print('Error in command: {}'.format(e))
|
||||
```
|
||||
|
||||
Le script commence par initialiser le périphérique série, puis vide l'ensemble
|
||||
des données présente dans le buffer du port série avec `ser.flushInput()` afin
|
||||
de repartie de zéro. Commence ensuite une bouble infinie (notre script reste
|
||||
résident en mémoire).
|
||||
|
||||
`line = ser.readline()` permet de mettre notre processus en attente passive tant
|
||||
qu'une fin de ligne de type `\n\r` n'a pas été reçue. A partir de là le script
|
||||
traite la linge reçue.
|
||||
|
||||
Le script lance la commande pour changer l'état du microphone puis la commande
|
||||
pour en vérifier l'état. L'instruction `ser.write()` transmet l'état de ce
|
||||
dernier au Macropad qui **agira en conséquence**.
|
||||
|
||||
Ici encore le script reste minimal, il suffit maintenant de le lancer et
|
||||
d'observer les différents messages ainsi que l'état di microphone :
|
||||
|
||||
```shell
|
||||
chmod +x serial_daemon.py
|
||||
./serial_daemon.py
|
||||
```
|
||||
|
||||
En appuyant sur le bouton adéquat du clavier, notre script `serial_daemon`
|
||||
devrait réagir comme ci-dessous dans la console:
|
||||
|
||||
```
|
||||
Begin loop
|
||||
command received: mute
|
||||
command sent: mute yes
|
||||
command received: mute
|
||||
command sent: mute no
|
||||
command received: mute
|
||||
command sent: mute yes
|
||||
```
|
||||
|
||||
Et la lumière sous la touche devrait changer de couleur en fonction de
|
||||
l'activation de la sourdine.
|
||||
|
||||
## En conclusion
|
||||
|
||||
Nous avons donc vu comment utiliser les ports série -- que se soir pour la
|
||||
connexion REPL ou pour les données -- sur notre *Macropad Adafruit*.
|
||||
Personnellement j'adore ce petit périphérique qui permet une infinité de
|
||||
possibilité et se programme relativement facilement grâce à *CircuitPython*.
|
||||
|
||||
Bien sût cet article n'a pas pour vocation d'aller en profondeur, que se soit
|
||||
dans les paramétrages des connexions séries que dans les possibilités offertes.
|
||||
Mais su le sujet vous intéresse une petite recherche sur les Internets vous
|
||||
donnera de quoi faire. Je ne peux cependant que vous conseiller l'excellent article
|
||||
de [Carlos Olmos] qui a utilisé le Macropad pour se créer un jukebox. Je m'en
|
||||
suis inspiré pour l'écriture de cet article.
|
||||
|
||||
[Carlos Olmos]:https://carlosolmos.dev/posts/the-macropad-jukebox/
|
Loading…
Add table
Add a link
Reference in a new issue