Fusionner sketchs MySensors - Comment gérer le SLEEP_TIME ? [RESOLU]

Forum dédie aux capteurs et gateway mysensors.org
lamaisondelou69
Messages : 24
Inscription : 16 mars 2020, 18:58

Fusionner sketchs MySensors - Comment gérer le SLEEP_TIME ? [RESOLU]

Message par lamaisondelou69 »

Bonjour,

Matériel : DOMOTICZ sur Raspberry, MySensors sur Arduino Uno

Je recontre une difficulté en fusionnant des sketches MySensors : j'ai fusionné des sketches Relais, détecteur de mouvement, interrupteurs et cellules photo-électriques, que j'avais testé individuellement, et fusionné petit à petit (ainsi, la partie relais, détecteur de mouvement et interrupteurs fonctionne sans problème).

Malheureusement, pour la partie cellule photoélectrique (idem pour les DHT22 d'ailleurs), il y a un sleep dans la partie Loop pour espacer les mesures de luminosité. Du coup, lorsque j'effectue une action sur un interrupteur par exemple, le changement d'état (On -> Off) ne vient se déclarer qu'après le sleep time dans Domoticz.

Comment puis-je modifier mon sketch Arduino pour passer outre ce sleep_time ?

Code : Tout sélectionner

// Enable debug prints to serial monitor
#define MY_DEBUG

// Enable gateway ethernet module type
#define MY_GATEWAY_W5100

// Enable Soft SPI for NRF radio (note different radio wiring is required)
// The W5100 ethernet module seems to have a hard time co-operate with
// radio on the same spi bus.
#if !defined(MY_W5100_SPI_EN) && !defined(ARDUINO_ARCH_SAMD)
#define MY_SOFTSPI
#define MY_SOFT_SPI_SCK_PIN 14
#define MY_SOFT_SPI_MISO_PIN 16
#define MY_SOFT_SPI_MOSI_PIN 15
#endif

// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
#define MY_IP_ADDRESS XXXX

// The port to keep open on node server mode / or port to contact in client mode
#define MY_PORT X

// The MAC address can be anything you want but should be unique on your network.
// Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use.
// Note that most of the Arduino examples use  "DEAD BEEF FEED" for the MAC address.
#define MY_MAC_ADDRESS X,X,X,X

// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
//#define MY_INCLUSION_BUTTON_FEATURE
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN  3

// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300

#if defined(MY_USE_UDP)
#include <EthernetUdp.h>
#endif
#include <Ethernet.h>
#include <MySensors.h>
#include <SPI.h>
#include <Bounce2.h>

#define MY_REPEATER_FEATURE

// Déclaration des variables
#define RELAY_PIN 4                         // <<<<<<<<<< indiquer le pin du premier relais (second on pin+1 etc)
#define NUMBER_OF_RELAYS 2                  // <<<<<<<<<<< Indiquer le nombre de relais ici

#define NUMBER_OF_SWITCHES 2                //<<<<<<<<<< indiquer le nombre d'interrupteurs ici
byte switchPin[NUMBER_OF_SWITCHES] = {8,9}; //<<<<<<<<<<< indiquer les pins interrupteurs ici

#define NB_DP 2                             //<<<<<<<<<< indiquer le nombre de motion sensor ici
byte DP_PIN[NB_DP] = {2,3};                 //<<<<<<<<<<< indiquer les pins de motion sensor ici (obligatoirement 2 et 3 sur UNO)

#define NB_CP 2                             //<<<<<<<< indiquer ici le nombre de capteurs photo-électriques            
byte CP_PIN[NB_CP] = {0,1};                 //<<<<<<<< indiquer ici les numéros de pin analogiques des capteurs photo-électriques
uint32_t SLEEP_TIME_CP = 3000;              //<<<<<< indiquer ici le temps de repos entre 2 lectures capteurs photo-électriques

// Variables pour relais
#define RELAY_ON 1  // GPIO value to write to turn on attached relay
#define RELAY_OFF 0 // GPIO value to write to turn off attached relay

// Variables pour interrupteurs
Bounce debouncer[NUMBER_OF_SWITCHES];
int oldValue[NUMBER_OF_SWITCHES];
MyMessage msgInter(0,V_LIGHT);
// Change to V_LIGHT if you use S_LIGHT in presentation below, V_TRIPPED si S_DOOR ou S_MOTION

// Variables pour détecteurs de présence
Bounce debouncerDP[NB_DP];
int oldValueDP[NB_DP];
MyMessage msg_DP(0,V_TRIPPED);

// Variables pour cellules photo-électriques
MyMessage msg_CP(NB_CP, V_LEVEL);
int lastLightLevel[NB_CP];
int lightlevel[NB_CP];

void before()
{
  for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        int num_relais = RELAY_PIN + sensor - 1;
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(num_relais)?RELAY_ON:RELAY_OFF);
    }
}

