Comment mesurer des facteurs environnementaux (température, illumination, humidité...) d'un champ qui est situé à des kilomètres de la moindre prise électrique et de tout réseau WiFi? La première solution qui nous vient à l'esprit est d'utiliser un téléphone Android et de brancher des capteurs Yoctopuce par USB. Cette solution fonctionne (comme illustré ici), mais pour alimenter ce type d'installation il faut utiliser un panneau solaire et une batterie relativement importante. Pour effectuer quelques mesures pendant une période assez courte (quelques semaines), il existe une alternative plus simple, et probablement moins chère au final: utiliser une liaison WiFi au lieu d’une liaison USB entre le téléphone et le capteur.
Connexion USB
La liaison USB entre un téléphone Android et un module Yoctopuce fonctionne très bien et permet à une application d’interagir avec le monde physique (par exemple contrôler une lampe, ou vérifier la qualité de l’air dans certains lieux). Malheureusement, seuls les téléphones relativement haut de gamme ont le support pour USB On the Go (OTG), nécessaire pour utiliser un capteur USB. Il est difficile de trouver un téléphone avec un support fiable à moins de 200 €.
Le téléphone communique par USB et alimente tout le hub USB et les deux modules Yoctopuce.
Mais surtout, le plus gros problème est l’autonomie: en USB c’est le téléphone qui doit alimenter tous les périphériques. Comme le SDK ne permet pas de désactiver le port USB, l’OS ne va jamais pouvoir entrer en veille profonde et va continuellement utiliser le CPU pour maintenir la communication USB. Concrètement, si vous branchez un hub USB et deux modules Yoctopuce, vous n’aurez jamais plus de 24h d’autonomie car la batterie du téléphone doit alimenter en permanence le CPU et les périphériques USB connectés. D'où la nécessité d'un panneau solaire relativement grand et d'une grosse batterie.
Connexion WiFi
L’alternative est d'utiliser un YoctoHub-Wireless et une connexion WiFi. On configure le téléphone pour qu'il serve de point d’accès WiFi sécurisé (avec une clef WPA), et on configure le YoctoHub-Wireless pour qu’il se connecte automatiquement sur ce réseau WiFi. Naturellement, comme le YoctoHub-Wireless ne possède pas de batterie, on l’alimente avec une simple petite batterie USB.
Le téléphone crée un réseau WiFi. Le YoctoHub-Wireless, qui est alimenté par sa propre batterie, s’enregistre sur ce réseau.
Cette solution a de nombreux avantages:
- on peut utiliser un téléphone bas de gamme nettement moins cher
- les capteurs et le téléphone ne sont plus reliés par un câble (on peut donc déporter plus facilement les senseurs)
- il est possible de désactiver le réseau WiFi en dehors des phases de communication depuis l’application
- quand il n’y a pas de communication, le téléphone peut entrer en veille prolongée (et diminuer encore sa consommation)
- le YoctoHub-Wireless a une horloge en temps réel (RTC) qui lui permet de se mettre en veille profonde (et de limiter sa consommation à 15uA)
- le YoctoHub-Wireless est capable de couper l’alimentation des modules connectés (c’est notamment le cas quand il est en veille profonde)
On pourrait penser que communiquer par WiFi est bien plus énergivore que par USB, mais ce n'est pas le cas: le YoctoHub-Wireless ne consomme pas plus qu'un hub USB standard (env. 100mA), donc le seul surcoût est l'interface WiFi du téléphone. Mais comme le WiFi rend possible la mise en veille profonde le téléphone et des modules pendant la période qui sépare les mesures, la consommation moyenne s'en retrouve drastiquement réduite.
Dans cette configuration, le YoctoHub-Wireless est en veille profonde et ne consomme que 15uA. Les deux autres modules Yoctopuce ne consomment rien car ils ne sont même pas alimentés.
Exemple de mise en œuvre
L'exemple suivant est très basique, il s'agit d'une application qui effectue une mesure de température, d'humidité, de pression atmosphérique et d'illumination toutes les trois heures pour l’enregistrer sur le téléphone.
La première étape est de configurer le point d'accès WiFi du téléphone et de configurer le YoctoHub-Wireless pour se connecter à ce réseau. Une fois cette étape réalisée, les deux machines peuvent communiquer ensemble. Pour vérifier que tout fonctionne, il suffit d'ouvrir le browser web d'Android et de se connecter sur l’interface web du YoctoHub-Wireless en utilisant l'adresse IP que le téléphone lui a attribuée.
Une fois fait, la seconde partie consiste à écrire le programme Android qui prendra en charge la gestion des phases de réveil/sommeil, y compris l'activation et la désactivation du réseau WiFi pour économiser les batteries. En détail, cela revient à:
- activer le réseau WiFi
- attendre que YoctoHub-Wireless se connecte sur le réseau WiFi et détecter son adresse IP
- initialiser l’API Yoctopuce pour se connecter au YoctoHub-Wireless
- effectuer les mesures
- calculer l’heure de la prochaine exécution
- programmer le YoctoHub-Wireless pour se réveiller à l’heure de la prochaine exécution
- mettre le YoctoHub-Wireless en veille profonde
- programmer une alarme pour redémarrer le service à l’heure de la prochaine exécution
- enregistrer les mesures dans la base de donnée SQLite
- désactiver le réseau WiFi
- terminer l’exécution du service.
Tout cela est fait en arrière plan, par un service Android tournant en tâche de fond. Une petite application toute simple permet de contrôler le service et d'utiliser les valeurs mesurées (dans le cas présent nous nous contenterons de les afficher pour garder le code au plus simple).
Code source
Le code source complet de cet exemple est disponible sur Github. Nous commenterons ici quelques aspects spécifiques aux modules Yoctopuce.
Pour contacter le hub par WiFi quand il se réveille, on enregistre le YoctoHub-Wireless à l'aide de son adresse IP avec YAPI.RegisterHub("xxx.xxx.xxx.xxx"). L'adresse IP est obtenue par l'analyse du fichier /proc/net/arp.
ArrayList<String> ips = apGetIPs();
// test all IP that are connected to the WiFi HotSpot
for (String ip : ips) {
try {
// test if this IP is a YoctoHub-Wireless
YAPI.RegisterHub(ip);
ok = true;
} catch (YAPI_Exception e) {
// the IP is not Yoctopuce hub
}
}
} while (!ok && timeout > System.currentTimeMillis());
if (ok) {
// get value from all sensors
YHumidity yHumidity = YHumidity.FirstHumidity();
if (yHumidity != null) {
result.setHumidity(yHumidity.get_currentValue());
}
YTemperature yTemperature = YTemperature.FirstTemperature();
if (yTemperature != null) {
result.setTemperature(yTemperature.get_currentValue());
}
YPressure yPressure = YPressure.FirstPressure();
if (yPressure != null) {
result.setPressure(yPressure.get_currentValue());
}
YLightSensor yLightSensor = YLightSensor.FirstLightSensor();
if (yLightSensor != null) {
result.setLight(yLightSensor.get_currentValue());
}
}
Pour la programmation des heures de réveil, il faut faire attention à bien utiliser l’heure UTC d’Android pour éviter les problèmes d'heure d’été et de timezone. Un autre piège est l’unité de temps: Android travaille en millisecondes alors que l’API Yoctopuce travaille en seconde pour la gestion de l'heure.
YWakeUpMonitor hub = YWakeUpMonitor.FirstWakeUpMonitor();
if (hub != null) {
// create Pending intent to start this service again
Intent intent = new Intent(this, BgSensorsService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// compute next wake up time (seconds since EPOCH)
long now = System.currentTimeMillis() / 1000;
long nextWakeup = (now + WAKEUP_INTERVAL);
// Program the next wake for YoctoHub-Wireless
hub.set_nextWakeUp(nextWakeup);
// put the YoctoHub-Wireless in deep sleep until next wake up
hub.set_sleepCountdown(2);
// Program the Android Alarm manager to start this service again
// at the next wake up time.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
am.set(AlarmManager.RTC, nextWakeup * 1000, pendingIntent);
} else {
am.setExact(AlarmManager.RTC, nextWakeup * 1000, pendingIntent);
}
}
Lors de la première exécution, il faut s’assurer que le YoctoHub-Wireless est réveillé, pour qu'il essaie de se connecter au réseau WiFi. Si ce n'est pas le cas, il suffit d’appuyer sur le bouton Wake du YoctoHub-Wireless. A partir de là, le hub sera programmé pour se mettre en veille jusqu'au prochain appel.
Conclusion
Cette nouvelle manière d'utiliser le YoctoHub-Wireless sans réseau WiFi domestique ouvre de nouvelles possibilités pour prendre des mesures dans des endroits isolés, sans devoir mettre en place une grosse installation solaire. Elle convient particulièrement lorsque l'on a besoin d'un suivi de mesures pour une période spécifique (par exemple pendant le dégel, ou pendant que les arbres portent des fruits). Si vous désirez installer des modules Yoctopuce dans des zones isolées à moindre frais, c'est une bonne solution.