PILBI-2013-Team1

De fablab
Révision de 8 août 2017 à 20:32 par Quemav (discussion | contributions) (Découpage laser de la maison)

(diff) ← Version précédente | Voir la version courante (diff) | Version suivante → (diff)
Aller à : navigation, rechercher

Sommaire

Auton'Home

Membres de l'équipe

  • Michel Kuhm (chef de projet)
  • Thibault Vernadat
  • Emilie Libessart
  • Cyril Lorenzetto
  • Philippe Tran
  • Syline Khamphousone
  • Eduardo Leon
  • Davide Tomatis

Contexte général du projet

Le bâtiment intelligent que nous souhaitons mettre en oeuvre, est réfléchi pour un couple hébergeant une personne du 3ème âge. Nous souhaitons assurer une partie de leur sécurité et faciliter leur vie au quotidien grâce à nos dispositifs.

Architecture globale du projet

Ce schéma montre l'organisation du projet.

Architecture.jpg

Construction de la maison et des meubles

Découpage laser de la maison

Pour réaliser la maison, nous avons utilisé la découpeuse laser du FabLab Ensimag qui permet également de réaliser des gravures, en modulant la puissance du laser.

Impression 3D d'un canapé et d'une TV

Ces objets ont été réalisés en utilisant l'imprimante 3D Makerbot Replicator présente dans le FabLab Ensimag. Les fichiers utilisés sont au format stl et ont été trouvés sur le site http://www.thingiverse.com/ .

Intégration des projets dans la maison

Les différents projets ont été intégrés dans la maison. Une pièce a été réservée au dépôt des composants centraux de la maison : arduino, raspberry pi, etc... L'idée de création d'un faux plancher pour intégrer proprement a été envisagée mais pour des raisons techniques, elle n'a pas été retenue (risque de débranchement de fil, facilité de modification de branchements, etc...).

Sous-projets


Caméra de surveillance

Description fonctionnelle

La sécurité dans une maison est un aspect important de la vie quotidienne. Se sentir en sécurité, c’est se sentir bien chez soi et c’est très important pour le bien être des habitants. La maison sera donc équipée d’une caméra de surveillance, simulée par une webcam. Lorsqu’un habitant de la maison le décide, la caméra est mise en marche. A ce moment-là, elle peut détecter la présence d’une personne en sachant s’il y a une différence entre une image de base et les images futures. Si la webcam détecte une différence, alors cela signifie qu’un intrus est entré dans la maison. Un email est alors envoyé aux habitants de la maison avec les images enregistrées pour signaler la présence d’un cambrioleur. De plus, les lumières de la maison se mettent à clignoter pour tenter de dissuader l’individu de commettre son larcin.

Description technique

  • ssmtp Version: 2.64-7
  • mailutils Version: 1:2.99.97-3
  • opencv Version: 2.3.1-11
Configurer SSTMP
sudo (emacs/nano/vim) /etc/ssmtp/ssmtp.conf

Ajouter à la fin du fichier :

AuthUser=ilbi.ensimag@gmail.com
AuthPass=ilbiEnsimag2013
FromLineOverride=YES
mailhub=smtp.gmail.com:587

UseSTARTTLS=YES


rules/demo.rules

Ajouter la règle suivante:


rule Startup
when
System started
then
say("Welcome at openHab!")
executeCommandLine ("/home/pi/opencv/WebcamDetector/motion");
end


WebcamDetector/Makefile
CC=g++
FILE=motion.cpp
EXEC=motion
CFLAGS = `pkg-config --cflags opencv`
LIBS = `pkg-config --libs opencv`


$(EXEC): $(FILE)
$(CC) $(CFLAGS) $(LIBS) -o $(EXEC) $(FILE)


clean:
rm -f $(EXEC)


WebcamDetector/motion.cpp
#include <opencv2/opencv.hpp>
#include <iostream>
#include <time.h>
#include <dirent.h>
#include <sstream>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <cstdlib>
#include <stdio.h>
#include <unistd.h> // usleep
#include <signal.h>

using namespace std;
using namespace cv;

unsigned long microseconds = 40000000; // 40 secondes
bool end = false;

void signalHandler (int signum) {
	cout << "Ctrl + C ... Bye, bye!\n";
	end = true;
}

bool directoryExists( const char* pzPath ) {
	if (pzPath == NULL) 
           return false;
	DIR *pDir;
	bool bExists = false;
	pDir = opendir (pzPath);
	if (pDir != NULL) {
		bExists = true;
		(void) closedir (pDir);
	}
	return bExists;
}

const string saveImg(Mat image, const string DIRECTORY, 
    const string EXTENSION, const char * DIR_FORMAT, 
    const char * FILE_FORMAT){
	// save image
	if (imwrite("/home/pi/Images/alert.jpg", image)) {
		return "/home/pi/Images/alert.jpg";
        } else 
		return NULL;
}

