Wake-up by interrupt doesn't work



  • Hi guys!

    I'm trying to develop my first battery-powered device which will be a moisture sensor with binary switch to activate a water pump.

    I've inherited a part of sleep/wake code from this example. And my device wakes up if I connect an interrupt pin with the ground. But it doesn't wake up when a gateway transmits data to binary switch.

    I've tried to replace my RF module with another one but it doesn't help. I assume it is likely an issue with RF moduels but would like to make sure I'm not missing something.

    So the question is when NRF should change it's IRQ pin state and how long does this new state should be? Any ideas on what else should I check are appreciated.

    My hw is: Nano powered by 3.7V 18650 battary via 5V pin (step-up converter is planned but not yet installed as it's prototype) + nRF24L01+

    My sketch is below (as I mentioned, it works if I ground an IRQ pin, but anyway):

    /*
     * 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-2019 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
     *
     * Arduino soil moisture based on gypsum sensor/resistive sensor to avoid electric catalyse in soil
     *  Required to interface the sensor: 2 * 4.7kOhm + 2 * 1N4148
     *
     * Gypsum sensor and calibration:
     *	DIY: See http://vanderleevineyard.com/1/category/vinduino/1.html
     *	Built: Davis / Watermark 200SS
     *		http://www.cooking-hacks.com/watermark-soil-moisture-sensor?_bksrc=item2item&_bkloc=product
     *		http://www.irrometer.com/pdf/supportmaterial/sensors/voltage-WM-chart.pdf
     *		cb (centibar) http://www.irrometer.com/basics.html
     *			0-10 Saturated Soil. Occurs for a day or two after irrigation
     *			10-20 Soil is adequately wet (except coarse sands which are drying out at this range)
     *			30-60 Usual range to irrigate or water (except heavy clay soils).
     *			60-100 Usual range to irrigate heavy clay soils
     *			100-200 Soil is becoming dangerously dry for maximum production. Proceed with caution.
     *
     * Connection:
     * D6, D7: alternative powering to avoid sensor degradation
     * A0, A1: alternative resistance measuring
     *
     *  Based on:
     *  "Vinduino" portable soil moisture sensor code V3.00
     *   Date December 31, 2012
     *   Reinier van der Lee and Theodore Kaskalis
     *   www.vanderleevineyard.com
     * Contributor: epierre
     */
    
    // Copyright (C) 2015, Reinier van der Lee
    // www.vanderleevineyard.com
    
    // This program is free software: you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation, either version 3 of the License, or
    // any later version.
    
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_RF24
    
    // Define channel (2440 MHz - somewhere in between 6th and 7th wi-fi channels)
    #define MY_RF24_CHANNEL 40
    
    //#define MY_RADIO_NRF5_ESB
    //#define MY_RADIO_RFM69
    //#define MY_RADIO_RFM95
    
    #define MY_BAUD_RATE 38400
    
    #define MY_IRQ_PIN 2 //MY_RF24_IRQ_PIN
    
    #include <MySensors.h>
    
    //#define CHILD_ID 0
    
    // Pump control pin
    #define PUMP_PIN 4
    // Pump max operation time in ms
    #define PUMP_OP_TIME 6000
    
    MyMessage msg_moisture(0, V_LEVEL);
    MyMessage msg_binary(1, V_STATUS);
    
    #define SLEEP_TIME 30 * 60 // Sleep time (in seconds)
    unsigned long sleepTime = SLEEP_TIME;
    int8_t wakeupReason = MY_WAKE_UP_BY_TIMER; // Initial value, will be set by sleep after the first run
    
    // Define pins. They will switch over every time we read the values.
    byte SENSOR_PIN1 = 19;
    byte SENSOR_PIN2 = 18;
    
    void setup()
    {
      // Settings
      // #define SENSOR_PIN1  19
      // #define SENSOR_PIN2  18
    	pinMode(SENSOR_PIN1, OUTPUT);
      pinMode(SENSOR_PIN2, INPUT);
      pinMode(PUMP_PIN, OUTPUT);
    }
    
    void presentation()
    {
    	sendSketchInfo("Soil Moisture Sensor", "1.0");
    	present(0, S_MOISTURE);
      present(1, S_BINARY);
    }
    
    void loop()
    {
      if (wakeupReason == digitalPinToInterrupt(MY_IRQ_PIN)) {
        sleepTime = getSleepRemaining() / 1000;
        if (sleepTime < 1) {
          sleepTime = 1;
        }
        Serial.println("!!!!    Wake up by interrupt");
      } else if (wakeupReason == MY_WAKE_UP_BY_TIMER) {
        // Power on sensor
        Serial.println("Power on");
        digitalWrite(SENSOR_PIN1, 1);
        delayMicroseconds(25);
        // Read sensor pins
        int moistureAn = analogRead(SENSOR_PIN2);
        float moisturePercent = moistureAn / 1023.0 * 100.0;
        Serial.print("Moisture analog: ");
        Serial.println(moistureAn);
        Serial.print("Moisture percent: ");
        Serial.println(moisturePercent);
        Serial.println("Power off");
        digitalWrite(SENSOR_PIN1, 0);
      
        // Switch pins
        Serial.println("Switching pins");
        byte tmpPin = SENSOR_PIN2;
        SENSOR_PIN2 = SENSOR_PIN1;
        SENSOR_PIN1 = tmpPin;
        pinMode(SENSOR_PIN1, OUTPUT);
        pinMode(SENSOR_PIN2, INPUT);
      
        //send back the values
        send(msg_moisture.set((int32_t)round(moisturePercent)));
        
        sleepTime = SLEEP_TIME;
      }
      Serial.print("Going to sleep for ");
      Serial.println(sleepTime);
      //wait(SLEEP_TIME * 1000);
      wakeupReason = smartSleep(digitalPinToInterrupt(MY_IRQ_PIN), CHANGE, sleepTime * 1000);
    }
    
    void receive(const MyMessage &message)
    {
      byte sensor = message.getSensor();
      if (message.getType()==V_STATUS) {
        bool newState = message.getBool();
        Serial.print("Incoming change for sensor: ");
        Serial.print(sensor);
        Serial.print(". Switching to: ");
        Serial.println(newState);
        if (newState == true) {
          digitalWrite(PUMP_PIN, HIGH);
          delay(PUMP_OP_TIME);
          Serial.println("Turning pump off after time out");
          digitalWrite(PUMP_PIN, LOW);
          msg_binary.set(false);
          send(msg_binary, false);
        } else {
          digitalWrite(PUMP_PIN, LOW);
        }
      }
    }
    

  • Mod

    @Max-Kurilov said in Wake-up by interrupt doesn't work:

    my device wakes up if I connect an interrupt pin with the ground. But it doesn't wake up when a gateway transmits data to binary switch.

    True, in MySensors the radio will be 'off' when a node sleeps, so nothing will be received. Your node will only wake up by an interrupt (eg the interrupt pin in your setup) or after a certain amount of time has elapsed.



  • @Yveaux said in Wake-up by interrupt doesn't work:

    True, in MySensors the radio will be 'off' when a node sleeps, so nothing will be received. Your node will only wake up by an interrupt (eg the interrupt pin in your setup) or after a certain amount of time has elapsed.

    What do you mean by saying "off"? It seems that there is a voltage when a node sleeps. So that the radio should be powered in my case.

    If the radio can't change its IRQ pin state while powered on what is the purpose of this pin? Maybe this is a rhetorical question.



  • More pragmatically: if this limitation has no workaround on hardware or library level, for how long is it safe to send node to a sleep mode while keeping data packets from losing.


  • Mod

    @Max-Kurilov said in Wake-up by interrupt doesn't work:

    What do you mean by saying "off"? It seems that there is a voltage when a node sleeps. So that the radio should be powered in my case.

    I tried to keep it simple as I don't know your background, but by 'off' i mean powered, but in sleep mode. Receiver is switched off. This is the case for nrf24, but might slightly differ per radio.

    It is a limitation of the radio, not of the mysensors library. Either sleep the node for minimum power usage, or keep it awake at higher power requirements.

    If the radio can't change its IRQ pin state while powered on what is the purpose of this pin? Maybe this is a rhetorical question.

    In case of nrf24 the irq can be used for buffering incoming messages on nodes with high load. Mainly used for gateways.
    Furthermore, for future hardware compatibility it is suggested to connect the irq line. If you're short of pins, you can decide differently.

    For other radios the irq line might be mandatory.


  • Mod

    @Max-Kurilov said in Wake-up by interrupt doesn't work:

    for how long is it safe to send node to a sleep mode while keeping data packets from losing.

    You should not sleep a node that must be responsive to incoming messages.



  • @Yveaux thank you for your replies.

    In my particular case, I'd rather be ok with delays for resending commands from my gateway to the node than spend too much battery charge.

    I've discovered a couple of threads regarding retransmission and reliable delivery in this forum. Most of them are for sensor data transmission case which can be made by handling send() results and which are useless in case I decide to implement resending in my gateway.

    Is there a reason for not including retransmission policy right into MySensors library which implements the gateway part?



  • If the delay is not of importance to you, you can also have the sensor request its state from the controller each time it wakes up. No special modifications are needed than.



  • @Yveaux said in Wake-up by interrupt doesn't work:

    You should not sleep a node that must be responsive to incoming messages.

    As smartSleep is used, this might work, but requires the controller software to also support the feature. Additionally, using ACK-request (in case the RF connection isn't reliable) might be a good idea.



  • @electrik said in Wake-up by interrupt doesn't work:

    If the delay is not of importance to you, you can also have the sensor request its state from the controller each time it wakes up. No special modifications are needed than.

    It's true. But the controller must switch its relay state without having ack received from the node. That's not what MySensors plugin for Vera does. But you gave me an idea to implement an additional relay buildin into the gateway which will work as a proxy for my real actuator. Thank you!


Log in to reply
 

Suggested Topics

  • 87
  • 7
  • 2
  • 3
  • 7
  • 5

16
Online

11.4k
Users

11.1k
Topics

112.7k
Posts