J'ai effectué deux stages (sur une période de 15 et 7 jours) dans l'entreprise Evotion, à Lyon, une startup spécialisée dans l'événementiel robotique.

Mon maître de stage, Maxime Vallet, m'a donné pour objectif de concevoir un prototype d'un boîtier à insérer dans le corps de la peluche d'un enfant afin de la rendre connectée. Ce boîtier devait remplir plusieurs fonctions :

  • Réagir à la luminosité ambiante en parlant afin de dire à l'enfant de se coucher
  • Réagir aux mouvements afin de détecter lorsque l'enfant le lance en l'air et de rire, et de détecter un câlin avec un mouvement latéral de gauche à droite afin de ronronner
  • Etre pilotable depuis le smartphone des parents afin qu'il puisse raconter des histoires.

Ces fonctions devaient être modulables, et l'objectif était de pouvoir en rajouter au fur et à mesure dans le but que je découvre de nouvelles notions en électronique et programmation en Arduino et en Swift 2.

J'ai décidé de me tourner vers un Arduino Yùn, non pas pour la connectivité WiFi, car la connexion avec le smartphone s'effectuera en Bluetooth, mais car l'Arduino Yùn dispose d'un second processeur avec une architecture Linux, me permettant de connecter une carte son, ainsi qu'un amplificateur et enfin un haut-parleur pour avoir du son, plutôt que d'avoir à acheter un module supplémentaire pour le son (les objets utilisés étant déjà présents sur mon lieu de stage).

En ce qui concerne les mouvements, j'ai opté pour un accéléromètre/gyroscope, le Flora de chez Adafruit, avec 9 degrés de liberté, afin de détecter les câlins et les lancers.

 

Pour la lumière, j'ai décidé de mettre une photorésistante, vu que l'Arduino dispose d'entrées analogiques, plutôt que de devoir acheter un module I2C ou SPI.

 

Enfin, pour le bluetooth, j'ai choisi un module Bluetooth LE d'Adafruit, qui communique via un port série virtuel (UART).

 

En ce qui concerne le boîtier, j'ai imprimé une coque en 3d afin de contenir tous les composants. Au début, ces derniers étaient juste connectés à l'Arduino et disposés "en vrac" dans le boîtier. Par la suite, j'ai opté pour deux plaques à point de soudure superposées, avec l'une connectée par des header à l'Arduino.

