How to stop execution of code if message is received during wait()...?



  • I am trying to do a very simple node with two relays for control of my venetian blinds.

    When the node receives an ON signal from the controller a relay is going to turn on for x seconds (line 115 in the below sketch). The mysensors function wait() is used to control the time (line 117). If a new message is received from the controller before wait is finished (e.g. OFF), then wait() should stop and the remaining lines of code (lines 118 to 123) should not be executed. How is that achieved? Hope someone can help. Thanks.

    1      // Enable debug prints
    2      // #define MY_DEBUG
    3  
    4      // Enable and select radio type attached
    5      #define MY_RADIO_NRF24
    6  
    7      #include <MySensors.h>
    8  
    9      #define CHILD_ID_BLIND 1
    10 
    11     #define EPROM_BLIND_STATE 1
    12     #define EPROM_SLAT_ANGLE 2
    13 
    14     #define LED_PIN 4
    15 
    16     #define BLIND_OFF 0
    17     #define BLIND_ON 1
    18 
    19     #define SN "Venetian Blind"
    20     #define SV "1.0"
    21 
    22     int16_t LastBlindState = BLIND_OFF;
    23     int16_t LastSlatAngle = 50;
    24 
    25     void setup()
    26     {
    27       // Retreive our last blind state from the eprom
    28       int BlindState = loadState(EPROM_BLIND_STATE);
    29       if (BlindState <= 1) {
    30         LastBlindState = BlindState;
    31         int SlatAngle = loadState(EPROM_SLAT_ANGLE);
    32         if ((SlatAngle >= 0) && (SlatAngle <= 100)) {
    33           LastSlatAngle = SlatAngle;
    34         }
    35         Serial.print("State and angle at setup: ");
    36         Serial.print(LastBlindState);
    37         Serial.print(", ");
    38         Serial.println(LastSlatAngle);
    39 
    40         pinMode(LED_PIN, OUTPUT); // LED for testing purposes
    41       }
    42 
    43       //Here you actualy switch on/off the blinds with the last known slat level
    44       SetCurrentState2Hardware();
    45 
    46       Serial.println( "Node ready to receive messages..." );
    47     }
    48 
    49     void presentation()
    50     {
    51       // Send the Sketch Version Information to the Gateway
    52       sendSketchInfo(SN, SV);
    53 
    54       present(CHILD_ID_BLIND, S_DIMMER );
    55     }
    56 
    57     void loop()
    58     {
    59     }
    60 
    61     void receive(const MyMessage &message)
    62     {
    63       if (message.type == V_STATUS) {
    64         Serial.print( "V_STATUS command received...: " );
    65 
    66         int bstate = atoi( message.data ); // atoi(): Convert string to integer
    67         if ((bstate < 0) || (bstate > 1)) {
    68           Serial.println( "V_STATUS data invalid (should be 0/1)" );
    69           return;
    70         }
    71         LastBlindState = bstate;
    72         Serial.println(LastBlindState);
    73         saveState(EPROM_BLIND_STATE, LastBlindState);
    74 
    75       } else if (message.type == V_PERCENTAGE) {
    76         Serial.print( "V_PERCENTAGE command received...: " );
    77         int slatvalue = atoi( message.data );
    78         if ((slatvalue < 0) || (slatvalue > 100)) {
    79           Serial.println( "V_PERCENTAGE data invalid (should be 0..100)" );
    80           return;
    81         }
    82 
    83         LastBlindState = BLIND_ON;
    84         LastSlatAngle = slatvalue;
    85         Serial.println(LastSlatAngle);
    86         saveState(EPROM_SLAT_ANGLE, LastSlatAngle);
    87         saveState(EPROM_BLIND_STATE, LastBlindState);
    88       }
    89       else {
    90         Serial.println( "Invalid command received..." );
    91         return;
    92       }
    93 
    94       //Here you set the actual light state/level
    95       SetCurrentState2Hardware();
    96     }
    97 
    98     void SetCurrentState2Hardware()
    99     {
    100      digitalWrite(LED_PIN, LOW); // Relays = off
    101      wait(1000);
    102
    103      if (LastBlindState == BLIND_OFF) {
    104        Serial.println( "Light state: OFF" );
    105
    106        digitalWrite(LED_PIN, HIGH); // up-relay on
    107        Serial.println("Going all the way up");
    108        wait(7500); // time to move blind all the way up
    109        digitalWrite(LED_PIN, LOW);  // up-relay off
    110      }
    111      else {
    112        Serial.print( "Light state: ON, Level: " );
    113        Serial.println( LastSlatAngle );
    114
    115        digitalWrite(LED_PIN, HIGH); // down-relay on
    116        Serial.println("Going all the way down");
    117        wait(7500); // time to move blind all the way down
    118        digitalWrite(LED_PIN, LOW);  // down-relay off
    119        wait(1000);
    120        digitalWrite(LED_PIN, HIGH); // up-relay on
    121        Serial.println("Adjusting slat angle");
    122        wait(100 * LastSlatAngle);
    123        digitalWrite(LED_PIN, LOW);  // up-relay off
    124      }
    125    }
    

  • Mod

    @arrawx set a global variable in receive(). In loop, look at the variable and call SetCurrentState2Hardware(). In SetCurrentState2Hardware, after each wait(), check the variable and call return immediately if the value is different from the expected value.

    Calling wait() from inside receive will cause the current message being overwritten when the next message arrives.


 

424
Online

7.9k
Users

8.8k
Topics

93.8k
Posts