void sendEmail (const string file){
  if (file.empty())
    return;
  const string SUBJECT = "\"ALERT CAMERA\"";
  const string EMAIL = " projet.autonhome@gmail.com ";
  const string COMMAND = "mpack -s " + SUBJECT + " " + 
    " " + file + " " + EMAIL;
  const char* EXEC = COMMAND.c_str(); // pass from string to char *.
  system(EXEC);
}

int main (int argc, char * const argv[]){
   // signal pour kill  
    signal(SIGINT, signalHandler);

    // const
    const string DIR = "/home/pi/Images/";
    const string EXT = ".jpg";
    const int DELAY = 700; // mseconds
    
    string DIR_FORMAT = "%d%h%Y";
    string FILE_FORMAT = DIR_FORMAT + "/" + "%d%h%Y_%H%M%S";
    
    // create all necessary instances
    CvCapture * camera = cvCaptureFromCAM(CV_CAP_ANY);
    Mat original =  cvQueryFrame(camera);
    Mat next_frame = original;
    Mat current_frame = cvQueryFrame(camera);
    Mat prev_frame = cvQueryFrame(camera);
    
    cvtColor(current_frame, current_frame, CV_RGB2GRAY);
    cvtColor(prev_frame, prev_frame, CV_RGB2GRAY);
    cvtColor(next_frame, next_frame, CV_RGB2GRAY);
    
    Mat d1, d2, result;
    int window = 200;
    bool movement;
    const string COMMAND = "/home/pi/openHAB/configurations/scripts/post_update.sh";
    const char* EXEC = COMMAND.c_str(); // pass from string to char *.
    while (!end && true){
        
        movement = false;
        absdiff(next_frame, current_frame, d1);
        absdiff(current_frame, prev_frame, d2);
        bitwise_xor(d1, d2, result);
        
        int middle_y = result.rows/2;
        int middle_x = result.cols/2;
        
        // Center window
        threshold(result, result, 140, 255, CV_THRESH_BINARY);
        for(int i = middle_x-window; i < middle_x+window; i++)
            for(int j = middle_y-window; j < middle_y+window; j++)
                if(result.at<int>(j,i)>0) {
                    movement = true;
                    break;
                }
        
        if(movement==true) {
		cout << "photo prise" << endl;
        	usleep (microseconds);
                sendEmail (saveImg(original,DIR,EXT,DIR_FORMAT.c_str(),FILE_FORMAT.c_str()));
  		system(EXEC);
        }        
        prev_frame = current_frame;
        current_frame = next_frame;
        
        // get image from webcam
        next_frame = cvQueryFrame(camera);
        cvtColor(next_frame, next_frame, CV_RGB2GRAY);
        
        // semi delay and quit when press Q/q
        int key = cvWaitKey (DELAY);
        if (key == 'q' || key == 'Q')
            break;
    }
	return 0;
}

Webographie

http://www.cedricve.me/2013/02/05/opencv-simple-motion-detection/
http://rpi.tnet.com/project/faqs/smtp
http://www.cplusplus.com/reference/cstdlib/system/
http://crunchbang.org/forums/viewtopic.php?id=19337

Lier un appareil à la box Wi-Fi

Description fonctionnelle

Le mot de passe par défaut d’une box Wi-Fi est très généralement à la norme WPA-PSK. Ce qui résulte dans le fait que celui-ci contient un très grand nombre de caractères. De plus, la nécessité de connaitre ce mot de passe n’est qu’épisodique car liée à l’ajout d’un nouveau matériel connecté en Wi-Fi à la box. Cela implique qu’il est très improbable de connaitre ce code par coeur.

Dans de très nombreux cas, la box est disposée dans un endroit pas aisément accessible où il est difficile de la manipuler afin de voir le code inscrit sur l’étiquette. De plus, la longueur de l’étiquette fait qu’il faut soit être à 2 personnes, soit le recopier en plusieurs fois avec les risques d’erreur inhérents. Pour pallier aisément à ce problème, une idée toute simple et directement applicable est de coller un autocollant NFC encodé avec un lien contenant les identifiants par défaut de la box sur celle-ci. Cela permet de voir directement sur son smartphone le code Wi-Fi et de le recopier plus facilement sur son nouveau matériel, ou de se connecter directement au réseau Wi-Fi grâce à l'application Android WifiTap.

Description technique

  1. Télécharger et installer de l'application WifiTap depuis le Google Play Store.
  2. La version est la 1.6 [[1]]
  3. Encoder le tag NFC depuis l'application avec les informations du réseau Wi-Fi demandées.
  4. Badger le tag NFC avec le téléphone et valider.
  5. La connexion avec le réseau Wi-Fi se fait toute seule si le réseau est à proximité.


