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
U

user2684

@user2684
Contest Winner
About
Posts
418
Topics
27
Shares
0
Groups
1
Followers
4
Following
0

Posts

Recent Best Controversial

  • NodeManager: plugin for a rapid development of battery-powered sensors
    U user2684

    Hi, being a newbie in this wonderful MySensors world, I found myself excited about the flexibility of the overall platform but also somehow implementing the same common functionalities across my sensors over and over again. I decided then to spend some reasonable amount of time to expand the idea behind MyExtention (https://forum.mysensors.org/topic/6062/myextension) into something I have called NodeManager (I know, I'm bad with names!).

    NodeManager is intended to take care on your behalf of all those common tasks a MySensors node has to accomplish, speeding up the development cycle of your projects. It should help who is new to MySensors to get up to speed quicker and for those already into the matter to delegate to NodeManager common and boring tasks so to focus on more interesting scenarios.

    NodeManager main features are:

    • Manage all the aspects of a sleeping cycle by leveraging smart sleep
    • Allow configuring the sleep mode and the sleep duration remotely
    • Allow waking up a sleeping node remotely at the end of a sleeping cycle
    • Allow powering on each connected sensor only while the node is awake to save battery
    • Report battery level periodically and automatically
    • Calculate battery level without requiring an additional pin and the resistors
    • Report battery voltage through a built-in sensor
    • Can report battery level on demand
    • Allow rebooting the board remotely
    • Provide out-of-the-box sensors personalities and automatically execute their main task at each cycle

    Specifically on this last point, the idea behind providing built-in the functionalities of most common sensors is to simplify the development especially for somebody new to it.
    E.g. if I connect a thermistor to one of the pin, I just need a single line to have it working, as it was leveraging some sort of embedded firmware:

    nodeManager.registerSensor(SENSOR_THERMISTOR,A2);
    

    The following built-in sensors are available:

    • SENSOR_ANALOG_INPUT Generic analog sensor, return a pin's analog value or its percentage
    • SENSOR_LDR LDR sensor, return the light level of an attached light resistor in percentage
    • SENSOR_THERMISTOR Thermistor sensor, return the temperature based on the attached thermistor
    • SENSOR_DIGITAL_INPUT Generic digital sensor, return a pin's digital value
    • SENSOR_DIGITAL_OUTPUT Generic digital output sensor, allows setting the digital output of a pin to the requested value
    • SENSOR_RELAY Relay sensor, allows activating the relay
    • SENSOR_LATCHING_RELAY Latching Relay sensor, allows activating the relay with a pulse
    • SENSOR_DHT11 DHT11 sensor, return temperature/humidity based on the attached DHT sensor
    • SENSOR_DHT22 DHT22 sensor, return temperature/humidity based on the attached DHT sensor
    • SENSOR_SHT21 SHT21 sensor, return temperature/humidity based on the attached SHT21 sensor
    • SENSOR_SWITCH Generic switch, wake up the board when a pin changes status
    • SENSOR_DOOR Door sensor, wake up the board and report when an attached magnetic sensor has been opened/closed
    • SENSOR_MOTION Motion sensor, wake up the board and report when an attached PIR has triggered
    • SENSOR_DS18B20 DS18B20 sensor, return the temperature based on the attached sensor

    I put the package on Sourceforce so to avoid leaving here piece of code which may become obsolete in a short time.

    The project is here: https://sourceforge.net/projects/mynodemanager
    I've also tried to document everything the best as I could on https://sourceforge.net/p/mynodemanager/wiki

    Thanks

    NodeManager

  • NodeManager v1.8 now available!
    U user2684

    NodeManager v1.8 is finally here!

    With 8 months of development from 12 different contributors, the new NodeManager v1.8 ships now as an Arduino library to allow an easier integration, a more consistent upgrade process across the versions and a simpler way of using it.

    This version includes also a number of enhancements and bug fixes, a better integration with the MySensors library (including the capability to use the web-based Log Parser) and support for an additional 11 new sensors, with a grand total of 62 built-in sensors that can be added to your project by just a single line of code.

    NodeManager v1.8 can be downloaded directly from Github https://github.com/mysensors/NodeManager where detailed installation instructions are also provided.
    Please read the README file carefully before starting so to get a sense on how to use it or what has changed from the previous releases.

    The full release notes for this version are listed below:

    • Split NodeManager's core classes in individual files and each sensor code in its own dedicated header file
    • New Arduino-compatible library structure to allow easier integration and more consistent updates across version
    • Included a complete set of examples which can be loaded directly from the Arduino IDE
    • Simplified the template sketch with a global nodeManager object and sensors that can be imported directly from there
    • Debug output is now fully compatible with the one used by the MySensors library and integrated into MySensors LogParser
    • Better control on how often, if and when to sync the time with the controller for time-aware nodes
    • Added a Measure Timer so to allow splitting between taking measures and reporting
    • Added support for every sensor to keep track of the last value assigned to a child in EEPROM and restoring it upon a reboot
    • Introduced new capabilities for reporting every minute/hour/day or only at a given minute/hour/day
    • Added ability to read from the serial port at the end of each loop cycle, useful for debugging interactive sensors
    • Added support for pH sensor
    • Added support for PCA9685 as RGB/RGBW/W dimmer
    • Added support for DSM501A dust sensor
    • Added support for PN532 NFC RFID module
    • Added support for CCS811 CO2/VOC sensor
    • Added support for MPR121 Capacitive Touch Sensor
    • Added support for serial GSM/SMS device
    • Added support for FPM10A fingerprint sensor
    • Added support for SDS011 Air quality sensor
    • Added support for ESP32 devices
    • Added support for nRF52 radio
    • Improved SensorDigitalInput and NeoPixelSensor
    • Si7021 sensor is now using the library from the MySensors example
    • Reviewed the MQ Sensor implementation
    • Optimized memory utilization
    • Added Travis Continuous Integration tests
    • Fixed wrong battery report when using battery pin and SensorRain/SensorSoilMoisture
    • Fixed DigitalOutput safeguard not working as expected
    • Fixed radio signal level reporting wrong values
    • Fixed SensorLatchingRelay2Pins wrong pin selection
    • Other minor bug fixes
    NodeManager

  • Clock with temperature, humidity and CO2 level sensors
    U user2684

    My bedside alarm clock recently got broken so I decided to build up one by myself.
    The prototype looks like that:
    0_1529326386412_1.png

    • 1: arduino pro mini 3.3v
    • 2: RFM69 radio
    • 3: MQ135 sensor to measure CO2 level
    • 4: 20k/10k voltage divider to connect the MQ AO pin to an analog pin of the arduino (the MQ sensor runs at 5v, the arduino at 3.3v so we need to "scale" the output)
    • 5: DS3231 RTC so when the power goes down the node will be able to restore its clock even without requesting time to the controller
    • 6: SHT21 sensor for temperature and humidity
    • 7: SSD1306 OLED display 128x64

    The "production" version looks like this:
    0_1529326672488_2.png
    I'm again using the versatile EasyPCB from @sundberg84, here in the middle. The voltage divider has been soldered on the board, where battery measurement level is used to be placed. Of course Vin is not connected but instead it is used for MQ's AO pin connection.
    The SH21 and MQ sensors are just outside the box so to have accurate readings. The project is powered by 0.5€ USB ttl Chinese key which allows to power both the board (3.3v) and the MQ sensor (5v).
    I've also added a push button, hidden within the case which will request the time to the controller for the first initialization of the RTC.

    As for the code this is what I'm using based on NodeManager (with the latest SensorMQ code change not yet merged into the development branch):

    /**********************************
     * MySensors node configuration
     */
    
    // General settings
    #define SKETCH_NAME "Clock"
    #define SKETCH_VERSION "1.0"
    //#define MY_DEBUG
    #define MY_NODE_ID 1
    
    // RFM69 radio settings
    #define MY_RADIO_RFM69
    //#define MY_RFM69_FREQUENCY RFM69_433MHZ
    #define MY_IS_RFM69HW
    #define MY_RFM69_NEW_DRIVER
    
    /***********************************
     * NodeManager modules for supported sensors
     */
    
    #define USE_SIGNAL
    #define USE_SHT21
    #define USE_INTERRUPT
    #define USE_MQ
    #define USE_SSD1306
    
    /***********************************
     * NodeManager built-in features
     */
    
    // Enable/disable NodeManager's features
    #define FEATURE_DEBUG OFF
    #define FEATURE_POWER_MANAGER OFF
    #define FEATURE_INTERRUPTS ON
    #define FEATURE_CONDITIONAL_REPORT OFF
    #define FEATURE_EEPROM OFF
    #define FEATURE_SLEEP OFF
    #define FEATURE_RECEIVE ON
    #define FEATURE_TIME ON
    #define FEATURE_RTC ON
    #define FEATURE_SD OFF
    #define FEATURE_HOOKING ON
    
    /***********************************
     * Load NodeManager Library
     */
    
    #include "NodeManagerLibrary.h"
    NodeManager node;
    
    /***********************************
     * Add your sensors below
     */
    
    // built-in sensors
    SensorSignal signal(node);
    
    // Attached sensors
    SensorSHT21 sht21(node);
    SensorMQ mq(node,A0);
    DisplaySSD1306 ssd1306(node);
    SensorInterrupt button(node,3);
    
    /***********************************
     * Main Sketch
     */
    
    void syncTime(Sensor* sensor) {
      // update the time with the controller
      node.syncTime();
      // update the display
      ssd1306.onLoop(ssd1306.children.get(1));
    }
    
    // before
    void before() {
      // setup the serial port baud rate
      Serial.begin(MY_BAUD_RATE);
      /*
      * Configure your sensors below
      */
    
      // temperature/humidity sensor
      sht21.setReportIntervalMinutes(5);
    
      // gas sensor
      mq.setReportIntervalMinutes(5);
      mq.setRoValue(56842);
      mq.setCurveScalingFactor(38.35);
      mq.setCurveExponent(-2.74);
      
      // display
      ssd1306.setReportIntervalSeconds(30);
    
      // button
      button.setInitialValue(HIGH);
      button.setInterruptMode(FALLING);
      button.setInterruptHook(&syncTime);
      
      /*
      * Configure your sensors above
      */
      node.before();
    }
    
    // presentation
    void presentation() {
      // call NodeManager presentation routine
      node.presentation();
    }
    
    // setup
    void setup() {
      // call NodeManager setup routine
      node.setup();
    }
    
    // loop
    void loop() {
      // call NodeManager loop routine
      node.loop();
    }
    
    #if FEATURE_RECEIVE == ON
    // receive
    void receive(const MyMessage &message) {
      // call NodeManager receive routine
      node.receive(message);
    }
    #endif
    
    #if FEATURE_TIME == ON
    // receiveTime
    void receiveTime(unsigned long ts) {
      // call NodeManager receiveTime routine
      node.receiveTime(ts);
    }
    #endif
    

    To show on the display only the information relevant for this project, I had to override DisplaySSD1306 onLoop() function in this way:

    void DisplaySSD1306::onLoop(Child* child) {
      long timestamp = now()+60*60*2;
      _oled->setCursor(0,0);
      // print the current date
      _oled->setFont(X11fixed7x14);
      _oled->print(F("    "));
      if (day(timestamp) < 10) _oled->print(F("0"));
      _oled->print(day(timestamp));
      _oled->print(F("-"));
      if (month(timestamp) < 10) _oled->print(F("0"));
      _oled->print(month(timestamp));
      _oled->print(F("-"));
      _oled->println(year(timestamp));
      // print the current time
      _oled->setFont(lcdnums12x16);
      _oled->set2X();
      if (hour(timestamp) < 10) _oled->print(F("0"));
      _oled->print(hour(timestamp));
      _oled->print(F(":"));
      if (minute(timestamp) < 10) _oled->print(F("0"));
      _oled->println(minute(timestamp));
      // print the sensors' data
      _oled->setFont(Adafruit5x7);
      _oled->set1X();
      _oled->println("");
      _oled->print(((ChildFloat*)_node->getChild(1))->getValueFloat());
      _oled->print(F("C "));
      _oled->print((int)((ChildFloat*)_node->getChild(2))->getValueFloat());
      _oled->print(F("% "));
      _oled->print(((ChildInt*)_node->getChild(3))->getValueInt());
      _oled->print(F("ppm"));
      _oled->clearToEOL();
    }
    

    Finally some pictures of the project once finalized:
    0_1529327416355_3.png

    0_1529327427911_4.png

    My Project

  • 💬 NodeManager
    U user2684

    Done! I've updated the documentation with four comprehensive examples including the full sketches

    OpenHardware.io contest2017 arduino newbie mysensors battery sensor

  • NodeManager: plugin for a rapid development of battery-powered sensors
    U user2684

    Hi, I've made an update of NodeManager in case can be of interest. Latest version v1.2 is available on https://sourceforge.net/projects/mynodemanager/.
    Short changelog:

    • Added out-of-the-box support for BH1750 light sensor
    • Added out-of-the-box support for HTU21D temperature and humidity sensor
    • Added out-of-the-box support for MLX90614 contactless temperature sensor
    • Added a few examples to the documentation (https://sourceforge.net/p/mynodemanager/wiki/NodeManager/#examples)
    • Fixed a few bugs
    NodeManager

  • Inexpensive, analog, temperature and light sensor
    U user2684

    Hi,

    I couldn't find a similar project already posted here so in case somebody is interested in a very inexpensive temperature and light sensor, this can be easily implemented with a thermistor and a LDR (light dependent resistor). Probably the measurement is not as accurate as with other more complex sensors but in all my tests I've never had significant bias.

    The BOM is really cheap since a Thermistor can cost around 0.08$ (https://www.aliexpress.com/store/product/10pcs-Free-Shipping-10k-OHM-NTC-Thermistor-Resistor-NTC-MF52AT-10K-1-3950/110055_32412200713.html?spm=2114.12010615.0.0.iB5eTq) and a LDR around 0.04$ (https://www.aliexpress.com/store/product/Free-shiping-1000pcs-x-5528-Light-Dependent-Resistor-LDR-5MM-Photoresistor-wholesale-and-retail-Photoconductive-resistance/110055_2041703245.html?spm=2114.12010615.0.0.I9uWY1) so a pro mini + RF24 + the two sensors can be all even below the 3$.

    Wiring is simple as well, both the thermistor and the LDR have a pin connected to ground and the other connected to a (different) 10k resistor and an analog input. The resistors' other pin goes to vcc. In the (bad) picture below, the black connector goes to GND, the orange to VCC, the white to A1, the green to A2.

    0_1487525894727_IMG_2879.JPG

    Code is pretty simple as well. You basically need to read the analog input and in case of the thermistor apply its formula (https://en.wikipedia.org/wiki/Thermistor) while for the LDR if you like normalize the value to a percentage and invert it (when dark the analog read would be 1024 so I prefer having 0% in this case).

    I'm using my NodeManager (https://sourceforge.net/projects/mynodemanager/) to make things simple, having the node sleeping and reporting both the measures every 10 minutes and power on the sensors with two arduino pins just before reading the measures (otherwise even if sleeping, there will be some current going from VCC to GND):

    // load user settings
    #include "config.h"
    // load MySensors library
    #include <MySensors.h>
    // load NodeManager library
    #include "NodeManager.h"
    
    // create a NodeManager instance
    NodeManager nodeManager;
    
    // before
    void before() {
      // setup the serial port baud rate
      Serial.begin(9600);  
      // instruct the board to sleep for 10 minutes for each cycle
      nodeManager.setSleep(SLEEP,10,MINUTES);
      // all the sensors' vcc and ground are connected to pin 6 (ground) and 7 (vcc. NodeManager will enable the vcc pin every time just before loop() and wait for 100ms for the sensors to settle
      nodeManager.setPowerPins(6,7,100);
      // register the sensors
      nodeManager.registerSensor(SENSOR_THERMISTOR,A1);
      nodeManager.registerSensor(SENSOR_LDR,A2);
      
      nodeManager.before();
    }
    
    // presentation
    void presentation() {
      // Send the sketch version information to the gateway and Controller
    	sendSketchInfo("AnalogTemperatureLight", "1.0");
      // call NodeManager presentation routine
      nodeManager.presentation();
    
    }
    
    // setup
    void setup() {
    }
    
    // loop
    void loop() {
      // call NodeManager loop routine
      nodeManager.loop();
    
    }
    
    // receive
    void receive(const MyMessage &message) {
      // call NodeManager receive routine
      nodeManager.receive(message);
    }
    
    
    

    If you want to read the values in the traditional way, the code would look like the following for the thermistor:

        int _nominal_resistor = 10000;
        int _nominal_temperature = 25;
        int _b_coefficient = 3950;
        int _series_resistor = 10000;
      // read the voltage across the thermistor
      float adc = analogRead(_pin);
      // calculate the temperature
      float reading = (1023 / adc)  - 1;
      reading = _series_resistor / reading;
      float temperature;
      temperature = reading / _nominal_resistor;     // (R/Ro)
      temperature = log(temperature);                  // ln(R/Ro)
      temperature /= _b_coefficient;                   // 1/B * ln(R/Ro)
      temperature += 1.0 / (_nominal_temperature + 273.15); // + (1/To)
      temperature = 1.0 / temperature;                 // Invert
      temperature -= 273.15;                         // convert to C
      if (! getControllerConfig().isMetric) temperature = temperature * 1.8 + 32;
    

    And this for the LDR:

      // read the value
      int adc= analogRead(_pin);
      value = 1024 - adc;
      // calculate the percentage
      int percentage = 0;
      float value = (float)adc;
      // scale the percentage based on the range provided
      float percentage = ((value - 0) / (1024 - 0)) * 100;
      if (percentage > 100) percentage = 100;
      if (percentage < 0) percentage = 0;
      
    

    Thanks

    My Project

  • 💬 NodeManager
    U user2684

    Every new version of NodeManager, I try to review and hopefully improve its architecture. This time looked like a simple and quick task but eventually ended up in a complete and deep review of the code. Many many many things have changed with the main objective to better integrate with the MySensors library and simplify the life of users willing to contribute or to add support for new sensors.

    The new file structure (with a dedicated file for each supported sensor) and the way the package is delivered (as an arduino library now) go into this direction. There are also included a good amount of new features but still in most of the cases, resulting a smaller code.

    All the details are available at https://github.com/mysensors/NodeManager/pull/391 which will be merged into the development branch shortly.

    Due to the many changes, if anybody would be willing to give it a try and report any bug, would be really great. Thanks!

    OpenHardware.io contest2017 arduino newbie mysensors battery sensor

  • NodeManager: plugin for a rapid development of battery-powered sensors
    U user2684

    Hello All,

    NodeManager v1.6 is finally available! Download and upgrade instructions can be found as always on https://github.com/mysensors/NodeManager

    First of all I want to thank everybody contributing to the project, especially those who have submitted pull requests to the repository.

    In v1.6 we have 36 out-of-the-box sensors as well as a good number fixes and enhancements. The most notable are for sure the capability to customize any sensor remotely through a brand new remote API and a more flexible and effective way to configure reporting intervals and sleep cycles:

    • Introduced new remote API to allow calling almost ALL NodeManager's and its sensors' functions remotely
    • Reporting interval configuration is now indipendent from the sleep cycle
    • Reporting interval can be customized per-sensor
    • All intervals (measure/battery reports) are now time-based
    • Added support for BMP280 temperature and pressure sensor
    • Added support for RS485 serial transport
    • Added support for TSL2561 light sensor
    • Added support for DHT21 temperature/humidity sensor
    • Added support for AM2320 temperature/humidity sensor
    • Added support for PT100 high temperature sensor
    • Added support for MH-Z19 CO2 sensor
    • Added support for analog rain and soil moisture sensors
    • Added support for generic dimmer sensor (PWM output)
    • Added support for power and water meter pulse sensors
    • Radio signal level (RSSI) is now reported automatically like the battery level
    • SensorRainGauge now supports sleep mode
    • SensorSwitch now supports awake mode
    • SensorLatchingRealy now handles automatically both on and off commands
    • SensorMQ now depends on its own module
    • Added safeguard (automatic off) to SensorDigitalOutput
    • Any sensor can now access all NodeManager's functions
    • DHT sensor now using MySensors' DHT library

    For those who have previously forked the repository, please ensure to merge the updated development branch first before submitting any new PR.

    Thanks!

    NodeManager

  • Battery powered fingerprint reader
    U user2684

    This project is about a battery powered fingerprint sensor I placed just outside the door of my house. The last person leaving the house or the first entering it would use the sensor so the controller could arm/disarm the alarm but of course can be used to control anything (e.g. opening the door). Since the controller gets the id of the fingerprint when there is a match, would also know who is entering the house so greeting the person by name out loud (kind of funny :P).

    The fingerprint sensor I'm using is a FPM10A that can be found on Aliexpress for 5$ (https://www.aliexpress.com/item/Fingerprint-Reader-Sensor-Module-FPM10A-Optical-Fingerprint-Fingerprint-Module-Locks-Serial-Communication-Interface-For-Arduino/32835820214.html).
    Wiring is pretty simple (http://www.duino.lk/image/cache/catalog/Components/fingerprint scaner/fingerprint_sensor_6pwhs7n-500x500.jpg) , it uses a serial connection for the communication and sample code and a library is available from Adafruit (together with a Windows utility that can be used for troubleshooting and for enrolling your fingerprints).

    If battery powered, the sensor cannot of course stay always on since consuming around 150mAh. This is why I've attached a button to the project so the person using it can press the button, the node wakes up, the sensor turns on and the person can put the finger on it. After that, the board goes back to sleep. I've also added a buzzer to shortly beep in case of a positive match.

    This is how the project looks like:
    alt text

    • 1: EasyPCB from @sundberg84 RFM69 version
    • 2: FPM10A sensor. RX and TX connected to pin 5 and 6 (using SoftwareSerial).
    • 3: MCP1302 voltage regulator to provide 3.3v out of the 3 AA batteries (4.5v). I preferred using this configuration since the FPM10A works so so when the voltage is below 3v. The regulator is placed in the booster position so to measure the battery level
    • 4: battery measurement, resistors 1M and 300k ohm
    • 5: since the FPM10A has to be powered on only on demand and an arduino pin cannot provide enough current, I'm using a pn2222a transistor connected to an arduino pin on one side through a 220ohm resistor (with a 10k resistor going to ground) and the FPM10A gound on the other side
    • 6: button for waking up the board and starting the fingerprint sensor
    • 7: 3 AA battery pack
    • 8: buzzer

    This is the code I'm using (from the NodeManager's development branch):

    /**********************************
     * MySensors node configuration
     */
    
    // General settings
    #define SKETCH_NAME "Fingerprint"
    #define SKETCH_VERSION "1.0"
    #define MY_NODE_ID 9
    
    // RFM69 radio settings
    #define MY_RADIO_RFM69
    #define MY_IS_RFM69HW
    #define MY_RFM69_NEW_DRIVER
    
    // Advanced settings
    #define MY_BAUD_RATE 9600
    #define MY_SPLASH_SCREEN_DISABLED
    
    /***********************************
     * NodeManager modules for supported sensors
     */
    
    #define USE_BATTERY
    #define USE_SIGNAL
    #define USE_DIGITAL_OUTPUT
    #define USE_INTERRUPT
    #define USE_FPM10A
    
    /***********************************
     * NodeManager built-in features
     */
    
    // Enable/disable NodeManager's features
    #define FEATURE_DEBUG ON
    #define FEATURE_POWER_MANAGER ON
    #define FEATURE_INTERRUPTS ON
    #define FEATURE_CONDITIONAL_REPORT OFF
    #define FEATURE_EEPROM OFF
    #define FEATURE_SLEEP ON
    #define FEATURE_RECEIVE ON
    #define FEATURE_TIME OFF
    #define FEATURE_RTC OFF
    #define FEATURE_SD OFF
    #define FEATURE_HOOKING ON
    
    /***********************************
     * Load NodeManager Library
     */
    
    #include "NodeManagerLibrary.h"
    NodeManager node;
    
    /***********************************
     * Add your sensors below
     */
    
    // built-in sensors
    SensorBattery battery(node);
    SensorSignal signal(node);
    PowerManager power(-1,A1,1000);
    
    // Attached sensors
    SensorFPM10A fingerprint(node,5,6);
    SensorDigitalOutput buzzer(node,A5);
    
    /***********************************
     * Main Sketch
     */
    
    void bip(Sensor* sensor) {
      if (fingerprint.success) buzzer.setStatus(ON);
    }
    
    // before
    void before() {
      // setup the serial port baud rate
      Serial.begin(MY_BAUD_RATE);
    
      // battery sensor
      battery.setMinVoltage(3.2);
      battery.setMaxVoltage(4.6);
      battery.setBatteryInternalVcc(false);
      battery.setBatteryPin(A0);
      battery.setBatteryVoltsPerBit(0.00459433);
    
      // buzzer sensor
      buzzer.setPulseWidth(20);
      
      // fingerprint sensor
      fingerprint.setPowerManager(power);
      fingerprint.setWaitFingerForSeconds(15);
      fingerprint.setInterrupt(3,FALLING,HIGH);
      fingerprint.setPostLoopHook(&bip);
    
      // node configuration
      node.setSleepMinutes(60);
    
      node.before();
    }
    
    // presentation
    void presentation() {
      // call NodeManager presentation routine
      node.presentation();
    }
    
    // setup
    void setup() {
      // call NodeManager setup routine
      node.setup();
    }
    
    // loop
    void loop() {
      // call NodeManager loop routine
      node.loop();
    }
    
    #if FEATURE_RECEIVE == ON
    // receive
    void receive(const MyMessage &message) {
      // call NodeManager receive routine
      node.receive(message);
    }
    #endif
    
    #if FEATURE_TIME == ON
    // receiveTime
    void receiveTime(unsigned long ts) {
      // call NodeManager receiveTime routine
      node.receiveTime(ts);
    }
    #endif
    

    Basically the node sleeps and wakes up every hour to report battery and signal level. When the button (attached to pin 3) is pressed, the node wakes up and the FPM10A is powered on by PowerManager (which turns HIGH pin A1 so saturating the transistor and activating the sensor). If there is a fingerprint match, then the fingerprint id is sent back to the gateway and the node goes back to sleep. Before doing so a short "bip" is sent to the buzzer.
    If nothing happens for 15 seconds, the node goes back to sleep regardless.

    Just a little trick, since I'm running all my arduino nodes at 1Mhz, the FPM10A has to be configured to work at 9600 baud (57600 is the default). The only library that I found with a working example to change this into the device is the following https://github.com/brianrho/FPM/blob/master/examples/setParam/setParam.ino

    My Project

  • NodeManager v1.7 now available!
    U user2684

    It took a few months but finally NodeManager v1.7 is here!
    With this release the entire NodeManager's architecture has been reviewed, mainly to improved the overall user experience and optimize the code so to use the memory in a more efficient manner. If coming from the previous release, you will find NodeManager way easier to use and more powerful now.
    Last but nost least the number of built-in sensors has no reached 52 (yes, fifty-two, including support for LCD displays), which can be enabled by just uncommeting a single line. For these sensors NodeManager will take care of importing the required library, presenting them to the gateway/controller, executing periodically the main function of the sensor, all without an additional line of code.

    Collaboration for this release has been also great with 15 PRs from other users of the community who I want to really thank.

    NodeManager v1.7 can be downloaded directly from Github https://github.com/mysensors/NodeManager.
    Please read the README file carefully before starting so to get a sense on how to use it or what has changed from the previous releases.

    The full release notes for this version are listed below:

    • Reviewed the entire NodeManager's architecture with children now automatically created from within each sensor
    • Optimized the code so to use the memory in a more efficient manner
    • Improved the overall user experience, also with sensors' patterns in the main sketch
    • Sensors can now be enabled by uncommenting the corresponding USE_* define and requiring a single line to be created and initialized
    • NodeManager's advanced features can be enabled/disabled by setting the corresponding FEATURE_* define
    • Simplified the configuration of each sensor, now without the need of getting the sensor back through a nasty casting
    • Merged config.h into the main sketch so to centralize the configuration in a single place
    • Added time-aware capability, with or without an attached RTC
    • Intra-sensor communication now possible with the possibility for the user to nicely hook into the sensor's code
    • Battery and signal reports are now available through the regular sensors SensorBattery and SensorSignal
    • Remote API interaction for all the sensors has been moved into the regular sensor SensorConfiguration
    • Fixed bug preventing negative temperatures to be reported for all the sensors
    • Added ability for each sensor to report only when value is above or below a configured threshold
    • Addded support for SD card reader
    • Added support for RFM95 radio
    • Added supoport for MySensors Sensebender Gateway and Sensebender Micro boards
    • Added support for generic LCD devices through an abstract Display class
    • SensorDimmer now supports both V_STATUS and V_PERCENTAGE
    • SensorPulseMeter now supports running on batteries
    • SensorDs18B20 optimized and now supporting V_ID
    • SensorSwitch (now renamed into SensorInterrupt) now catches interrupt in a more reliable way
    • SensorLatchingRelay now specialized and renamed into SensorLatchingRelay1Pin and SensorLatchingRelay2Pins
    • Added support for HD44780 i2c LCD
    • Added support for MG996R Servo sensor
    • Added support for VL53L0X laser time-of-flight distance sensor
    • Added support for SensorPlantowerPMS particulate matter sensors
    • Added support for SHT31 temperature and humidity sensor
    • Added support for SI7021 temperature and humidity sensor
    • Added support for for Neopixel LED
    • Added support for Chirp Sensor soil moisture sensor
    • Added support for SparkFun RGB and Gesture Sensor
    • Added support for TTP226/TTP229 Touch control sensor
    NodeManager

  • Compact battery-powered motion + temperature + humidity project
    U user2684

    Very compact battery powered project based on @NeverDie Arduino Pro Mini Shield for RFM69(H)W board (https://www.openhardware.io/view/268/Arduino-Pro-Mini-Shield-for-RFM69HW) with attached a:

    • Mini Pir motion sensor (https://www.aliexpress.com/item/New-Arrival-Mini-IR-Pyroelectric-Infrared-PIR-Motion-Human-Sensor-Automatic-Detector-Module-high-reliability-12mm/32749804501.html)
    • SHT21 temperature + humidity sensor (https://www.aliexpress.com/item/HTU21D-SHT21-IIC-I2C-Digital-Temperature-Humidity-Sensor-Breakout-Board-Module-For-Weather-Stations-Humidor-Control/32846196764.html)

    I'd warmly recommend that PIR sensor, it's tiny, it works down to 2.7v (so not requiring any voltage regulator for this 3.3v project especially if the arduino runs at 1Mhz like all my boards), consumes nothing and produces very little false positives.

    Code and pictures down below.

    /**********************************
     * MySensors node configuration
     */
    
    // General settings
    #define SKETCH_NAME "Pir"
    #define SKETCH_VERSION "1.0"
    //#define MY_DEBUG
    #define MY_NODE_ID 6
    
    // RFM69 radio settings
    #define MY_RADIO_RFM69
    //#define MY_RFM69_FREQUENCY RFM69_433MHZ
    #define MY_IS_RFM69HW
    #define MY_RFM69_NEW_DRIVER
    //#define MY_RFM69_ENABLE_ENCRYPTION
    #define MY_RFM69_NETWORKID 110
    //#define MY_DEBUG_VERBOSE_RFM69
    //#define MY_RF69_IRQ_PIN D1
    //#define MY_RF69_IRQ_NUM MY_RF69_IRQ_PIN
    //#define MY_RF69_SPI_CS D2
    //#define MY_RFM69_ATC_MODE_DISABLED
    
    // Advanced settings
    #define MY_BAUD_RATE 9600
    //#define MY_SMART_SLEEP_WAIT_DURATION_MS 500
    #define MY_SPLASH_SCREEN_DISABLED
    //#define MY_DISABLE_RAM_ROUTING_TABLE_FEATURE
    //#define MY_SIGNAL_REPORT_ENABLED
    
    /***********************************
     * NodeManager modules for supported sensors
     */
    
    #define USE_BATTERY
    #define USE_SIGNAL
    #define USE_CONFIGURATION
    #define USE_SHT21
    #define USE_INTERRUPT
    
    /***********************************
     * NodeManager built-in features
     */
    
    // Enable/disable NodeManager's features
    #define FEATURE_DEBUG ON
    #define FEATURE_POWER_MANAGER ON
    #define FEATURE_INTERRUPTS ON
    #define FEATURE_CONDITIONAL_REPORT OFF
    #define FEATURE_EEPROM OFF
    #define FEATURE_SLEEP ON
    #define FEATURE_RECEIVE ON
    #define FEATURE_TIME OFF
    #define FEATURE_RTC OFF
    #define FEATURE_SD OFF
    #define FEATURE_HOOKING OFF
    
    /***********************************
     * Load NodeManager Library
     */
    
    #include "NodeManagerLibrary.h"
    NodeManager node;
    
    /***********************************
     * Add your sensors below
     */
    
    // built-in sensors
    SensorBattery battery(node);
    SensorConfiguration configuration(node);
    SensorSignal signal(node);
    
    // Attached sensors
    SensorSHT21 sht21(node);
    SensorMotion motion(node,3);
    
    /***********************************
     * Main Sketch
     */
    
    // before
    void before() {
      // setup the serial port baud rate
      Serial.begin(MY_BAUD_RATE);
      /*
      * Configure your sensors below
      */
    
      // battery sensor
      battery.setMinVoltage(1.8);
      battery.setMaxVoltage(3.2);
      
      // pir sensor
      motion.setInterruptMode(RISING);
      motion.setInitialValue(LOW);
    
      // sht21 sensor
      sht21.setReportIntervalMinutes(5);
    
      // node configuration
      node.setSleepMinutes(5);
      
      /*
      * Configure your sensors above
      */
      node.before();
    }
    
    // presentation
    void presentation() {
      // call NodeManager presentation routine
      node.presentation();
    }
    
    // setup
    void setup() {
      // call NodeManager setup routine
      node.setup();
    }
    
    // loop
    void loop() {
      // call NodeManager loop routine
      node.loop();
    }
    
    #if FEATURE_RECEIVE == ON
    // receive
    void receive(const MyMessage &message) {
      // call NodeManager receive routine
      node.receive(message);
    }
    #endif
    
    #if FEATURE_TIME == ON
    // receiveTime
    void receiveTime(unsigned long ts) {
      // call NodeManager receiveTime routine
      node.receiveTime(ts);
    }
    #endif
    

    0_1532192269076_1.png

    0_1532192281955_2.png

    My Project

  • 💬 myHouse
    U user2684

    @Gouds I've just added support for Ubuntu (well, should now run fine on any debian-based distribution) in this dev release: https://sourceforge.net/p/my-house/code/ci/8c70a57ed0267f0f2eda3ad9fbaada0462f95765/tree/ if you want to give it a try. Overwrite the files in the existing folder and run again the install.py and upgrade.py scripts.

    If you have any issue during installation/configuration which is not MySensors-related, please drop a message here: https://sourceforge.net/p/my-house/forum/general
    Thanks!

    Announcements

  • NodeManager: plugin for a rapid development of battery-powered sensors
    U user2684

    Pretty big enhancement in the development branch of NodeManager if anybody is interested. I spent quite a good amount of time working on the core code to introduce mainly two features opening up the door to a good list of enhancements.

    The first one is a sort of countdown utility. Can be based on the number of sleeping cycles or minutes. It detects automatically a sleeping node and instead of using millis sum up the sleep interval and reports when the time is over. This approach has been used to:

    • Allow different sensors reporting at different timeframes (e.g. by configuring a specific sensor to report every e.g. 5 minutes or 10 sleeping cycles instead of at the end of each cycle)
    • For output sensors optionally use the input value as an elapsed time (e.g. the output will be turned on and the input value will be used as a timer to turn it off automatically). For example by sending 3 to a relay, it will be turned on and after 3 minutes turned off automatically. Useful if you already know for how long the output should stay on.
    • For output sensors optionally set a safeguard (e.g. after a relay is set to on, turn it off automatically after 1 hour). Useful if e.g. you are controlling a boiler and you are afraid something could prevent the command to turn it off to reach the board.
    • Add timeframe option for reporting battery level (e.g. instead of reporting every 10 sleeping cycles, report every 1 hour regardless of how long is the sleeping cycles).

    The other big change is a an complete remote API. With the current version you could send to NodeManager's service child id a limited list of commands to change the behavior of the board remotely, mainly to alter the duration of the sleep cycle. In the development release instead, almost every function of both NodeManager AND of every sensor can be invoked remotely. This is done by sending a V_CUSTOM message with a function_id and optional value to pass along to the service child id or each sensor's child id. More details here: https://github.com/mysensors/NodeManager/tree/development#communicate-with-nodemanager-and-its-sensors

    This development branch is available here: https://github.com/mysensors/NodeManager/tree/development

    NodeManager

  • Door + flood sensor
    U user2684

    Pretty simple door + flood project based on @sundberg84 EasyPCB RFM69 board with attached a:

    • Flood sensor: https://www.aliexpress.com/item/DC-220V-Liquid-Water-Level-Sensor-Right-Angle-Float-Switch-for-Fish-Tank/32643554836.html
    • Door sensor: https://www.aliexpress.com/item/10pairs-lot-NC-and-NO-two-kinds-type-Wired-Metal-Roller-Shutter-Door-Magnetic-Contact-Switch/32843185792.html

    Both the sensors have one wire connected to Ground and on the other wire to an Arduino pin. Principle is simple: we write HIGH to the pin (or let NodeManager doing the job), when the sensor switches (e.g. the circuit is closed), we catch the FALLING interrupt (or the LOW value).

    Since battery powered, the door sensor has to be normally open (e.g. when the door is closed, the circuit is open and no current is wasted). Many Chinese vendors, at least from my experience, makes confusion on this topic and send the wrong one or call it in a wrong way. This is why I bought those sensors with both NO and NC, so I'm sure to have enough flexibility.

    Code with NodeManager's is pretty simple, down below. Only caveat is both the sensors theoretically would be interrupt based but on a Pro Mini there is only one usable pin for it. I've gone crazy trying to use PinChangeInterrupt with NodeManager so eventually I decided to go for the easy way: if there is a water leakage inside my house, I can wait up to 5 minutes, so I'm just polling the flood sensor's pin periodically and send the value to the controller at a regular interval (using SensorDigitalInput).

    Pictures of the project down below.

    /**********************************
     * MySensors node configuration
     */
    
    // General settings
    #define SKETCH_NAME "Door"
    #define SKETCH_VERSION "1.0"
    //#define MY_DEBUG
    #define MY_NODE_ID 5
    
    // RFM69 radio settings
    #define MY_RADIO_RFM69
    //#define MY_RFM69_FREQUENCY RFM69_433MHZ
    #define MY_IS_RFM69HW
    #define MY_RFM69_NEW_DRIVER
    //#define MY_RFM69_ENABLE_ENCRYPTION
    #define MY_RFM69_NETWORKID 110
    //#define MY_DEBUG_VERBOSE_RFM69
    //#define MY_RF69_IRQ_PIN D1
    //#define MY_RF69_IRQ_NUM MY_RF69_IRQ_PIN
    //#define MY_RF69_SPI_CS D2
    //#define MY_RFM69_ATC_MODE_DISABLED
    
    // Advanced settings
    #define MY_BAUD_RATE 9600
    //#define MY_SMART_SLEEP_WAIT_DURATION_MS 500
    #define MY_SPLASH_SCREEN_DISABLED
    //#define MY_DISABLE_RAM_ROUTING_TABLE_FEATURE
    //#define MY_SIGNAL_REPORT_ENABLED
    
    /***********************************
     * NodeManager modules for supported sensors
     */
    
    #define USE_BATTERY
    #define USE_SIGNAL
    #define USE_CONFIGURATION
    #define USE_DIGITAL_INPUT
    #define USE_INTERRUPT
    
    /***********************************
     * NodeManager built-in features
     */
    
    // Enable/disable NodeManager's features
    #define FEATURE_DEBUG ON
    #define FEATURE_POWER_MANAGER OFF
    #define FEATURE_INTERRUPTS ON
    #define FEATURE_CONDITIONAL_REPORT OFF
    #define FEATURE_EEPROM OFF
    #define FEATURE_SLEEP ON
    #define FEATURE_RECEIVE ON
    #define FEATURE_TIME OFF
    #define FEATURE_RTC OFF
    #define FEATURE_SD OFF
    #define FEATURE_HOOKING OFF
    
    /***********************************
     * Load NodeManager Library
     */
    
    #include "NodeManagerLibrary.h"
    NodeManager node;
    
    /***********************************
     * Add your sensors below
     */
    
    // built-in sensors
    SensorBattery battery(node);
    SensorConfiguration configuration(node);
    SensorSignal signal(node);
    
    // Attached sensors
    SensorDigitalInput flood(node,6);
    SensorMotion door(node,3);
    
    /***********************************
     * Main Sketch
     */
    
    // before
    void before() {
      // setup the serial port baud rate
      Serial.begin(MY_BAUD_RATE);
      /*
      * Configure your sensors below
      */
    
      // battery sensor
      battery.setMinVoltage(1.8);
      battery.setMaxVoltage(3.2);
      
      // door sensor
      door.setInitialValue(HIGH);
      door.setInterruptMode(FALLING);
      door.setInvertValueToReport(true);
    
      // flood sensor
      flood.setReportIntervalMinutes(5);
      flood.children.get(1)->setPresentation(S_BINARY);
      flood.children.get(1)->setType(V_STATUS);
    
      // node configuration
      node.setSleepMinutes(5);
      
      /*
      * Configure your sensors above
      */
      node.before();
    }
    
    // presentation
    void presentation() {
      // call NodeManager presentation routine
      node.presentation();
    }
    
    // setup
    void setup() {
      // call NodeManager setup routine
      node.setup();
    }
    
    // loop
    void loop() {
      // call NodeManager loop routine
      node.loop();
    }
    
    #if FEATURE_RECEIVE == ON
    // receive
    void receive(const MyMessage &message) {
      // call NodeManager receive routine
      node.receive(message);
    }
    #endif
    
    #if FEATURE_TIME == ON
    // receiveTime
    void receiveTime(unsigned long ts) {
      // call NodeManager receiveTime routine
      node.receiveTime(ts);
    }
    #endif
    

    0_1532190948397_1.png

    0_1532190963945_2.png

    My Project

  • MyExtension
    U user2684

    Hi,

    Even if I'm not very good with programming and terrible with C/C++, I tried to put together a sort of extension to the core engine providing additional functionalities but without impacting the core code. The idea was to embed within the sketch (better if in the future in a library), a sort of additional service taking care of common tasks automatically so to simplify the development. The "extension" hooks up (well, manually) into setup(), presentation(), loop() and receive(), present itself as a child-id node type S_CUSTOM to the controller and communicates with it with V_CUSTOM messages. A summary of what it does is:

    • Report battery level periodically and automatically, the period is configurable
    • Able to reboot the board on demand with the default bootloader, by connecting one of the pins to RST
    • Support multiple sleep mode: no sleep, sleep once and sleep cycle
    • Sleep mode and sleep time can be configured remotely with V_CUSTOM messages
    • Sleep mode and sleep time are made persistent within the EEPROM once changed
    • A pin can be configure to wake up a sleeping board when connected to ground
    • Can report battery level on demand
    • Allow changing the node_id remotely
    • Stop sleeping when a WAKEUP message is sent just after a smart sleeping cycle
    • Calculate battery from internal vcc without requiring a pin and the resistors
    • Can calculate the battery percentage using custom boundaries
    • Return the battery voltage through the custom service

    A message to the service would look like 254;200;2;0;48;HELLO and the language (kind of inspired by the old ciseco LLAP) used in the payload of the S_CUSTOM message is the following:

    • BATT: return the battery level
    • HELLO: hello request
    • NOSLEEP: set and save sleeping mode to no sleep
    • SLEEPONCE: set and save sleeping mode to sleep once and go to sleep just after
    • SLEEPCYCLE: set and save sleeping mode to sleep cycle and got to sleep just after
    • SLEEPnnnX: set and save the sleep interval to nnn where X is S=Seconds, M=mins, H=Hours, D=Days. E.g. SLEEP010M would be 10 minutes
    • MYxxx: change the node id to the provided one. E.g. MY025: change the node id to 25. Requires a reboot/restart
    • WAKEUP: when received after a sleeping cycle, abort cycle sleeping since the controller needs us awake
    • REBOOT: reboot the board
    • RESET: clear the user's eeprom
    • VERSION: send back the extension's version

    Now, this is just a proof of concept not suitable for production but I would like to hear your feedback. Does the idea make some sense? Do you see anything that could be interesting to have in the core engine instead? Should I go on developing the idea or trash everything?

    Thanks in advance!

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <MySensors.h>
    
    /*
     * MyExtension
     */
     // sample request messages
     /*
    254;200;2;0;48;BATT
    254;200;2;0;48;HELLO
    254;200;2;0;48;SLEEP005S
    254;200;2;0;48;WAKEUP
    254;200;2;0;48;NOSLEEP
    254;200;2;0;48;SLEEPONCE
    254;200;2;0;48;SLEEPCYCLE
    254;200;2;0;48;SLEEP010M
    254;200;2;0;48;REBOOT
    254;200;2;0;48;VERSION
      */
    // define supported sleeping mode
    #define MY_EXT_NO_SLEEP 0
    #define MY_EXT_SLEEP_CYCLE 1
    #define MY_EXT_SLEEP_ONCE 2
    #define MY_EXT_SLEEP_UNIT_S 0
    #define MY_EXT_SLEEP_UNIT_M 1
    #define MY_EXT_SLEEP_UNIT_H 2
    #define MY_EXT_SLEEP_UNIT_D 3
    // define eeprom addresses
    #define MY_EXT_EEPROM_SLEEP_SAVED 0
    #define MY_EXT_EEPROM_SLEEP_MODE 1
    #define MY_EXT_EEPROM_SLEEP_TIME_MAJOR 2
    #define MY_EXT_EEPROM_SLEEP_TIME_MINOR 3
    #define MY_EXT_EEPROM_SLEEP_UNIT 4
    // version
    #define MY_EXT_VERSION 1.0
    
    /*
     * configuration settings
     */
    // define if the board has to sleep every time entering loop(). It can be MY_EXT_NO_SLEEP (no sleep), MY_EXT_SLEEP_ONCE (sleep only once) or MY_EXT_SLEEP_CYCLE (sleep at every cycle)
    #define MY_EXT_SLEEP_MODE MY_EXT_NO_SLEEP
    // define for how long the board will sleep
    #define MY_EXT_SLEEP_TIME 0
    // define the unit of MY_EXT_SLEEP_TIME. It can be MY_EXT_SLEEP_UNIT_S (seconds), MY_EXT_SLEEP_UNIT_M (minutes), MY_EXT_SLEEP_UNIT_H (hours), MY_EXT_SLEEP_UNIT_D (days)
    #define MY_EXT_SLEEP_UNIT MY_EXT_SLEEP_UNIT_S
    // if defined, allow modifying sleep mode and interval remotely with NOSLEEP/SLEEPONCE/SLEEPCYCLE and SLEEPnnnX
    #define MY_EXT_SLEEP_REMOTE_CONFIGURATION
    // if defined, reset the board with the configured pin when receiving a REBOOT message
    
    #define MY_EXT_SOFT_REBOOT
    // the pin to connect to the RST pin to reboot the board
    #define MY_EXT_SOFT_REBOOT_PIN 4
    // if defined, wakeup from sleep when the configured pin changes
    
    #define MY_EXT_SLEEP_INTERRUPT
    // if defined, when waking up from the interrupt, the board stops sleeping. Disable it when attaching e.g. a motion sensor
    #define MY_EXT_SLEEP_INTERRUPT_ABORT_SLEEP
    // the pin to connect sued for waking up a sleeping board. Can be either 2, 3 or a different pin provided is reconfigured to act as an interrupt pin
    #define MY_EXT_SLEEP_INTERRUPT_PIN 3
    // the interrupt mode. Can be either FALLING or RISING 
    #define MY_EXT_SLEEP_INTERRUPT_MODE FALLING
    // the expected vcc when the batter is fully charged, used to calculate the percentage
    
    #define MY_EXT_BATTERY_MAX 3.3
    // the expected vcc when the batter is fully discharged, used to calculate the percentage
    #define MY_EXT_BATTERY_MIN 2.8
    // if defined, report automatically the battery level back to the controller after the given number of hours (if the board sleeping it will be reported when awake next)
    #define MY_EXT_REPORT_BATTERY
    // how frequently (in hours) to report the battery level to the controller
    #define MY_EXT_REPORT_BATTERY_H 1
    // if defined, enable debug of the extension on serial port
    
    #define MY_EXT_DEBUG
    // the sensor child id used by the extension to send messages to the controller
    #define MY_EXT_CHILD_ID 200
    
    /*
     * class definition
     */
    class MyExtension {
    	public:
        MyExtension();
        // functions to be explicitely called within the sketch allow the extension hooking into the flow
    		void setup();
    		void presentation();
    		void loop();
        void receive(const MyMessage &);
    	private:
        // define if and how to sleep
        int _sleep_mode = MY_EXT_SLEEP_MODE;
        // define for how long to sleep (time)
        int _sleep_time = MY_EXT_SLEEP_TIME;
        // define for how long to sleep (unit)
        int _sleep_unit = MY_EXT_SLEEP_UNIT;
        // store last time the battery level has been reported
        long _battery_last_reported = millis();
        // implement custom sleep
        void _sleep();
        // process an incoming message/command
        void _process(const char *);
        // the container of the message used to respond to any request
        MyMessage msg;
    };
    
    /*
     * implementation
     */
    // constructor
    inline MyExtension::MyExtension() {
      // initialize the response message container
      msg = MyMessage(MY_EXT_CHILD_ID,V_CUSTOM);
    }
    
    // what to do when called within setup()
    inline void MyExtension::setup() {
      #ifdef MY_EXT_SOFT_REBOOT
        // setup the reboot pin 
        digitalWrite(MY_EXT_SOFT_REBOOT_PIN,HIGH);
        pinMode(MY_EXT_SOFT_REBOOT_PIN,OUTPUT);
      #endif
      #ifdef MY_EXT_SLEEP_INTERRUPT
        // setup the sleep interrupt pin 
        pinMode(MY_EXT_SLEEP_INTERRUPT_PIN,INPUT);
        digitalWrite(MY_EXT_SLEEP_INTERRUPT_PIN,HIGH ? MY_EXT_SLEEP_INTERRUPT_MODE == FALLING : LOW);
      #endif
      #ifdef MY_EXT_SLEEP_REMOTE_CONFIGURATION
        // restore sleep configuration from eeprom
        if (loadState(MY_EXT_EEPROM_SLEEP_SAVED) == 1) {
          // sleep settings found in the eeprom, restore them
          _sleep_mode = loadState(MY_EXT_EEPROM_SLEEP_MODE);
          _sleep_time = loadState(MY_EXT_EEPROM_SLEEP_TIME_MINOR);
          int major = loadState(MY_EXT_EEPROM_SLEEP_TIME_MAJOR);
          if (major == 1) _sleep_time =  _sleep_time + 250;
          if (major == 2) _sleep_time =  _sleep_time + 250*2;
          if (major == 3) _sleep_time =  _sleep_time + 250*3;
          _sleep_unit = loadState(MY_EXT_EEPROM_SLEEP_UNIT);
          #ifdef MY_EXT_DEBUG
            Serial.print("Restored from eeprom sleep settings: sleep_mode=");
            Serial.print(_sleep_mode);
            Serial.print(" sleep_time=");
            Serial.print(_sleep_time);
            Serial.print(" sleep_unit=");
            Serial.println(_sleep_unit);
          #endif
        }
      #endif
    }
    
    // what to do when called within presentation()
    inline void MyExtension::presentation() {
      // present the extension as a custom sensor to the controller
      present(MY_EXT_CHILD_ID,S_CUSTOM);
      #ifdef MY_EXT_REPORT_BATTERY
        // report battery level
        MyExtension::_process("BATT");
      #endif
    }
    
    // what to do when called within loop()
    inline void MyExtension::loop() {
      // continue/start sleeping if requested
      if (_sleep_mode != MY_EXT_NO_SLEEP) MyExtension::_sleep();
    }
    
    // wrapper of smart sleep
    inline void MyExtension::_sleep() {
      // calculate the seconds to sleep
      long sleep_sec = _sleep_time;
      if (_sleep_unit == MY_EXT_SLEEP_UNIT_M) sleep_sec = sleep_sec*60;
      else if (_sleep_unit == MY_EXT_SLEEP_UNIT_H) sleep_sec = sleep_sec*3600;
      else if (_sleep_unit == MY_EXT_SLEEP_UNIT_D) sleep_sec = sleep_sec*43200;
      long sleep_ms = sleep_sec*1000;
      #ifdef MY_EXT_DEBUG
        Serial.print("Going to sleep for ");
        Serial.print(sleep_sec);
        Serial.println("s");
      #endif
      // notify the controller I'm going to sleep
      send(msg.set("SLEEPING"));
      // go in smart sleep for the requested sleep interval
      #ifdef MY_EXT_SLEEP_INTERRUPT
        // sleep and wakeup when the interrupt triggers
        int ret = sleep(digitalPinToInterrupt(MY_EXT_SLEEP_INTERRUPT_PIN),MY_EXT_SLEEP_INTERRUPT_MODE,sleep_ms,true);
      #else
        // sleep without any interrupt
        int ret = sleep(sleep_ms,true);
      #endif
      #ifdef MY_EXT_SLEEP_INTERRUPT
        if (ret > -1) {
          #ifdef MY_EXT_DEBUG
            Serial.println("Woke up by interrupt");
          #endif
          #ifdef MY_EXT_SLEEP_INTERRUPT_ABORT_SLEEP
            // when waking up from an interrupt on the wakup pin, stop sleeping
            _sleep_mode = MY_EXT_NO_SLEEP;
          #endif
          // restore the sleep interrupt pin 
          digitalWrite(MY_EXT_SLEEP_INTERRUPT_PIN,HIGH ? MY_EXT_SLEEP_INTERRUPT_MODE == FALLING : LOW);
        }
      #endif
      // coming out of sleep
      #ifdef MY_EXT_DEBUG
        Serial.println("Awake");
      #endif
      // if supposed to sleep once, reset sleep mode
      if (_sleep_mode == MY_EXT_SLEEP_ONCE) _sleep_mode = MY_EXT_NO_SLEEP;
      // notify the controller I am awake
      send(msg.set("AWAKE"));
      #ifdef MY_EXT_REPORT_BATTERY
        if ( (millis()-_battery_last_reported)/1000/3600 > MY_EXT_REPORT_BATTERY_H) {
          // time to report the battery level again
          MyExtension::_process("BATT");
          _battery_last_reported = millis();
        }
      #endif
    }
    
    // process a message/command
    inline void MyExtension::_process(const char *message) {
      // BATT: return the battery level
      if (strcmp(message,"BATT") == 0) {
        // measure the provided vcc
        float volt = (float)hwCPUVoltage()/1000;
        // send the measure back with a custom message
        char reply[25] = "BATT";
        dtostrf(volt,1,2,&reply[strlen(reply)]);
        send(msg.set(reply));
        // calculate the percentage
        int percentage = 100-(MY_EXT_BATTERY_MAX-volt/(MY_EXT_BATTERY_MAX-MY_EXT_BATTERY_MIN));
        if (percentage > 100) percentage = 100;
        if (percentage < 0) percentage = 0;
        // send battery level percentage
        sendBatteryLevel(percentage);
      }
      // HELLO: hello request
      else if (strcmp(message,"HELLO") == 0) {
        send(msg.set("HELLO"));
      }
      #ifdef MY_EXT_SLEEP_REMOTE_CONFIGURATION
        // NOSLEEP: set and save sleeping mode to no sleep
        else if (strcmp(message,"NOSLEEP") == 0) {
          // go to sleep
          _sleep_mode = MY_EXT_NO_SLEEP;
          // save it to the eeprom
          saveState(MY_EXT_EEPROM_SLEEP_SAVED,1);
          saveState(MY_EXT_EEPROM_SLEEP_MODE,MY_EXT_NO_SLEEP);
          send(msg.set(message));
        }
        // SLEEPONCE: set and save sleeping mode to sleep once and go to sleep just after
        else if (strcmp(message,"SLEEPONCE") == 0) {
          // go to sleep
          _sleep_mode = MY_EXT_SLEEP_ONCE;
          // save it to the eeprom
          saveState(MY_EXT_EEPROM_SLEEP_SAVED,1);
          saveState(MY_EXT_EEPROM_SLEEP_MODE,MY_EXT_SLEEP_ONCE);
        }
        // SLEEPCYCLE: set and save sleeping mode to sleep cycle and got to sleep just after
        else if (strcmp(message,"SLEEPCYCLE") == 0) {
          // go to sleep
          _sleep_mode = MY_EXT_SLEEP_CYCLE;
          // save it to the eeprom
          saveState(MY_EXT_EEPROM_SLEEP_SAVED,1);
          saveState(MY_EXT_EEPROM_SLEEP_MODE,MY_EXT_SLEEP_CYCLE);
        }
        // SLEEPnnnX: set and save the sleep interval to nnn where X is S=Seconds, M=mins, H=Hours, D=Days. E.g. SLEEP010M would be 10 minutes
        else if (strlen(message) == 9 && strncmp("SLEEP",message,strlen("SLEEP")) == 0) {
          // parse and set the sleep interval
          int offset = 5;
          // extract the unit (S=secs, M=mins, H=hours, D=Days)
          char unit[2];
          sprintf(unit,"%c",message[3+offset]);
          unit[1] = '\0';
          if (strcmp(unit,"S") == 0) _sleep_unit = MY_EXT_SLEEP_UNIT_S;
          else if (strcmp(unit,"M") == 0) _sleep_unit = MY_EXT_SLEEP_UNIT_M;
          else if (strcmp(unit,"H") == 0) _sleep_unit = MY_EXT_SLEEP_UNIT_H;
          else if (strcmp(unit,"D") == 0) _sleep_unit = MY_EXT_SLEEP_UNIT_D;
          else return;
          // extract the requested time
          char s[4];
          s[0] = message[0+offset];
          s[1] = message[1+offset];
          s[2] = message[2+offset];
          s[3] = '\0';
          _sleep_time = atoi(s);
          #ifdef MY_EXT_DEBUG
            Serial.print("Set sleep_interval to "); 
            Serial.print(_sleep_time);
            Serial.print(" ");
            Serial.println(_sleep_unit);
          #endif
          // save it to eeprom
          saveState(MY_EXT_EEPROM_SLEEP_UNIT,_sleep_unit);
          // encode sleep time
          int major = 0;
          if (_sleep_time > 750) major = 3;
          else if (_sleep_time > 500) major = 2;
          else if (_sleep_time > 250) major = 1;
          int minor = _sleep_time - 250*major;
          saveState(MY_EXT_EEPROM_SLEEP_SAVED,1);
          saveState(MY_EXT_EEPROM_SLEEP_TIME_MINOR,minor);
          saveState(MY_EXT_EEPROM_SLEEP_TIME_MAJOR,major);
          // interval set, reply back with the same message to acknowledge. Wait for SLEEP to start sleeping
          send(msg.set(message));
        }
      #endif
      // MYxxx: change the node id to the provided one. E.g. MY025: change the node id to 25. Requires a reboot/restart
      else if (strlen(message) == 5 && strncmp("MY",message,strlen("MY")) == 0) {
        // extract the node id
        char s[4];
        s[0] = message[2];
        s[1] = message[3];
        s[2] = message[4];
        s[3] = '\0';
        int node_id = atoi(s);
        // Save static ID to eeprom
        hwWriteConfig(EEPROM_NODE_ID_ADDRESS, (uint8_t)node_id);
        _transportConfig.nodeId = (uint8_t)node_id;
      }
      // WAKEUP: when received after a sleeping cycle, abort cycle sleeping since the controller needs us awake
      else if (strcmp(message,"WAKEUP") == 0) {
        send(msg.set(message));
        _sleep_mode = MY_EXT_NO_SLEEP;
      }
      // REBOOT: reboot the board
      else if (strcmp(message,"REBOOT") == 0) {
        #ifdef MY_EXT_SOFT_REBOOT
          // set the reboot pin connected to RST to low so to reboot the board
          send(msg.set(message));
          digitalWrite(MY_EXT_SOFT_REBOOT_PIN,LOW);
        #endif
      }
      // RESET: clear the user's eeprom
      else if (strcmp(message,"RESET") == 0) {
        for (int i = 0; i<=255; i++) saveState(i,0xFF);
        send(msg.set(message));
      }
      // VERSION: send back the extension's version
      else if (strcmp(message,"VERSION") == 0) {
        send(msg.set(MY_EXT_VERSION,1));
      }
      
    }
    
    // what to do when called within receive()
    inline void MyExtension::receive(const MyMessage &message) {
      // ignore messages not for this extension
      if (message.sensor != MY_EXT_CHILD_ID) return;
      #ifdef MY_EXT_DEBUG
        Serial.print("Received message from=");
        Serial.print(message.sender);
        Serial.print(" command=");
        Serial.print(message.getCommand());
        Serial.print(" type=");
        Serial.print(message.type);
        Serial.print(" payload=");
        Serial.println(message.getString());
      #endif
      // parse incoming req messages
    	if (message.getCommand() == C_REQ && message.type == V_CUSTOM) {
        // process only V_CUSTOM messages
    		MyExtension::_process(message.getString());
    	}
    }
    
    // instantiate MyExtension
    MyExtension extension;
    
    //setup
    void setup() {
      // setup MyExtension
      extension.setup();
    }
    
    // presentation
    void presentation() {
      // Send the sketch version information to the gateway and Controller
    	sendSketchInfo("Test Sketch", "1.0");
      // present MyExtension
    	extension.presentation();
      
    }
    
    // loop
    void loop() {
      // loop for MyExtension
      extension.loop();
    }
    
    // receive
    void receive(const MyMessage &message) {
      // receive for MyExtension
      extension.receive(message);
    }
    
    Development

  • Request for contribution - controller selection matrix
    U user2684

    Done it! (https://www.mysensors.org/controller/egeoffrey). I've already removed the legacy myHouse project and updated the spreadsheet. If there is anything wrong in the changes, just let me know. Do I also need to create a subcategory under https://forum.mysensors.org/category/3/controllers? Thanks!

    Controllers

  • 💬 NodeManager
    U user2684

    After a few months working behind the scene, NodeManager got kind of a full review in terms of architecture and usability. The code should be now simpler to understand for new users, the memory utilization has been optimized and the overall user experience has been improved.

    The looooong list of things that have been changed are detailed on https://github.com/mysensors/NodeManager/pull/229.
    Please note this is only available in the development branch (https://github.com/mysensors/NodeManager/tree/development) and will be generally available only when NodeManager's v1.7 will be released (it will take I guess still a few months).

    Since this change was blocking other pending changes, I hope now the development will be faster and feel free to submit your PRs now that the new architecture has been finalized.
    As always, any feedback is more than welcome.
    Thanks

    OpenHardware.io contest2017 arduino newbie mysensors battery sensor

  • Browser-based firmware generator
    U user2684

    @rakeshpai fully agree with you. I'll start working in order to push those changes which are not a priority or too complex to implement to a future release in order to finalize v1.6 asap and give you the time to start working with something stable. Mean while I'll let you know once the development code will be good enough to start working on it. I can probably target a final v1.6 by end of August and a stable version in a couple of weeks if it fits your plans. I've also created a specific thread we can use to discuss about the integration (https://forum.mysensors.org/topic/7212/integrating-nodemanager-with-sketch-generator) so to keep this as clean as possible from implementation details. Thanks!

    Development

  • MLX90614 contactless temperature sensor
    U user2684

    In case somebody can be interested (I've not seen any old posts talking about it), I've just tested this contactless temperature sensor from aliexpress (https://www.aliexpress.com/item/Free-Shipping-GY-906-MLX90614ESF-New-MLX90614-Contactless-Temperature-Sensor-Module-For-Arduino-Compatible/32465332978.html?spm=2114.13010608.0.0.gJhz6T) which is pretty cool.

    It reports BOTH the ambient temperature and the object temperature (the latter ranging from -70 to +380 C), has a standard i2c interface and works great with this library: https://github.com/adafruit/Adafruit-MLX90614-Library.

    The price is also pretty interesting, being around 3.5$.

    It can be used in many applications to e.g. measure the temperature of a body, the temperature of an oven, the temperature of a board, or whatever object could make sense in your project.

    Hardware

  • 💬 Selecting a Controller
    U user2684

    Thanks @rmtucker! @hek, I'll take care of sharing the description and feature list here as soon as the new version of MyHouse with the MySensors plugin will be made available (of course if anybody is interested to give it a try, please come in touch with me). So far the plugin in the development version is working fine so I'm confident to finalize it soon.
    Thanks

    Announcements
  • Login

  • Don't have an account? Register

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