Commutateur USB compatible Alexa – Contrôle intelligent des périphériques USB
Composants et fournitures
| Composant | Quantité |
|---|---|
| Arduino MKR1000 | 1 |
| Condensateur 0,1 µF 0805 | 8 |
| LED (générique) | 4 |
| Bouton poussoir (long) | 4 |
| INA219 (SOIC-8) | 1 |
| LM3526M | 2 |
| Prise USB (verticale) | 4 |
| Résistance 1 kΩ 0805 | 4 |
| Résistance de détection de courant 0,1 Ω | 1 |
| Condensateur 1 µF 0805 | 1 |
Outils et machines nécessaires
- Imprimante 3D (générique)
- Fer à souder (générique)
Applications et services en ligne
- Amazon Alexa Skills Kit
- Tinamous
- Amazon Web Services AWS Lambda
À propos du projet
« Alexa, allume le ThingyStick… »
Contexte
De plus en plus d'appareils sont alimentés par USB, mais beaucoup restent des périphériques « muets » sans connectivité Internet ni options de domotique (par exemple, des lampes LED). Comment les automatiser ou les contrôler à distance ? Une alimentation USB branchée sur une prise connectée est une solution, mais c'est disproportionné si l'on veut contrôler quatre appareils individuellement.
Ce projet permet de contrôler l'alimentation de périphériques USB via Internet, et grâce à la compétence Tinamous SmartHome pour Alexa, d'activer le contrôle vocal pour vos appareils USB « muets ».
Actuellement, il existe très peu de dispositifs sur le marché pour contrôler l'alimentation USB à distance. Au démarrage du projet, il n'y en avait aucun (au Royaume-Uni), mais quelques-uns sont apparus récemment dans des multiprises (l'idée date d'il y a longtemps, dans une galaxie lointaine). Ces produits proviennent de fabricants non marqués (ex. ZLD-34UK), ce qui soulève des questions : quel cloud utilisent-ils ? Les données vont-elles en Chine ? Que se passe-t-il si le fabricant disparaît ? Quelle est la sécurité ? Le logiciel est-il utilisable ? Sans parler de la non-hackabilité comparée à un Arduino open source.
Cas d'utilisation
Exemples de périphériques USB à contrôler :
- Lampes USB
- Clés Kindle Fire / Chromecast (surtout dans les chambres d'enfants pour limiter la TV)
- Humidificateurs USB
- Echo Dot (éteindre Alexa pour la nuit ou redémarrer l'appareil)
- Cartes de développement (redémarrer un projet bloqué en boucle infinie)
- Appareils difficiles d'accès nécessitant un redémarrage occasionnel (capteurs dans le grenier)
- Appareils chez des clients où l'on veut vérifier l'alimentation (via mesure de courant et tension)
Contrôle simple : Commutation d'alimentation via Internet, par commande vocale Alexa ou autres commandes Tinamous. Marche/Arrêt.
Contrôle intelligent : De nombreuses lampes USB ont des commandes tactiles ; on ne peut les allumer à distance, mais on peut les éteindre. C'est souvent suffisant (endormissement, lumière oubliée, sortie). Avec le mode intelligent, la commande « off » coupe l'alimentation quelques secondes avant de la rétablir : la lampe s'éteint, mais fonctionne normalement ensuite.
Automatisation par minuterie : Extinction programmée à heures fixes. Les enfants regardent la Fire TV trop tard ? Coupure automatique à 20 h.
Surveillance de consommation : Pour développer du matériel USB, on veut connaître le courant absorbé, surtout au démarrage, ou profiler la charge de batteries. L'INA219 embarqué permet un échantillonnage ~1 kHz. La chute de tension sur les câbles USB à fort courant est aussi détectée. Un bornier permet des courants plus élevés et des câbles plus gros.
Détection de panne d'alimentation : Grâce à l'option batterie du MKR1000, on surveille la tension d'entrée et on envoie une alerte en cas de coupure. Utile pour des installations distantes ou simple détection de coupure secteur à la maison.
Matériel
Le cœur est un Arduino MKR1000. La commutation USB utilise deux LM3526M pour commutation côté haute et détection de défauts (sous-tension, surintensité), avec surveillance tension/courant via INA219, plus LEDs et boutons pour contrôle local.
Un PCB a été fabriqué chez DirtyPCBs.com (aussi possible via OSHPark.com). Les pads du socket Arduino permettent des extensions : capteurs environnementaux, petit écran OLED tension/courant.
Le dépôt GitHub propose versions 2 et 4 ports. Attention : sur la version 2 ports, le layout des prises USB est inversé (polarité inversée !).
Victoire née de l'échec : Monter les prises USB au dos du PCB s'est révélé une bonne solution (connexions correctes). L'Arduino avec headers en socket manquait de hauteur pour sortir les prises du boîtier ; cela a conduit à refaire le PCB avec composants au verso et deux ports supplémentaires → version 4 ports (LEDs mal alignées sur la version 2 corrigées).
Rien n'empêche d'étendre à 6 ou 8 ports, mais LEDs/boutons devraient être repensés.
Le schéma semble complexe mais beaucoup de résistances sont optionnelles. R23, 19, 27, 26 sont des pull-ups pour boutons ; R20-22, R14, R15 pour contrôle USB et détection défauts. Elles peuvent être remplacées par INPUT_PULLUP sur Arduino, mais si mise en veille basse consommation avec interruptions, mieux vaut les souder pour éviter flottements.

Résistances optionnelles sur lignes D+/D- des USB pour signaler la puissance disponible, mais souvent ignorées par les appareils « muets ». Seule R24 (limitation courant LED) est nécessaire ; R2-5 et R28 restent vides.

LEDs et boutons sont totalement optionnels. Pour une boîte autonome de contrôle à distance, ne les installez pas.
Alimentation
Trois options :
- Interne (JP6 broches 1-2) : alimentation 5 V via broche 5 V de l'Arduino (donc connecteur USB Arduino). Uniquement pour faibles charges.
- Externe via J2 (connecteur micro-USB embarqué) : JP6 broches 2-3.
- Externe via JP8 (bornier) : JP6 broches 2-3.
Ne pas utiliser J2 et JP8 simultanément. L'alimentation externe est aussi routée vers la broche VIn de l'Arduino.
Bonus : en ajoutant des résistances 0 Ω sur R10, R11 et J2, on obtient un passage USB 3 pour redémarrer un périphérique USB connecté — très pratique en développement pour ne pas user les ports du PC.

Boîtier
Un boîtier imprimable en 3D est inclus. Il utilise des inserts filetés M3 pour fixation PCB et couvercle (tolérances suffisantes pour ajustement par friction).
Options du couvercle :
- Avec ou sans compartiment batterie.
- Avec ou sans pieds (trous de fixation pour visser le boîtier).
La base est configurable (OpenSCAD) pour ouvertures selon les trois sources d'alimentation.



Connexion à Tinamous
L'Arduino MKR1000 assure la connectivité WiFi. Si nouveau sur cette carte, ajoutez l'option « board » dans l'IDE Arduino.
On utilise le serveur MQTT Tinamous (développé par l'auteur). On souscrit au topic « Status.To » pour recevoir les messages envoyés au périphérique.
Avant de coder : mettre à jour le firmware du MKR1000 et installer les certificats SSL pour connexion sécurisée à Tinamous. (Pour serveur MQTT local sans SSL, adapter le code.)
Étape 1 : Mise à jour firmware
Ouvrir l'IDE Arduino, charger l'exemple FirmwareUpdater (menu WiFi101). Téléverser sur la carte.
Étape 2 : Outil de mise à jour
Menu Outils > WiFi101 Firmware Updater.
Étape 3 : Certificats SSL
Tester la connexion, puis Update Firmware. Ajouter le domaine tinamous.com via bouton « Add domain », puis « Upload Certificates to WiFi module ».
Étape 4 : Firmware personnalisé
Les fichiers sont joints au projet et sur GitHub (version la plus récente).
Ajouter les bibliothèques WiFi101 et MQTT Client (par Joel Gaehwiler).
Le fichier secrets.h doit contenir vos paramètres WiFi et Tinamous MQTT :
#define SECRET_SSID "Votre SSID"
#define SECRET_PASS "Votre mot de passe WiFi"
/************************* Configuration MQTT Tinamous *********************************/
#define MQTT_SERVER "<nom_compte_tinamous>.tinamous.com"
#define MQTT_SERVERPORT 8883
#define MQTT_USERNAME "UsbSwitch.<nom_compte_tinamous>"
#define MQTT_PASSWORD "Votre mot de passe"
#define MQTT_CLIENT_ID "UsbSwitch"
#define DEVICE_USERNAME "UsbSwitch"
Si pas encore de compte Tinamous, créez-en un gratuit. Le nom de compte/organisation devient votre espace privé (ex. AlexaExample → https://AlexaExample.Tinamous.com).
Étape 5 : Ajouter le périphérique dans Tinamous
Page « Devices » → bouton « Add ». Les paramètres MQTT pour l'exemple AlexaExample :
/************************* Configuration MQTT Tinamous *********************************/
#define MQTT_SERVER "AlexaExample.tinamous.com"
#define MQTT_SERVERPORT 8883
#define MQTT_USERNAME "UsbSwitch.AlexaExample"
#define MQTT_PASSWORD "MonSuperMotDePasseQuiNEstPasPassw0rd..."
#define MQTT_CLIENT_ID "UsbSwitch"
#define DEVICE_USERNAME "UsbSwitch"
Pour ajouter d'autres périphériques, mettez à jour DEVICE_USERNAME et MQTT_USERNAME (MQTT n'envoie pas d'en-têtes HTTP, Tinamous a besoin du compte dans le nom d'utilisateur).
Étape 6 : Téléverser le code
Téléversez le code joint (avec votre secrets.h mis à jour). Examinez TinamousMQTTClient.ino : il gère les interactions MQTT et les commandes Alexa.
Utiliser WiFiSSLClient pour SSL. Pour serveur MQTT local sans SSL, WiFiClient port 1883 suffit, mais pour Internet, SSL obligatoire.
Réserver plus que le buffer MQTT par défaut : 4096 octets.
WiFiSSLClient networkClient;
MQTTClient mqttClient(4096);
Configurer le client et définir le gestionnaire de messages :
mqttClient.begin(MQTT_SERVER, MQTT_SERVERPORT, networkClient);
mqttClient.onMessage(messageReceived);
Connexion et souscription au topic :
if (!mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {
if (mqttClient.lastError() == LWMQTT_CONNECTION_DENIED) {
// Identifiants incorrects
}
if (mqttClient.lastError() == -6) {
// Certificat SSL manquant
}
delay(10000);
return false;
}
mqttClient.subscribe("/Tinamous/V1/Status.To/" DEVICE_USERNAME);
La timeline Tinamous fonctionne comme un Twitter privé pour vous et vos périphériques : ils envoient/reçoivent des messages via MQTT, API REST ou bots.
Pour tester sans Alexa, utilisez la timeline Tinamous pour envoyer des messages au périphérique.
La compétence Tinamous Smart Home pour Alexa
La compétence est en cours d'approbation (au moment de l'écriture). Une fois publiée, elle permettra de créer votre propre commutateur USB.
La compétence est générique : elle ne connaît pas les périphériques ni comment leur parler. On applique des étiquettes (tags) aux périphériques dans Tinamous, et la compétence crée les appareils appropriés dans Alexa. Ainsi, avec quelques lignes de code sur le périphérique, vous pouvez activer le contrôle vocal Alexa pour vos propres projets.
Le code (C# .NET Core 2.0, tests inclus) est dans le dépôt Tinamous SmartHome. Développé initialement pour le projet BOFF Smart Fan, étendu ici pour gérer plusieurs sorties (ports) comme citoyens de première classe dans Alexa Smart Home.
Développement avec Visual Studio 2017 + outils AWS pour déploiement Lambda.
Le framework désérialise les directives Alexa en objets exploitables, agit selon l'espace de noms et le nom de directive, et renvoie une réponse appropriée.
Messages principaux :
- Association de compte (Account Linking)
- Découverte (Discovery)
- Rapport d'état (State Report)
- Contrôle d'alimentation (Power Control)
Association de compte
Gérée par Alexa. Après ajout de la compétence, Alexa demande l'authentification → page d'autorisation Tinamous. Entrer : nom de compte (AlexaExample), nom d'utilisateur, mot de passe.
Découverte
Une fois le compte lié, Alexa lance la découverte. La compétence interroge Tinamous pour les périphériques étiquetés Alexa.SmartDevice. Les autres sont ignorés.
Étiquettes appliquées via l'édition du périphérique dans Tinamous (page Devices).
Si étiqueté MultiPort, chaque port est énuméré et ajouté comme appareil distinct. On ajoute aussi des étiquettes selon les directives supportées : Alexa.PowerController et catégorie d'affichage (ex. SmartPlug).

Autres interfaces possibles (ex. Alexa.BrightnessController) mais moins pertinentes ici. Voir README du dépôt.
Pour exposer les ports individuels à Alexa sur un périphérique MultiPort, configurer les variables d'état (State Variables) sur la page d'édition du périphérique.

PortCount = nombre de ports. Port-1..Port-n = noms utilisés par Alexa. Port sans nom = ignoré. Modifiable à tout moment, relancer la découverte pour mise à jour Alexa.
Pendant la découverte, la compétence cherche un champ étiqueté/nommé powerState ou powerState-port-n. S'il existe, il est assigné comme capacité supportée (voir State Report).

Rapport d'état
Durant la découverte, on a déclaré les capacités du périphérique → Alexa enverra des requêtes StateReport pour obtenir les valeurs.
Derniers tags à appliquer sur les champs du périphérique. Une fois le périphérique envoi des données (message SenML via MQTT dans le code Arduino), Tinamous crée les champs. Utiliser l'option « Advanced » dans la liste des champs pour les éditer. Les tags sont plus polyvalents : pas besoin de nom exact dans le firmware, renommage libre.


Si champs spécifiques au port non trouvés, fallback sur champ non-spécifique (powerState).
Contrôle d'alimentation
Alexa enverra deux directives : TurnOn et TurnOff. Le point d'entrée principal de la compétence cherche l'espace de noms Alexa.PowerController, puis délègue à PowerController.cs.
La compétence publie simplement un message de statut sur la timeline Tinamous :
@UsbSwitch Turn On
@UsbSwitch Turn On port-1
Autres interfaces gérées de façon identique. Le périphérique surveille ce message et agit. Alexa relit l'état via StateReport.
Création de la fonction AWS Lambda
Outils AWS dans Visual Studio pour publier la compétence compilée sur Lambda. D'abord créer la Lambda.
Astuce : Créer la Lambda dans la région AWS appropriée à la langue. Anglais (UK) → eu-west-1 (Irlande).
Nouvelle fonction Lambda « from scratch ». Les blueprints existants sont limités/obsolètes (supportent seulement V2 SmartHome, déprécié — nous utilisons V3).
Créer un rôle pour accès aux ressources. Sélectionner « Simple Microservices » (donne plus que nécessaire). Si pas de logs dans CloudWatch, ajouter permissions IAM pour logs.

Publier les binaires depuis Visual Studio : clic droit sur le projet → « Publish to AWS Lambda... »

Remplir les détails et « Upload ».


Tester la Lambda, puis « Publish new version » dans le menu Actions.

Donner permission à la compétence d'accéder à cette Lambda : cliquer sur déclencheur « Alexa Smart Home », entrer le Skill ID (pas encore connu à ce stade).

Création de la compétence sur la console Alexa
Avec la Lambda prête, aller sur https://developer.amazon.com → Alexa Skills Kit → nouvelle compétence.
Sélectionner « Smart Home Skill API », langue (ex. English UK), version de payload V3 (recommandée).

Page Configuration : entrer l'ARN de la Lambda versionnée (coin supérieur droit). Doit se terminer par :1, :2, :5246...

Dans Lambda, coller le « Skill ID » (ex. amzn1.ask.skill.2_______________50). Sauvegarder.
Pour l'association de compte, créer une application OAuth sur Tinamous via le bot Alexa. Page Bots Tinamous → ajouter bot Alexa → la boîte de dialogue donne tous les détails pour configurer l'association.
Note : si vous utilisez la compétence Tinamous SmartHome publiée, pas besoin de bot Alexa.


L'application créée par le bot permet à tout utilisateur Tinamous d'utiliser votre compétence et lier son compte. Vous pouvez garder la compétence privée. Pour un autre cloud, entrez ses détails OAuth.
Page Test : régler « Show this skill in the Alexa App » sur « Yes ».
Sauvegarder → alexa.amazon.co.uk (ou région appropriée) ou app Alexa. Skills → Your Skills → DEV SKILLS → votre compétence avec marqueur vert.


Les phrases d'exemple (« Alexa, éteins la lumière USB ») et infos supplémentaires se configurent sur la page « Publishing Information » (remplissable en développement sans publication complète).
Pour mettre à jour le code : nouvelle version Lambda, réajouter déclencheur SmartHome + Skill ID, coller l'ARN versionné dans la console compétence.
Succès !
Avec le code en Lambda et la compétence installée, lancer la découverte et contrôler les appareils.
Consulter les logs CloudWatch pour le débogage.
Débogage et astuces
Alexa donne presque aucun retour développeur en cas d'erreur. On passe des heures à deviner.
- Éviter tout sauf alphanumériques dans les
endpointID(*casse tout discrètement,#fonctionne). - Logger tout. Vérifier les logs à l'invocation. Pas de log → authentification ou Lambda non autorisé.
- Comptes email AWS et Alexa identiques.
- Lambda dans même région que la compétence (Irlande pour UK).
- Si compétence invoquée mais Alexa ne répond pas (pas de liste appareils), format de réponse probablement incorrect.
- Pour ne pas utiliser votre compte Alexa principal : Amazon Household pour ajouter un second compte adulte (limité à 2, changement lent).
Alexa, Switch Profilespour basculer profil développeur/normal.- Espérons que la refonte de la console Alexa apporte de meilleurs outils de débogage. Actuellement : gros boîtes, validation légèrement meilleure, logs de succès seulement (métriques feel-good management), retard 36 h = inutile pour déboguer.
Une compétence, n'importe quel objet IoT !
Avec la compétence Tinamous SmartHome, tant que votre objet IoT se connecte au serveur MQTT Tinamous (ou via un bot supporté), ajouter le contrôle Alexa SmartHome ne demande que quelques lignes de code pour gérer « Turn On », « Turn Off », « Set brightness 20 ». Ajoutez les tags dans Tinamous, et…
« Alexa, découvre les appareils connectés ».
Code
AlexaUsbSwitcher.inoTinamousMQTTClient.inoUsbControl.inoWiFiClient.inoSecrets.h
AlexaUsbSwitcher.ino (principal)
#include <MQTTClient.h>
#include <system.h>
#include <WiFi101.h>
#include <Adafruit_INA219.h>
#include "Secrets.h"
// ================================
// Configuration 4 ports (version finale)
#define MAX_USB_PORTS 4
int led_pin[MAX_USB_PORTS][2] = {{14, 14}, {13,13}, {7,7}, {6,6}};
int switch_pin[] = {A0, A1, A2, A3};
int usb_enable_pin[] = {5, 4, 1, 3};
int usb_fault_pin[] = {2, 2, 2, 2};
bool usb_port_state[] = {false, false, false, false};
// Mode 0 = éteindre demandé. Mode 1 = éteindre puis rallumer après délai (lampes tactiles).
int usb_power_mode[] = {1, 0, 0, 0};
// Automatisation
unsigned long usb_power_switch_on_at[] = {0, 0, 0, 0};
unsigned long usb_power_switch_off_at[] = {1, 1, 1, 1};
Adafruit_INA219 ina219;
bool has_usb_fault = false;
float shunt_voltage = 0, bus_voltage = 0, current_mA = 0, load_voltage = 0, power_mW = 0;
float max_current_mA = 0, max_busvoltage = 0, min_busvoltage = 20;
unsigned long last_measurement_time = 0;
bool power_failed = false, over_current = false;
int update_interval_seconds = 20;
unsigned long next_message_send_at = 0;
void setup() {
pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH);
for (int c=0; c MAX_USB_PORTS) return;
SetLeds(stage-1, true, true);
}
void loop() {
if (!hasPoweredPorts()) digitalWrite(LED_BUILTIN, LOW);
bool faulted = false;
for (int c=0; c max_current_mA) max_current_mA = current_mA;
if (bus_voltage > max_busvoltage) max_busvoltage = bus_voltage;
if (bus_voltage < min_busvoltage) min_busvoltage = bus_voltage;
printPowerSkinny();
}
void checkPowerSupply() {
if (power_failed && bus_voltage > 4.5) {
Serial.print("External power restored. Bus voltage: "); Serial.print(bus_voltage); Serial.println(" V");
publishTinamousStatus("External power has been restored."); power_failed = false;
}
if (bus_voltage < 4.2 && !power_failed) {
Serial.print("External power failed! Bus voltage: "); Serial.print(bus_voltage); Serial.println(" V.");
publishTinamousStatus("External power lost!"); power_failed = true;
}
if (over_current && current_mA < 1500) { publishTinamousStatus("Current fault cleared!"); over_current = false; }
if (current_mA > 2000 && !over_current) { publishTinamousStatus("Over Current!"); over_current = true; }
}
void sendStatus() {
if (millis() > next_message_send_at) {
Serial.println("------------------------");
Serial.println("MQTT publish measurements");
if (power_failed) sentNextPublishAt(update_interval_seconds * 10);
else sentNextPublishAt(update_interval_seconds);
String senml = "{'e':[";
// Voltage, Max/Min voltage, Current, Max current, mAh, powerState, ports...
// (code complet dans le fichier source)
publishTinamousSenMLMeasurements(senml);
Serial.println("------------------------"); Serial.println();
}
}
// ... fonctions auxilières (printPowerSkinny, resetStats, runAutomation, etc.)
TinamousMQTTClient.ino (connectivité MQTT)
#include <MQTTClient.h>
#include <system.h>
#include "secrets.h"
WiFiSSLClient networkClient;
MQTTClient mqttClient(4096);
bool was_connected = false;
String senml = ""; unsigned long nextSendMeasurementsAt = 0;
bool setupMqtt() {
senml.reserve(4096);
Serial.print("Connecting to Tinamous MQTT Server on port:"); Serial.println(MQTT_SERVERPORT);
Serial.print("Server:"); Serial.println(MQTT_SERVER);
mqttClient.begin(MQTT_SERVER, MQTT_SERVERPORT, networkClient);
mqttClient.onMessage(messageReceived);
connectToMqttServer();
}
bool connectToMqttServer() {
if (mqttClient.connected()) return true;
Serial.println("Reconnecting...."); Serial.println("checking wifi...");
if (WiFi.status() != WL_CONNECTED) {
Serial.print("WiFi Not Connected. Status: "); Serial.print(WiFi.status(), HEX); Serial.println();
delay(10000); return false;
}
Serial.println("Connecting to MQTT Server...");
if (!mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {
Serial.println("Failed to connect to MQTT Server.");
Serial.print("Error: "); Serial.print(mqttClient.lastError());
Serial.print(", Return Code: "); Serial.print(mqttClient.returnCode()); Serial.println();
if (mqttClient.lastError() == LWMQTT_CONNECTION_DENIED)
Serial.println("Access denied. Check username/password. Username should be 'DeviceName.AccountName'");
if (mqttClient.lastError() == -6)
Serial.println("Check Arduino has SSL Certificate for Tinmaous.com");
delay(10000); return false;
}
Serial.println("Connected to Tinamous MQTT!");
mqttClient.subscribe("/Tinamous/V1/Status.To/" DEVICE_USERNAME);
Serial.println("Subscribed to status.to topic.");
publishTinamousStatus("Hello! Usb switch is now connected. @ me with help for help.");
was_connected = true; return true;
}
void mqttLoop() { connectToMqttServer(); mqttClient.loop(); }
void publishTinamousStatus(String message) {
Serial.println("Status: " + message);
mqttClient.publish("/Tinamous/V1/Status", message);
}
void publishTinamousSenMLMeasurements(String senml) {
Serial.println("SenML Measurement: " + senml);
mqttClient.publish("/Tinamous/V1/Measurements/SenML", senml);
if (mqttClient.lastError() != 0) {
Serial.print("MQTT Error: "); Serial.print(mqttClient.lastError()); Serial.println();
}
Serial.println("Done.");
}
void messageReceived(String &topic, String &payload) {
Serial.println("Message from Tinamous on topic: " + topic + " - " + payload);
if (payload.startsWith("@")) {
payload.toLowerCase();
if (handleStatusMessage(payload)) { Serial.println("@ me status message handled."); return; }
}
publishTinamousStatus("Hello! Sorry I didn't understand the message. @ me with help for help.");
}
bool handleStatusMessage(String payload) {
char buffer[25];
for (int port = 0; port < MAX_USB_PORTS; port++) {
sprintf(buffer, "turn on port-%01d", port + 1);
if (payload.indexOf(buffer) > 0) { Serial.print("Turn on port "); Serial.println(port); setUsb(port, true); return true; }
sprintf(buffer, "turn off port-%01d", port + 1);
if (payload.indexOf(buffer) > 0) { Serial.print("Turn off port "); Serial.println(port); setUsb(port, false); return true; }
}
if (payload.indexOf("turn on") > 0) { allOn(); return true; }
if (payload.indexOf("turn off") > 0) { allOff(); return true; }
if (payload.indexOf("help") > 0) {
publishTinamousStatus("Send a message to me (@" DEVICE_USERNAME ") then: 'Turn on Port-1' to turn on usb port 1, 'Turn off Port-1' to turn off usb port 1, 'Turn on' to turn on all usb ports, 'Turn off' to turn off all usb ports. Port number can be 1, 2, 3 or 4.");
return true;
}
Serial.print("Unknown status message: "); Serial.println(payload); return false;
}
UsbControl.ino (contrôle puissance USB)
bool hasPoweredPorts() {
for (int c=0; c
WiFiClient.ino (gestion WiFi)
#include "Secrets.h"
char ssid[] = SECRET_SSID; char pass[] = SECRET_PASS; int status = WL_IDLE_STATUS;
void setupWiFi() {
Serial.println("Connecting to WiFi...");
if (WiFi.status() == WL_NO_SHIELD) { Serial.println("WiFi shield not present"); while(true); }
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: "); Serial.println(ssid);
status = WiFi.begin(ssid, pass); delay(10000);
}
Serial.println("You're connected to the network");
printCurrentNet(); printWiFiData();
}
void printWiFiData() {
IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip);
byte mac[6]; WiFi.macAddress(mac);
Serial.print("MAC address: ");
for(int i=5;i>=0;i--) { Serial.print(mac[i], HEX); if(i>0) Serial.print(":"); } Serial.println();
}
void printCurrentNet() {
Serial.print("SSID: "); Serial.println(WiFi.SSID());
byte bssid[6]; WiFi.BSSID(bssid);
Serial.print("BSSID: ");
for(int i=5;i>=0;i--) { Serial.print(bssid[i], HEX); if(i>0) Serial.print(":"); } Serial.println();
long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi);
byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println();
}
Secrets.h (à personnaliser)
#define SECRET_SSID "<Votre point d'accès WiFi>"
#define SECRET_PASS "<Votre mot de passe WiFi>"
/************************* Configuration MQTT Tinamous *********************************/
#define MQTT_SERVER "<Votre nom de compte>.tinamous.com"
#define MQTT_SERVERPORT 8883
#define MQTT_USERNAME "<Nom utilisateur périphérique>.<Votre nom de compte>"
#define MQTT_PASSWORD "Mot de passe du périphérique"
#define MQTT_CLIENT_ID "ID client aléatoire"
#define DEVICE_USERNAME "<Nom utilisateur périphérique>"
Pièces personnalisées et boîtiers
Version avec tous les connecteurs (trous pour Arduino, bornier, micro-USB additionnel). Version sans premières couches de texte (certaines imprimantes peinent). Version la plus simple et rapide à imprimer.
Schémas


Envoyer chez OSHPark ou DirtyPCBs pour fabrication.
arduinostandaloneusbswitch-4port_q16AoF01Aq.brdarduinostandaloneusbswitch-v2_Xd45dtjndI.sch

Dépôt GitHub USB Power Switcher
Dossier Arduino/StandAlone/ et version 4 ports : https://github.com/ThingySticks/USBPowerSwitcher

Processus de fabrication
- Maîtriser l'instruction Switch C# : Syntaxe, exemples et bonnes pratiques
- TI présente les chargeurs batterie buck‑boost BQ25790/BQ25792 ultra‑compacts, haute efficacité
- Capteur de coupure secteur 230 VAC pour Raspberry Pi : Économique, Compact et Sécurisé
- Interrupteur d'Alimentation AC Intelligent Contrôlé par SMS avec Raspberry Pi et Hologram
- L'énergie éolienne : transformer le mouvement de l'air en électricité propre
- Maîtriser les marteaux-pilons : guide complet pour la forge moderne
- Comprendre les presses à puissance automatiques : caractéristiques, avantages et applications
- Comprendre les mandrins de puissance : définition, utilisations et avantages
- Mandrins de puissance : guide complet pour l'usinage de précision