Domotique

De Wiki L.A.B
Aller à : navigation, rechercher

Le projet "Domotique" du LAB doit nous permettre de construire nos propres "Systèmes domotiques" en utilisant des briques matérielles et logicielles existantes ou conçues au LAB.

Principes

Protocoles

Protocole MQTT

Exemple de mise en œuvre du Protocole MQTT

Ce premier exemple montre comment mettre en œuvre le protocole MQTT sur un réseau IP :

  • Un premier arduino capte des données et les émet sur le réseau.
  • Un second arduino reçoit les données transmises et les affiche.
  • Un raspberry pi sert de broker.

Montage Démo MQTT

Broker (Raspberry Pi)


Installation de Mosquitto MQTT broker sur Raspberry Pi (RP)

Installation Avahi Daemon :

sudo apt-get install avahi-daemon avahi-discover libnss-mdns

Installation Mosquiitto MQTT Broker :

sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
sudo apt-get update 
sudo apt-get install mosquitto python-mosquitto
sudo apt-get install mosquitto-clients


Pour donner une adresse IP (192.168.0.9) au RP (ne sera valable que provisoirement) :

sudo ip addr add 192.168.0.9/24 dev eth0


Pour fixer l’adresse IP statique (sera valable définitivement) :

sudo nano /etc/network/interfaces


remplacer :
iface eth0 inet dhcp


par :
iface eth0 inet static
    	address 192.168.0.9
    	netmask 255.255.255.0
    	network 192.168.0.0


Pour vérifier l’adresse IP :

ip addr


Pour visualiser les données dans la console :

mosquitto_sub -t "#" -v


Pour prendre la main depuis un PC (avahi daemon doit être installé sur RP) :

Utiliser PuTTy :
entrer l’adresse IP (192.168.0.9)
login : pi
password : raspberry



Emetteur (arduino + shield Ethernet + DHT 11
Matériel
  • Arduino Uno
  • Shield Ethernet (avec chip W5100)
  • Capteur DHT11 ou DHT22
  • Résistance 4,7kΩ (ou 10kΩ) 1/4W (si besoin)


Montage

Montage DHT11
Remarque : le shield Ethernet, n'est pas représenté ici.

Programme

Voici le programme qu'il faut éditer dans l'IDE Arduino, puis compiler et charger dans la carte Arduino.
Il utilise la librairie DHT. Pour télécharger la librairie : DHT
Il faut également télécharger la librairie MQTTClient : MQTTClient

/*******************************************************************************
 * Copyleft (c) 2014 LabAixBidouille
 *
 * Contributors:
 *    Nicolas MULLER & Guy SINNIG
 *******************************************************************************/

#define MQTTCLIENT_QOS2 1

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetStack.h>
#include <Countdown.h>
#include <MQTTClient.h>
#include <DHT.h>

#define DHTPIN 2 // broche de branchement (entrée) avec résistance de 4,7 ou 10k
#define DHTTYPE DHT11 //#define DHTTYPE DHT22 (pour un capteur DHT22)

DHT dht(DHTPIN, DHTTYPE);

float h = 0;
float t = 0;

/**************************
 * CONFIGURATION
 **************************/

// IP for the Broker
char hostname[] = "192.168.0.9";

// The port for the broker
int port = 1883;

// The topic where to publish the message
const char* topicTemperature = "LABdemo/temperature";
const char* topicHumidite = "LABdemo/humidite";

// replace with your device's MAC
byte mac[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };  
byte ip[] = { 192,168,0,28 }; // adresse IP arduino émetteur

/**************************
 * DECLARATIONS
 **************************/
 
int compteur = 0;
int temperature = 0;
char printbuf[100];

// Send and receive QoS  message
char buf[200];

EthernetStack ipstack;
MQTT::Message message;
MQTT::Client<EthernetStack, Countdown> client = MQTT::Client<EthernetStack, Countdown>(ipstack);

/**************************
 * METHODES
 **************************/
 
// Connection to the Broker MQTT
void connect()
{
  sprintf(printbuf, "Connecting to %s:%d\n", hostname, port);
  Serial.print(printbuf);
  int rc = ipstack.connect(hostname, port);
  if (rc != 1)
  {
    sprintf(printbuf, "rc from TCP connect is %d\n", rc);
    Serial.print(printbuf);
  }
 
  Serial.println("MQTT connecting");
  MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       
  data.MQTTVersion = 3;
  data.clientID.cstring = (char*)"arduino-sample";
  rc = client.connect(data);
  if (rc != 0)
  {  
    sprintf(printbuf, "rc from MQTT connect is %d\n", rc);
    Serial.print(printbuf);
  }
  Serial.println("MQTT connected");  
}

/**************************
 * SETUP ARDUINO
 **************************/
 
void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac,ip);
  Serial.println("MQTT demo Temp");
  connect();
  dht.begin();
}

