Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Composants et fournitures

Composant Quantité
Arduino 101 1
LED (générique) - 1 bleue, 1 jaune, 1 verte, 2 rouges 5
Résistance 221 Ω 5
Plaque d'essai (breadboard) générique (non obligatoire) 1
Seeed Base Shield V2 1
Seeed Grove LCD RGB Rétroéclairage 1
Seeed Grove Capteur de son 1
Seeed Grove Buzzer 1
Seeed Grove Capteur de température 1
Clavier matriciel (Keypad) 1
Fils de liaison (jumper wires) génériques 1
Pile 9V (générique) 1
Connecteur pile 9V 1
Panneau de fibres à densité moyenne (MDF) 20x30 cm, 3 mm 1

Outils et machines nécessaires

Applications et services en ligne

À propos du projet

Qu'est-ce que SMART CUBE ?

Smart Cube est un contrôleur pour vos appareils domotiques.

De nos jours, gérer de manière plus intelligente tous les appareils de notre foyer devient une exigence. Nous avons besoin de quelque chose de simple et intuitif à utiliser. Smart Cube pourrait être une solution : c'est un appareil portable qui contient une carte Arduino 101 et des capteurs qui communiquent avec les appareils et actionneurs de votre maison connectée.

L'innovation de cette télécommande est liée à l'innovation de la carte Arduino 101. Elle utilise le Bluetooth (BLE) pour contrôler les lumières, la température et votre TV, et vous pouvez aussi la synchroniser avec votre smartphone. Mais la véritable innovation réside dans la façon dont vous interagissez avec Smart Cube par vos gestes grâce au gyroscope et à l'accéléromètre. Le cube a 6 faces et chacune contrôle une fonction particulière. La fonction que vous voulez utiliser est détectée grâce au gyroscope qui reconnaît la face supérieure. Par exemple, vous pouvez allumer les lumières de la pièce où vous vous trouvez simplement en positionnant le cube avec la « face lumière » en position haute. Si vous voulez éteindre la lumière, il suffit de secouer le cube.

Si une face est HAUTE et ne bouge pas pendant plus de 2 secondes, la fonction correspondante est activée. Ce délai est prévu pour que vous ayez le temps de tourner et manipuler le cube pour trouver la face dont vous avez besoin sans activer accidentellement d'autres fonctions. Lorsque vous secouez le cube pendant plus de 2 secondes, la dernière fonction activée est fermée.

Ce projet vise à vous aider à construire un contrôleur intelligent. Cet appareil a besoin d'un récepteur (centrale domotique sur l'image) qui interprète les données et gère les fonctions de votre maison connectée. La principale sortie du cube est un signal BLE qui peut être utilisé de multiples façons : par exemple, vous pouvez connecter le cube avec une application smartphone (ou créer la vôtre), ou construire une station avec un autre Arduino qui collecte les données BLE et contrôle directement les appareils de votre maison. Comme les cas d'usage sont variés, cette partie dépend de vos besoins. Dans ce guide, nous verrons comment construire un Smart Cube et comment le personnaliser.

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Fonctions :

