Le UNIHIKER M10 est une carte compacte intégrant un système basé sur Linux, des capteurs et des interfaces matérielles sur une seule carte. Elle contient un processeur quad-core Arm Cortex-A35 avec 512 Mo de RAM et 16 Go de stockage eMMC.
La carte est également équipée d’un écran tactile de 2,8 pouces avec une résolution de 240 × 320 pixels, ainsi que de connectivités Wi-Fi et Bluetooth. Les capteurs intégrés comprennent un capteur de lumière, un accéléromètre, un gyroscope et un microphone.
Comme la carte fonctionne sous Linux et supporte la programmation en Python, elle peut être utilisée pour de nombreuses applications. Dans ce tutoriel, vous apprendrez à implémenter un assistant vocal sur la carte UNIHIKER M10. Le clip vidéo court suivant montre l’assistant vocal :
Vous devrez peut-être augmenter le volume de votre ordinateur pour entendre ma voix. Notez également que cet assistant ne produit pas de sortie vocale, bien qu’il serait facile d’en ajouter une.
Pièces requises
Vous aurez besoin d’une carte UNIHIKER M10. Vous pouvez l’obtenir chez DFRobot ou sur Amazon, par exemple :

UNIHIKER M10
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Matériel du Unihiker M10
Le UNIHIKER M10 est construit autour d’une puce Rockchip RK3308. Cette puce utilise quatre cœurs Arm Cortex-A35 et fonctionne à une fréquence allant jusqu’à 1,2 GHz. Le processeur exécute un système d’exploitation Debian Linux complet avec Python 3.7 préinstallé. De nombreuses bibliothèques Python scientifiques sont également préinstallées, telles que Numpy, Matplotlib, Jupyter, Pandas, Seaborn, Tensorflow, entre autres.
La carte comprend 512 Mo de mémoire système DDR3. Cette mémoire est utilisée par le système Linux et les applications utilisateur. Le stockage des programmes est assuré par 16 Go de mémoire flash eMMC embarquée.
En plus du processeur principal, la carte intègre un microcontrôleur GD32VF103C8T6 en tant que coprocesseur. Il dispose de 64 Ko de mémoire flash et de 32 Ko de SRAM. Le microcontrôleur gère de nombreuses tâches matérielles telles que la gestion des capteurs, le contrôle des GPIO et le pilotage des actionneurs.
Affichage et interface utilisateur
Le UNIHIKER M10 est équipé d’un écran tactile couleur de 2,8 pouces. L’écran a une résolution de 240 × 320 pixels. La carte comprend un bouton Home et deux boutons utilisateur programmables nommés A et B, comme illustré ci-dessous :

Capteurs intégrés
Les capteurs intégrés comprennent un capteur de lumière, un accéléromètre, un gyroscope et un microphone. L’extension matérielle est possible via des ports USB, des connecteurs de capteurs Gravity, et un connecteur edge compatible micro:bit qui expose des interfaces GPIO, I2C, SPI et UART.

De plus, un buzzer passif et une LED de statut fournissent une sortie audio et visuelle simple pour les notifications et le débogage. Un haut-parleur externe peut être connecté via le port USB.
Connectivité et réseau
La communication sans fil est assurée par un module combiné Wi-Fi et Bluetooth. La carte supporte le Wi-Fi 2,4 GHz et la connectivité Bluetooth 4.0. Le Wi-Fi peut être configuré via une interface Web accessible à l’adresse 10.1.2.3.
Interfaces et options d’extension
La carte offre plusieurs interfaces physiques pour connecter du matériel externe. Un connecteur USB Type-C est utilisé pour l’alimentation et la communication avec un ordinateur. La carte peut être alimentée en 5 V via ce port.
Un port hôte USB Type-A permet de connecter des périphériques USB tels que des dispositifs de stockage, des claviers ou des adaptateurs. La carte comprend également un slot pour carte microSD pour étendre la capacité de stockage ou transférer des fichiers.
De plus, plusieurs connecteurs d’extension sont disponibles pour les capteurs et actionneurs. Les connecteurs 3 broches compatibles Gravity donnent accès aux entrées PWM et analogiques. Des connecteurs 4 broches dédiés fournissent la communication I2C pour les capteurs et modules numériques.