void setup()
{
	// Setup locally attached sensors*
  // Interrupteurs
  for (int j = 0; j < NUMBER_OF_SWITCHES; j++)
  {
    pinMode(switchPin[j],INPUT_PULLUP);
    debouncer[j] = Bounce();
    debouncer[j].attach(switchPin[j]);
    debouncer[j].interval(5);
  }

  // Détecteurs de mouvement
  for (int z = 0; z < NB_DP; z++)
  {
    pinMode(DP_PIN[z],INPUT_PULLUP);
    debouncerDP[z] = Bounce();
    debouncerDP[z].attach(DP_PIN[z]);
    debouncerDP[z].interval(5);
  }

}

void presentation()
{
	// present sensor to gateway

  sendSketchInfo("Relay", "1.0");

    for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Register all sensors to gw (they will be created as child devices)
        int num_relais = RELAY_PIN + sensor - 1;
        present(num_relais, S_BINARY);
    }

  // Détecteurs de mouvement
  // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 
  // If S_LIGHT is used, remember to update variable type you send in. See "msg_DP" above.
  for (int z = 0; z < NB_DP; z++)
  {
    present(DP_PIN[z], S_MOTION);
    delay(150);
  }

  // Interrupteurs
  // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 
  // If S_LIGHT is used, remember to update variable type you send in. See "msgInter" above.
  for (int j = 0; j < NUMBER_OF_SWITCHES; j++)
  {
    present(switchPin[j], S_LIGHT);
    delay(250);
  }

  // Cellules photoélectriques
    sendSketchInfo("Light Sensor", "1.0");
    for (int k = 0; k < NB_CP; k++){
      present(CP_PIN[k], S_LIGHT_LEVEL);
      delay(250);
    }
  
}

void loop()
{
	// Send locally attached sensors data here
  // Détecteurs de mouvement
  for (int z = 0; z < NB_DP; z++)
  {
    debouncerDP[z].update();
    int valueDP = debouncerDP[z].read();
    if (valueDP != oldValueDP[z]) 
    {
      send(msg_DP.setSensor(DP_PIN[z]).set(valueDP == HIGH? true : false), false); 
    }
    oldValueDP[z] = valueDP;
  }

  // Interrupteurs
  for (int j = 0; j < NUMBER_OF_SWITCHES; j++)
  {
    debouncer[j].update();
    int value = debouncer[j].read();
    if (value != oldValue[j]) 
    {
      send(msgInter.setSensor(switchPin[j]).set(value == HIGH? true : false), false); 
    }
    oldValue[j] = value;
  }

  // Cellules photoélectriques
  for (int k = 0; k < NB_CP; k++)
    {
  
  int lightLevel = (analogRead(CP_PIN[k]));
  if (lightLevel != lastLightLevel[k]) {
        send(msg_CP.setSensor(CP_PIN[k]).set(lightLevel));
        lastLightLevel[k] = lightLevel;
    }
  sleep(SLEEP_TIME_CP);
    }
  
}

void receive(const MyMessage &message)
{
  // We only expect one type of message from controller. But we better check anyway.
  // Relais
    if (message.getType()==V_STATUS) {
        // Change relay state
        digitalWrite(message.getSensor(), message.getBool()?RELAY_ON:RELAY_OFF);  
        // Store state in eeprom
        saveState(message.getSensor(), message.getBool());
    }
}
Merci d'avance pour vos suggestions éclairées !
Dernière modification par lamaisondelou69 le 04 mai 2020, 14:18, modifié 2 fois.
lamaisondelou69
Messages : 24
Inscription : 16 mars 2020, 18:58

Re: Fusionner sketchs MySensors - Comment gérer le SLEEP_TIME ? [RESOLU]

Message par lamaisondelou69 »

Je n'aurais jamais trouvé tout seul, merci les forums (celui de mysensors en l'occurence) !

Donc, la solution est simple et élégante. On supprime la commande sleep de la boucle loop par une fonction personnalisée (ici update_CP) qu'on va créer ensuite (un nouveau paragraphe void).

Et ça donne ça (compilé et testé).

Code : Tout sélectionner

// Enable debug prints to serial monitor
#define MY_DEBUG

// Enable gateway ethernet module type
#define MY_GATEWAY_W5100

// Enable Soft SPI for NRF radio (note different radio wiring is required)
// The W5100 ethernet module seems to have a hard time co-operate with
// radio on the same spi bus.
#if !defined(MY_W5100_SPI_EN) && !defined(ARDUINO_ARCH_SAMD)
#define MY_SOFTSPI
#define MY_SOFT_SPI_SCK_PIN 14
#define MY_SOFT_SPI_MISO_PIN 16
#define MY_SOFT_SPI_MOSI_PIN 15
#endif

// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
#define MY_IP_ADDRESS X.X.X.X    //<<<<<< indiquer ici l'adresse IP que vous voulez donner à l'Arduino

// The port to keep open on node server mode / or port to contact in client mode
#define MY_PORT X     //<<<<<<< indiquer ici le port à utliser (utiliser le même dans DOMOTICZ)

// The MAC address can be anything you want but should be unique on your network.
// Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use.
// Note that most of the Arduino examples use  "DEAD BEEF FEED" for the MAC address.
#define MY_MAC_ADDRESS X,X,X,X    //<<<<<<< indiquer ici l'adresse MAC de l'Arduino (à récupérer avec le sketch Récupérer adresse MAC

// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
//#define MY_INCLUSION_BUTTON_FEATURE
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN  3

// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300

#if defined(MY_USE_UDP)
#include <EthernetUdp.h>
#endif
#include <Ethernet.h>
#include <MySensors.h>
#include <SPI.h>
#include <Bounce2.h>

#define MY_REPEATER_FEATURE

// Déclaration des variables
#define RELAY_PIN 4                         // <<<<<<<<<< indiquer le pin du premier relais (second on pin+1 etc)
#define NUMBER_OF_RELAYS 2                  // <<<<<<<<<<< Indiquer le nombre de relais ici

#define NUMBER_OF_SWITCHES 2                //<<<<<<<<<< indiquer le nombre d'interrupteurs ici
byte switchPin[NUMBER_OF_SWITCHES] = {8,9}; //<<<<<<<<<<< indiquer les pins interrupteurs ici

#define NB_DP 2                             //<<<<<<<<<< indiquer le nombre de motion sensor ici
byte DP_PIN[NB_DP] = {2,3};                 //<<<<<<<<<<< indiquer les pins de motion sensor ici (obligatoirement 2 et 3 sur UNO)

#define NB_CP 2                             //<<<<<<<< indiquer ici le nombre de capteurs photo-électriques            
byte CP_PIN[NB_CP] = {0,1};                 //<<<<<<<< indiquer ici les numéros de pin analogiques des capteurs photo-électriques
uint32_t SLEEP_TIME_CP = 3000;              //<<<<<< indiquer ici le temps de repos entre 2 lectures capteurs photo-électriques

// Variables pour relais
#define RELAY_ON 1  // GPIO value to write to turn on attached relay
#define RELAY_OFF 0 // GPIO value to write to turn off attached relay

// Variables pour interrupteurs
Bounce debouncer[NUMBER_OF_SWITCHES];
int oldValue[NUMBER_OF_SWITCHES];
MyMessage msgInter(0,V_LIGHT);
// Change to V_LIGHT if you use S_LIGHT in presentation below, V_TRIPPED si S_DOOR ou S_MOTION

// Variables pour détecteurs de présence
Bounce debouncerDP[NB_DP];
int oldValueDP[NB_DP];
MyMessage msg_DP(0,V_TRIPPED);

// Variables pour cellules photo-électriques
MyMessage msg_CP(NB_CP, V_LEVEL);
int lastLightLevel[NB_CP];
int lightlevel[NB_CP];

