Prise Ethernet 2

Prise Ethernet quadruple pilotée par ESP32 et MQTT

La multiprise en service

Prise de courant Ethernet ESP32 MQTT

L’interface Home Assistant de l’atelier

Interface Home Assistant Atelier

L’objet

Comme exprimé dans mon article « Gestion d’accès et commande électrique pour atelier », il me manquait des prises de courant commutables à distance.
Le code fourni dans ce précédent sujet prend déjà en compte les 4 prises de ce montage pour l’affichage sur le petit écran extérieur.
Avec ces quatre prises supplémentaires placées à un autre endroit de l’atelier, je gère l’alimentation de :

  • La Creality K1c;
  • La Creality K2 PRO;
  • Le SpacePi X4 Creality;
  • La caméra de surveillance.

Du coup, j’ai modifié l’assignation des 4 prises de l’article ci-dessus comme suit :

  • Le PC;
  • La musique;
  • Le chauffage;
  • Le laser et la CNC.

Il convient d’être prudent car ce montage présente des tensions pouvant être mortelles. Ne vous y risquez pas si vous ne maîtrisez pas ce domaine !

Le schéma

Celui-ci montre le module de commutation à quatre relais trouvés sur Aliexpress.
Cependant, rien n’interdit de les réaliser soi-même.

Schéma Prise Ethernet

Le fonctionnement

Un message MQTT est reçu par le microcontrôleur via la connexion Ethernet. Si son contenu concerne un équipement branché sur l’une des prises, le µC fait passer sa broche GPIO correspondante à 0, ce qui éclaire la LED de l’optocoupleur et sature son transistor. Le transistor du relais devient donc passant et celui-ci s’active, laissant passer le courant vers la prise.
Un interrupteur, au niveau de Q2 et Q3, court-circuite le collecteur et l’émetteur du transistor afin de forcer l’alimentation de ces prises.
Cela permet d’éviter d’interrompre les longues impressions 3D en cas de fausse manoeuvre au niveau de la centrale domotique !

Le matériel

Les liens ci-dessous sont donnés à titre d’exemples !

  • Un microcontrôleur ESP32 Devkit1c;
  • Un module Enc28j60 SPI;
  • Deux interrupteurs;
  • Un module à 4 relais;
  • Un boîtier imprimé en PLA;
  • Un câble d’alimentation muni d’une fiche avec terre;
  • Quatre prises pour boîtier. Dans mon cas, deux plates et deux rondes;
  • Une alimentation IRM10-5.

La partie software

Platformio.ini