Connecteur Edge
La carte dispose également d’un connecteur edge compatible micro:bit. Ce connecteur expose jusqu’à 19 broches GPIO et supporte des interfaces telles que I2C, UART et SPI. Il fournit aussi plusieurs entrées ADC et sorties PWM pour contrôler du matériel externe. L’image ci-dessous montre le brochage du connecteur edge :

Schémas
Pour plus d’informations techniques détaillées, consultez les schémas du UNIHIKER M10 disponibles ci-dessous :
Spécifications techniques
Le tableau suivant résume les spécifications techniques de la carte UNIHIKER M10 :
| Caractéristique | Spécification |
|---|---|
| Processeur principal | Rockchip RK3308 |
| Architecture CPU | Quad-core Arm Cortex-A35 |
| Fréquence CPU | Jusqu’à 1,2 GHz |
| Mémoire système | 512 Mo DDR3 |
| Stockage interne | 16 Go eMMC |
| Coprocesseur | Microcontrôleur RISC-V GD32VF103C8T6 |
| Fréquence MCU | Jusqu’à 108 MHz |
| Mémoire MCU | 64 Ko Flash, 32 Ko SRAM |
| Système d’exploitation | Debian Linux |
| Écran | Écran tactile 2,8 pouces |
| Résolution d’écran | 240 × 320 pixels |
| Connectivité sans fil | Wi-Fi 802.11 b/g/n (2,4 GHz), Bluetooth 4.0 |
| Capteurs | Capteur de lumière, IMU 6 axes (accéléromètre + gyroscope), microphone |
| Entrées utilisateur | Bouton Home, boutons utilisateur A/B, écran tactile |
| Sortie audio | Buzzer passif |
| Ports USB | 1 × USB-C (alimentation et données), 1 × USB-A hôte |
| Extension de stockage | Slot pour carte microSD |
| Interfaces d’extension | Connecteurs 3 broches Gravity (analogique/PWM), connecteurs I2C |
| Connecteur Edge | Connecteur edge compatible micro:bit |
| Interfaces supportées | GPIO, ADC, PWM, I2C, SPI, UART |
| Tension d’alimentation | Entrée 5 V via USB-C |
| Niveau logique | 3,3 V |
| Courant typique | Jusqu’à ~2 A |
| Dimensions de la carte | Environ 51,6 mm × 83 mm × 13 mm |
Programmation du UNIHIKER M10
Plusieurs applications sont disponibles pour programmer le UNIHIKER M10, telles que Jupyter Notebook, Mind+, VSCode, Python IDLE ou Thonny. Pour des instructions détaillées sur la configuration de ces applications, consultez la section Getting Started de la documentation UNIHIKER.
Installation de Thonny
Personnellement, j’ai trouvé Thonny le plus simple à utiliser pour un petit projet comme celui de ce tutoriel. Pour les instructions d’installation, consultez la section Download and Install Thonny de la documentation UNIHIKER.
Connexion de Thonny au UNIHIKER M10
Après l’installation de Thonny, connectez votre UNIHIKER M10 à votre ordinateur avec le câble USB. Ensuite, ouvrez Thonny et cliquez sur « Run -> Select interpreter … »:

Cela ouvrira une boîte de dialogue où vous choisirez « Remote Python 3 (SSH) » comme interpréteur. Dans Host, entrez « 10.1.2.3 », pour Username entrez « root » et pour Authentication method sélectionnez « password »:

Après avoir cliqué sur « Run -> Stop/Restart backend », Thonny sera connecté à votre UNIHIKER M10 et vous pourrez éditer et exécuter des programmes Python dessus.

Installation de Putty et de la bibliothèque OpenAI
Ensuite, nous aurons besoin d’un outil qui nous permette d’installer des bibliothèques Python, comme la bibliothèque OpenAI sur le UNIHIKER M10. J’ai essayé d’installer des bibliothèques via Thonny (« Manage Packages », « Open System Shell… ») mais cela n’a pas fonctionné.
À la place, j’ai utilisé Putty. Pour les instructions d’installation, consultez la section SSH Tools de la documentation UNIHIKER. Une fois installé, ouvrez Putty et créez une session avec 10.1.2.3 comme HOST :

Puis cliquez sur le bouton « Open » et dans le shell Putty entrez « root » comme nom d’utilisateur et « dfrobot » comme mot de passe :

Vous pouvez maintenant installer la bibliothèque OpenAI via la commande « pip install openai » :