La structure du code est facile à personnaliser (nous l'analyserons plus tard) pour que vous puissiez décider quelles fonctions contrôler. Voici celles que j'ai choisies :

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

LUMIÈRES : Cette face en position HAUTE allume les lumières de la pièce où vous êtes. Si vous secouez le cube, les lumières s'éteignent et une LED jaune sur cette face s'allume pour retrouver le cube dans l'obscurité. La communication avec vos lampes se fait via le BLE de la carte 101.

TEMPÉRATURE : Cette face HAUTE active (via BLE) la climatisation s'il fait chaud ou le chauffage s'il fait froid. Elle détecte la température à l'aide d'un capteur thermique et allume une LED bleue si la climatisation est active (flocon de neige) ou une rouge si le chauffage est activé (soleil).

MINUTERIE : Cette face HAUTE démarre un minuteur visible sur l'écran LCD. Un buzzer fonctionne comme alarme quand le compte à rebours est fini. Si vous secouez, vous arrêtez le minuteur et voyez le temps restant. Quand le compte à rebours se termine, la couleur du LCD passe du bleu au rouge et le buzzer émet trois bips.

TV : Cette face HAUTE allume la TV. Le cube devient une télécommande pour votre TV. Un panneau de boutons avec chiffres est activé uniquement si cette face est HAUTE pour éviter les touches accidentelles. Le chiffre appuyé est envoyé via BLE à la centrale qui est connectée à votre TV. Secouer le cube éteint la TV.

SON : Cette face HAUTE active une LED dont la luminosité est basée sur le niveau sonore de la pièce. Le bruit est détecté grâce au capteur de son. Si vous secouez le cube, vous fermez cette fonction. (Si vous le souhaitez, vous pouvez activer votre fonction personnelle en claquant des mains).

Face OFF : Si vous ne secouez pas le cube, cette face est comme une position neutre où rien ne change. Si vous voulez tout éteindre, positionnez le cube avec la face OFF en HAUT et secouez-le. Ce geste est comme le bouton Home de votre smartphone pour sortir rapidement. Une LED rouge permet de retrouver le cube dans l'obscurité.

Différences par rapport au concept initial :

Le plan initial prévoyait d'utiliser aussi la communication IR pour connecter directement votre TV au cube. Comme l'Arduino 101 ne supporte pas (pour l'instant) la bibliothèque gérant les signaux IR, j'ai décidé d'envoyer l'information via BLE vers une station capable de gérer cette bibliothèque (comme un Arduino UNO). À cause de ce problème, j'ai supprimé la fonction radio (très similaire à la face TV), la remplaçant par une face capteur de son. Cette face pourrait servir à reconnaître un bruit fort (comme des applaudissements) pour activer quelque chose. Le plus grand changement concerne le matériau du cube. Au départ, je pensais l'imprimer en 3D mais j'ai opté pour la découpe laser. Ainsi, il est plus facile de remplacer une face si vous voulez changer une fonction. Par exemple, vous pouvez retirer la face minuteur et la remplacer par une face qui remplit automatiquement la gamelle de votre chat. Étant modulaire, vous n'avez pas besoin de reconstruire toute la structure !

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Construisons-le :

Suivez ces instructions pour construire votre propre Smart Cube. Nous commencerons par le matériel, en assemblant d'abord les composants électroniques, puis le corps du cube découpé au laser en MDF. Ensuite, j'expliquerai comment le code fonctionne et comment le personnaliser. Après avoir téléversé le code sur votre Arduino 101, vous pourrez télécharger l'application pour voir la sortie BLE du cube ou le connecter directement à votre maison connectée !

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Matériel - Électronique :

Partons de votre Arduino 101. Voici le schéma Fritzing à suivre :

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Montez le Grove Base Shield sur votre carte et commencez les connexions.

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Keypad : connectez les fils dans l'ordre aux broches : 10, 8, 7, 6, 5, 4, 2.

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Connexions LED :

Préparez d'abord les LED :

Connectez maintenant les fils rouges à votre Arduino : LED VERTE broche 9, LED JAUNE broche 11, LED ROUGE broche 12, LED BLEUE broche 13, dernière ROUGE broche A2.

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Capteurs Grove :

Connectez les capteurs Grove au shield (voir schéma en pièce jointe). Buzzer sur D3, LCD RGB sur I2C, Capteur température sur A0, Capteur son sur A1.

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Tous les composants électriques sont maintenant connectés. Passons au boîtier.

Matériel - Boîtier

Vous pouvez télécharger le plan du cube pour la découpe laser. Les lignes rouges sont les symboles des faces, gravez-les simplement. Les lignes noires doivent être découpées. La dimension interne du cube est de 9 cm. Le plan est prévu pour du matériau 3 mm, si vous utilisez une épaisseur différente, vous devrez le modifier (utilisez ce site : makercase.com).

Le matériau choisi est du MDF (Medium Density Fiber) mais vous pouvez utiliser ce que vous voulez.

Voici quelques photos de la découpe laser :

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Maintenant, il faut l'assembler.

J'ai collé des morceaux de carton pour créer de l'épaisseur pour les LED. Ainsi, elles seront alignées avec la surface.

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Montons maintenant le keypad. Insérez-le dans le trou, retirez le film adhésif, puis rebranchez les broches.

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Maintenant le LCD RGB. Il s'insère parfaitement dans le trou.

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Préparons le connecteur de pile :

J'ai découpé une vieille fiche de transformateur et l'ai connectée à un connecteur de pile. Cela fait gagner de la place à l'intérieur.

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée
Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

À ce stade, vous devriez avoir ceci :

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Il ne reste plus qu'à connecter la pile, téléverser le code et fermer le cube !

ASTUCE : fixez la carte et la pile au boîtier pour qu'ils restent stables quand vous secouez le cube.

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Code

Le code se trouve dans les pièces jointes. Téléversez-le sur votre carte avec l'Arduino IDE (pensez à mettre à jour votre logiciel pour la compatibilité Arduino 101).

J'ai commenté presque chaque ligne pour le rendre le plus compréhensible possible. Ne soyez pas effrayé par les 500+ lignes, la structure n'est pas si compliquée.

Au début se trouvent les bibliothèques et la déclaration de toutes les variables.

Dans cette partie, il y a aussi la définition des services et caractéristiques BLE. J'ai utilisé le service Automation IO. J'ai utilisé la caractéristique Digital pour les lumières et la température (2 bits, donc 4 cas possibles) et l'Analog pour la TV (pour envoyer tous les codes du keypad).

Puis le setup. Cette partie s'exécute une seule fois au début. On y initialise les composants en entrées/sorties, le BLE et le gyroscope de la carte 101.

La partie principale est la loop. Elle est divisée en quatre parties :

Vous pouvez modifier les fonctions des faces avec quelques modifications du code. La structure principale doit rester telle que décrite. Vous pouvez changer la partie à l'intérieur des conditions if de chaque face.

if (face2 == true) { // TEMPERATURE face
  //START CHANGING HERE
  digitalWrite (LEDOFF, LOW); // si cette face est vraie, la LED OFF est LOW
  if (central.connected() == true) { // si le cube est connecté en BLE
    // lecture valeur température
    int val = analogRead(pinTemp); // valeur analogique
    resistance=(float)(1023-val)*10000/val; // résistance
    temperature=1/(log(resistance/10000)/B+1/298.15)-273.15; // calcul température
    // conditions d'activation
    if (temperature > tooHot) { // activer clim
      digitalWrite(LEDhot, LOW); // éteindre LED chauffage
      digitalWrite(LEDcold, HIGH); // allumer LED clim
      termoChar.setValue(1); // 1 = clim on - chauffage off
    }
    if (temperature < tooCold) { // activer chauffage
      digitalWrite(LEDhot, HIGH);
      digitalWrite(LEDcold, LOW);
      termoChar.setValue(2); // 2 = clim off - chauffage on
    }
    if (temperature > tooCold && temperature < tooHot) { // température idéale
      digitalWrite(LEDhot, LOW);
      digitalWrite(LEDcold, LOW);
      termoChar.setValue(0); // 0 = clim off - chauffage off
    }
  }
  //END HERE
}

Vous devez aussi coder la partie « false » quand le cube est secoué :

// TEMPERATURE désactivation
if (lastFUNCTION == 2) { // TEMPERATURE face
  //START CHANGING HERE
  if (central.connected() == true) {
    digitalWrite(LEDhot, LOW); // éteindre LED température rouge
    digitalWrite(LEDcold, LOW); // éteindre LED température bleue
    termoChar.setValue(0); // signal BLE température: 0 = clim off - chauffage off
  }
  //END HERE
  Serial.println("TEMPERATURE false - CLOSE");
  face2 = false; // face TEMPERATURE devient false
}

N'oubliez pas de mettre la face à false quand vous la secouez.

Application :

Pour voir les sorties BLE du cube, vous pouvez télécharger cette application : nRF Connect

https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp&hl=it

À l'ouverture, recherchez les appareils et connectez-vous à « smartcubesketch ». Vous verrez trois onglets « Automation IO », cliquez dessus et activez la collecte continue de données.

Il est important de connecter le cube car certaines fonctions (lumières, température, TV) ne s'exécutent que si le cube est connecté.

Fonctionnement : VIDÉO

Téléversez le code, insérez la pile, fermez la boîte et...

... vous avez maintenant un SMART CUBE !

J'ai fait une vidéo pour vous montrer toutes les fonctions du cube et comment l'utiliser.

Conclusions

Ce projet n'est que la première étape vers une maison connectée. Mon but était d'utiliser le potentiel de la carte Arduino 101 pour créer quelque chose de nouveau. Je pense que l'accéléromètre et le gyroscope offrent à la carte de nouvelles opportunités en termes de mobilité. Avec le BLE, en plus d'être portable, il est aussi facile à connecter.

C'est la première fois que je réalise concrètement l'un de mes projets (un prototype fonctionnel). Ce fut difficile et il y eut des obstacles, mais à la fin j'ai beaucoup appris et je suis satisfait du résultat. J'espère que tous ceux qui liront ce guide pourront apprendre de mon travail et adapter ce projet à leurs besoins. Excusez mon anglais approximatif, j'espère que les images vous aideront.

Dans le futur de ce projet, je compte créer la centrale qui fera le pont entre le Smart Cube et les actionneurs (lumières, température, TV...). Cette centrale recevra le signal BLE du cube et utilisera cette information pour faire des choses intelligentes chez vous.

Je suis très content d'avoir pu utiliser l'Arduino 101 et le Grove kit (le kit est très simple et rapide pour le prototypage).

J'espère que l'utilisation de la carte de cette façon pourra être une inspiration pour vos projets. Vous pouvez le personnaliser comme vous voulez : je suis curieux de voir quelles fonctions vous créerez et dans quels contextes différents vous l'utiliserez !

Ce n'est peut-être pas une révolution, mais c'est une nouvelle façon d'interagir avec votre maison.

J'espère que ce tutoriel vous a plu.

Maintenant, c'est à votre tour : mettez la main sur le cube et hackez-le !

Code

SMART CUBE - Code complet commenté (Arduino)
// Libraries
#include "CurieIMU.h" // Accéléromètre & Gyroscope
#include <CurieBLE.h> // Bluetooth Low Energy
#include <Wire.h>
#include "rgb_lcd.h" // LCD
#include <Keypad.h> // Keypad

rgb_lcd lcd; // Initialisation LCD

// Initialisation Bluetooth:
BLEPeripheral blePeripheral; // Périphérique BLE (la carte que vous programmez)

// Services BLE
BLEService lightsService("1815"); // Automation IO (1815) - infos lumières
BLEService termoService("1815"); // Automation IO - infos température
BLEService TVService("1815"); // Automation IO - infos TV

// Caractéristiques BLE
BLEUnsignedCharCharacteristic lightsChar("2A56", // Digital (2A56) - lumières
  BLERead | BLENotify);
BLEUnsignedCharCharacteristic termoChar("2A56", // Digital - température
  BLERead | BLENotify);
BLEUnsignedCharCharacteristic TVChar("2A58", // Analog (2A58) - TV
  BLERead | BLENotify);

// Constantes et déclaration variables:
// Fonctions orientation face et shake:
int lastOrientation = -1; // orientation précédente (pour comparaison)
unsigned long previousMillis = 0; // dernier temps mis à jour
unsigned long interval = 2000; // temps à attendre en position haute avant activation face
unsigned long SHAKEpreviousMillis = 0; // dernier temps mis à jour
unsigned long SHAKEinterval = 2000; // temps à attendre pendant secousse pour désactivation face
boolean keep = false; // utilisé pour compter une seule fois le changement d'orientation
int lastFUNCTION = -1; // utilisé pour connaître l'orientation précédente

// Initialisation faces: au début toutes fausses
boolean face0 = false;
boolean face1 = false;
boolean face2 = false;
boolean face3 = false;
boolean face4 = false;
boolean face5 = false;

// Face LUMIÈRES
const int LEDlights = 11; // broche 11: LED jaune

// Face TEMPÉRATURE
const int pinTemp = A0; // broche A0: capteur température
const int LEDhot = 12; // broche 12: LED rouge
const int LEDcold = 13; // broche 13: LED bleue
float temperature; // mémorisation température
int B=3975; // valeur B du thermistor
float resistance; // mémorisation résistance
float tooHot = 26.0; // température activation clim [RÉGLABLE]
float tooCold = 23.0; // température activation chauffage [RÉGLABLE]

// Face MINUTERIE
int BUZZER = 3; // broche 3: buzzer
boolean KEEPtime = false; // utilisé pour compter une seule fois le changement (ne pas redémarrer pendant comptage)
int TIMERmillis = 0; // pour détermination compte à rebours
int prevSHOWsecond = 0;
int CountdownInMillis = 0;
int SHOWmillis = 0; // résultat calcul millis
int SHOWminute = 0; // minutes à afficher sur moniteur
int SHOWseconds = 0; // secondes à afficher sur moniteur
const int SETminute = 2; // régler minuteur 2 minutes [RÉGLABLE]
const int SETsecond = 30; // régler 30 secondes [RÉGLABLE]

// Face SON
const int soundLED = 9; // broche 9: LED verte
const int soundSENSOR = A1; // broche A1: capteur son
int brightness = 0; // initialisation luminosité LED verte

// Face TV
const byte ROWS = 4; // 4 lignes keypad
const byte COLS = 3; // 3 colonnes keypad
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
}; // valeurs boutons keypad
byte rowPins[ROWS] = {10,8,7,6}; // broches 10,8,7,6: lignes keypad
byte colPins[COLS] = {5,4,2}; // broches 5,4,2: colonnes keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); // initialisation keypad

// Face OFF
const int LEDOFF = A2; // broche A2: LED rouge

void setup() {
  pinMode(LEDlights, OUTPUT); // toutes les LED en sortie
  pinMode(LEDhot, OUTPUT);
  pinMode(LEDcold, OUTPUT);
  pinMode(soundLED, OUTPUT);
  pinMode(LEDOFF, OUTPUT);
  Serial.begin(9600); // communication série
  CountdownInMillis = (SETminute*60 + SETsecond)*1000; // calcul millis correspondant aux minutes/secondes
  lcd.begin(16, 2); // initialisation LCD
  lcd.setRGB(0, 0, 0); // LCD RGB éteint au début
  // initialisation dispositif
  Serial.println("Initializing IMU device...");
  CurieIMU.begin(); // initialisation IMU
  CurieIMU.setAccelerometerRange(2); // plage accéléromètre 2G
  // Activation détection choc
  CurieIMU.setDetectionThreshold(CURIE_IMU_SHOCK, 7000); // 7.0g = 7000 mg (intensité choc)
  CurieIMU.setDetectionDuration(CURIE_IMU_SHOCK, 2000); // 2000ms (durée choc)
  CurieIMU.interrupts(CURIE_IMU_SHOCK); // interruption sur choc
  // Initialisation BLE
  blePeripheral.setLocalName("SmartCubeSketch"); // nom du projet
  blePeripheral.setAdvertisedServiceUuid(lightsService.uuid()); // UUID service lumières
  blePeripheral.addAttribute(lightsService); // service BLE lumières
  blePeripheral.addAttribute(lightsChar); // caractéristique BLE lumières
  lightsChar.setValue(3); // valeur initiale = 3
  // Signification valeurs BLE lumières: 0=éteint, 1=allumé, 3=état initial, 4=non utilisé
  blePeripheral.setAdvertisedServiceUuid(termoService.uuid()); // UUID service température
  blePeripheral.addAttribute(termoService); // service BLE température
  blePeripheral.addAttribute(termoChar); // caractéristique BLE température
  termoChar.setValue(0); // valeur initiale 0: clim off - chauffage off
  // Signification BLE température: 0=clim off-chauffage off, 1=clim on-chauffage off, 2=clim off-chauffage on, 3=non utilisé
  blePeripheral.setAdvertisedServiceUuid(TVService.uuid()); // UUID service TV
  blePeripheral.addAttribute(TVService); // service BLE TV
  blePeripheral.addAttribute(TVChar); // caractéristique TV
  TVChar.setValue('x'); // valeur initiale (x = rien)
  // Signification BLE TV: #chiffre=bouton pressé, C: fermer TV, O: ouvrir TV, x: état initial
  blePeripheral.begin();
  Serial.println("Bluetooth device active, waiting for connections...");
} // fin setup

void loop() {
  BLECentral central = blePeripheral.central(); // connexion BLE
  unsigned long currentMillis = millis(); // temps actuel en millisecondes

  // Code provenant de www.arduino.cc/en/Tutorial/Genuino101CurieIMUAccelerometerOrientation
  // Utilisé pour détecter l'orientation de la carte
  int orientation = -1; // orientation de la carte
  String orientationString; // chaîne pour description orientation
  // lecture accéléromètre:
  int x = CurieIMU.readAccelerometer(X_AXIS);
  int y = CurieIMU.readAccelerometer(Y_AXIS);
  int z = CurieIMU.readAccelerometer(Z_AXIS);
  // valeurs absolues pour déterminer la plus grande
  int absX = abs(x);
  int absY = abs(y);
  int absZ = abs(z);
  if ((absZ > absX) && (absZ > absY)) { // orientation base sur Z
    if (z > 0) { orientationString = "up"; orientation = 0; }
    else { orientationString = "down"; orientation = 1; }
  } else if ((absY > absX) && (absY > absZ)) { // orientation base sur Y
    if (y > 0) { orientationString = "digital pins up"; orientation = 2; }
    else { orientationString = "analog pins up"; orientation = 3; }
  } else { // orientation base sur X
    if (x < 0) { orientationString = "connector up"; orientation = 4; }
    else { orientationString = "connector down"; orientation = 5; }
  }
  // Fin code tutoriel.
  // À ce point, vous avez la valeur d'orientation constamment mise à jour:
  /* Orientations de la carte:
     0: à plat, processeur face haute (MINUTERIE)
     1: à plat, processeur face basse (TV)
     2: paysage, broches analogiques bas (TEMPÉRATURE)
     3: paysage, broches analogiques haut (OFF)
     4: portrait, connecteur USB haut (LUMIÈRES)
     5: portrait, connecteur USB bas (SON) */

  // Pour ce projet, il faut savoir si la face a changé par rapport à la précédente [lastFUNCTION != orientation]
  // Mais cette info n'est affichée que si la face reste en position HAUTE pendant plus de [interval] temps
  // Et une seule fois [keep] (pas besoin d'activer constamment, une fois suffit)
  // Comme orientation est constamment mise à jour, il faut commencer à compter quand elle change [orientation != lastOrientation]
  if (orientation != lastOrientation) {
    // si orientation a changé, commencer à compter le temps
    lastOrientation = orientation; // mémoriser orientation actuelle
    previousMillis = currentMillis; // mémoriser temps du changement
    keep = false;
  } else if (currentMillis - previousMillis > interval && keep == false && lastFUNCTION != orientation) {
    // cette condition affiche l'orientation seulement si la face est haute pour un intervalle
    // et une seule fois (keep)
    // et seulement si la face est différente de la boucle précédente
    Serial.println(orientationString); // afficher orientation
    // la face courante [orientation] est mise à true (fonction face activée)
    if (orientation == 1) { // face TV
      face1 = true;
      lastFUNCTION = orientation;
      Serial.println("TV true");
      TVChar.setValue('O'); // O: signal ouverture TV (BLE): TV ouverte une seule fois
    }
    if (orientation == 4) { // face LUMIÈRES
      face4 = true;
      lastFUNCTION = orientation;
      Serial.println("LIGHTS true");
    }
    if (orientation == 3) { // face OFF
      face3 = true;
      lastFUNCTION = orientation;
      Serial.println("OFF true");
    }
    if (orientation == 5) { // face SON
      face5 = true;
      lastFUNCTION = orientation;
      Serial.println("SOUND true");
    }
    if (orientation == 2) { // face TEMPÉRATURE
      face2 = true;
      lastFUNCTION = orientation;
      Serial.println("TEMPERATURE true");
    }
    if (orientation == 0) { // face MINUTERIE
      face0 = true;
      lastFUNCTION = orientation;
      Serial.println("TIMER true");
      if (KEEPtime == false) { // minuteur activé seulement si 1er cycle ou arrêté
        TIMERmillis = currentMillis; // commencer à compter
      }
    }
    keep = true; // [keep] change pour ne pas réentrer dans cette condition si face ne change pas
  }

  // Condition pour fonction shake: si secoué plus de [SHAKEinterval] temps, face désactivée
  if (CurieIMU.getInterruptStatus(CURIE_IMU_SHOCK) && currentMillis - SHAKEpreviousMillis > SHAKEinterval) {
    Serial.println("SHAKE"); // afficher "SHAKE" si secousse détectée
    // la dernière face activée [lastFUNCTION] est mise à false (fonction désactivée)
    // Désactivation TV
    if (lastFUNCTION == 1) { // face TV
      TVChar.setValue('C'); // C: signal fermeture TV BLE
      Serial.println("TV false - CLOSE");
      face1 = false; // face TV devient false
    }
    // Désactivation LUMIÈRES
    if (lastFUNCTION == 4) { // face LUMIÈRES
      if (central.connected() == true) { // si centrale connectée
        lightsChar.setValue(0); // signal BLE lumières OFF
        digitalWrite(LEDlights, HIGH); // allumer LED jaune pour voir cube dans noir
      }
      Serial.println("LIGHTS false - CLOSE");
      face4 = false; // face LUMIÈRES devient false
    }
    // Face OFF
    if (lastFUNCTION == 3) { // face OFF
      // Face OFF secouée: tout fermer et LED rouge OFF allumée
      digitalWrite(LEDOFF, HIGH); // LED rouge OFF allumée quand cube fermé
      // Fermer toutes fonctions activées:
      // FERMER TV
      TVChar.setValue('C'); // C: signal fermeture TV BLE
      Serial.println("TV false - CLOSE");
      face1 = false;
      // FERMER LUMIÈRES
      Serial.println("LIGHTS false - CLOSE");
      if (central.connected() == true) {
        lightsChar.setValue(0);
        digitalWrite(LEDlights, LOW); // LED lumières éteinte si face OFF secouée
      }
      face4 = false;
      // FERMER SON
      analogWrite(soundLED, LOW); // éteindre LED son
      Serial.println("SOUND false - CLOSE");
      face5 = false;
      // FERMER TEMPÉRATURE
      if (central.connected() == true) {
        digitalWrite(LEDhot, LOW);
        digitalWrite(LEDcold, LOW);
        termoChar.setValue(0); // signal BLE température: 0 = clim off - chauffage off
      }
      Serial.println("TEMPERATURE false - CLOSE");
      face2 = false;
      // FERMER MINUTERIE
      Serial.println("TIMER false - CLOSE");
      lcd.setRGB(0, 0, 0); // LCD RGB éteint
      lcd.clear();
      KEEPtime = false;
      face0 = false;
      // Cube inactif, seule LED OFF active
      Serial.println("OFF false - CLOSE");
      face3 = false; // face OFF devient false
    }
    // Désactivation SON
    if (lastFUNCTION == 5) { // face SON
      analogWrite(soundLED, LOW); // éteindre LED son
      Serial.println("SOUND false - CLOSE");
      face5 = false; // face SON devient false
    }
    // Désactivation TEMPÉRATURE
    if (lastFUNCTION == 2) { // face TEMPÉRATURE
      if (central.connected() == true) {
        digitalWrite(LEDhot, LOW); // éteindre LED température rouge
        digitalWrite(LEDcold, LOW); // éteindre LED température bleue
        termoChar.setValue(0); // signal BLE température: 0 = clim off - chauffage off
      }
      Serial.println("TEMPERATURE false - CLOSE");
      face2 = false; // face TEMPÉRATURE devient false
    }
    // Désactivation MINUTERIE
    if (lastFUNCTION == 0) { // face MINUTERIE
      Serial.println("TIMER false - CLOSE");
      face0 = false; // face MINUTERIE devient false
      // si on secoue le cube pendant que le temps tourne, LCD devient rouge et affiche temps restant
      lcd.setRGB(180, 40, 0); // rétroéclairage RGB rouge
      lcd.clear(); // LCD effacé
      lcd.setCursor(0, 0);
      lcd.print("STOP AT ");
      lcd.setCursor(8, 0);
      lcd.print(SHOWminute); // minutes au moment de la secousse
      lcd.setCursor(9, 0);
      lcd.print(":");
      lcd.setCursor(10, 0);
      lcd.print(SHOWseconds); // secondes au moment de la secousse
      tone(BUZZER,1000,1000); // son court
      delay(2000);
      lcd.clear(); // effacer LCD
      lcd.setRGB(0, 0, 0); // rétroéclairage LCD éteint
      KEEPtime = false; // face MINUTERIE devient false
    }
    SHAKEpreviousMillis = currentMillis; // mémoriser pour calcul [SHAKEinterval]
  }

  // Instructions suivantes exécutées en boucle seulement si face activée
  if (face1 == true) { // face TV
    digitalWrite(LEDOFF, LOW); // si face vraie, LED OFF LOW
    if (central.connected() == true) { // si cube connecté BLE
      char key = keypad.getKey(); // lecture valeur keypad
      if (key && orientation == 1) { // si touche pressée et seulement si face TV haute (évite pressions involontaires)
        if (key == '0') { TVChar.setValue(key); Serial.println(key); }
        if (key == '1') { TVChar.setValue(key); Serial.println(key); }
        if (key == '2') { TVChar.setValue(key); Serial.println(key); }
        if (key == '3') { TVChar.setValue(key); Serial.println(key); }
        if (key == '4') { TVChar.setValue(key); Serial.println(key); }
        if (key == '5') { TVChar.setValue(key); Serial.println(key); }
        if (key == '6') { TVChar.setValue(key); Serial.println(key); }
        if (key == '7') { TVChar.setValue(key); Serial.println(key); }
        if (key == '8') { TVChar.setValue(key); Serial.println(key); }
        if (key == '9') { TVChar.setValue(key); Serial.println(key); }
        if (key == '*') { TVChar.setValue(key); Serial.println(key); }
        if (key == '#') { TVChar.setValue(key); Serial.println(key); }
      }
    }
  }
  if (face4 == true) { // face LUMIÈRES
    digitalWrite(LEDOFF, LOW);
    if (central.connected() == true) {
      lightsChar.setValue(1); // signal BLE lumières ACTIVÉES
      digitalWrite(LEDlights, LOW); // LED jaune éteinte car lumières maison allumées
    }
  }
  if (face3 == true) { // face OFF
    // quand face OFF haute, rien n'est fait
    digitalWrite(LEDOFF, LOW); // LED OFF activée seulement quand cube secoué, donc LOW maintenant
  }
  if (face5 == true) { // face SON
    digitalWrite(LEDOFF, LOW);
    // capteur son activé, luminosité LED régulée par le son
    // code issu exemple régulation luminosité
    long sum = 0;
    for (int i=0; i<32; i++) {
      sum += analogRead(soundSENSOR);
    }
    sum >>= 5;
    brightness = (sum*255)/1024; // calcul valeur luminosité
    analogWrite(soundLED, brightness); // intensité LED verte régulée par bruit
    delay(50); // fin exemple régulation
  }
  if (face2 == true) { // face TEMPÉRATURE
    digitalWrite(LEDOFF, LOW);
    if (central.connected() == true) {
      // lecture température
      int val = analogRead(pinTemp); // valeur analogique
      resistance=(float)(1023-val)*10000/val; // résistance
      temperature=1/(log(resistance/10000)/B+1/298.15)-273.15; // calcul température
      // conditions activation
      if (temperature > tooHot) { // activer clim
        digitalWrite(LEDhot, LOW); // éteindre LED chauffage
        digitalWrite(LEDcold, HIGH); // allumer LED clim
        termoChar.setValue(1); // 1 = clim on - chauffage off
      }
      if (temperature < tooCold) { // activer chauffage
        digitalWrite(LEDhot, HIGH);
        digitalWrite(LEDcold, LOW);
        termoChar.setValue(2); // 2 = clim off - chauffage on
      }
      if (temperature > tooCold && temperature < tooHot) { // température idéale
        digitalWrite(LEDhot, LOW);
        digitalWrite(LEDcold, LOW);
        termoChar.setValue(0); // 0 = clim off - chauffage off
      }
    }
  }
  if (face0 == true) { // face MINUTERIE activée
    digitalWrite(LEDOFF, LOW);
    // calcul temps à afficher
    SHOWmillis = (CountdownInMillis - (currentMillis - TIMERmillis))/1000;
    SHOWminute = SHOWmillis/60; // minutes pour LCD
    SHOWseconds = SHOWmillis%60; // secondes pour LCD
    lcd.setRGB(50, 100, 70); // LCD RGB bleu
    if (prevSHOWsecond != SHOWseconds) { // rafraîchir écran chaque seconde
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("TIMER ");
      lcd.setCursor(7, 0);
      lcd.print(SETminute); // minutes réglées
      lcd.setCursor(8, 0);
      lcd.print(":");
      lcd.setCursor(9, 0);
      lcd.print(SETsecond); // secondes réglées
      lcd.setCursor(0, 1);
      lcd.print(SHOWminute); // minutes restantes
      lcd.setCursor(1, 1);
      lcd.print(":");
      lcd.setCursor(2, 1);
      lcd.print(SHOWseconds); // secondes restantes
      KEEPtime = true;
      prevSHOWsecond = SHOWseconds; // pour rafraîchir chaque seconde
    }
    if (SHOWminute == 0 && SHOWseconds == 0) { // fin compte à rebours
      lcd.clear();
      lcd.setCursor(4, 0);
      lcd.setRGB(180, 40, 0); // LCD RGB rouge
      lcd.print("TIME OUT");
      tone(BUZZER,1000,500); // trois sons
      delay(900);
      tone(BUZZER,1000,500);
      delay(900);
      tone(BUZZER,1000,1000);
      delay(1500);
      lcd.clear(); // effacer et fermer LCD
      lcd.setRGB(0, 0, 0);
      face0 = false; // face MINUTERIE fermée (false)
      KEEPtime = false;
    }
  }
} // fin loop

Pièces personnalisées et boîtiers

Fichier (.dxf) à charger sur votre découpeuse laser. J'ai utilisé du MDF (panneau de fibres à densité moyenne) de 3 mm. Découpez les lignes noires et gravez les lignes rouges. Important : si l'épaisseur de votre matériau diffère, vous devez modifier ce plan.

smart_cube_8sVCflFmhM.dxf

Même fichier mais dans un format différent : .pdf

Schémas

Schéma Fritzing (fils jaunes = composants Grove)

Smart Cube : La télécommande gestuelle nouvelle génération pour la maison connectée

Schéma des connexions sur le Grove Shield

_cI0IwUsPVZ.Base%20shield%20connections

Processus de fabrication

  1. Panneaux solaires : un investissement judicieux pour votre maison
  2. Pourquoi un design légèrement plus grand peut accélérer l'innovation et réduire les risques
  3. Comment la technologie maison intelligente transforme la vie quotidienne
  4. Construire un réseau de capteurs sans fil abordable pour votre maison
  5. Surveiller la température de votre maison avec un tableau de bord Raspberry Pi
  6. Combler le fossé des compétences smart home : pourquoi la Grande-Bretagne traîne l'Europe
  7. Évolution maison intelligente : ce que l'avenir réserve pour le connected living
  8. Sécurité intelligente : stratégies d'experts pour protéger vos appareils IoT domestiques des hackers
  9. Comment renforcer la sécurité de votre maison intelligente : conseils d'experts