Enregistrement d'une séquence d'actions liées à un profil utilisateur

Description fonctionnelle

Lorsqu’une personne rentre chez elle, elle effectue très souvent un certain nombre d’actions identiques jour après jour. Dès lors, pourquoi devoir les répéter sans cesse et perdre un certain temps ? Chaque personne n’ayant pas le même comportement, les actions doivent être liées à des profils utilisateurs.


L’idée est d’avoir un lecteur NFC / RFID près de l’entrée. Chaque habitant dispose d’une puce NFC / RFID contenant son profil personnel d’actions à effectuer. Ainsi, lorsqu’elle rentre, la personne aura juste à passer sa puce devant le lecteur NFC / RFID afin d’activer les actions prédéfinies en rapport avec son profil personnel. La puce étant très peu encombrante, on peut très bien imaginer la coller directement sur son téléphone ou la ranger dans son portefeuille.


Les différentes actions dépendraient donc du profil et pourraient être :
- Allumer / éteindre la lumière du couloir

- Allumer / éteindre la caméra de vidéosurveillance

Description technique

Installation

Installation Library : libusb
Version: 0.1-4
apt-get install libusb-dev libusb++-0.1-4c2


Package : libccid
Version: 1.4.7-1
apt-get install libccid


Package : pcsc-lite
Version: 1.8.4-1+deb7u1
apt-get install pcscd


Package : libpcsclite1
Version: 1.8.4-1+deb7u1
apt-get install libpcsclite1


Library : libpcsclite-dev
Version: 1.8.4-1+deb7u1


apt-get install libpcsclite-dev


Packages : nfc-tools (pour installer nfc-mfultralight)


wget http://libnfc.googlecode.com/files/1.7.0.tar.bz2
tar -xjf
cd lib...
./configure -prefix=/usr
make all
sudo make install

Pour ecrire dans un tag

sudo nfc-mfultralight w dump.mfd
NFC device: 	/ CCID USB Reader opened
Found MIFARE Ultralight card with UID: 040c82da4b2880
Write OTP bytes ? [yN] y
Write Lock bytes ? [yN] y
Write UID bytes (only for special writeable UID cards) ? [yN] N


Note : le fichier dump.mfd (binaire) doit avoir l'entete du logiciel nfc-mfultralight. On a utilisé Emacs pour éditer le fichier binaire avec le mode hex (M-x hexl-mode)


Script pour lire le tag et envoyer les commands vers openHAB(home/pi/sequenceActions/script.sh)

#!/bin/bash


echo "Script pour lire le tag dans le repertoire sequenceActions"

while true
do
# error code du command pour lire le tag
out=1
while [ $out -ne 0 ]
do
# s'il n'y a pas un tag, le logiciel nfc-mfultralight va envoyer
# un code d'erreur 1, donc on lit pendant qu'il n'y a rien
sudo nfc-mfultralight r dump.mfd  > /dev/null 2>&1
out=$?
# on dort le script pour sauvagarder un peu le cpu
sleep 5
done

# tuer la camera
sudo /home/pi/openHAB/configurations/scripts/kill_motion.script
wget "http://129.88.242.54:9999/CMD?Camera=OFF"

# contenu mis par la commande:  nfc-mfultralight r dump.mfd
infoTag=`cat dump.mfd`


# prendre le contenu entre []
user=$(echo $infoTag | cut -d "[" -f2 | cut -d "]" -f1)


# affiche le contenu du tag sans les entetes binaries, affiche le contenu entre []
echo $user


# commandes pour openHAB
if [[ $user == "toto" ]]
then
        wget "http://129.88.242.54:9999/CMD?Light=ON"
elif [[ $user == "tata" ]]
then
        wget "http://129.88.242.54:9999/CMD?Light=OFF"
        wget "http://129.88.242.54:9999/CMD?Camera=ON"
fi


# supprimer fichiers crees par wget, s'il y en a
rm CMD\?* > /dev/null 2>&1
done


Webographie
http://www.gnu.org/software/emacs/manual/html_node/emacs/Editing-Binary-Files.html
http://nfc-tools.org/index.php?title=Libnfc#Debian_.2F_Ubuntu
http://www.hardill.me.uk/wordpress/tag/linux/
http://code.google.com/p/openhab-samples/wiki/Tricks#Use_URL_to_manipulate_items
https://github.com/mstorsjo/fdk-aac/issues/6

Allumage automatique de la lampe à l'entrée de la maison

Description fonctionnelle