Si d’autres bibliothèques Python manquent, vous pouvez les installer de la même manière. Notez cependant que le UNIHIKER M10 doit être connecté via le câble USB.
Configuration du Wi-Fi
Enfin, il faut aussi configurer la connexion Wi-Fi pour que notre assistant vocal ait accès à Internet et puisse appeler les outils AI d’OpenAI.
Pour cela, ouvrez un navigateur web et entrez « 10.1.2.3 » dans la barre d’adresse. Vous verrez une page web avec un élément « Network Settings » dans la barre latérale. Cliquez dessus et saisissez vos identifiants Wi-Fi dans la boîte de dialogue à droite :

Obtention de la clé API OpenAI
Notre assistant vocal va utiliser les modèles AI fournis par OpenAI. Vous aurez donc besoin d’un compte OpenAI. Rendez-vous sur https://platform.openai.com et inscrivez-vous avec une adresse email ou un compte Google ou Microsoft existant.
Après avoir vérifié votre email et complété la configuration initiale, connectez-vous au tableau de bord OpenAI, platform.openai.com/api-keys et trouvez ou créez votre clé API (=CLÉ SECRÈTE) comme montré ci-dessous :

La clé API est une chaîne unique et longue, commençant par « sk-proj-« , nécessaire pour authentifier vos requêtes API (voir ci-dessous). Vous devrez copier cette chaîne entière dans le code de l’assistant vocal.
sk-proj-xcA.......................OtDu0U
C’est tout ce dont vous avez vraiment besoin, mais je vous recommande aussi de définir une limite d’utilisation pour votre compte. Cela évite de recevoir une facture élevée à cause d’un bug dans votre code (par exemple, l’envoi de centaines de requêtes).
Vous pouvez définir des limites d’utilisation et consulter les tarifs (coûts) des différents modèles AI dans l’onglet Billing (platform.openai.com/settings/organization/billing).
Nous sommes maintenant prêts à écrire le code de l’assistant vocal.
Code pour l’assistant vocal
Dans Thonny, créez un nouveau fichier, j’ai nommé le mien « assistant_tk.py » et copiez-collez le code ci-dessous.

