Publié le

Station météo maison couplée à une station Netatmo Part.1

Les modules additionnels Netatmo étant un peu cher, j’ai décidé de me faire des petits modules maison avec un ESP8266 et des ds18b20/DHT11-22.

Bien sur, je n’ai pas envie de faire un truc tout moche, donc pour les graphiques je me suis penché sur Highstocks.

Alors d’entrée j’ai bloqué : on doit utiliser du Javascript et moi je sais pas en faire… Ça commence bien…

Alors j’ai essayé de comprendre quand même, mais l’import des données avec json.encode() dans le php m’a un peu saoulé car sur les démos de Highstocks, c’était pas encodé pareil… Du coup sauce maison !

Pour la partie base de donnée, il suffit de regarder mes tutos précédents pour alimenter la BDD avec les relevés Netamo.

1. Encodage des données pour Highstock :

En regardant les démos, j’ai vu que le format des données étaient du style :

[
[data1,data2],
[data1,data2],
[data1,data2],
[data1,data2],
[data1,data2],
[data1,data2],
[data1,data2]
]

Du coup, je me suis fait un fichier temperaturenetatmo.php qui quand je l’exécute m’affiche les données sous cette forme :

<?php
include('connexionDB.php');

$date = 1445538928*1000;
echo "[";
$i=0;
$sth = mysql_query("SELECT datemesure, temp_int, temp_ext, pres, hum_int, hum_ext FROM netatmo");
$rows = array();

while($r = mysql_fetch_array($sth)) {
    if (date("I",time())==0){
    	if (($r["datemesure"]+3600)*1000-$date > 30*60*1000)
    	{
    		$date2 = $date + 1000;
    		$rows[] = "[".$date2.",null,null,null,null,null]";
    		$i = $i +1;
    	}
    	$date = ($r['datemesure']+3600)*1000 ;
    	$rows[] = "[".$date.",".$r["temp_int"].",".$r["temp_ext"].",".$r["pres"].",".$r["hum_int"].",".$r["hum_ext"]."]";
    	$i = $i +1;
	}
	else {
		if (($r["datemesure"]+3600)*1000-$date > 10*360*1000)
    	{
    		$date2 = $date + 1000;
    		$rows[] = "[".$date2.",null]";
    		$i = $i +1;
    	}
		$date = ($r['datemesure']+3600)*1000 ;
		$rows[] = "[".$date.",".$r["temp_int"].",".$r["temp_ext"].",".$r["pres"].",".$r["hum_int"].",".$r["hum_ext"]."]";
        $i = $i+1;
	}
}
for ($j = 0 ; $j<$i-1; $j ++){
	echo $rows[$j];
	echo ",";
}
echo $rows[$i-1];
echo "]";

mysql_close($con);
?>

Quelques précisions :

$date = 1445538928*1000;

Est la PREMIERE date de ma table (elle me permet de définir mes « null » quand il n’y a pas de données dans un intervalle de 30 minutes.

On remarque aussi que je multiplie toutes mes dates par 1000 : le temps en javascript prend en compte les milisecondes, on multiplie donc le timestamp php qui lui ne les prend pas.

Voici un extrait de la sortie :

[
[1428155100000,20.4,14.4,1015.1,67,61],
[1428156900000,20.5,14.3,1014.9,67,63],
[1428158700000,20.2,14.4,1014.6,68,63],
[1428158701000,null,null,null,null,null],
[1428176700000,20.4,12.1,1014.1,67,74]
]

La première partie est finie (j’y ai passé 3 jours quand même (en comptant le temps passé avec json.encode() ).

2. La partie Highstock :

Avant de vous dire le pourquoi du comment, voilà ce que je voulais obtenir :

chart

C’est là que la déprime a commencé… Heureusement que les démos sur Highstocks sont pas mal, je me suis inspiré de :

Et voilà mon code :

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Surveillance maison</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>



<script type="text/javascript">



$(function () {
    var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
Highcharts.setOptions({
lang: {

months: ["Janvier "," Février ","Mars "," Avril "," Mai "," Juin "," Juillet "," Août "," Septembre ",
" Octobre "," Novembre "," Décembre"],
weekdays: ["Dim "," Lun "," Mar "," Mer "," Jeu "," Ven "," Sam"],
shortMonths: ['Jan', 'Fev', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil','Août', 'Sept', 'Oct', 'Nov', 'Déc'],
decimalPoint: ',',
resetZoom: 'Reset zoom',
resetZoomTitle: 'Reset zoom à 1:1',
downloadPNG: "Télécharger au format PNG image",
downloadJPEG: "Télécharger au format JPEG image",
downloadPDF: "Télécharger au format PDF document",
downloadSVG: "Télécharger au format SVG vector image",
exportButtonTitle: "Exporter image ou document",
printChart: "Imprimer le graphique",
loading: "Chargement...",
rangeSelectorFrom: "Du",
rangeSelectorTo: "au"
 }

});
    $.getJSON('temperaturenetatmo.php', function (data) {

        // split the data set into temp_int and temp_ext
        var temp_int = [],
            temp_ext = [],
            rose = [],
            pression = [],
            hum_int = [],
            hum_ext = [],
            dataLength = data.length,
            // set the allowed units for data grouping


            i = 0;

        for (i; i < dataLength; i += 1) {
            temp_int.push([
                data[i][0], // the date
                data[i][1], // température intérieure

            ]);

            temp_ext.push([
                data[i][0], // the date
                data[i][2] // température extérieure
            ]);

            rose.push([
                data[i][0], // the date
                (Math.pow(data[i][5] /100,0.125)  )*(112+0.9*data[i][2])+0.1*data[i][2]-112 // point de rosée
            ]);

             pression.push([
                data[i][0], // the date
                data[i][3] // pression
            ]);
            hum_int.push([
                data[i][0], // the date
                data[i][4] // hum int
            ]);
            hum_ext.push([
                data[i][0], // the date
                data[i][5] // hum ext
            ]);
            }


        // create the chart
        $('#container2').highcharts('StockChart', {

             rangeSelector : {
                buttons : [ {
                    type : 'hour',
                    count : 12,
                    text : '12h'
                },{
                    type : 'day',
                    count : 1,
                    text : '1j'
                },{
                    type : 'day',
                    count : 7,
                    text : '1s'
                },{
                    type : 'month',
                    count : 1,
                    text : '1m'
                }, {
                    type : 'all',
                    count : 1,
                    text : 'Tout'
                }],
                selected : 1
            },

            title: {
                text: 'Données Netatmo'
            },

            yAxis: [{

                labels: {
                    align: 'right',
                    x: -3
                },
                title: {
                    text: 'Température'
                },
                height: '30%',
                lineWidth: 2
            }, {
                labels: {
                    align: 'right',
                    x: -3
                },
                height: '30%',
                offset: 0,
                lineWidth: 2
            },{
                labels: {
                    align: 'right',
                    x: -3
                },
                title: {
                    text: 'Pression'
                },
                top: '35%',
                height: '30%',
                offset: 0,
                lineWidth: 2,
                plotLines: [{
                value: 1015,
                width: 1,
                color: 'red',
                zIndex : 2,
            }],
            },{
                labels: {
                    align: 'right',
                    x: -3
                },
                title: {
                    text: 'Humidité'
                },
                top: '70%',
                height: '25%',
                offset: 0,
                lineWidth: 2
            },{
                labels: {
                    align: 'right',
                    x: -3
                },
                top: '70%',
                height: '25%',
                offset: 0,
                lineWidth: 2
            }],
            xAxis: {
                ordinal: false,
                alternateGridColor: '#F0FFFF'
            },
            tooltip: {
                    xDateFormat: '%a %d %b %H:%M'

                },
            plotOptions: {
                line: {
                    connectNulls: false
                        }
            },
            series: [{
                name: 'T° Intérieure',
                data: temp_int,
                tooltip: {
                    valueDecimals: 2,
                    valueSuffix:' °C'
                }
            }, {
                name: 'T° Extérieure',
                data: temp_ext,
                yAxis:0,
                tooltip: {
                    valueDecimals: 2,
                    valueSuffix:' °C'
                }
            },{
                name: 'Point de Rosée',
                data: rose,
                yAxis:0,
                tooltip: {
                    valueDecimals: 2,
                    valueSuffix:' °C'
                }
            },{
                name: 'Pression',
                data: pression,
                yAxis: 2,
                tooltip: {
                    valueDecimals: 0,
                    valueSuffix:' hPa'
                }
            },
            {
                name: 'Humidité intérieur',
                data: hum_int,
                yAxis: 3,
                tooltip: {
                    valueDecimals: 0,
                    valueSuffix:' %'
                }
            },{
                name: 'Humidité extérieur',
                data: hum_ext,
                yAxis: 3,
                tooltip: {
                    valueDecimals: 0,
                    valueSuffix:' %'
                }
            }]
        });
    });
});


</script>

<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script src="http://code.highcharts.com/stock/modules/exporting.js"></script>
    </head>
    <body>

       <div id="container2" style="width: 50%; height: 95%; float: left; "></div>


    </body>
</html>

 

Publié le

Afficher les données de Netatmo avec… Un ESP8266 ESP1

Et pourquoi ne pas réduire un peu ce que j’ai fait sur l’autre tuto ?

Alors oui on pourrait remplacer l’Arduino Méga par un nano, mais pour le Wifi on fait comment ?

Dans mon précédant tuto, je parle de l’ESP8266, mais comment ça fonctionne ?

1. L’ESP8266

Voici l’ESP8266 ESP01.

WiFi Serial Transceiver Module

On pourrait reprendre la formule « Petit mais costaud », c’est petit, assez sympa, mais aussi très galère au début quand on y connait rien !

1.1 Les pins :

images

8 pins seulement, on a pas besoin de plus (on pourrait même faire avec 6…).

1.2 On le programme avec Arduino IDE !

Et oui, on ne s’embête pas pour le programmer on peut le faire à l’aide de l’IDE Arduino, mais avant il faut la préparer un peu :

1.2.1 Configuration de l’interface Arduino :

Alors dans un premier temps on installe Arduino 1.6.5.

On ouvre les préférences et dans « Additional Bords Manager URLs » on ajoute l’URL

http://arduino.esp8266.com/stable/package_esp8266com_index.json

prefs

Et on clique sur Ok.

Ensuite on va dans Outils > type de carte > Boards Manager , dans le champ de recherche on tape esp8266 et On voit apparaitre un cadre avec esp8266… On clique dessus puis sur install.

Une fois installé dans Outils > type de carte en bas on va retrouver l’esp8266 :

Esp

 

On utilisera le type de carte « Generic ESP8266 module ». L’interface est donc prête, on ferme l’interface Arduino pour installer les librairies.

1.2.2 Installation des librairies :

Première étape, on va sur le Github de Sandeepmistery et on télécharge la dernière release.

Ensuite on va dans le dossier Arduino, le dossier dans mes documents qui contient les sketches Arduino et on crée un dossier hardware.

Une fois le fichier télécharger (archive Zip) on copie-colle le dossier esp8266 dans le dossier hardware que nous venons de créer.

Attention : mon nom de compte sur mon pc est JiPé et Arduino n’aime pas ça, j’ai donc un second compte utilisateur nomé JiP, (oui oui avec une virgule à la place du é) et c’est dans ce compte utilisateur que j’ai du faire ces manipulations.

 

2. Premiers pas : récupération du fichier out.txt.

On revient en fait à l’étape 3.1 du tuto  Afficher les données Netatmo avec un Arduino.

Voici le code utilisé (d’après un exemple contenu dans la libairie esp8266wifi) :

#include <ESP8266WiFi.h>

const char* ssid     = "SSID Wifi";
const char* password = "MDP Wifi";

const char* host = "192.168.1.50";

void setup() {
  Serial.begin(115200);
  delay(10);

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

int value = 0;

void loop() {
  ++value;

  Serial.print("connecting to ");
  Serial.println(host);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  // We now create a URI for the request
  String url = "/Netatmo/out.txt";


  Serial.print("Requesting URL: ");
  Serial.println(url);

  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
 "Host: " + host + "\r\n" + 
 "Connection: close\r\n\r\n");
  delay(10);

  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('r');
    Serial.print(line);
  }

  Serial.println();
  Serial.println("closing connection");
  delay(60000);
}

Et en sortie j’obtient :

Capture

 

3. Affichage LCD des données reçues :

Alors la partie qui m’a pris le plus de temps (en oubliant une ligne dans le code c’est sur que ça ne peut pas fonctionner).

L’ESP8266 ESP1 a deux GPIO qui peuvent servir pour l’I2C :

  • GPIO0 => SDA
  • GPIO2 => SCL

Du coup il est facile d’afficher sur un écran LCD avec une interface I2C.

Voici le code utilisé :

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <ESP8266WiFi.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

const char* ssid     = "SSID Wifi";
const char* password = "MDP Wifi";

const char* host = "192.168.1.50";

void setup() {
  Serial.begin(115200);
  delay(10);
  Wire.begin(0,2);                                  //LIGNE LA PLUS IMPORTANTE POUR DEMARRER L'I2C SUR L'ESP8266
  lcd.begin();
  lcd.backlight();

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

int value = 0;

void loop() {

  ++value;

  Serial.print("connecting to ");
  Serial.println(host);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  // We now create a URI for the request
  String url = "/Netatmo/out.txt";


  Serial.print("Requesting URL: ");
  Serial.println(url);

  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
 "Host: " + host + "\r\n" + 
 "Connection: close\r\n\r\n");
  delay(10);
  String line = "";
  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    line = client.readStringUntil('r');
   // Serial.print(line);
  }

//Serial.println(line);



char messageChar[500];
  line.toCharArray(messageChar,500);

  char dlm[] = "[";
            int cnt = 0;
            char* tab[255] = { 0 };
            char *pch = strtok(messageChar, dlm);
            while ( pch != NULL ) {
              if (cnt < 60) {
              tab[cnt++] = pch;
              } else {
              break;
              }
            pch = strtok (NULL, dlm);
            }


  char *chaine = tab[1];
  //Serial.println(chaine);
  char dlm2[] = "n";
            int cnt2 = 0;
            char* tab2[255] = { 0 };
            char *pch2 = strtok(chaine, dlm2);
            while ( pch2 != NULL ) {
              if (cnt2 < 60) {
              tab2[cnt2++] = pch2;
              } else {
              break;
              }
            pch2 = strtok (NULL, dlm2);
            }

lcd.clear();
lcd.print("T:");
lcd.print(tab2[0]);
lcd.print(" CO2:");
lcd.print(tab2[1]);
lcd.setCursor(0,1);
lcd.print("H:");
lcd.print(tab2[2]);
lcd.print(" P:");
lcd.print(tab2[3]);

  Serial.println();
  Serial.println("closing connection");
  delay(60000);
}

Et du coup :

 

IMG_0012

Publié le

Afficher les données Netatmo avec un Arduino

L’inconvénient des stations météo Netatmo c’est qu’il faut avoir un smartphone/pc/tablette à disposition pour pouvoir consulter les données de la station (ou avoir un Karotz comme Mathieu).

Du coup je me suis mis à la recherche de pistes pour faire un afficheur LCD avec un Arduino pour avoir les données en temps réel !

Du coup il faut pas mal de choses :

  • Un NAS Synology (ou un pc sous Unix ou un Raspberry Pi),
  • un Arduino avec un lcd,
  • de la patience quand on est pas doué comme moi.

Et il faut aussi quelques connaissances :

  • Savoir programmer sur Arduino,
  • maitriser le PHP,
  • savoir bidouiller dans son NAS (merci encore une fois à Mathieu).

 

1. Créer une application Netatmo :

La première étape est d’aller créer un application sur dev.netatmo.com.

On clique en haut sur « CREATE AN APP » et on se connecte avec nos identifiants Netatmo.

On remplit les champs avec astérisque, dans mon cas :

 

Netatmo1

On descend en bas de la page, on pose la case et on valide.

On arrive ensuite sur la page OAUTH SETTINGS d’ou nous allons récupérer les identifiants de l’application :

Sans titre

On récupère le « Client id » et le « Client secret » qui vont nous servir dans la partie PHP.

2. Partie PHP / Synology

2.1 Partie PHP :

On a donc les « Client id » et « Client secret » de notre application Netatmo, on va maintenant mettre tout ça dans un fichier PHP pour récupérer les informations de la station météo Netatmo.

Voici le code de mon fichier netatmo.php (qui à l’origine vient de Domotique Info mais que j’ai modifié).

<?php
$password="Mot de passe du compte Netatmo";
$username="Identifiant du compte Netatmo";
$app_id = "Client id de l'app";
$app_secret ="client secret de l'app";

$token_url = "https://api.netatmo.net/oauth2/token";
$postdata = http_build_query(
        array(
            'grant_type' => "password",
            'client_id' => $app_id,
            'client_secret' => $app_secret,
            'username' => $username,
            'password' => $password
    )
);

$opts = array('http' =>
    array(
        'method'  => 'POST',
        'header'  => 'Content-type: application/x-www-form-urlencoded',
        'content' => $postdata
    )
);

$context  = stream_context_create($opts);
$response = file_get_contents($token_url, false, $context);

$params = null;
$params = json_decode($response, true);
$api_url = "https://api.netatmo.net/api/getuser?access_token=" . $params['access_token'];
$requete = file_get_contents($api_url);

$url_devices = "https://api.netatmo.net/api/devicelist?access_token=" .  $params['access_token'];
$resulat_device = file_get_contents($url_devices);
$json_devices = json_decode($resulat_device,true);
$module_interne = $json_devices["body"]["devices"][0]["_id"];
$module_externe = $json_devices["body"]["modules"][0]["_id"];

$url_mesures_internes = "https://api.netatmo.net/api/getmeasure?access_token=" .  $params['access_token'] . "&device_id=" . $module_interne . "&scale=max&type=Temperature,CO2,Humidity,Pressure,Noise&date_end=last";
$mesures_internes = file_get_contents($url_mesures_internes);

$url_mesures_externes = "https://api.netatmo.net/api/getmeasure?access_token=" .  $params['access_token'] . "&device_id=" . $module_interne . "&module_id=" . $module_externe . "&scale=max&type=Temperature,Humidity&date_end=last";
$mesures_externes = file_get_contents($url_mesures_externes);

$int = substr($mesures_internes,42,25);
$ext = substr($mesures_externes,42,25);

$interieur=explode(",", $int);
$exterieur=explode(",",$ext);
$h_ext=explode("]",$exterieur["1"]);
$decibel=explode("]", $interieur["4"]);
$message = "[".$interieur["0"]."n".$interieur["1"]."n".$interieur["2"]."n".$interieur["3"]."n".$decibel["0"]."n".$exterieur["0"]."n".$h_ext["0"]."[";
echo $message;


?>

Petites précision sur la fin du script php :

Quand le script exécute

$url_mesures_internes = "https://api.netatmo.net/api/getmeasure?access_token=" .  $params['access_token'] . "&device_id=" . $module_interne . "&scale=max&type=Temperature,CO2,Humidity,Pressure,Noise&date_end=last";
$mesures_internes = file_get_contents($url_mesures_internes);

il nous renvoie un résultat du type :

{"body":[{"beg_time":1444133653,"value":[[24.1,433,60,1007.7,50]]}],"status":"ok","time_exec":0.020297050476074,"time_server":1444134057}

sachant que les valeurs dont nous avons besoin sont : 24.1,433,60,1007.7,50 (Température, CO2, Humidité, Pression, Décibels).

Du coup pour ne récupérer que ça (et pas toute la chaine $mesures_internes) je vais me placer sur le premier chiffre pour la température, j’extrait 25 caractères et ensuite je découpe entre avec mon séparateur « , » puis pour la dernière mesure je découpe avec le séparateur « ] ». (Je ne suis pas en pro, on doit bien pouvoir faire plus propre, mais je fais avec mes connaissances !).

Une fois fait, je compose un message à afficher après avoir exécuté le script PHP sous forme d’un écho qu’on récupèrera avec l’arduino (message avec les séparateurs « [ » et « n » on verra ça dans la partie Arduino).

2.2 Mise en place sur le Synology :

J’ai déjà un serveur Web installé sur mon NAS, donc je suis allé dans le dossier « www », j’ai créé un dossier « Netatmo » et j’ai copié mon fichier « netatmo.php » dedans. Pour automatiser l’exécution de mon script, direction le panneau de configuration et « planificateur de tâche ».

On clique sur créer et on rentre le code suivant :

/usr/bin/php -f /volume1/web/Netatmo/netatmo.php > /volume1/web/Netatmo/out.txt

Voilà ce qu’on obtient :

syno1

 

On va dans l’onglet Programmer :

syno2

On valide et on exécute le script (pour voir si tout se passe bien, le fichier out.txt devrait apparaitre dans le dossier Netatmo.

Le contenu du fichier doit ressembler à ça :

[24.3n450n60n1007.8n51n26.9n45[

Génial c’est la chaine qu’on va récupérer sur l’Arduino !

Note : ne pas faire de bêtises et ne pas effacer le fichier /usr/bin/php (ne me demandez pas comment je l’ai fait, merci à Mathieu de m’avoir envoyé le sien).

 

3. Récupération et affichage sur un LCD : Partie ARDUINO.

3.1 Tests préliminaires (Et il y en a eu…) :

Habituellement, je travaille avec des ESP8266, mais il y a un mois, je me suis commandé un shield CC3000 sur ebay qui ressemble à ça :

$_57

Avantage : il fonctionne avec les librairies ADAFRUIT que l’on trouve ici.

Pour le codage, j’ai fait le flemmard. J’avais déjà testé le code exemple WebClient.ino fournit avec la librairie ADAFRUIT, donc je l’ai bêtement repris.

Il faut juste modifier un peu les premières ligne (je ne montre que les premières lignes) :

#define WLAN_SSID       "LE SSID DE LA BOX"           // cannot be longer than 32 characters!
#define WLAN_PASS       "MOT DE PASSE WIFI"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

#define IDLE_TIMEOUT_MS  3000      // Amount of time to wait (in milliseconds) with no data
                                   // received before closing the connection.  If you know the server
                                   // you're accessing is quick to respond, you can reduce this value.

// What page to grab!
#define WEBSITE      "IP DU NAS"
#define WEBPAGE      "/Netatmo/out.php"  // lien vers out.txt

Sur la voie série quand j’exécute mon programme, j’ai la visualisation suivante :

Hello, CC3000!

Free RAM: 5687

Initializing...

Attempting to connect to Livebox-4246
Connected!
Request DHCP

IP Addr: 192.168.1.65
Netmask: 255.255.255.0
Gateway: 192.168.1.1
DHCPsrv: 192.168.1.1
DNSserv: 192.168.1.1
192.168.1.50 -> 192.168.1.50-------------------------------------
HTTP/1.1 200 OK
Date: Tue, 06 Oct 2015 13:02:00 GMT
Server: Apache
Last-Modified: Tue, 06 Oct 2015 13:01:11 GMT
ETag: "1d-5216f395e9d25"
Accept-Ranges: bytes
Content-Length: 29
Vary: Accept-Encoding
Content-Type: text/plain

[24.5n455n60n1007.9n51n27n44[-------------------------------------


Disconnecting

En fait le programme WebClient.ino me renvoie la réponse donnée par le site web, mais la réponse COMPLETE, c’est à dire :

HTTP/1.1 200 OK
Date: Tue, 06 Oct 2015 13:02:00 GMT
Server: Apache
Last-Modified: Tue, 06 Oct 2015 13:01:11 GMT
ETag: "1d-5216f395e9d25"
Accept-Ranges: bytes
Content-Length: 29
Vary: Accept-Encoding
Content-Type: text/plain

[24.5n455n60n1007.9n51n27n44[

Et devinez ce dont on a besoin ? Et oui juste la fin de la réponse…

3.2 Après les tests, le programme fonctionnel :

Donc j’ai passé un peu de temps à voir comment récupérer juste le contenu de mon fichier « out.txt », j’ai retravaillé le fichier « WebClient.ino » car d’une part, tout était dans le void setup, et d’autre part, il me fallait récupérer l’essentiel (c’est lors de cette étape que j’ai rajouté les délimiter « [ » dans le fichier netatmo.php).

Voici mon code :

#include <Adafruit_CC3000.h>
#include <LiquidCrystal.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"


#define ADAFRUIT_CC3000_IRQ   3  // MUST be an interrupt pin!
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIVIDER); // you can change this clock speed

#define WLAN_SSID       "SSID Wifi"           // cannot be longer than 32 characters!
#define WLAN_PASS       "Mot de passe Wifi"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

#define IDLE_TIMEOUT_MS  3000      // Amount of time to wait (in milliseconds) with no data
                                   // received before closing the connection.  If you know the server
                                   // you're accessing is quick to respond, you can reduce this value.

// What page to grab!
#define WEBSITE      "192.168.1.50"             //ip NAS
#define WEBPAGE      "/Netatmo/out.txt"         //Chemin du fichier Out


LiquidCrystal lcd(42,41,37,38,39,40);

/**************************************************************************/
/*!
    @brief  Sets up the HW and the CC3000 module (called automatically
            on startup)
*/
/**************************************************************************/

uint32_t ip;

void setup(void)
{
  Serial.begin(115200);
  lcd.begin(16,2);
  lcd.clear();
  lcd.write("test");
}

void loop(void)
{
    Serial.println(F("Hello, CC3000!n"));

  Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);

  /* Initialise the module */
  Serial.println(F("nInitializing..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);
  }

  // Optional SSID scan
  // listSSIDResults();

  Serial.print(F("nAttempting to connect to ")); Serial.println(WLAN_SSID);
  if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
    Serial.println(F("Failed!"));
    while(1);
  }

  Serial.println(F("Connected!"));

  /* Wait for DHCP to complete */
  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(100); // ToDo: Insert a DHCP timeout!
  }

  /* Display the IP address DNS, Gateway, etc. */
  while (! displayConnectionDetails()) {
    delay(1000);
  }

  ip = 0;
  // Try looking up the website's IP address
  Serial.print(WEBSITE); Serial.print(F(" -> "));
  while (ip == 0) {
    if (! cc3000.getHostByName(WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }

  cc3000.printIPdotsRev(ip);

  // Optional: Do a ping test on the website
  /*
  Serial.print(F("nrPinging ")); cc3000.printIPdotsRev(ip); Serial.print("...");
  replies = cc3000.ping(ip, 5);
  Serial.print(replies); Serial.println(F(" replies"));
  */

  /* Try connecting to the website.
     Note: HTTP/1.1 protocol is used to keep the server from closing the connection before all data is read.
  */
  Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80);
  if (www.connected()) {
    www.fastrprint(F("GET "));
    www.fastrprint(WEBPAGE);
    www.fastrprint(F(" HTTP/1.1rn"));
    www.fastrprint(F("Host: ")); www.fastrprint(WEBSITE); www.fastrprint(F("rn"));
    www.fastrprint(F("rn"));
    www.println();
  } else {
    Serial.println(F("Connection failed"));
    return;
  }

  Serial.println(F("-------------------------------------"));
  int i=0;
  String message ="";
  /* Read data until either the connection is closed, or the idle timeout is reached. */
  unsigned long lastRead = millis();
  while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
    while (www.available()) {
      char c = www.read();
      message += c;
      Serial.print(c);
      lastRead = millis();
    }
  }

 //Serial.println(message);
  www.close();
  Serial.println(F("-------------------------------------"));

  /* You need to make sure to clean up after yourself or the CC3000 can freak out */
  /* the next time your try to connect ... */
  Serial.println(F("nnDisconnecting"));
  cc3000.disconnect();

  char messageChar[500];
  message.toCharArray(messageChar,500);

  char dlm[] = "[";
            int cnt = 0;
            char* tab[255] = { 0 };
            char *pch = strtok(messageChar, dlm);
            while ( pch != NULL ) {
              if (cnt < 60) {
              tab[cnt++] = pch;
              } else {
              break;
              }
            pch = strtok (NULL, dlm);
            }


  char *chaine = tab[1];
  //Serial.println(chaine);
  char dlm2[] = "n";
            int cnt2 = 0;
            char* tab2[255] = { 0 };
            char *pch2 = strtok(chaine, dlm2);
            while ( pch2 != NULL ) {
              if (cnt2 < 60) {
              tab2[cnt2++] = pch2;
              } else {
              break;
              }
            pch2 = strtok (NULL, dlm2);
            }
 char *temp = tab2[0];
 Serial.print(temp);
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.write("t:");
 lcd.write(temp);
 lcd.write("C CO2:");
 lcd.write(tab2[1]);
 lcd.setCursor(0,1);
 lcd.write("h:");
 lcd.write(tab2[2]);
 lcd.write("% p:");
 lcd.write(tab2[3]);

 delay(120000);
}

/**************************************************************************/
/*!
    @brief  Begins an SSID scan and prints out all the visible networks
*/
/**************************************************************************/

void listSSIDResults(void)
{
  uint32_t index;
  uint8_t valid, rssi, sec;
  char ssidname[33];

  if (!cc3000.startSSIDscan(&index)) {
    Serial.println(F("SSID scan failed!"));
    return;
  }

  Serial.print(F("Networks found: ")); Serial.println(index);
  Serial.println(F("================================================"));

  while (index) {
    index--;

    valid = cc3000.getNextSSID(&rssi, &sec, ssidname);

    Serial.print(F("SSID Name    : ")); Serial.print(ssidname);
    Serial.println();
    Serial.print(F("RSSI         : "));
    Serial.println(rssi);
    Serial.print(F("Security Mode: "));
    Serial.println(sec);
    Serial.println();
  }
  Serial.println(F("================================================"));

  cc3000.stopSSIDscan();
}

/**************************************************************************/
/*!
    @brief  Tries to read the IP address and other connection details
*/
/**************************************************************************/
bool displayConnectionDetails(void)
{
  uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;

  if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
  {
    Serial.println(F("Unable to retrieve the IP Address!rn"));
    return false;
  }
  else
  {
    Serial.print(F("nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
    Serial.print(F("nNetmask: ")); cc3000.printIPdotsRev(netmask);
    Serial.print(F("nGateway: ")); cc3000.printIPdotsRev(gateway);
    Serial.print(F("nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
    Serial.print(F("nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
    Serial.println();
    return true;
  }
}

Et voici le résultat :

IMG_2739

3.3 Ce qu’il reste à faire :

  • J’ai commandé un écran LCD 20×4 I2C car sur le 16×2 (qui n’est pas en I2C) je ne peux pas tout afficher.
  • Voir pour récupérer les infos du pluviomètre.
Publié le

Mes premiers pas avec mon Raspberry pi 2

Depuis la sortie du Raspberry Pi, je voulais m’en offrir un, mais je n’ai jamais sauté le pas.

Cette semaine je me suis enfin décidé et j’ai reçu hier mon Raspberry Pi 2 !

Bien entendu j’avais déjà un projet en tête quand je l’ai commandé : faire un serveur IOT avec EasyIOT.

 

Installation du Raspberry Pi :

Première étape, créer une carte micro SD avec le système Raspbian.

Je ne vais pas détailler ici comment j’ai créé la carte micro SD car la documentation est très bien faite.

Une fois la carte prête, direction le Raspberry Pi.

J’ai configuré mon Raspberry Pi sans écran (pratique de le configurer en se connectant par ssh depuis mon iMac).

 

Réglages initiaux :

Par défaut le nom d’utilisateur du Rasperry Pi est « pi » et le mot de passe « raspberry ».

Pour la connection ssh, il suffit de taper dans le terminal

ssh pi@192.168.1.66

(En remplaçant 192.168.1.66 par l’adresse ip du Raspberry Pi).

La première étape est de changer le mot de passe de l’utilisateur « pi » :

pi@raspberrypi ~ $ sudo raspi-config

La fenêtre de configuration s’affiche :

config

On se place sur le choix 2, on valide et :

Capture2

On valide et on se retrouve dans le shell. On tape le mot de passe on valide avec entrée, on le confirme avec entrée.

La première étape est finie !

On va voir maintenant comment installer EasyIOT !

 

Installation de EasyIOT :

Première chose à faire, aller faire un tout sur iot-playground.

Je pourrais vous dire de suivre le tuto, mais j’ai eu quelques galères donc autant les partager ici.

 

Téléchargement d’EasyIOT :

J’ai eu quelques soucis avec la version v0.9, donc j’ai décidé d’installer la version v0.8, il se télécharge ici.

Je l’ai extrait sur le bureau et direction le terminal :

imac-de-jean-pierre:~ jp$ cd Desktop/
imac-de-jean-pierre:Desktop jp$ tar cf easy.tar easyiot
imac-de-jean-pierre:Desktop jp$ sftp pi@192.168.1.66
pi@192.168.1.66's password:
Connected to 192.168.1.66.
sftp> put easy.tar
Uploading easy.tar to /home/pi/easy.tar
easy.tar                                      100% 4559KB   4.5MB/s   00:01
sftp> exit

Direction le terminal avec la connexion ssh ouverte (oui ce terminal on ne le ferme pas) :

pi@raspberrypi ~ $ tar xf easy.tar
pi@raspberrypi ~ $ rm easy.tar

On a ainsi extrait notre dossier et effacé notre archive.

 

Préparation avant la configuration d’EasyIOT :

Petit tour de nouveau dans la configuration du Raspberry Pi :

sudo raspi-config

Choix 8 « Advanced Options », choix A6 « SPI »

« Would you like the SPI interface to be enabled » => Yes.

On valide.

« Would you like the SPi kernel module to be loaded by default ? » => Yes

Si le système ne le demande pas, on fait un petit reboot :

sudo reboot

On va connecter un module NRF24L01+ au Raspberry Pi (je ne l’utilise pas encore, mais on va quand même le connecter).

Attention là aussi avec le tuto, le modèle du Raspberry pi présenté n’est pas un Pi 2.

Untitled Sketch_bb

Installation de MONO :

Allez on attaque l’installation de Mono :

sudo apt-get update
sudo apt-gat upgrade
sudo apt-get install mono-complete

Ca prend en gros 5 minutes, des fois moins.

Configuration de EasyIOT :

Première étape, on se place dans le dossier d’EasyIOT pour changer les permission de fichiers  :

cd /home/easyiot
sudo chown -R root log
sudo chmod -R 644 log
sudo chown -R root config
sudo chmod -R 644 config

Je rajoute une étape par rapport au tuto sur IOT Playground car sinon les mesures n’étaient pas sauvegardées dans la base de données :

sudo chown -R EasyIoTDatabase.sqlite

Pour nous simplifier la vie, on va lancer EasyIOT comme un service (il sera donc lancé au démarrage du Raspberry PI) :

On commence par télécharger l’archive easyiot

Un petit coup de sftp comme tout à l’heure pour l’envoyer sur le Raspberry Pi, on repasse sur la console ssh (note on est toujours dans le dossier easyiot) et :

sudo mv ../easyiot.tar /etc/init.d/
sudo tar xf /etc/init.d/easyiot
sudo rm easyiot.tar

Il ne nous reste plus qu’à terminer la configuration pour le lancement automatique :

sudo chmod +x /etc/init.d/easyiot
sudo chmod +x startup.sh
sudo update-rc.d easyiot defaults

On peut stopper et mettre en en route le service avec les commandes :

sudo /etc/init.d/easyiot stop

sudo /etc/init.d/easyiot start

A présent EasyIOT est installé sur le Raspberry Pi et fonctionnel.

Prochaine étape ajouter un capteur température !

Publié le

Capteur RFID

Semaine très chargée et week-end à venir encore plus… Je vais quand même prendre un peu de temps pour vous présenter le capteur RFID RC522 que j’ai reçu aujourd’hui.

Déballage :

Voici le petit bijou que j’ai reçu :

 

IMG_2665

Il se compose donc :

  • Un module  RV522
  • Une carte RFID
  • Un porte clef RFID

Le montage :

  • Un arduino MEGA
  • Deux LEDS
  • Deux résistances de 330Ω
  • Des fils…

Pour la connection du capteur RFID sur une arduino MEGA :

MOSI: Pin 51 / ICSP-4
MISO: Pin 50 / ICSP-1
SCK : Pin 52 / ISCP-3
SDA : Pin 53 (Configurable)
RST : Pin 5 (Configurable)

Si ce n’est pas un MEGA :

MOSI: Pin 11 / ICSP-4
MISO: Pin 12 / ICSP-1
SCK : Pin 13 / ISCP-3
SDA : Pin 10 (Configurable)
RST : Pin 9 (Configurable)

Je vous propose le montage COMPLET (c’est à dire avec les LEDS mais qui ne vont pas servir dans la première partie de l’article :

ATTENTION LE MODULE RFID FONCTIONNE EN 3,3V 

RFID-mega_bb1 RFID-Nano_bb

Lecture de l’identifiant de la carte et du porte clef :

Les cartes RFID possèdent un identifiant qu’il va falloir retrouver pour pouvoir ensuite savoir si notre carte est autorisée ou refusée.

#include <SPI.h>                            // Librairies nécessaires
#include <RFID.h>

RFID monModuleRFID(53,5);                  // On déclare les PINS SDA et RST Pour le NANO : monModuleRFID(10,9)

int UID[5];                                // On crée notre variable qui vit stocker l'UID de notre carte

void setup()
{
  Serial.begin(9600);
  SPI.begin();
  monModuleRFID.init();                    // On initialise le module RFID

}

void loop()
{
    if (monModuleRFID.isCard()) {
          if (monModuleRFID.readCardSerial()) {
            Serial.print("L'UID est: ");
            for(int i=0;i<=4;i++)
            {
              UID[i]=monModuleRFID.serNum[i];
              Serial.print(UID[i],DEC);
              Serial.print(".");
            }
            Serial.println("");
          }
          monModuleRFID.halt();
    }
    delay(5000);
}

En sortie j’obtient ceci (J’ai passé le porte clef et premier puis la carte) :

Sans-titre2

  • Porte clef : 105.115.122.158.254
  • Carte : 138.55.50.59.180

Commande d’une LED :

Mettons en pratique l’authentification. Je vais programmer pour que le porte clef soit reconnu comme valide (LED verte) et que la carte soit invalide (LED ROUGE) :

#include <SPI.h>
#include <RFID.h>

const char DOUT_LED_ROUGE = 2;
const char DOUT_LED_VERTE = 3;

RFID monModuleRFID(53,5);

int UID[5]={};
int MASTERKEY[5]={105,115,122,158,254};

void setup()
{
  Serial.begin(9600);
  SPI.begin();
  monModuleRFID.init();
  pinMode(DOUT_LED_ROUGE, OUTPUT);
  pinMode(DOUT_LED_VERTE, OUTPUT);
  digitalWrite(DOUT_LED_ROUGE, LOW);
  digitalWrite(DOUT_LED_VERTE, LOW);

}

void loop()
{
    if (monModuleRFID.isCard()) {
          if (monModuleRFID.readCardSerial()) {
            Serial.print("L'UID est: ");
            for(int i=0;i<=4;i++)
            {
              UID[i]=monModuleRFID.serNum[i];
              Serial.print(UID[i],DEC);
              Serial.print(".");
            }
            Serial.println("");
          }

          if (UID[0] == MASTERKEY[0]
           && UID[1] == MASTERKEY[1]
           && UID[2] == MASTERKEY[2]
           && UID[3] == MASTERKEY[3]
           && UID[4] == MASTERKEY[4])
          {
              digitalWrite(DOUT_LED_VERTE, HIGH);
              delay(500);
              digitalWrite(DOUT_LED_VERTE, LOW);
          }
          else
          {
              digitalWrite(DOUT_LED_ROUGE, HIGH);
              delay(500);
              digitalWrite(DOUT_LED_ROUGE, LOW);
          }
          monModuleRFID.halt();
    }
    delay(1);
}

Le résultat en vidéo :

Téléchargement des librairies ICI

Publié le

Sonde humidité pour le sol

Ce soir, je vous propose de nous occuper de nos plantes vertes. on va prendre le cas d’une plante qui a besoin d’un taux d’humidité du sol supérieur à 75%, si le taux d’humidité est entre 50% et 75% il faut arroser et si on passe en dessous de 50% c’est critique.

Matériel requis :

  • Un Arduino NANO ;
  • 3 Résistances 330Ω;
  • Un capteur humidité pour le sol.

Le capteur :

Mon kit est en deux parties, une carte et la fourche à mettre dans le sol. Il y a deux possibilités pour le relier à l’Arduino :

  • D0 : sortie digitale qui va nous renvoyer soit 1, soit 0
  • A0 : sortie analogique qui nous renvoie une valeur entre 0 et 1023

Ici je ne vais m’intéresser qu’à la sortie analogique vu que je souhaite obtenir un taux d’humidité pour le sol.

Le montage :

humité sol_bb

Programmation :

Intoduction – Déclarations :

int pinA =A0;          // Pin Analogique du capteur
int Sensor = 3;        // Pin d'alimentation du capteur
int ledR = 4;          // Pin LED Rouge
int ledJ = 5;          // Pin LED Jaune
int ledV = 6;          // Pin LED Verte

Dans le Void Setup

void setup() {
 Serial.begin(9600);
 pinMode(pinA,INPUT);
 pinMode(ledR,OUTPUT);
 pinMode(ledJ,OUTPUT);
 pinMode(ledV,OUTPUT);
 pinMode(Sensor,OUTPUT);
}

Dans le Void loop :

void loop() {
digitalWrite(Sensor,HIGH);
delay(1000);
float h=analogRead(pinA);
float taux = (1023.0-h)/7.0;
 Serial.print(h);
 Serial.print(" ");
 Serial.println(taux);
 led(taux);
 digitalWrite(Sensor,LOW);
 delay(20000);

}

Dans le void led() :

void led(float taux)
{

  digitalWrite(ledV,LOW);
  digitalWrite(ledJ,LOW);
  digitalWrite(ledR,LOW);

  if (taux > 70)
      digitalWrite(ledV,HIGH);
      else {
        if (taux > 50)
            digitalWrite(ledJ,HIGH);
            else digitalWrite(ledR,HIGH);
          }
}

Résultat :

Si je laisse la sonde à l’air libre, pas de conduction entre les deux fourches de la sonde, valeur renvoyée sur le pin A0 : 1023, la led rouge est allumée.

IMG_2574

Si je met la sonde dans un verre d’eau, conduction entre les deux fourches de la sonde, valeur mesurée sur le pin A0 : 300, la led verte est allumée.

IMG_2575

Je passe l’explication mathématique pour définir l’équation d’une fonction affine, ce qui m’a permit de définir que

taux = (1023.0-h)/7.0;

Si je tiens la fourche de la sonde avec les doigts légèrement humides, j’obtiens une valeur intermédiaire qui allume la led jaune.

IMG_2576

 

Publié le

Capteur humidité / température DHT22

Et pourquoi ne pas se faire une petite station météo avec l’Arduino ?

Pour cela je vais vous parler aujourd’hui des sondes humidité – température DHT.

Il existe 2 types de DHT :

  • DHT11 : Précision humidité 5%, température 2°C
  • DHT22 : Précision humidité 2%, température 0,5°C

 

Matériel requis :

Le montage :

DHT

 

Programmation :

Intoduction – Déclarations :

#include <DHT.h>

#define DHTPIN 2                  // Declaration du pin du DHT

//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22

DHT dht(DHTPIN, DHTTYPE); // Initialisation du capteur

Dans le Void Setup

void setup() {
 Serial.begin(9600);
 Serial.print("Test du DHT");
 Serial.println(DHTTYPE);
 dht.begin();
}

Dans le Void loop

void loop(){
// Pause en début pour laisser le temps au capteur de démarrer
 delay(5000);

 float h = dht.readHumidity();
 float t = dht.readTemperature();

 Serial.print("Humidity: ");
 Serial.print(h);
 Serial.print(" %t");
 Serial.print("Temperature: ");
 Serial.print(t);
 Serial.println(" *C ");
}

Capture

Publié le

Controle d'un module Relais par une module RTC

Je vous ai déjà présenté les modules Relais et RTC, mais qu’en est il d’un module RTC qui pourrait commander un relais ?

 

Matériel requis :

  • Un Arduino MEGA;
  • 1 Résistances 330Ω;
  • Une led;
  • Un module RTC ici
  • Un module Relais ici

 

Le montage :

Pour le montage, on fait une fusion des deux concernant Relais et RTC :

RTC_relai

 

Programmation :

Intoduction – Déclarations :

#include <Wire.h>
#include <RTClib.h>

RTC_DS1307 RTC;                  // Declaration du module RTC

const int RELAIS = 3;           // Declaration broche 3 output
float temp;
boolean etatRelais = 0;

Dans le Void Setup

void setup() {
 pinMode(RELAIS, OUTPUT);      // Configure la broche RELAIS en sortie
 digitalWrite(RELAIS,0);       // On place le relais dans l'etat off
 Wire.begin();
 RTC.begin();
}

Dans le Void loop

void loop(){
heure();                      // On fait tourner la fonction heure
}

La fonction « heure »

void heure()
{
 DateTime now = RTC.now();                     // On récupère le temps actuel
 if (now.hour() <=17 && now.minute() <= 45)    // Boucle de condition avec des variables
 {
 etatRelais=1;                                 // Si la condition est respectée on allume la led
 digitalWrite(RELAIS,etatRelais);
 }
 else
 {
 etatRelais=0;                                 // Si la condition n'est pas respectée on éteint la led
 digitalWrite(RELAIS,etatRelais);
 }
}


Publié le

Module RTC et Arduino

Aujourd’hui je vais me pencher sur les modules RTC (Real Time Clock) et voir ce qu’on peut en faire avec un Arduino (Méga dans mon cas).

 

Matériel requis :

 

  • Un Arduino MEGA;
  • Un module RTC DS3231;

Description du module RTC :

 

Le module que j’ai choisit dispose d’une batterie Lithium pour nous permettre de de sauvegarder l’heure et la date si on le débranche (plus pratique qu’un module RTC sans pile).

IMG_2461

Dans cet exemple, nous n’allons utiliser que les entrée SDA et SCL (Nous verrons plus tard à quoi servent 32K et SQW).

Nous allons avoir besoin de deux librairies pour faire fonctionner le programme :

  • Wire.h qui est inclue dans les librairies Arduino
  • RTClib.h que vous pouvez trouver ici : RTClib.h

Pour connecter le module RTC sur un Arduino MEGA, il suffit juste de raccorder SCL sur le pin 21 et SDA sur le pin 20 ainsi que l’alimentation évidement !

RTC_bb

 

Programmation :

Premier test : 

#include <Wire.h>
#include <RTClib.h>

RTC_DS1307 RTC; // Avec cette librairie on déclare le DS3231 comme un DS1307

void setup() {
 Serial.begin(9600);
 Wire.begin();
 RTC.begin();
}

void loop() {
  //Affichage de l'heure
  DateTime now = RTC.now(); // Lit l'heure du module
  Serial.print(now.day(), DEC); // Affiche le jour
  Serial.print('/');
  Serial.print(now.month(), DEC); // Affiche le mois
  Serial.print('/');
  Serial.print(now.year(), DEC);  //Affiche l'année
  Serial.print(' ');
  Serial.print(now.hour(), DEC); //Affiche les heures
  Serial.print(':');
  Serial.print(now.minute(), DEC); // Affiche les minutes
  Serial.print(':');
  Serial.print(now.second(), DEC); // Affiche les secondes
  Serial.println();
  delay(3000);

}

Résultat :

Progr1

Ah non, nous ne sommes pas le 1er Janvier 2000 à minuit !

 

Mise à l’heure du module :

Nous allons ouvrir un nouvel onglet pour créer une fonction qui va mettre notre module à l’heure par rapport à l’heure de compilation du programme. Assez pratique même si nous aurons quelques secondes de décalage par rapport à l’heure de notre PC.

On modifie juste le « void setup » pour ajouter la fonction « reglageheure() »

void setup() {
 Serial.begin(9600);
 Wire.begin();
 RTC.begin();
reglageheure();
}

On ouvre un onglet pour la fonction avec le code suivant :

void reglageheure()
{
  Serial.println("Mise a l'heure");
  RTC.adjust(DateTime(__DATE__, __TIME__));
  DateTime now = RTC.now();
  Serial.print(now.day(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.year(), DEC);
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
  delay(5000);
}

On compile et on ouvre le moniteur série :

mise à l'heure

Heure de mon iMac : 16:45:06

Heure du module RTC : 16:44:52

Nous avons donc 14 secondes d’écart entre les deux ce qui reste convenable.

 

Publié le

Commande d'éclairage de LEDs par un relais avec un Arduino

Les relais peuvent être utile pour commander un appareil en 220V à partir de l’Arduino. Par exemple on peut commander un éclairage, une pompe… Ici je vous propose de voir simplement comment fonctionne un relais :

 

Matériel requis :

  • Un Arduino Mega;
  • 2 Résistances 330Ω;
  • 2 LEDs (une bleu, une rouge);
  • Des fils;

Le montage :

 

Pour étudier le relais on va tester les deux sorties du relais, la led bleu sera allumée puis la rouge et ainsi de suite :

relais+led_bb

Programmation :

Programmation relativement simple ici, on change juste l’état du pin 3 pour faire commuter le relais :

const int RELAIS = 3; // On déclare le PIN sur lequel est connecté In1 du relais
boolean EtatRelais = 0; // On crée un booléen ( 0 - 1) pour définir l'état du PIN 3

void setup() {
  pinMode(RELAIS,OUTPUT); // On définit le pin 3 comme une sortie

}

void loop() {
  EtatRelais =! EtatRelais; // On inverse la valeur du booléen ( Note : "!=" signifie différent et "=!" donne l'inverse)
  digitalWrite(RELAIS,EtatRelais);
  delay(2500*);

}

 

Résultat :

Et voilà, on sait a présent faire fonctionner le relais.