Menu Fermer

Communication socket – ESP8266 – Raspberry Pi – Python – Java

Pour les makers, j’ai aussi passé à MicroPython, dont voici un de mes autres articles paru dans le magazine Programmez : MicroPython, NodeMCU ESP8266 et Thonny.

J’ai adoré faire cet exercice. Il permet de vérifier que nous maîtrisons:

  • l’écriture de sketchs sur un ESP8266
  • l’utilisation du PC pour développer, vérifier nos sketchs et programmer notre code Java ou Python
  • programmer une communication socket entre un ESP8266 et un Raspberry Pi

Le code qui suit est facilement modifiable pour ajouter un LM35. L’article Contrôle de température avec un Raspberry Pi par un LM35 déposé sur un NODEMCU esp8266 utilisait une interface Web avec le serveur sur l’ESP8266 avec un LM35. Ici c’est le Raspberry Pi qui sera le serveur de l’interface socket et l’ESP8266 qui enverra en continu la « température » (ou autre) mesurée.

Une interface socket client en Java ou en Python serait aussi possible pour communiquer entre plusieurs Raspberry Pi pour échanger des données ponctuelles ou distribuées. Le code n’est pour l’instant pas présenté ici.

Le sketch sur l’ESP8266

#include <ESP8266WiFi.h>
#include <WiFiClient.h>

const char* ssid = "....";
const char* pass = "....";
const char* host = "192.168.2.9";
const int   port = 3333;

void setup() {
  delay(500);
  Serial.begin(38400);
  Serial.println();
  Serial.print("Connecté à ");
  Serial.println(ssid);
  Serial.println("Essai de connection à ");
  Serial.println(host);
  
  WiFi.mode(WIFI_STA); 
  delay(1000);
  WiFi.begin(ssid, pass);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
}

void loop() {
  long randNumber = random(300);
  WiFiClient client;
  
  if (!client.connect(host, port)) {
    Serial.println(".");
    return;
  }
  
  Serial.println();
  Serial.print("Connecté à ");
  Serial.println(host);

  Serial.print("Envoi d'une température: ");
  Serial.println(randNumber);

  client.println(randNumber);
  delay(100);
  
  String line = client.readStringUntil('\n');
  Serial.print(line);

  client.flush();
  client.stop();
}

Nous utiliserons l’Arduino IDE  comme pour l’article Contrôle de température avec un Raspberry Pi par un LM35 déposé sur un NODEMCU esp8266  où est décrit l’installation et la configuration pour le NODEMCU, un modèle d’ESP8266.

Si je trouve le temps, j’essaierai de décrire ce code en détails.
Il faudra évidemment mettre les valeurs juste au ssid et pass (mot de passe) pour notre routeur. Ici l’adresse IP est un peu particulière: c’est mon Laptop Windows connecté à un second routeur dans ma maison. Les tests Python et Java ont été fait sur ce Laptop avec Eclipse et Thonny (voir ci-dessous). Lorsqu’on déplacera le code Java compilé ou le script Python sur un Raspberry Pi, il faudra modifier l’adresse IP avec celui du Raspberry Pi. Ce dernier devrait être fixé dans le routeur (voir le livre).

L’instruction random(300) est volontaire. Cela donnerait par exemple 241 pour une température de 24.1 degrés. C’est plus facile de convertir après.

Le code Python du serveur

# coding: utf-8
import socket

HOST = ''
PORT = 3333 # Port de lecture

print('Socket serveur sur: ', PORT)

while True:
  with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as soc:
    soc.bind((HOST, PORT))
    soc.listen()
    conn, addr = soc.accept()
    with conn:
      print('Connecté par ', addr)
      while True:
        data = conn.recv(1024)
        if not data:
          break
        print('Reçu: ', data.decode("utf-8"))
        conn.sendall(data)
        break

A nouveau, si je trouve le temps, j’essaierai de décrire ce code en détails en particulier le très important HOST. Le port 3333 est évidemment le même que celui défini dans le sketch précédent.

Je mes suis amusé avec Tonny qui marche très bien. J’aime aussi bien essayer de nouveaux outils, et simple comme ce dernier. Tout en gardant l’ESP8266 connecté avec un câble USB pour corriger mon sketch, j’ai pu aussi vérifier l’exécution de ce code dans le Shell de Tonny et modifier le script Python (3.5.3 sous Windows).

Dès que nous aurons reçu une donnée de l’ESP8266, nous coupons la communication, après avoir envoyé un écho, et nous recommençons.

Le code Java du serveur

import java.io.*;
import java.net.*;

public class Server {
static final int port = 3333;

public static void main(String[] args) throws Exception {
  for(;;) {
    ServerSocket ss = new ServerSocket(port);
    Socket soc = ss.accept();

    BufferedReader bR = new BufferedReader(
                   new InputStreamReader(soc.getInputStream()));

    PrintWriter pW = new PrintWriter(new BufferedWriter(
            new OutputStreamWriter(soc.getOutputStream())), true);

    while (true) {
      String tempStr = bR.readLine(); // Lecture de la température
      if (tempStr == null) {
        Thread.sleep(1000);
        break;
      }

      System.out.println("Température = " + tempStr);
      pW.println("Ok"); // Renvoi d'un écho
      break;
    }

    bR.close();
    pW.close();
    soc.close();
    ss.close();
   }
 }
}

A nouveau, encore une fois, si je trouve le temps, je devrais décrire ce code en détails. Nous renvoyons aussi un Echo. Le code Java est très similaire à la lecture et l’écriture de fichiers Java (chapitre 10).

Nous sommes sur Eclipse, dans un projet Eclipse, et c’est dans la console d’Eclipse que viennent les « températures » depuis l’ESP8266 qui est toujours connecté avec un câble USB (sans Thonny actif évidemment) et une console IDE Arduino avec l’autre partie du protocole socket et l’éditeur du sketch toujours actif.

Tout ce travail se fait très très rapidement … sauf le communication PC au ESP8266 pour compiler et télécharger le sketch corrigé! C’est normal.

Exercice 1

Ajouter un LM35 sur un ESP8266 (un NODEMCU par exemple), adapter le sketch et vérifier que les valeurs reçues sont correctes en touchant le capteur avec deux doigts pour faire varier la température.

Exercice 2

Déposer le script Python et le code Java sur un Raspberry Pi et modifier l’adresse IP du sketch. Vérifier la température reçue par les deux programmes dans une console bash à partir de Putty.

Exercice 3

Insérer le code Java ci-dessus dans un Thread Java (chapitre 12), l’adapter, activer une sirène buzzer (chapitre 17) avec un SOS répétitif (intervalle à définir) si la température passe en dessous d’un certain niveau (défini comme paramètre (chapitre 10)) et implémenter une séquence d’arrêt de la sirène avec un bouton poussoir (chapitre 19). Si le bouton pressoir n’est pas touché après un intervalle à définir (aussi comme paramètre), stopper la sirène et envoyer un e-mail (chapitre 24).

Développer tout le code sous Windows et Eclipse, avec simulation, comme expliquer à plusieurs occasions dans le livre.  Faire tout de même un exercice de débogage à distance sur le Raspberry Pi (chapitre 15).

Date de la dernière modification: 23 juin 2019