Ce code implémente un assistant vocal. Il enregistre l’audio lorsque le bouton A est maintenu, transcrit la parole en texte avec le modèle Whisper d’OpenAI, envoie le texte à un modèle de langage GPT pour obtenir une réponse, et affiche la question et la réponse sur l’interface graphique de l’appareil.
# www.makerguides.com
# Python 3.7
# openai 1.39.0
# PyAudio 0.2.11
# pinpong 0.6.1
# numpy 1.21.6
import time
import threading
import numpy as np
import pyaudio
import io
import wave
from openai import OpenAI
from pinpong.extension.unihiker import button_a
import tkinter as tk
from tkinter import ttk
from typing import List
API_KEY = "sk-proj-my-api-key"
DEVICE_INDEX = 2
SAMPLE_RATE = 16000
CHANNELS = 1
CHUNK = 1024
client = OpenAI(api_key=API_KEY)
# GUI -----------------------------------------------------
root = tk.Tk()
root.title("Voice Chatbot")
root.geometry("240x320")
status_var = tk.StringVar()
status_var.set("Hold Button A to speak")
status_label = ttk.Label(root, textvariable=status_var,
font=("Arial", 11), anchor="center")
status_label.pack(fill="x", padx=6, pady=4)
frame = tk.Frame(root)
frame.pack(fill="both", expand=True)
scrollbar = tk.Scrollbar(frame, width=18)
scrollbar.pack(side="right", fill="y")
text_box = tk.Text(frame, wrap="word",
yscrollcommand=scrollbar.set, font=("Arial", 10))
text_box.bind("<Motion>", lambda e: "break")
text_box.bind("<B1-Motion>", lambda e: "break")
text_box.bind("<Button-1>", lambda e: "break")
text_box.pack(side="left", fill="both", expand=True)
scrollbar.config(command=text_box.yview)
def set_status(text):
status_var.set(text)
root.update_idletasks()
def show_answer(text):
text_box.delete("1.0", tk.END)
text_box.insert(tk.END, text)
text_box.see(tk.END)
# Audio helpers -----------------------------------------------
def normalize(pcm_bytes: bytes) -> bytes:
samples = np.frombuffer(pcm_bytes, dtype=np.int16).astype(np.float32)
peak = np.max(np.abs(samples))
if peak == 0:
return pcm_bytes
gain = (0.9 * 32767) / peak
normalized = np.clip(samples * gain, -32768, 32767).astype(np.int16)
return normalized.tobytes()
def record_while_held() -> bytes:
frames: List[bytes] = []
pa = pyaudio.PyAudio()
stream = pa.open(
format=pyaudio.paInt16,
channels=CHANNELS,
rate=SAMPLE_RATE,
input=True,
input_device_index=DEVICE_INDEX,
frames_per_buffer=CHUNK
)
set_status("Hold Button A to speak")
while not button_a.is_pressed():
time.sleep(0.01)
set_status("recording...")
while button_a.is_pressed():
data = stream.read(CHUNK, exception_on_overflow=False)
frames.append(data)
stream.stop_stream()
stream.close()
pa.terminate()
return b"".join(frames)
def pcm_to_wav(pcm_bytes: bytes) -> bytes:
buf = io.BytesIO()
with wave.open(buf, "wb") as wf:
wf.setnchannels(CHANNELS)
wf.setsampwidth(2)
wf.setframerate(SAMPLE_RATE)
wf.writeframes(pcm_bytes)
return buf.getvalue()
# OpenAI -----------------------------------------------
def transcribe(wav_bytes: bytes) -> str:
audio_file = io.BytesIO(wav_bytes)
audio_file.name = "recording.wav"
set_status("transcribing...")
response = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
language="en",
temperature=0
)
return response.text
def ask_gpt(question: str) -> str:
set_status("thinking...")
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": "You are a helpful assistant. Answer clearly and concisely."
},
{"role": "user", "content": question}
],
)
return response.choices[0].message.content
# Main assistant loop -----------------------------------------------
def assistant_loop():
while True:
raw_pcm = record_while_held()
if not raw_pcm:
continue
normalized_pcm = normalize(raw_pcm)
wav_bytes = pcm_to_wav(normalized_pcm)
question = transcribe(wav_bytes)
answer = ask_gpt(question)
set_status("ready")
show_answer(question + "\n\n" + answer)
threading.Thread(target=assistant_loop, daemon=True).start()
root.mainloop()
Imports
Le code commence par importer plusieurs modules nécessaires à son fonctionnement. Cela inclut des bibliothèques standard comme time, threading, et io pour la gestion du temps, l’exécution concurrente et la manipulation de flux d’octets. Il importe aussi numpy pour les opérations numériques sur les données audio, pyaudio pour l’enregistrement audio, et wave pour la gestion du format audio WAV.
Le client Python OpenAI est importé pour interagir avec l’API OpenAI. Le module spécifique UNIHIKER button_a est importé pour détecter les pressions sur les boutons. Enfin, tkinter et ttk sont importés pour créer l’interface graphique, et List de typing est utilisé pour les annotations de type.
import time import threading import numpy as np import pyaudio import io import wave from openai import OpenAI from pinpong.extension.unihiker import button_a import tkinter as tk from tkinter import ttk from typing import List
Constantes et initialisation du client
Plusieurs constantes sont définies pour configurer les paramètres d’enregistrement audio, comme la clé API OpenAI, l’index du périphérique audio d’entrée, la fréquence d’échantillonnage, le nombre de canaux et la taille des blocs audio. Un objet client OpenAI est ensuite créé avec la clé API fournie, permettant la communication avec les services OpenAI.
API_KEY = "sk-proj-my-api-key" DEVICE_INDEX = 2 SAMPLE_RATE = 16000 CHANNELS = 1 CHUNK = 1024 client = OpenAI(api_key=API_KEY)
Notez que vous devez remplacer la valeur fictive « sk-proj-my-api-key » de API_KEY par votre propre clé API OpenAI !
Interface graphique (GUI)
L’interface graphique est construite avec tkinter. Une fenêtre principale est créée avec un titre et une taille fixe. Un label de statut est ajouté pour informer l’utilisateur de l’état actuel, comme l’invite à maintenir le bouton A pour parler ou l’affichage de messages de progression.