Ce scénario a pour objectif d’éviter d’allumer la lumière sous le porche de l’entrée de sa maison toute la journée, alors que c’est juste utile lorsque nous rentrons le soir pour pouvoir déverrouiller la porte avec notre clef.

L’idée est donc de placer un capteur d’ultrasons et un capteur de luminosité juste à l’entrée sous le porche. Ces deux capteurs seront couplés, ainsi si le capteur de luminosité détecte la tombée de la nuit et que le capteur d’ultrasons détecte un mouvement alors la lumière de l’entrée s’allumera. Nous aurons donc économisé de l’énergie qui aurait été gaspillée inutilement dans la journée.

Le principe du capteur à ultrason est d’envoyer une onde à l’aide d’un émetteur et de chronométrer le temps que met l’onde à revenir sur le récepteur placé à côté de l’émetteur. Ainsi connaissant la vitesse du son et la distance du capteur au mur (ici le sol de la porte) nous pouvons facilement calculer la distance de l’émetteur à l’obstacle. Nous aurons une distance initiale et si jamais cette dernière change alors cela se traduit par le fait qu’une personne s’est postée devant la porte, d’où l’activation de l’éclairage de l’entrée de la maison. Bien entendu au bout d’un certain temps la lumière s’éteint toute seule si jamais le capteur de mouvement ne détecte pas de nouvelles perturbations (environ 10s).


Description technique


Pour réaliser ce montage, nous avons utilisé un capteur de lumière, un capteur infrarouge et une LED. Le code source utilisé avec un Arduino Uno est le suivant:

int photocellPin = 1; // The cell and 2K pulldown are connected to A1
int photocellReading; // The analog reading from the analog resistor divider

const int outp = 12; // Power for the IR sensor
const int outp_led = 13; // Power for lamp
const int sensIR = 5; // Sensor IR input

void setup(void)
{
  pinMode(outp, OUTPUT);
  pinMode(outp_led, OUTPUT);
  pinMode(sensIR, INPUT_PULLUP);
  Serial.begin(9600);
}

void lux_captor(void)
{
  photocellReading = analogRead(photocellPin);
  Serial.print("Analog reading = ");
  Serial.print(photocellReading);

  // We have different cases depending on what we read (lux)
  if (photocellReading < 65) {
    Serial.println(" - Sombre");
    digitalWrite(outp, HIGH);
    if (digitalRead(sensIR) == false) {
      Serial.println("Detected");
      digitalWrite(outp_led, HIGH);
      delay(5000);
      digitalWrite(outp_led, LOW);
    }
  } else {
    Serial.println(" - Lumineux");
    digitalWrite(outp, LOW);
  }
  delay(1000);
}

void loop(void)
{
  lux_captor();
}

Allumage automatique de télévision

Description fonctionnelle

Lorsqu’on s’assoit dans le canapé du salon, c’est généralement pour regarder la télévison. De ce fait, pour ne pas avoir à chercher la télécommande, nous avons mis en place un détecteur de pression. Lorsque l’utilisateur s’assoit dans le canapé, le capteur de pression envoie une tension plus forte à l’arduino. Celui-ci va allumer la télévision. Tant que l’utilisateur ne se relève pas, la tension entre le capteur et l’arduino ne change pas. Lorsque l’utilisateur se lève, l’arduino attend 10 minutes avant de désactiver d’éteindre la télévision. Si avant la fin des 10 minutes l’utilisateur se rassoit dans le canapé, alors la télévision continuera de fonctionner normalement.

Description technique

Pour réaliser ce montage, nous avons utilisé un capteur de pression, un potentiomètre ainsi qu'une LED simulant l'allumage de la TV. Le code source utilisé avec un Arduino Uno est le suivant:

#include <IRremote.h>

#define INTERVAL 250 // interval between loop iteration
#define RELAY_1 2 // relay pin (or led if no relay)
#define ForceSensorPin A0 //analogic force sensor pin

IRsend irsend;
int Senval=0;

int TimerStandUp=10000/INTERVAL;

int counter = 0;
int allume = 0;
int counterParkage = 0;

void setup()
{
	Serial.begin(115200);
	pinMode(RELAY_1, OUTPUT);  
	digitalWrite(RELAY_1, LOW); //initialisation
}
void loop()
{
	sofaForceSensor();
	delay(INTERVAL);
}
void sofaForceSensor() {
	Senval=analogRead(ForceSensorPin);
	if( Senval < 512 ) {
		if( allume == 1 ) {
			//Serial.println("augmentation compteur");
			counter++;
			if( counter >= TimerStandUp ) {
				// signal exit pour sortir de l'écran de veille
				irsend.sendNEC(0x1FE609F, 32);
				// signal on/off
				irsend.sendNEC(0x1FE7887, 32);
				//Serial.println("extinction");
				counter = 0;
				allume = 0;
				digitalWrite(RELAY_1, LOW);
			}
		} else
			Serial.println("sofa=0");
	} else {
		counter = 0;
		if( allume == 0 ) {
			// signal on/off
 			irsend.sendNEC(0x1FE7887, 32);
			//Serial.println("allumage");
			allume = 1;
			digitalWrite(RELAY_1, HIGH);
    	}
		Serial.println("sofa=1");
    }
}