/**************************
 * LOOP ARDUINO
 **************************/

// Push la temperature sur le topic adequate
void pushData(int valeur, const char *topic)
{
     sprintf(buf, "%d", valeur);
     Serial.println(buf);
     message.retained = false;
     message.dup = false;
     message.payload = (void*)buf;
     message.qos = MQTT::QOS1;
     message.payloadlen = strlen(buf)+1;
     int rc = client.publish(topic, message);
}

void loop()
{
  if (!client.isConnected()) connect();
  h = dht.readHumidity();
  t = dht.readTemperature();
  if (isnan(t) || isnan(h))
  {
    Serial.println( "Lecture impossible !");
  } 
  int temperature = t;
  int humidite = h;
  pushData(temperature, topicTemperature);
  pushData(humidite, topicHumidite);
  delay(1000);
}
Récepteur (arduino + shield Ethernet + shield LCD)
Matériel
  • Arduino Uno
  • Shield Ethernet (avec chip W5100)
  • Shield LCD (DFR0009)


Montage

Uniquement composé de l'Arduino et des 2 shields

Programme

Voici le programme qu'il faut éditer dans l'IDE Arduino, puis compiler et charger dans la carte Arduino. Il utilise la librairie LiquidCrystal (fournie en standard) .

/*******************************************************************************
 * Copyleft (c) 2014 LabAixBidouille
 *
 * Contributors:
 *    Nicolas MULLER & Guy SINNIG
 *******************************************************************************/

#define MQTTCLIENT_QOS2 1

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetStack.h>
#include <Countdown.h>
#include <MQTTClient.h>
#include <LiquidCrystal.h>

/**************************
 * CONFIGURATION
 **************************/

// IP for the Broker
char hostname[] = "192.168.0.9";

// The port for the broker
int port = 1883;

// The topic where to publish the message
const char* topicTemperature = "LABdemo/temperature";
const char* topicHumidite = "LABdemo/humidite";

byte mac[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x54 };  // adresse MAC arduino
byte ip[] = { 192,168,0,27 }; // adresse IP arduino récepteur

// broches shield LCD DFRobot DFR0009
const int RS=8; 
const int E=9;

const int D4=4;
const int D5=5;
const int D6=6;
const int D7=7;

// Variable utile pour ne pas rafraichir 
// inutilement l'afficheur
int previousTemperature = -1;
int previousHumidite = -1;

LiquidCrystal lcd(RS, E, D4, D5, D6, D7);// initialisation LCD en mode 4 bits 

/**************************
 * DECLARATIONS
 **************************/

char printbuf[100];
int arrivedcount = 0;
 
EthernetStack ipstack;
MQTT::Message message;
MQTT::Client<EthernetStack, Countdown> client = MQTT::Client<EthernetStack, Countdown>(ipstack);

/**************************
 * PARTIE MQTT SUBSCRIBE
 **************************/

