Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. isAck(): differentiation between sent and received messages

isAck(): differentiation between sent and received messages

Scheduled Pinned Locked Moved Development
5 Posts 2 Posters 103 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    frober
    wrote on last edited by
    #1

    Excuse my English, I have to work with translators.

    Hello, everybody,
    I get messages about Fhem and request and send messages to Fhem as well.
    Now I want to use Software-ACK and isAck() (new isEcho()) to make sure that the sent messages arrive.
    Problem is, the requests and messages from Fhem do not contain Ack and the serial port goes into endless loop.
    How can I check the messages in this regard (set, request)?

    1 Reply Last reply
    1
    • F Offline
      F Offline
      frober
      wrote on last edited by
      #2

      I have found a way:

      message.getCommand()

      skywatchS 1 Reply Last reply
      1
      • F frober

        I have found a way:

        message.getCommand()

        skywatchS Offline
        skywatchS Offline
        skywatch
        wrote on last edited by
        #3

        @frober Great news! - Perhaps you can post an example to help others who may hit the same problem?

        1 Reply Last reply
        1
        • F Offline
          F Offline
          frober
          wrote on last edited by frober
          #4

          As soon as all tests are positive, I will publish an example.

          I found my solution here, first entry:
          Sketch

          1 Reply Last reply
          1
          • F Offline
            F Offline
            frober
            wrote on last edited by
            #5

            The approach to differentiate the message did not work for my purpose:

            • commands sent from Fhem are a set message
            • requests return as set message
            • Status message of the node (set message) returns as set message with Ack

            I.e. all are set messages (no differentiation possible)

            Because I use a counter to limit the resending of the status message from the node I used this counter to get to the destination.

            In short: If the reception was successful the counter goes to 0, the request to <0 and the send to >0.

            Here is my sketch, it is for switching several time controlled relays, for clarity I have removed the debug messages:

            /**
            * The MySensors Arduino library handles the wireless radio link and protocol
            * between your home built sensors/actuators and HA controller of choice.
            * The sensors forms a self healing radio network with optional repeaters. Each
            * repeater and gateway builds a routing tables in EEPROM which keeps track of the
            * network topology allowing messages to be routed to nodes.
            *
            * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
            * Copyright (C) 2013-2018 Sensnology AB
            * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
            *
            * Documentation: http://www.mysensors.org
            * Support Forum: http://forum.mysensors.org
            *
            * This program is free software; you can redistribute it and/or
            * modify it under the terms of the GNU General Public License
            * version 2 as published by the Free Software Foundation.
            *
            *******************************
            *
            * DESCRIPTION
            * The RS485 Gateway prints data received from sensors on the serial link.
            * The gateway accepts input on seral which will be sent out on
            * the RS485 link.
            *
            * Wire connections (OPTIONAL):
            * - Inclusion button should be connected between digital pin 3 and GND
            * - RX/TX/ERR leds need to be connected between +5V (anode) and digital pin 6/5/4 with resistor 270-330R in a series
            *
            * LEDs (OPTIONAL):
            * - RX (green) - blink fast on radio message received. In inclusion mode will blink fast only on presentation received
            * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
            * - ERR (red) - fast blink on error during transmission error or receive crc error
            *
            * If your Arduino board has additional serial ports
            * you can use to connect the RS485 module.
            * Otherwise, the gateway uses AltSoftSerial to handle two serial
            * links on one Arduino. Use the following pins for RS485 link
            *
            *  Board          Transmit  Receive   PWM Unusable
            * -----          --------  -------   ------------
            * Teensy 3.0 & 3.1  21        20         22
            * Teensy 2.0         9        10       (none)
            * Teensy++ 2.0      25         4       26, 27
            * Arduino Uno        9         8         10
            * Arduino Leonardo   5        13       (none)
            * Arduino Mega      46        48       44, 45
            * Wiring-S           5         6          4
            * Sanguino          13        14         12
            *
            */
            
            #define SN "MultiTimerRelay"
            #define SV "1.0"
            
            // Enable debug prints to serial monitor
            #define MY_DEBUG
            
            // Enable RS485 transport layer
            #define MY_RS485
            
            // Define this to enables DE-pin management on defined pin
            //#define MY_RS485_DE_PIN 2
            
            // Set RS485 baud rate to use
            #define MY_RS485_BAUD_RATE 19200
            
            // Enable this if RS485 is connected to a hardware serial port
            #define MY_RS485_HWSERIAL Serial
            
            #define MY_NODE_ID 2   // Id of the Node
            #define MY_TRANSPORT_WAIT_READY_MS 30000  //loop is beginning at 3000ms whitout connection
            
            
            #include <MySensors.h>
            
            //++++++++ Relays +++++++++
            #define RELAY_ON 1                         // switch around for ACTIVE LOW / ACTIVE HIGH relay
            #define RELAY_OFF 0
            #define noRelays 3                         // min 2
            const int relayPin[] = {7, 8, 9};          // switch around pins to your desire
            uint32_t relayTime[] = {0, 0, 0};          // on time for Relay to set from Fhem
            volatile uint32_t startTime[] = {0, 0, 0}; // time to switch Relay on
            int relayAckCountR[noRelays];              // ACK retry counter relay
            int relayAckCountT[noRelays];              // ACK retry counter time
            const uint32_t timeFactor = 1000UL;        // to send minutes = 60000UL or seconds = 1000UL; UL says compiler is unsigned long!!!
            
            class Relay                                // relay class, store all relevant data (equivalent to struct)
            {
              public:
                int relayPin;                          // physical pin number of relay
                boolean relayState;                    // relay status (also stored in EEPROM)
                uint32_t relayTime;                    // on time for Relay
                uint32_t startTime;                    // time to switch Relay on
                int relayAckCountR;                     // ACK retry counter relay
                int relayAckCountT;                     // ACK retry counter time
            };
            
            Relay Relays[noRelays];
            MyMessage msgRelay[noRelays];
            MyMessage msgTime[noRelays];
            
            
            void before() 
            {
              
            }
            
            void presentation() 
            {
              // Send the sketch version information to the gateway and Controller
              sendSketchInfo(SN, SV);
            
               //++++++++ Relays +++++++++
               for (int i = 0; i < noRelays; i++)
              {
                present(i, S_DIMMER);                                  // present sensor to gateway
                wait(20);
              }
             }
            
            void setup()
            {
              //++++++++ Relays +++++++++
              for (int i = 0; i < noRelays; i++) {    
                Relays[i].relayPin = relayPin[i];           // assign physical pins
                Relays[i].startTime = startTime[i];         // assign time to switch relay on
                Relays[i].relayTime = relayTime[i];         // assign time for relay on
                msgRelay[i].sensor = i;                     // initialize messages
                msgRelay[i].type = V_STATUS;
                msgTime[i].sensor = i;                       
                msgTime[i].type = V_PERCENTAGE;
                pinMode(Relays[i].relayPin, OUTPUT);
                Relays[i].relayState = RELAY_OFF;           // set all relaysState off
                digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF); // write all relays off
                //send(msgRelay[i].set(Relays[i].relayState ? true : false));
                wait(20);
                }
              for (int i = 0; i < noRelays; i++)
              {
                request(i, V_STATUS);                        // Set relay to last known state
                Relays[i].relayAckCountR = -1;               // for the control of the request
                wait(100);
                request(i, V_PERCENTAGE);                   // Set relay to last known state
                Relays[i].relayAckCountT = -1;              // for the control of the request
                wait(100);
              }
            }
            
            void loop() 
            {
              //++++++++ Relays +++++++++
              uint32_t currentTime = millis();
              
              //Zeitsteuerung der Relays
              for (byte i = 0; i < noRelays; i++) {
                if ( Relays[i].relayState == RELAY_ON && (currentTime - Relays[i].startTime > Relays[i].relayTime)) {
                  digitalWrite(Relays[i].relayPin, !Relays[i].relayState ? RELAY_ON : RELAY_OFF);
                  Relays[i].relayState = !Relays[i].relayState;
                  send(msgRelay[i].set(Relays[i].relayState ? true : false), true); // Send value to gw with ACK
                  Relays[i].relayTime = 0;
                  Relays[i].relayAckCountR = 3;
                  wait(100);
                  send(msgTime[i].set(Relays[i].relayTime), true); // Send value to gw with ACK
                  Relays[i].relayAckCountT = 3;
                  wait(100);
            
                 }
              }
              for (int i = 0; i < noRelays; i++) {
                if (Relays[i].relayAckCountR < 0) {
                  wait(200);
                  request(i, V_STATUS);                        // Set relay to last known state
                  Relays[i].relayAckCountR = 0;
                  wait(100);
               
                 }
                 if (Relays[i].relayAckCountT < 0) {
                  wait(200);
                  request(i, V_PERCENTAGE);                    // Set relay to last known state
                  Relays[i].relayAckCountT = 0;
                  wait(100);
                
                 }
              if (Relays[i].relayAckCountR > 0) {
                  wait(200);
                  send(msgRelay[i].set(Relays[i].relayState ? true : false), true); // Send value to gw with ACK
                  wait(100);
                 
                 }
                 if (Relays[i].relayAckCountT > 0) {
                  wait(200);
                  send(msgTime[i].set(Relays[i].relayTime), true); // Send value to gw with ACK
                  wait(100);
                  
                 }
              }
            }
            
            
            void receive(const MyMessage &message) {
            
             //++++++++ Relays +++++++++
              if (message.type == V_STATUS && Relays[message.sensor].relayAckCountR <= 0) {
                Relays[message.sensor].relayAckCountR = 0;
                if (message.sensor < noRelays) {          // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
                  Relays[message.sensor].relayState = message.getBool();
                  digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly
                  //saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
                  }
                if (Relays[message.sensor].relayState == RELAY_ON) {
                  Relays[message.sensor].startTime = millis();
                }
             }
             else if (message.isAck() && message.type == V_STATUS && Relays[message.sensor].relayAckCountR > 0) {
                  Relays[message.sensor].relayAckCountR = 0;
             }
             else if (!message.isAck() && message.type == V_STATUS && Relays[message.sensor].relayAckCountR > 0) {
                  Relays[message.sensor].relayAckCountR--;
             }
             else if (message.type == V_PERCENTAGE && Relays[message.sensor].relayAckCountT <= 0) {
                if (message.sensor < noRelays) {          // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
                  Relays[message.sensor].relayTime = (message.getByte() * timeFactor);    // calculate to millis
                  }
             }
             else if (message.isAck() && message.type == V_PERCENTAGE && Relays[message.sensor].relayAckCountT > 0) {
                  Relays[message.sensor].relayAckCountT = 0;
             }
             else if (!message.isAck() && message.type == V_PERCENTAGE && Relays[message.sensor].relayAckCountT > 0) {
                  Relays[message.sensor].relayAckCountT --;
             }
            }
             
            
            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            10

            Online

            11.7k

            Users

            11.2k

            Topics

            113.1k

            Posts


            Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • MySensors
            • OpenHardware.io
            • Categories
            • Recent
            • Tags
            • Popular