Reapeter and relay actuactor



  • Hi all,

    First, thanks for all the work on MySesnor project, it's fun and working perfectly.
    But still have one question on repeater and relay actuator.

    From my house, i have a serial gateway on a Arduino Uno, different node, and one node as repeater because some node are far away and sometime reach the gateway directly, sometime not.
    For this repeater, could it work with a "receive" function i use for a relay actuator ? Seem not, but not sure.
    Or do I need to add some function in the receive function in order to process incoming messages to repeat ?

    Here, the same code use for the far node and repeater, off course, i enable repeat feature if need

    Some comment on best codung is also possible, i'm not a king in coding ;)

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Noeud 3 ârent par défaut, si le neoud répond pas une nouvelle election a lieu
    //#define MY_PARENT_NODE_ID 3
    
    //#define MY_PARENT_NODE_IS_STATIC
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    // Set LOW transmit power level as default, if you have an amplified NRF-module and
    // power your radio separately with a good regulator you can turn up PA level.
    #define MY_RF24_PA_LEVEL RF24_PA_MAX  //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH or RF24_PA_MAX.
    
    // Enable repeater functionality for this node
    #define MY_REPEATER_FEATURE
    
    #include <SPI.h>
    #include <MySensors.h>
    
    
    #include <DallasTemperature.h>
    #include <OneWire.h>
    #include <Bounce2.h>  //pour les boutons
    
    #define ONE_WIRE_BUS 4 // Pin where dallase sensor is connected 
    #define MAX_ATTACHED_DS18B20 16
    #define INTER1 2
    #define INTER2 3
    
    #define RELAY_1  6  // Lamp as a RELAYArduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 1 // Total number of attached relays
    #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
    
    OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature.
    float lastTemperature[MAX_ATTACHED_DS18B20];
    int numSensors = 1;
    bool receivedConfig = false;
    bool metric = true;
    // Initialize temperature message
    MyMessage msg(4, V_TEMP);
    MyMessage msg1(1, V_TRIPPED);
    MyMessage msg2(2, V_TRIPPED);
    MyMessage msg4(5, V_STATUS);
    
    Bounce debouncer_one = Bounce();
    Bounce debouncer_two = Bounce();
    
    void before() {
    
      sensors.begin();
    
    }
    
    void setup() {
      pinMode(INTER1, INPUT); // sets the digital pin as input
      pinMode(INTER2, INPUT); // sets the digital pin as input
    
      // Activate internal pull-ups  ?
      digitalWrite(INTER1, LOW);
      digitalWrite(INTER2, LOW);
    
    
      // After setting up the button, setup debouncer
      debouncer_one.attach(INTER1);
      debouncer_one.interval(100);
    
      // Deuxieme bouton
      debouncer_two.attach(INTER2);
      debouncer_two.interval(50);
    
      for (int RELAY = 5, pin = RELAY_1; RELAY <= NUMBER_OF_RELAYS + 5; RELAY++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
      }
    
    }
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Boitier Complet", "1.9");
    
      for (int RELAY = 5, pin = RELAY_1; RELAY <= NUMBER_OF_RELAYS + 4; RELAY++, pin++) {
        // Register all sensors to gw (they will be created as child devices)
        present(RELAY, S_LIGHT);
    
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(RELAY) ? RELAY_ON : RELAY_OFF);
      }
    
      // Fetch the number of attached temperature sensors
      numSensors = sensors.getDeviceCount();
    
      // Present all sensors to controller
      for (int i = 4; i < numSensors + 4 && i < MAX_ATTACHED_DS18B20; i++) {
        present(i, S_TEMP);
      }
    
      // Present all button to controler
      for (int i = 1; i < 3; i++) {
        present(i, S_DOOR);
      }
    
    }
    
    
    void loop()
    {
      // Gestion de la temperature
      // Fetch temperatures from Dallas sensors
      sensors.requestTemperatures();
    
      // Read temperatures and send them to controller
      for (int i = 0; i < numSensors && i < MAX_ATTACHED_DS18B20; i++) {
    
        // Fetch and round temperature to one decimal
        float temperature = static_cast<float>(static_cast<int>(( sensors.getTempCByIndex(i)) * 10.)) / 10.;
    
        float TempValue1 = temperature * 10;
        int TempValue2 = (int)TempValue1;
        int Calcul = TempValue2 - lastTemperature[i] ;
        Calcul = abs(Calcul);
    
    
        // Only send data if temperature has changed and no error
        if ( Calcul > 2 ) {
    
          // Send in the new temperature
          send(msg.setSensor(i + 4).set(temperature, 1));
          lastTemperature[i] = TempValue2;
    
        }
      }
    
      boolean stateChanged_one = debouncer_one.update();
    
    
      if ( stateChanged_one ) {
    
        // Get relay state
        boolean Relay_state = loadState(msg4.sensor) ? RELAY_ON : RELAY_OFF ;
        boolean New_state = 0;
        // Change relay state
        if (Relay_state == RELAY_ON ) {
          // Nouvel Etat
          New_state = 0;
        }
        else {
          New_state = 1;
        }
        // Activation du PIN
        digitalWrite(msg4.sensor - 5 + RELAY_1, New_state);
        //digitalWrite(RELAY_1, New_state);
        // Envoi des infos au controleur
        send(msg4.set(New_state ? "1" : "0"), 0);
        // Envoi du changement d'état de l'inter
        send(msg1.set(digitalRead(INTER1) ? "1" : "0"), 0);
        // Store state in eeprom
        saveState(msg4.sensor, New_state);
      }
    
      // Deuxieme bouton
    
      boolean stateChanged_two = debouncer_two.update();
    
      if ( stateChanged_two ) {
    
        send(msg2.set(digitalRead(INTER2) ? "1" : "0"), 0);
    
      }
    
    }
    
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type == V_LIGHT) {
        // Change relay state
        digitalWrite(message.sensor - 5 + RELAY_1, message.getBool() ? RELAY_ON : RELAY_OFF);
        // Store state in eeprom
        saveState(message.sensor, message.getBool());
        // Write some debug info
        Serial.print("Incoming change for sensor:");
        Serial.print(message.sensor);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
      }
    }
    

    Thanks a lot



  • @guillaume-brucker
    Just enabling the repeater feature should do the trick - as you already did.

    But: The way you solved the DS18B20 part will most likely cause troubles:
    First, imo, it is not recommended to make a measurement each time you go through the loop(), to me, it seems to be better to skip this part as long as not a minimum time has passed since last measurement - if you want to know how to achieve this: see e.g. the ServoActuator-Example.

    Second, usually one has to wait a conversionTime, until the DS18x20 gives an answer. This can be done blocking (this seems to be standard), but has the disadvantage, that you may also miss keypresses within this periode (1sec. as default).
    Imo you may get around that by initialising the sensors with sensors.setWaitForConversion(false); (after begin() in before()) and issue a requestTemperatures after minPeriod has passed an then read the temperatures, if minPeriod+conversionTime has passed (use an older Version of the DStemp-lib, if you encounter problems with conversionTime) .

    May sound a little complicated at first glance, but isn't rocket science...



  • @rejoe2
    Hi ,

    So if i understand, no need to chnage receive function to process repeater feature and incoming message for actuator.
    But one issue of communication in repeater, and other node, may be the way i process the D18b20 component.
    I'll check and keep you inform

    Thanks



  • This post is deleted!


  • @guillaume-brucker
    In fact the question, is
    Does i need to make change if i want to make a repeater sensor with a relay actuator.
    There is lot of example of repeater, repeater with sensor, but not with actuator, Mine can be the first :)



  • @guillaume-brucker It is definitely not first! I got at least one working for more than 20 months:simple_smile:
    So the simple answer remains: beside the definition of the repeater feature itself there is no need for any further change in the code of any working node's code - apart from the obvious check that there is no "sleep()" used anywhere in the sketch:laughing:.
    Onother question may be to suply the node with enough power. Relays need some when working and the node may have to handle more transmissions.



  • @rejoe2
    Thanks rojoe2,
    I don't really use relay, too much power consumption, i use opto-triac to manage light.
    Less consumption and noise
    Will try with a single repeater, but you're right with the D18B20, it take much time each loop, i'll see the change when power on the light, there is no delay now :+1:


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.