void messageTempArrived(MQTT::MessageData& md)
{
  MQTT::Message &message = md.message;
  
  sprintf(printbuf, "Message %d arrived: qos %d, retained %d, dup %d, packetid %d\n", 
                ++arrivedcount, message.qos, message.retained, message.dup, message.id);
  Serial.print(printbuf);
  sprintf(printbuf, "Payload %s\n", (char*)message.payload);
  Serial.print(printbuf);
  lcd.setCursor(0, 1) ; // positionne le curseur à l'endroit voulu (colonne, ligne) (1ère colonne =0, 2ème ligne=1) 
  lcd.print((char*)message.payload);
  lcd.setCursor(3, 1) ;// positionne le curseur à : 15ème colonne =14, 2ème ligne=1
  lcd.print("  ");
  lcd.setCursor(3, 1) ;// positionne le curseur à : 15ème colonne =14, 2ème ligne=1
  lcd.write(0xDF); // affichage °
  lcd.print("C");  
}

void messageHumiArrived(MQTT::MessageData& md)
{
  MQTT::Message &message = md.message;
  
  sprintf(printbuf, "Message %d arrived: qos %d, retained %d, dup %d, packetid %d\n", 
                ++arrivedcount, message.qos, message.retained, message.dup, message.id);
  Serial.print(printbuf);
  sprintf(printbuf, "Payload %s\n", (char*)message.payload);
  Serial.print(printbuf);
  lcd.setCursor(11, 1) ; // positionne le curseur à l'endroit voulu (colonne, ligne) (1ère colonne =0, 2ème ligne=1) 
  lcd.print((char*)message.payload);
  lcd.setCursor(14, 1) ;// positionne le curseur à : 15ème colonne =14, 2ème ligne=1
  lcd.print("%");  

}

/**************************
 * METHODES
 **************************/
 
// Connection to the Broker MQTT
void connect()
{
  sprintf(printbuf, "Connecting to %s:%d\n", hostname, port);
  Serial.print(printbuf);
  int rc = ipstack.connect(hostname, port);
  if (rc != 1)
  {
    sprintf(printbuf, "rc from TCP connect is %d\n", rc);
    Serial.print(printbuf);
  }
 
  Serial.println("MQTT connecting");
  MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       
  data.MQTTVersion = 3;
  data.clientID.cstring = (char*)"arduino-sample2";
  rc = client.connect(data);
  if (rc != 0)
  {
    sprintf(printbuf, "rc from MQTT connect is %d\n", rc);
    Serial.print(printbuf);
  }
  Serial.println("MQTT connected");
  
  rc = client.subscribe(topicTemperature, MQTT::QOS1, messageTempArrived);   
  if (rc != 0)
  {
    sprintf(printbuf, "Temperature // rc from MQTT subscribe is %d\n", rc);
    Serial.print(printbuf);
  }
  Serial.println("MQTT subscribed for temperature");
  
  rc = client.subscribe(topicHumidite, MQTT::QOS1, messageHumiArrived);   
  if (rc != 0)
  {
    sprintf(printbuf, "Humidite // rc from MQTT subscribe is %d\n", rc);
    Serial.print(printbuf);
  }
  Serial.println("MQTT subscribed for humidite");
}

/**************************
 * SETUP ARDUINO
 **************************/
 
void setup()
{
  Serial.begin(9600);
  lcd.begin(16,2); // Initialise le LCD avec 16 colonnes x 2 lignes
  lcd.print("TEMP   /   HUMI") ; // affiche la chaîne texte - message de test 
  Ethernet.begin(mac,ip);
  Serial.println("MQTT Transmission Data");
  connect();
}

/**************************
 * LOOP ARDUINO
 **************************/
 
void loop()
{
  // If client is not connected, you have to connect to network...
  if (!client.isConnected()) 
      connect();   
  client.yield(1000);  
}

Matériels

Logiciels

Exemple de réalisation : Mini-serre