Sous le label de statut, une zone de texte avec une barre de défilement est prévue pour afficher la question transcrite et la réponse de l’assistant. La zone de texte est en lecture seule, empêchant toute modification par interaction souris.
root = tk.Tk()
root.title("Voice Chatbot")
root.geometry("240x320")
status_var = tk.StringVar()
status_var.set("Hold Button A to speak")
status_label = ttk.Label(root, textvariable=status_var,
font=("Arial", 11), anchor="center")
status_label.pack(fill="x", padx=6, pady=4)
frame = tk.Frame(root)
frame.pack(fill="both", expand=True)
scrollbar = tk.Scrollbar(frame, width=18)
scrollbar.pack(side="right", fill="y")
text_box = tk.Text(frame, wrap="word",
yscrollcommand=scrollbar.set, font=("Arial", 10))
text_box.bind("<Motion>", lambda e: "break")
text_box.bind("<B1-Motion>", lambda e: "break")
text_box.bind("<Button-1>", lambda e: "break")
text_box.pack(side="left", fill="both", expand=True)
scrollbar.config(command=text_box.yview)
Fonctions de statut et d’affichage
Deux fonctions auxiliaires gèrent les mises à jour de l’interface. La fonction set_status() met à jour le texte du label de statut et force le rafraîchissement immédiat de l’interface. La fonction show_answer() efface la zone de texte, insère un nouveau texte, puis fait défiler jusqu’à la fin pour afficher le contenu le plus récent.
def set_status(text):
status_var.set(text)
root.update_idletasks()
def show_answer(text):
text_box.delete("1.0", tk.END)
text_box.insert(tk.END, text)
text_box.see(tk.END)
Fonctions audio auxiliaires
Le code inclut plusieurs fonctions pour le traitement audio. La fonction normalize() convertit les octets audio PCM bruts en échantillons flottants, puis les met à l’échelle pour que l’amplitude maximale atteigne 90 % de la plage maximale d’un entier 16 bits. Cette normalisation assure un volume audio cohérent pour la transcription.
def normalize(pcm_bytes: bytes) -> bytes:
samples = np.frombuffer(pcm_bytes, dtype=np.int16).astype(np.float32)
peak = np.max(np.abs(samples))
if peak == 0:
return pcm_bytes
gain = (0.9 * 32767) / peak
normalized = np.clip(samples * gain, -32768, 32767).astype(np.int16)
return normalized.tobytes()
La fonction record_while_held() enregistre l’audio depuis le périphérique d’entrée spécifié tant que le bouton A est maintenu.
Elle initialise un flux PyAudio avec les paramètres configurés et attend que le bouton A soit pressé. Ensuite, elle lit continuellement des blocs audio qu’elle ajoute à une liste jusqu’à ce que le bouton soit relâché. Les trames audio enregistrées sont concaténées et retournées sous forme d’octets bruts PCM.
def record_while_held() -> bytes:
frames: List[bytes] = []
pa = pyaudio.PyAudio()
stream = pa.open(
format=pyaudio.paInt16,
channels=CHANNELS,
rate=SAMPLE_RATE,
input=True,
input_device_index=DEVICE_INDEX,
frames_per_buffer=CHUNK
)
set_status("Hold Button A to speak")
while not button_a.is_pressed():
time.sleep(0.01)
set_status("recording...")
while button_a.is_pressed():
data = stream.read(CHUNK, exception_on_overflow=False)
frames.append(data)
stream.stop_stream()
stream.close()
pa.terminate()
return b"".join(frames)
La fonction pcm_to_wav() convertit les octets PCM bruts en un flux de bytes au format WAV à l’aide du module wave. Ceci est nécessaire car l’API de transcription OpenAI attend des fichiers audio dans des formats standards comme WAV.
def pcm_to_wav(pcm_bytes: bytes) -> bytes:
buf = io.BytesIO()
with wave.open(buf, "wb") as wf:
wf.setnchannels(CHANNELS)
wf.setsampwidth(2)
wf.setframerate(SAMPLE_RATE)
wf.writeframes(pcm_bytes)
return buf.getvalue()
Interaction avec l’API OpenAI
Deux fonctions gèrent la communication avec l’API OpenAI. La fonction transcribe() envoie les octets audio WAV au modèle Whisper pour obtenir une transcription textuelle. Elle met à jour le label de statut pour indiquer que la transcription est en cours et retourne le texte reconnu.
def transcribe(wav_bytes: bytes) -> str:
audio_file = io.BytesIO(wav_bytes)
audio_file.name = "recording.wav"
set_status("transcribing...")
response = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
language="en",
temperature=0
)
return response.text
La fonction ask_gpt() envoie la question transcrite à un modèle de complétion de chat basé sur GPT. Elle affiche « thinking… » pendant l’attente de la réponse. Ensuite, un message système est construit pour indiquer au modèle d’être un assistant utile. Enfin, la fonction retourne le texte de la réponse de l’assistant.
def ask_gpt(question: str) -> str:
set_status("thinking...")
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": "You are a helpful assistant. Answer clearly and concisely."
},
{"role": "user", "content": question}
],
)
return response.choices[0].message.content
Boucle principale de l’assistant
La fonctionnalité principale s’exécute dans la fonction assistant_loop(), qui tourne dans un thread séparé pour garder l’interface graphique réactive.
Elle attend continuellement que l’utilisateur maintienne le bouton A et enregistre l’audio pendant que le bouton est pressé. Si aucun audio n’est capturé, elle redémarre la boucle. Sinon, elle normalise l’audio, le convertit en format WAV, transcrit la parole, puis interroge le modèle GPT pour obtenir une réponse.
Après traitement, elle met à jour le statut à « ready » et affiche la question et la réponse dans la zone de texte.
def assistant_loop():
while True:
raw_pcm = record_while_held()
if not raw_pcm:
continue
normalized_pcm = normalize(raw_pcm)
wav_bytes = pcm_to_wav(normalized_pcm)
question = transcribe(wav_bytes)
answer = ask_gpt(question)
set_status("ready")
show_answer(question + "\n\n" + answer)
Démarrage de l’assistant et boucle principale GUI
Enfin, la boucle de l’assistant est lancée dans un thread daemon, lui permettant de tourner en arrière-plan. La boucle principale d’événements de l’interface graphique est ensuite démarrée avec root.mainloop(), ce qui maintient la fenêtre ouverte et réactive aux interactions utilisateur.
threading.Thread(target=assistant_loop, daemon=True).start() root.mainloop()
Messages d’erreur
Si vous exécutez le code, vous pouvez voir les avertissements suivants dans la console Thonny :
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_a52.c:823:(_snd_pcm_a52_open) a52 is only for playback
ALSA lib conf.c:5014:(snd_config_expand) Unknown parameters {AES0 0x6 AES1 0x82 AES2 0x0 AES3 0x2 CARD 0}
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM iec958:{AES0 0x6 AES1 0x82 AES2 0x0 AES3 0x2 CARD 0}
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
Cela est dû au fait que lors de l’initialisation de pyaudio.PyAudio(), la bibliothèque ALSA (Advanced Linux Sound Architecture) sous-jacente scanne votre système pour tous les périphériques audio et configurations possibles (comme le son surround 5.1, HDMI ou S/PDIF numérique).
Comme le UNIHIKER M10 est un ordinateur monocarte compact, il n’a pas de « haut-parleurs arrière » ni de « ports modem », donc ALSA se plaint de ne pas les trouver. Si votre code fonctionne et gère l’audio malgré ces avertissements, votre configuration est correcte.
Conclusions
Dans ce tutoriel, vous avez appris à implémenter un assistant vocal sur le UNIHIKER M10 en utilisant les services OpenAI. Pour d’autres exemples de code plus simples, consultez la section Python Coding Examples de la documentation UNIHIKER.
Notez que vous pouvez facilement étendre et améliorer l’assistant vocal en ajoutant un historique de conversation et la possibilité d’appeler des outils. J’ai utilisé Tkinter pour créer une interface simple, mais pour une meilleure GUI, vous pouvez utiliser QtPy, qui est également préinstallé sur le UNIHIKER M10.
De plus, vous pouvez ajouter un haut-parleur, via USB, Bluetooth ou sortie ligne, pour que votre assistant vocal réponde avec de l’audio. Voir le tutoriel AI Language Tutor with UNIHIKER M10 pour un exemple.
Pour un chatbot visuel capable de voir et répondre à des questions sur des images, consultez notre tutoriel Vision Chatbot with DFRobot ESP32-S3 AI Camera and OpenAI. Et pour plus d’exemples d’IA, consultez la section AI Projects de la documentation UNIHIKER.
Si vous avez des questions, n’hésitez pas à les poser dans la section commentaires.
Bon bricolage 😉