Contrôle des lumières et de l'alarme via smartphone

Description fonctionnelle

La démocratisation des smartphones permet désormais d’utiliser son téléphone en tant que télécommande « universelle ». Une fois installé dans son sofa pour regarder un film, l’utilisateur peut utiliser une application dédiée / le centre de contrôle de OpenHAB pour éteindre ou rallumer les lumières du salon à sa convenance. De même, une fois qu’il sera dans son lit, il pourra activer l’alarme de son habitation grâce à son téléphone, puis éteindre les lumières de sa chambre. Au passage, cela lui permet de visualiser en un clin d’œil si tout est bien fermé ou éteint dans la maison avant de s’endormir.

Description technique

Arduino vers OpenHAB

Écrire dans un fichier arduinoVersOpenHAB.ino :

 String inputString = "";         // a string to hold incoming data
 boolean stringComplete = false;  // whether the string is complete
 int led = 13;
 int alarme = 8;
 
 void setup() {
   // initialize serial:
   Serial.begin(9600);
   pinMode(led, OUTPUT);  
   pinMode(alarme, OUTPUT);  
   pinMode(boutonPoussoir, INPUT);
   // reserve 200 bytes for the inputString:
   inputString.reserve(200);
   Serial.println("RAS");
 }
 
 void loop() {
   if (stringComplete) {
     if (inputString.equals("Lights=ON\n")){
       Serial.println("LightsOnOk");
         digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
     }
     if (inputString.equals("Lights=OFF\n")){
         digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
               Serial.println("LightsOffOk");
     }
     if (inputString.equals("Alarm=ON\n")){
         Serial.println("Alarm=OnOk");
         for (int i=0; i<10 ; i++){
           digitalWrite(alarme, HIGH);
           delay(300);
           digitalWrite(alarme, LOW);
           delay(300);
         }
        Serial.println("Alarm=OffOk");
     }
     if (inputString.equals("OutsideLight=ON\n")){
         Serial.println("OutsideLight=OnOk");
         for (int i=0; i<10 ; i++){
           digitalWrite(alarme, HIGH);
           delay(300);
           digitalWrite(alarme, LOW);
           delay(300);
         }
         digitalWrite(alarme, HIGH);
         delay(9000);
         delay(6000);
         for (int i=0; i<10 ; i++){
           digitalWrite(alarme, HIGH);
           delay(300);
           digitalWrite(alarme, LOW);
           delay(300);
         }
         Serial.println("OutsideLight=OffOk");
     }
     
     // clear the string:
    inputString = "";
    stringComplete = false;
   }
 }
 
 /*
   SerialEvent occurs whenever a new data comes in the
  hardware serial RX.  This routine is run between each
  time loop() runs, so using delay inside loop can delay
  response.  Multiple bytes of data may be available.
  */
 void serialEvent() {
   while (Serial.available()) {
     // get the new byte:
     char inChar = (char)Serial.read(); 
     // add it to the inputString:
     inputString += inChar;
     // if the incoming character is a newline, set a flag
     // so the main loop can do something about it:
     if (inChar == '\n') {
       stringComplete = true;
     } 
   }
 }

Code de OpenHAB, à rajouter à la fin du fichier demo.items :

 /* Autonom items */
 Switch Light    "Light"                 (All)
 Switch Alarm    "Alarm"                 (All)
 
 /* Arduinos */
 String Arduino0              "Arduino 0 [%s]"  (All)    { serial="/dev/ttyACM0"}

Rules OpenHAB à rajouter dans le fichier demo.rules :

rule "Switch Lights off"
when
        Item Light received command OFF
then
        logInfo("SwitchLightsOff","Switching off")
        sendCommand(Arduino0, "Lights=OFF\n")
end


rule "Switch Lights on"
when
        Item Light received command ON
then
        logInfo("SwitchLightsOn","Switching on")
        sendCommand(Arduino0, "Lights=ON\n")
end


rule "Switch Alarm on"
when
        Item Alarm received command ON
then
        logInfo("SwitchAlarmOn", "Switching on")
        sendCommand(Arduino0, "Alarm=ON\n")
end

Ouverture automatisée d'une porte de garage

Description fonctionnelle