[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
monitor_speed=115200
lib_deps = 
	uipethernet/UIPEthernet@^2.0.12
	sstaub/TickTwo@^4.4.0
	knolleary/PubSubClient@^2.8

jagprod.h

#ifndef jagprod_h
#define jagprod_h

// WiFi
#define sid "votre SSID"
#define wifi_sesame "Votre mot de passe WiFi"

// IP (Si utilisation en DHCP, supprimer cette partie)
const uint8_t ip[4] = {Adresse IP de l'hôte dans votre réseau};
const uint8_t mask[4] = {Masque de sous-réseaux};
const uint8_t ns[4] = {Adresse IP du serveur DNS};
const uint8_t gw[4] = {Adresse de la passerelle};

// MQTT
const char *mqtt_serveur = "adresse IP du serveur MQTT";
const uint16_t mqtt_port = port MQTT;
const char *mqtt_identifiant = "identifiant MQTT";
const char *mqtt_sesame = "Mot de passe MQTT";

#endif

main.cpp

4.97 KB
#include <Arduino.h>
#include <jagprod.h>
#include <WiFi.h>
#include <esp_wifi.h>

// Ethernet IP
#include <UIPEthernet.h>
#include <Dns.h>
const int ethernet_cs = 5;
void network_monitor();
int dnsetat = 0;
DNSClient dnscli;
bool network_statut = false;

// MQTT
#include <PubSubClient.h>
unsigned long derniere_connexion_mqtt = 0;
unsigned long mqtt_timeout = 5000;
bool mqtt_statut = false;
EthernetClient prisex4_1;
PubSubClient mqtt_client(prisex4_1);
void mqtt_reception(char *topic, byte *payload, unsigned int length);
static String message;

void network_monitor()
{
  if (Ethernet.linkStatus() != 1)
  {
    mqtt_client.disconnect();
    network_statut = false;
    mqtt_statut = false;
    return;
  }
  else
  {
    Serial.println("✅ Lien Ethernet ok");
    if (dnsetat != 1)
    {
      Ethernet.begin(mac, ip, ns, gw, mask);
      Serial.println("Stack IP redémarré !");
    }
    dnscli.begin(Ethernet.dnsServerIP());
    IPAddress ipcloud;
    int result = dnscli.getHostByName("cloud.vicou.be", ipcloud);
    dnsetat = result;
    if (dnsetat == 1)
    {
      Serial.println("Liaison IP ok");
      network_statut = true;
    }
  }
}

// Timers
#include <TickTwo.h>
TickTwo network_monitor_timer(network_monitor, 10000);

// Commande
const int relaistapo = 16;
const int relaisk1 = 4;
const int relaisk2 = 17;
const int relaisdrybox = 13;
bool etatrelaistapo = true;
bool etatrelaisk2 = true;
bool etatrelaisdrybox = true;
bool etatrelaisk1 = true;

void setup()
{
  Serial.begin(115200);
  // Commande
  pinMode(relaistapo, OUTPUT);
  pinMode(relaisk1, OUTPUT);
  pinMode(relaisk2, OUTPUT);
  pinMode(relaisdrybox, OUTPUT);
  digitalWrite(relaistapo, etatrelaistapo);
  digitalWrite(relaisdrybox, etatrelaisdrybox);
  digitalWrite(relaisk2, etatrelaisk2);
  digitalWrite(relaisk1, etatrelaisk1);
  WiFi.mode(WIFI_OFF);
  btStop();
  esp_wifi_stop();
  esp_wifi_deinit();

  // Ethernet IP
  Ethernet.init(ethernet_cs);

  // MQTT
  mqtt_client.setServer(mqtt_serveur, mqtt_port);
  mqtt_client.setCallback(mqtt_reception);

  network_monitor();
  network_monitor_timer.start();
}

void loop()
{
  network_monitor_timer.update();
  if (Ethernet.linkStatus() == 1)
  { // Pour éviter les blocages si le câble réseau est déconnecté !
    Ethernet.maintain();
    if (mqtt_client.state() == 0)
    {
      mqtt_client.loop();
    }
  }
  if (network_statut == true and mqtt_statut == false and millis() - derniere_connexion_mqtt > mqtt_timeout)
  {
    Serial.println("Tentative de connexion MQTT");
    if (mqtt_client.connect("prisex4_1", mqtt_identifiant, mqtt_sesame))
    {
      Serial.println("connecté ✅");
      mqtt_statut = true;
      // Réabonnement aux topics
    mqtt_client.subscribe("homeassistant/status");
    mqtt_client.subscribe("labo4/tapo/relais");
    mqtt_client.publish("labo4/tapo/connecte", "online");
    mqtt_client.subscribe("labo4/k1/relais");
    mqtt_client.publish("labo4/k1/connecte", "online");
    mqtt_client.subscribe("labo4/k2/relais");
    mqtt_client.publish("labo4/k2/connecte", "online");
    mqtt_client.subscribe("labo4/drybox/relais");
    mqtt_client.publish("labo4/drybox/connecte", "online");
    }
    else
    {
      Serial.print("⚠️ Échec (code ");
      Serial.print(mqtt_client.state());
      mqtt_statut = false;
    }
    derniere_connexion_mqtt = millis();
  }
}

void mqtt_reception(char *topic, byte *payload, unsigned int length)
{
  message = "";
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  for (unsigned int i = 0; i < length; i++)
  {
    message += (char)payload[i];
  }
  Serial.print("contenu : ");
  Serial.println(message);
  if (strcmp(topic, "labo4/tapo/relais") == 0)
  {
    etatrelaistapo = message.toInt();
    digitalWrite(relaistapo, etatrelaistapo);
    mqtt_client.publish("labo4/tapo/etat", etatrelaistapo ? "ON" : "OFF", true);
  }
  else if (strcmp(topic, "labo4/k1/relais") == 0)
  {
    etatrelaisk1 = message.toInt();
    digitalWrite(relaisk1, etatrelaisk1);
    mqtt_client.publish("labo4/k1/etat", etatrelaisk1 ? "OFF" : "ON", true);
  }
  else if (strcmp(topic, "labo4/k2/relais") == 0)
  {
    etatrelaisk2 = message.toInt();
    digitalWrite(relaisk2, etatrelaisk2);
    mqtt_client.publish("labo4/k2/etat", etatrelaisk2 ? "OFF" : "ON", true);
  }
  else if (strcmp(topic, "labo4/drybox/relais") == 0)
  {
    etatrelaisdrybox = message.toInt();
    digitalWrite(relaisdrybox, etatrelaisdrybox);
    mqtt_client.publish("labo4/drybox/etat", etatrelaisdrybox ? "OFF" : "ON", true);
  }
  else if (strcmp(topic, "homeassistant/status") == 0)
  {
    if (message == "online")
    {
      mqtt_client.publish("labo4/tapo/connecte", "online");
      mqtt_client.publish("labo4/k1/connecte", "online");
      mqtt_client.publish("labo4/k2/connecte", "online");
      mqtt_client.publish("labo4/drybox/connecte", "online");
    }
  }
}

Le boîtier

Le boîtier, imprimé en 3D, est réalisé à partir de ce modèle : « Boîtes rectangulaires personnalisables »

J’ai toutefois commis une petite erreur de conception 🫢.
La fixation à la droite du boîtier est gênée par la prise plate latérale !
Du coup, pour pouvoir attacher la boîte, il faut sortir ce soquet (prévoir des vis et câbles assez longs), placer les deux vis et ensuite, rentrer la prise. 😒
Je recommande plutôt de modifier le dessin du boîtier en allongeant la patte de fixation du côté droit.

Les fichiers, s’ils ne sont pas directement téléchargeables sont disponibles à la demande.

Laissez un commentaire et posez vos questions ci-dessous

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *