Обычный выключатель

Ответить
mikhail
Сообщения: 15
Зарегистрирован: Вс июн 12, 2016 4:57 pm
Благодарил (а): 3 раза
Поблагодарили: 8 раз

Обычный выключатель

Сообщение mikhail » Сб янв 27, 2018 11:37 am

Для тех у кого голова болит от кода больше 100 строк, привожу пример честно украденный с форума mysensors.org :D
Функционал скетча - обычная кнопка и реле в одном модуле. Я ни где не мог найти пример , то разнесенная кнопка и модуль , то лишний функционал , разобраться в котором с моими знаниями очень тяжело.

Данное устройство работает и выполняет свои функции даже если не доступен шлюз . И при восстановлении связи со шлюзом передает свое состояние.
Статус не обновляется только в одной ситуации. Когда перегружается контролер вмсесте со шлюзом , и в это время меняется статус NODE. После запуска контроллера и шлюза статус отображается неверно.
Сам скетч.
СпойлерПоказать

Код: Выделить всё

/*
   Relay with button sketch
   modified to work with no uplink
   to gateway and try to maintain sync to controller
*/


#define MY_DEBUG                               // Enable debug prints to serial monitor

//#define MY_RADIO_RFM69
//#define MY_RFM69_FREQUENCY RF69_868MHZ
//#define MY_IS_RFM69HW                         // Enable and select radio type attached

#define MY_RADIO_NRF24 // Определаем тип радио модуля


#define MY_TRANSPORT_WAIT_READY_MS 5000        //set how long to wait for transport ready in milliseconds

// Enabled repeater feature for this node
#define MY_REPEATER_FEATURE

// Node id defaults to AUTO (tries to fetch id from controller)
#define MY_NODE_ID 118

#include <MySensors.h>
#include <Bounce2.h>

#define RELAY_PIN  3      // Arduino Digital I/O pin number for relay 
#define BUTTON_PIN  6     // Arduino Digital I/O pin number for button 
#define CHILD_ID 1        // Id of the sensor child
#define RELAY_ON 1
#define RELAY_OFF 0

Bounce debouncer = Bounce();
int oldValue = 0;
bool uplinkAvailable = true;
bool state = false;
bool requestState;
bool firstStart = true;
unsigned long uplinkCheckTime ;                // holder for uplink checks
unsigned long uplinkCheckPeriod = 30*1000;     // time between checks for uplink in milliseconds
unsigned long returnWait = 1000;               // how long to wait for return from controller in milliseconds
MyMessage msg(CHILD_ID, V_STATUS);

void setup(){
  pinMode(BUTTON_PIN, INPUT_PULLUP);           // Setup the button pin, Activate internal pull-up
  
  debouncer.attach(BUTTON_PIN);                // After setting up the button, setup debouncer
  debouncer.interval(5);

  pinMode(RELAY_PIN, OUTPUT);                 // set relay pin in output mode
  digitalWrite(RELAY_PIN, RELAY_OFF);         // Make sure relay is off when starting up
}

void presentation()  {
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo("Relay & Button", "1.0");

  // Register all sensors to gw (they will be created as child devices)
  present(CHILD_ID, S_BINARY);
}


void loop(){
  if (firstStart) {                            // this code is only run once at startup
    Serial.println("First run started");
    if (request( CHILD_ID, V_STATUS)) {       // request the current state of the switch on the controller and check that an ack was received
      Serial.println("uplink available");
      wait (returnWait);                      //wait needed to allow request to return from controller
      Serial.print("controller state --- ");
      Serial.println(requestState);
      if (requestState != state) {           // check that controller is corectly showing the current relay state
        send(msg.set(state), false);         // notify controller of current state
      }
    }
    else {
      Serial.println("uplink not available");
      uplinkAvailable = false;               // no uplink established
      uplinkCheckTime = millis();
    }
    firstStart = false;                     // set firstStart flag false to prevent code from running again
  }

  debouncer.update();
  int value = debouncer.read();                               // Get the update value
  if (value != oldValue && value == 0) {                      // check for new button push
    state =  !state;                                          // Toggle the state
    digitalWrite(RELAY_PIN, state ? false:true  );    // switch the relay to the new state
    if (!send(msg.set(state), true)) {                        //Attempt to notify controller of changed state
      Serial.println("uplink not available");
      uplinkAvailable = false;                                // no uplink available
      uplinkCheckTime = millis();                             
    }
  }
 oldValue = value;

  if (!uplinkAvailable && (millis() - uplinkCheckTime > uplinkCheckPeriod) ) {       // test to see if function should be called
    uplinkCheck();                                                                  // call uplink checking function
  }

}

/*-------------------start of functions--------------------------*/

void receive(const MyMessage &message) {
  if (message.type == V_STATUS) {                                   // check to see if incoming message is for a switch
    switch (message.getCommand()) {                                 // message.getCommand will give us the command type of the incomming message
      case C_SET:                                                   //message is a set command  from controller to update relay state
        state = message.getBool();                                  // get the new state
        digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);      // switch relay to new state
        uplinkAvailable = true;                                     //  uplink established
        /*---- Write some debug info----*/
        Serial.print("Incoming change for sensor:");
        Serial.print(message.sensor);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
        break;
      case C_REQ:                                               // message is a returning request from controller
        requestState = message.getBool();                       // update requestState with returning state
        break;
    }
  }
}

void uplinkCheck() {
  if (request( CHILD_ID, V_STATUS)) {         // request the current state of the switch on the controller and check that the request was succsessful
    Serial.println("uplink re-established");
    wait (returnWait);                        //wait needed to allow request to return from controller
    if (requestState != state) {              // check that controller is corectly showing the current relay state
      send(msg.set(state), false);            // notify controller of current state no ack
      uplinkAvailable = true;                 //  uplink established
    }
  }
  uplinkCheckTime = millis();                // reset the checktime
  Serial.println("uplinkchecktime reset");
}
 
ahelper
Сообщения: 105
Зарегистрирован: Ср фев 08, 2017 5:04 pm
Благодарил (а): 34 раза
Поблагодарили: 66 раз

Re: Обычный выключатель

Сообщение ahelper » Вт фев 13, 2018 6:31 pm

Потестил данный выключатель, нужно еще дорабатывать! Глюки с отправкой последнего состояния на шлюз.
Ответить