Quand on arrive en voiture devant le garage on allume le transmetteur présent à bord de la voiture qui commence à envoyer le mot de passe pour l’ouverture du garage. Un transmetteur positionné à l’intérieur de la maison reçoit le mot de passe et vérifie qu’il soit bon. Dans ce cas la porte du garage s’ouvre et la voiture peut rentrer et se garer.

Description technique

  1. Utilisation de bon pinout pour brancher le NRF24L01 sur les deux Arduino
  2. Téléversement du bon code sur les deux Arduino

Schema connections Arduino - NRF

___________________

Voici le code source de ce projet :

Transmetteur:

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#define  DIM  6
int i;
char alfa[DIM] = "Home#";
  
void setup(){
    Serial.begin(9600);
    i=0;
    Mirf.spi = &MirfHardwareSpi;
    Mirf.init();
    Mirf.setRADDR((byte *)"clie1");
    Mirf.payload = sizeof(char);
    Mirf.config();
}
void loop(){
    char temp = alfa[i];
    Mirf.setTADDR((byte *)"serv1");
    Mirf.send((byte *)&temp);
    while(Mirf.isSending()){}
    while(!Mirf.dataReady()){}
    Mirf.getData((byte *) &temp);
    if(temp=='o'){
        setup();
    }
    i++;
    i=i%(DIM-1);
}

Recepteur:

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#define  DIM 6


char beta[DIM*2+1];
char alfa[DIM] = "Home";
int i,j;

int cerca(){
  int count=0;
  int k=0;
  int j=0;
  int part=0;
  int flag=0;
  char conf[DIM]; 
  for(k=0;k<DIM;k++) conf[k]=0;
  for(j=0;j<(DIM*2-1);j++){
    if(beta[j]=='#'){
      count++;
      if(count==1){
        part=j+1;
      }
      if(count==2){
        for(k=0;k<j-part;k++){
          conf[k]=beta[part+k];
          if(conf[k]!=alfa[k]){
            flag=1;
            break;
          }
        }
      }
      if(flag==1) break;
    }
  }
  if(flag==0) return 1;
  else        return 0;
}
void setup(){
  Serial.begin(9600);
  i=0;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"serv1");
  Mirf.payload = sizeof(char);
  Mirf.config();
}
void loop(){
  int flag=0;  
  char temp;
  char invio = 's';
  if(!Mirf.isSending() && Mirf.dataReady()){
    Mirf.getData((byte *) &temp);    
    beta[i]=temp;
    Mirf.setTADDR((byte *)"clie1");
    Mirf.send((byte *) &invio);
    i++;
    if(i==(DIM*2-1)){
      int res = cerca();
      if(res == 1){
        Serial.println("GarageLight=ON");
        for(j=0;j<6;j++)
          delay(1000);
        delay(9000);
        delay(6000);
        for(j=0;j<6;j++)
          delay(1000);
        Serial.println("GarageLight=OFF");
        Serial.println("Led off: garage closed...");
        invio='o';
        Mirf.send((byte *) &invio);
        delay(1000);
        flag=1;
        setup();
      }
    }
    if(flag==0)
      i=i%(DIM*2-1);
  }
}

Parkage assisté

Description fonctionnelle

Un capteur ultrason est placé au fond du garage pour calculer la distance à laquelle se trouve la voiture qui est en train de se garer. Une LED est également placée sur la paroi du fond du garage pour signaler le rapprochement de la voiture. Quand le garage est ouvert l’utilisateur commence à entrer lentement avec sa voiture jusqu’à ce que le capteur ultrason détecte qu’il se trouve à une certaine distance. Lorsque l'utilisateur se rapproche du fond du garage, la LED clignote de plus en plus lentement puis lorsque la voiture est placée correctement, la LED sur la paroi reste allumée pour signaler au conducteur qu’il l’a garée correctement et qu’il peut s’arrêter.

Description technique

Nous avons pour cette partie utilisé un capteur ultrason, ainsi qu'une LED. Voici le code source de ce projet :

#include <NewPing.h>

#define INTERVAL 250 // interval between loop iteration
#define MAX_DISTANCE 50 // max distance in cm to ping w/ ultasound sensor
#define ULTRA_CAR_PARKAGE_TRIGGER_PIN 6 // car parkage ultrasonic sensor trigger pin
#define ULTRA_CAR_PARKAGE_ECHO_PIN 7 // car parkage ultrasonic sensor echo pin
#define CAR_PARKAGE_LED_PIN 8 // car parkage led
#define CAR_PARKAGE_BASE 100 //variable used internally for the led blinking frequency

int Senval=0;
NewPing carSonar = NewPing(ULTRA_CAR_PARKAGE_TRIGGER_PIN, ULTRA_CAR_PARKAGE_ECHO_PIN, MAX_DISTANCE);
int currentSensorDistance;
int counter = 0;
int counterParkage = 0;

