Sleepy end device causing missed report of variable change

Greetings, i'm developing a custom sleepy end device whose role is to detect whether a certain event is occurring, this triggers the update (EDIT: via interrupt handler) of a custom cluster boolean attribute that is then reported to the coordinator, once the event stops being detected, the boolean attribute is then reset by means of a Zephyr timer.

I have noticed that, with the sleepy end device behavior configured, sometimes the device fails to report the change from "false" to "true", but then reports correctly the change back to false when the timer expires.

A check with a packet sniffer further confirmed the fact that the packet is simply not being sent.

How can i solve this issue?
Thanks in advance

EDIT: addendum
After setting up the project to log to RTT and checking more with a DK running the Shell sample as coordinator, i see the following:
-the sending of the report packet seems delayed by around 2-4 seconds (tested by counting the time between a led turning off, signaling the update of the attribute to false and the reception of the report)
-the RTT does not seem to grab all logs in a timely manner, sometimes losing or receiving LOG_INF in a delayed manner, i do not know if this is related

Parents
  • Hi,

    -the RTT does not seem to grab all logs in a timely manner, sometimes losing or receiving LOG_INF in a delayed manner, i do not know if this is related

    In Zephyr, logging will be delayed to print after other more important things have happened. This is likely the reason for this.
    If you want to make logging immediate, configure CONFIG_LOG_MODE_IMMEDIATE.

    fails to report the change from "false" to "true"

    Will the interrupt in the SED signaling this change still trigger when this fails?

    Regards,
    Sigurd Hellesvik

  • The print seems to be delayed until some other messages are sent
    example: timer expires and starts a Zephyr work, in the work the following happens: attribute changes to false, LED is turned off, a LOG_INF is executed for debugging purposes notifying of the change. In this case the LOG_INF is not sent until i cause the device to print something else first (by triggering the event it's supposed to measure for example).

    > Will the interrupt in the SED signaling this change still trigger when this fails?


    Unless i'm misunderstanding the question, yes, the interrupt responsible for changing the attribute from false to true does happen and i can verify it by observing the state of a LED on our board as well as by reading the printout. 


    static void trigger_handler(const struct device *dev,
        const struct sensor_trigger *trig) {
      k_timer_start(&mytimer, /*K_SECONDS(1)*/ K_SECONDS(5), K_NO_WAIT); //(re)set the timer
      shakes++;
    
      if (shakes >= MAXCOUNT && !dev_ctx.shake_attr.is_shaked) { // if we shaked enough AND is_shaked is FALSE, we set it to true
        zb_bool_t current_value = 1;
        ZB_ZCL_SET_ATTRIBUTE(10,
            ZB_ZCL_CLUSTER_ID_SHAKE_TRACKER,
            ZB_ZCL_CLUSTER_SERVER_ROLE,
            ZB_ZCL_ATTR_SHAKE_TRACKER_IS_SHAKED,
            (zb_uint8_t *)&current_value,
            ZB_FALSE);
    
        LOG_INF("We have shaked enough! Is_shaked=%d",
            dev_ctx.shake_attr.is_shaked);
        dk_set_led(IS_SHAKED_LED,1);
      }
    
      fetch_and_display(dev);
    }

Reply
  • The print seems to be delayed until some other messages are sent
    example: timer expires and starts a Zephyr work, in the work the following happens: attribute changes to false, LED is turned off, a LOG_INF is executed for debugging purposes notifying of the change. In this case the LOG_INF is not sent until i cause the device to print something else first (by triggering the event it's supposed to measure for example).

    > Will the interrupt in the SED signaling this change still trigger when this fails?


    Unless i'm misunderstanding the question, yes, the interrupt responsible for changing the attribute from false to true does happen and i can verify it by observing the state of a LED on our board as well as by reading the printout. 


    static void trigger_handler(const struct device *dev,
        const struct sensor_trigger *trig) {
      k_timer_start(&mytimer, /*K_SECONDS(1)*/ K_SECONDS(5), K_NO_WAIT); //(re)set the timer
      shakes++;
    
      if (shakes >= MAXCOUNT && !dev_ctx.shake_attr.is_shaked) { // if we shaked enough AND is_shaked is FALSE, we set it to true
        zb_bool_t current_value = 1;
        ZB_ZCL_SET_ATTRIBUTE(10,
            ZB_ZCL_CLUSTER_ID_SHAKE_TRACKER,
            ZB_ZCL_CLUSTER_SERVER_ROLE,
            ZB_ZCL_ATTR_SHAKE_TRACKER_IS_SHAKED,
            (zb_uint8_t *)&current_value,
            ZB_FALSE);
    
        LOG_INF("We have shaked enough! Is_shaked=%d",
            dev_ctx.shake_attr.is_shaked);
        dk_set_led(IS_SHAKED_LED,1);
      }
    
      fetch_and_display(dev);
    }

Children
Related