void before()
{
  for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        int num_relais = RELAY_PIN + sensor - 1;
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(num_relais)?RELAY_ON:RELAY_OFF);
    }
}

void setup()
{
	// Setup locally attached sensors*
  // Interrupteurs
  for (int j = 0; j < NUMBER_OF_SWITCHES; j++)
  {
    pinMode(switchPin[j],INPUT_PULLUP);
    debouncer[j] = Bounce();
    debouncer[j].attach(switchPin[j]);
    debouncer[j].interval(5);
  }

  // Détecteurs de mouvement
  for (int z = 0; z < NB_DP; z++)
  {
    pinMode(DP_PIN[z],INPUT_PULLUP);
    debouncerDP[z] = Bounce();
    debouncerDP[z].attach(DP_PIN[z]);
    debouncerDP[z].interval(5);
  }

}

void presentation()
{
	// present sensor to gateway

  sendSketchInfo("Relay", "1.0");

    for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Register all sensors to gw (they will be created as child devices)
        int num_relais = RELAY_PIN + sensor - 1;
        present(num_relais, S_BINARY);
    }

  // Détecteurs de mouvement
  // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 
  // If S_LIGHT is used, remember to update variable type you send in. See "msg_DP" above.
  for (int z = 0; z < NB_DP; z++)
  {
    present(DP_PIN[z], S_MOTION);
    delay(150);
  }

  // Interrupteurs
  // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 
  // If S_LIGHT is used, remember to update variable type you send in. See "msgInter" above.
  for (int j = 0; j < NUMBER_OF_SWITCHES; j++)
  {
    present(switchPin[j], S_LIGHT);
    delay(250);
  }

  // Cellules photoélectriques
    sendSketchInfo("Light Sensor", "1.0");
    for (int k = 0; k < NB_CP; k++){
      present(CP_PIN[k], S_LIGHT_LEVEL);
      delay(250);
    }
  
}

void loop()
{
	// Send locally attached sensors data here
  // Détecteurs de mouvement
  for (int z = 0; z < NB_DP; z++)
  {
    debouncerDP[z].update();
    int valueDP = debouncerDP[z].read();
    if (valueDP != oldValueDP[z]) 
    {
      send(msg_DP.setSensor(DP_PIN[z]).set(valueDP == HIGH? true : false), false); 
    }
    oldValueDP[z] = valueDP;
  }

  // Interrupteurs
  for (int j = 0; j < NUMBER_OF_SWITCHES; j++)
  {
    debouncer[j].update();
    int value = debouncer[j].read();
    if (value != oldValue[j]) 
    {
      send(msgInter.setSensor(switchPin[j]).set(value == HIGH? true : false), false); 
    }
    oldValue[j] = value;
  }

  // Cellules photoélectriques
  update_CP(SLEEP_TIME_CP);
}

void update_CP(int frequence_CP)
{
  static unsigned long lastupdateTime_CP;
  if (millis() - lastupdateTime_CP >= frequence_CP)
  {
    for (int k = 0; k < NB_CP; k++)
    {
  
      int lightLevel = (analogRead(CP_PIN[k]));
      if (lightLevel != lastLightLevel[k]) 
      {
        send(msg_CP.setSensor(CP_PIN[k]).set(lightLevel));
        lastLightLevel[k] = lightLevel;
      }
    }
    lastupdateTime_CP += frequence_CP;
  }
  
}

void receive(const MyMessage &message)
{
  // We only expect one type of message from controller. But we better check anyway.
  // Relais
    if (message.getType()==V_STATUS) {
        // Change relay state
        digitalWrite(message.getSensor(), message.getBool()?RELAY_ON:RELAY_OFF);  
        // Store state in eeprom
        saveState(message.getSensor(), message.getBool());
    }
}
domdom
Messages : 79
Inscription : 20 mai 2016, 10:48
Localisation : Ille-et-Vilaine

Re: Fusionner sketchs MySensors - Comment gérer le SLEEP_TIME ? [RESOLU]

Message par domdom »

Bonsoir,
Rien à ajouter, la solution est en effet élégante et pertinente.
Merci d'avoir pris la peine de venir poster la réponse ici.
Bonne soirée
Répondre