void setup()
{
	Serial.begin(115200);
	pinMode(CAR_PARKAGE_LED_PIN, OUTPUT);
}
void loop()
{
	carParkageUltrasound();
	delay(INTERVAL);
}
void carParkageUltrasound() {
	carSonar.timer_stop();
	carSonar.ping_timer(echoCheck);
	Serial.print("parkage=");
	Serial.println(ultrasoundRead());
	if( ultrasoundRead()  < 20 && ultrasoundRead() > 0 ) {
		counterParkage++;
		if( counterParkage >= CAR_PARKAGE_BASE ) 
			counterParkage = 0;
		if( ultrasoundRead() <= 5 && ultrasoundRead > 0) {
			digitalWrite(CAR_PARKAGE_LED_PIN, HIGH);   // turn the LED on (HIGH is the voltage level)
		} else {
		        int nbBlink = 20-ultrasoundRead();
		        for( int i = 0; i < nbBlink; i++ ) {
		          digitalWrite(CAR_PARKAGE_LED_PIN, HIGH);   // turn the LED on (HIGH is the voltage level)
		          delay(20);               // wait for a second
		          digitalWrite(CAR_PARKAGE_LED_PIN, LOW);    // turn the LED off by making the voltage LOW
		        }
		}
	} else
		digitalWrite(CAR_PARKAGE_LED_PIN, LOW);    // turn the LED off by making the voltage LOW
}
int ultrasoundRead() {
	return currentSensorDistance;
}
// If ping received, set the sensor distance to array.
void echoCheck() {
	if( carSonar.check_timer() )
		currentSensorDistance = carSonar.ping_result / US_ROUNDTRIP_CM;
}


Collier d'assistance pour personne âgée

Description fonctionnelle

Les personnes âgées sont parfois fragiles et méritent toute notre attention. Lorsqu’elles ont un problème ou qu’elles chutent et sont dans l’incapacité de se relever, elles ont besoin d’un système leur permettant d’avertir un proche, ou encore les urgences. Dans cette optique, nous développons un collier qui utilise un bouton poussoir ainsi qu’un arduino couplé avec le RaspberryPi via OpenHAB afin de pouvoir résoudre ce problème. La personne âgée n’aurait donc plus qu’à appuyer sur le bouton afin de prévenir la personne à contacter en cas d’urgence. Un mail sera envoyé à cette personne ainsi qu’une notification sur son portable.

Description technique

Préparation du montage électrique

  • Un bouton poussoir
  • Une résistance de quelques KOhms. (nous avons pris 10 KOhms).
  • Une led pour tester est un plus.

Code arduino

 void setup() {
   Serial.begin(9600); // initialise la communication série
   // vérifier que le débit utilisé est le même dans le Terminal Série
   pinMode(2, INPUT); // met la broche 2 en sortie
   Serial.println(0);
 }


 void loop() {
   int sensorValue = digitalRead(2); // lit l'état de la broche 2 et met le résultat dans la variable
   //Serial.println(sensorValue, DEC); // affiche la variable dans le Terminal Serie
   if (sensorValue == 1){
      Serial.println(1); 
      delay(10000);
      Serial.println(0);
   }    
 }


Le fichier code source est accessible à l'URL suivante : http://fablab.ensimag.fr/images/5/56/BoutonPoussoir.ino.zip


Configuration de openHAB

Remarques préliminaires:

- Initialement, nous avons testé de faire fonctionner notre code OpenHAB avec javaSE 1.8.0. Cependant, les objects ‘Item’ du fichier configurations/demo.items n’étaient pas chargés au démarrage d’openHAB, et certaines méthodes natives d’openHAB, comme sendEmail que nous utilisons pour notifier une action, n’étaient pas chargées. Nous avons cependant réussi à faire fonctionner notre code en passant à la version 1.7.40 de java, version ARM avec calcul flottants matériel. - Une deuxième remarque est que si on lance openHAB avec le script start_debug.sh, le code ne fonctionne pas (même avec java 1.7.40), alors qu’il fonctionne dans la version standard start.sh. - Nous avons aussi du modifier certains paramètres au lancement de openHAB dans la configuration de java. Nos options sont les suivantes:

java -Xmx140m -Xms140m -Djava.rmi.server.hostname=192.168.0.20 -Dcom.sun.management.jmxremote.port=9898
-Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
-Dosgi.clean=true -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Djetty.port=$HTTP_PORT
-Djetty.port.ssl=$HTTPS_PORT -Djetty.home=. -Dlogback.configurationFile=configurations/logback.xml
-Dfelix.fileinstall.dir=addons -Djava.library.path=lib -Djava.security.auth.login.config=./etc/login.conf
-Dorg.quartz.properties=./etc/quartz.properties -Dequinox.ds.block_timeout=240000
-Dequinox.scr.waitTimeOnBlock=60000 -Dfelix.fileinstall.active.level=4 -Djava.awt.headless=true
-jar $cp $* -console 

