🛠 Contrôler une LED depuis Android

Arduino Mega ADK (Rev3) · intermediaire · Schéma : IMG-mega-adk-intermediaire-3-mega-adk-controle-led-android.svg — Curseur de luminosité sur le téléphone, commandes PWM reçues par la Mega ADK, LED sur la broche 9

Objectifs

Inverser le sens du flux : un curseur de luminosité dans l'application Android pilote en direct une LED via MLI sur la Mega ADK. C'est le schéma de commande de l'ancien DemoKit officiel (trames [commande][broche][valeur]) que l'on réduit à l'essentiel. On révise les 15 canaux PWM (broches 2 à 13 et 44 à 46) et la mise en état sûr quand le téléphone est débranché.

Matériel

Code complet

Côté carte (réception des ordres PWM) :

// mega-adk-controle-led-android.ino — Board: "Arduino Mega ADK"
#include <Usb.h>
#include <usbhub.h>
#include <adk.h>

USB Usb;
USBHub hub0(&Usb);
ADK adk(&Usb, "AtelierADK", "PilotageLED", "LED PWM broche 9",
        "1.0", "http://example.org", "SN000003");

const byte LED = 9;   // PWM : broches 2-13 et 44-46

void setup {
  Serial.begin(115200);
  pinMode(LED, OUTPUT);
  if (Usb.Init == -1) { Serial.println(F("OSCOKIRQ failed to assert")); while (1); }
}

void loop {
  Usb.Task;
  if (!adk.isReady) { analogWrite(LED, 0); return; }  // état sûr

  uint8_t trame[3]; uint16_t len = sizeof(trame);
  // trame [0x02][LED][0..255] envoyée par l'application
  if (adk.RcvData(&len, trame) == 0 && len == 3 && trame[0] == 0x02) {
    analogWrite(trame[1], trame[2]);
    Serial.print(F("PWM broche ")); Serial.print(trame[1]);
    Serial.print(F(" = ")); Serial.println(trame[2]);
  }
  delay(5);
}

Côté Android (curseur SeekBar 0–255) :

// PilotageActivity.java (extrait) — SeekBar -> trame [0x02][9][valeur]
SeekBar curseur = findViewById(R.id.curseurLuminosite);
curseur.setMax(255);
curseur.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener {
    @Override public void onProgressChanged(SeekBar s, int valeur, boolean parUtilisateur) {
        if (!parUtilisateur || out == null) return;
        try {
            byte[] trame = { 0x02, 9, (byte) valeur };
            out.write(trame);            // FileOutputStream sur l'accessoire
        } catch (IOException deconnexion) { etatDeconnecte; }
    }
    @Override public void onStartTrackingTouch(SeekBar s) { }
    @Override public void onStopTrackingTouch(SeekBar s) { }
});
// L'activité gère aussi ACTION_USB_ACCESSORY_DETACHED pour griser le curseur.

Vérification attendue

Le curseur fait varier la luminosité de la LED sans latence perceptible (trame de 3 octets à chaque changement). Quand on retire le câble, la LED s'éteint (état sûr analogWrite(LED, 0)) et l'application grise le curseur. La console affiche chaque ordre reçu avec sa valeur.

Erreurs fréquentes

  1. LED sur une broche non PWM (par exemple 14) : analogWrite ne produit aucun effet — vérifier la liste 2-13 et 44-46.
  2. État sûr oublié : sans remise à 0 quand adk.isReady est faux, la LED reste allumée à la dernière consigne après débranchement.
  3. Inversion des octets de la trame entre le code Java et le code Arduino : tester d'abord avec une valeur fixe (128) avant de brancher le curseur.
  4. RAZ de la consigne à chaque Usb.Task : ne pas réécrire analogWrite en boucle avec une valeur par défaut, sinon le curseur « n'obéit pas ».
  5. Inonder le lien avec un write par pixel de curseur : sans drainer Usb.Task assez souvent, les écritures s'accumulent ; garder le delay(5) côté carte ou limiter la cadence côté application.
  6. Permission USB non accordée à la reconnexion : l'application doit redemander la permission après ACTION_USB_ACCESSORY_ATTACHED, sinon le flux reste null.

Autres tutoriels pour cette carte

Exemples de code pour cette carte

← Retour à la fiche 🛠 Tous les tutoriels