Voilà le code (encore en développement en ce qui concerne l'accéléromètre) présent dans l'Arduino :

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#if not defined (_VARIANT_ARDUINO_DUE_X_) && not defined (_VARIANT_ARDUINO_ZERO_)
#include 
#endif
#include 
#include « Adafruit_BLE.h »
#include « Adafruit_BluefruitLE_UART.h »
#include « BluefruitConfig.h »
#define FACTORYRESET_ENABLE 0
#define MINIMUM_FIRMWARE_VERSION « 0.6.6 »
#define MODE_LED_BEHAVIOUR « MODE »
Adafruit_NeoPixel bande = Adafruit_NeoPixel(8, 6, NEO_GRB + NEO_KHZ800);
Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0(1000);
SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);
Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN,
BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);
Process p;
Process date;
Process histoire;
byte hours, minutes, seconds;
int lastSecond = -1;
byte luminosite = 0;
boolean first = 0;
int ennui = 0;
boolean firstcharge = 0;
int calin, calintemps, startcalin = 0;
void error(const __FlashStringHelper*err) {
Console.println(err);
while (1);
}
void setup() {
if (digitalRead(7) == HIGH) {
firstcharge = 1;
}
bande.begin();
bande.show();
if (!lsm.begin()) {
while (1);
}
sensor_t accel, mag, gyro, temp;
lsm.getSensor(&accel, &mag, &gyro, &temp);
lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_2G);
lsm.setupMag(lsm.LSM9DS0_MAGGAIN_2GAUSS);
lsm.setupGyro(lsm.LSM9DS0_GYROSCALE_245DPS);
delay(500);
Bridge.begin();
while (!Console);
Console.begin();
if ( !ble.begin(VERBOSE_MODE) )
{
}
Console.println( F(« OK! ») );
if ( FACTORYRESET_ENABLE )
{
if ( ! ble.factoryReset() ) {
}
}
ble.sendCommandCheckOK(« AT+GAPDEVNAME=Peluche » );
ble.echo(false);
ble.info();
ble.verbose(false)
while (! ble.isConnected()) {
delay(500);
}
if ( ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) )
{
ble.sendCommandCheckOK(« AT+HWModeLED= » MODE_LED_BEHAVIOUR);
}
ble.setMode(BLUEFRUIT_MODE_DATA);
for (int i = 4; i <= 5; i++) {
pinMode(i, INPUT);
digitalWrite(i, LOW);
}
pinMode(8, INPUT);
digitalWrite(7, LOW);
pinMode(7, INPUT);
digitalWrite(13, HIGH);
}
void loop() {
sensors_event_t accel, mag, gyro, temp;
lsm.getEvent(&accel, &mag, &gyro, &temp);
double storedVector = accel.acceleration.x * accel.acceleration.x;
storedVector += accel.acceleration.y * accel.acceleration.y;
storedVector += accel.acceleration.z * accel.acceleration.z;
storedVector = sqrt(storedVector);
Console.println(abs(storedVector));
calin = accel.acceleration.x * accel.acceleration.x;
if (calin <= -10) { startcalin = 1; calintemps = millis(); } if (calin > 10 && startcalin == 1) {
if (calintemps + 800 > millis() && calintemps + 1500 < millis()) { startcalin = 0; p.runShellCommand(« madplay /mnt/sda1/calin.mp3 »); while (p.running()); } } if (calintemps + 1500 > millis()) {
startcalin = 0;
calintemps = 0;
}
if (abs(storedVector) > 25) {
p.runShellCommand(« madplay /mnt/sda1/rire.mp3 »);
while (p.running());
}
while ( ble.available() )
{
int c = ble.read();
if (((char)c) == ‘A’) {
for (int i = 0; i < 8; i++) {
bande.setPixelColor(i, bande.Color(0, 250, 0));
bande.show();
}
p.runShellCommand(« madplay /mnt/sda1/chut.mp3 »);
while (p.running());
}
if (((char)c) == ‘1’) {
p.runShellCommand(« madplay /mnt/sda1/histoire1.mp3 »);
for (int i = 0; i < 8; i++) { bande.setPixelColor(i, bande.Color(250, 0, 0)); bande.show(); } while (p.running()) { if (ble.available()) { if (ble.read() == ‘S’) { histoire.close(); } } } } } if (digitalRead(7) == LOW && firstcharge == 1) { p.runShellCommand(« madplay /mnt/sda1/chargement.mp3 »); while (p.running()); firstcharge = 0; } luminosite = map(analogRead(0), 500, 1000, 0, 100); if (luminosite > 170) {
first = 1;
}
if (luminosite <= 170 && first == 1 && luminosite != 0) {
for (int i = 0; i < 8; i++) { bande.setPixelColor(i, bande.Color(0, 0, 250)); bande.show(); } p.runShellCommand(« madplay /mnt/sda1/dodo.mp3 »); while (p.running()); first = 0; } ennui = random(0, 3600000); Console.println(ennui); if (ennui == 3 && luminosite > 170) {
p.runShellCommand(« madplay /mnt/sda1/ennui.mp3 »);
while (p.running());
}
}

Je suis en train de développer une application en Swift 2 afin de contrôler la lecture d'histoires en Bluetooth en envoyant des messages au module bluetooth low energy qui les transmettra en UART à l'Arduino

Voici quelques photos du système actuel :
  

Première image : La carte supérieure avec le haut-parleur, le module bluetooth, le PowerBoost pour convertir les 3.7V de la batterie en 5V et pour la recharger et l'accéléromètre.

Deuxième image : La plaque intermédiaire avec l'Arduino Yùn en-dessous.

Troisième image : Le système complet sans le boîtier.

Quatrième image : Une autre vue de la plaque supérieure.

Enfin, ces deux dernières images représentent respectivement la connexion entre les deux plaques et la carte son usb.