Nous utilisons openHAB 1.3.1.

Modifications des fichiers de conf de openHAB:

Pour la suite, on se place dans le dossier ‘configurations’ de openHAB.

openhab.cfg

Modifier la partie email de la façon suivante :

 ######################## Mail Action configuration ####################################
#
# The SMTP server hostname, e.g. "smtp.gmail.com"
 mail:hostname=smtp.gmail.com
# the SMTP port to use (optional, defaults to 25 (resp. 587 for TLS))
 mail:port=587
# the username and password if the SMTP server requires authentication
 mail:username=projet.autonhome@gmail.com
 mail:password=ilbi2013
# The email address to use for sending mails
 mail:from=projet.autonhome@gmail.com
# set to "true", if TLS should be used for the connection
# (optional, defaults to false)
 mail:tls=true
# set to "true", if POP before SMTP (another authentication mechanism)
# should be enabled. Username and Password are taken from the above
# configuration (optional, default to false)
#mail:popbeforesmtp=


sitemaps/demo.sitemap

Ajouter une frame de la facon suivante:

Frame label="BoutonPoussoir" {
		Text item=BoutonPoussoir
}

items/demo.items

Ajouter un item de la facon suivante, ou ‘/dev/ttyACM0’ est votre numéro de device pour l’arduino (varie en fonction de l’OS, et de vos périphériques USB)

String BoutonPoussoir              "Bouton Poussoir [%s]"  (All)    { serial="/dev/ttyACM0" }

rules/demo.rules

Ajouter la règle suivante:

 rule "SendEmail"
   when Item Arduino0 received update then 
      logInfo("SendMail", "Arduino0 state: " + Arduino0.state) 
      if (Arduino0.state.toString.contains("URGENCE")){ 
          postUpdate(Collier, ON) 
          notifyMyAndroid("c2c02c2a965007853cf787bb2b008ebf8aa7797a8aff6775","Urgent","Push button pressed") 
          logInfo("SendMail", "Phone notified!") 
          executeCommandLine ("/home/pi/openHAB/configurations/scripts/kill_motion.script") 
          logInfo("SendMail", "Motion program killed!")Thread::sleep(30000) 
          executeCommandLine ("/home/pi/opencv/WebcamDetectorPhoto/photo") 
          Thread::sleep(30000) 
          logInfo("SendMail", "Photo taken!") 
          logInfo("SendMail", "Mail preparing...") 
          sendMail("projet.autonhome@gmail.com","Your grandma fell",
                "Hey dear, your grandma fell. Better do something about it. Cheers", "http://129.88.242.54:9999/images/photo.jpg")
          logInfo("SendMail", "Mail sent!") 
          if (Camera.state.toString.contains("ON")) { 
             executeCommandLine ("/home/pi/opencv/WebcamDetector/motion") 
             logInfo("SendMail", "Motion program restarted!") 
          } 
       } 
       if (Arduino0.state.toString.contains("RAS")){ 
          postUpdate(Collier, OFF) 
       } 
       if (Arduino0.state.toString.contains("Alarm=OffOk")){ 
          postUpdate(Alarm, OFF) 
       } 
    end

Pour la fonction notifyMyAndroid, les paramètres sont dans l’ordre: votre clé API de votre compte notifymyandroid.com (s’inscrire pour l’obtenir), la priorité, le message associé à la notification. Pour sendMail: email source, objet de l’email, contenu de l’email.


Ajouter les jar dans le dossier addons de openHAB

- org.openhab.action.mail-1.3.1.jar
- org.openhab.action.nma-1.3.1.jar

Interactions entre les projets

L’alarme de la maison sera automatiquement désactivée lorsque l’utilisateur ouvrira la porte de son garage ou lorsqu’il s’identifiera quand il rentrera dans sa maison. En outre lorsqu’une personne utilisera le système d’assistance personnelle, en plus du mail d’urgence, une photo prise par la caméra de surveillance sera envoyée à la personne à contacter en cas d’urgence. Ces interactions sont gérées par des rules openHAB.

Librairies Arduino utilisées

Fichier:Arduino libraries.zip

Affiche & Flyer

Slides soutenance

Fichier:Gr1 soutenance.pdf

Cahier des charges

Fichier:Gr1 cahierdescharges.pdf

Manuel utilisateur

Fichier:Gr1 manuelutilisateur.pdf

Code source

Fichier:Gr1 arduino.tar.gz

Vidéos

Fichier:Gr1 videos.zip