Skip to content
  • 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
H

Heizelmann

@Heizelmann
  • Getting Started
  • Controller
  • Build
  • Hardware
  • Download/API
  • Forum
  • Store
About
Posts
60
Topics
5
Shares
0
Groups
0
Followers
0
Following
0

Posts

Recent Best Controversial

  • Help me build a 6-light-sensor & 2 ch relay node.
    H Heizelmann

    Only if you send a correct message from the controller to the node
    the receive function is called. I don't see a receive in your log.

    I think in your case the receive-function is not called (or called with a wrong message type or node id). Put a

     serial.print("receive() is called with type "); serial.println(message.getType());
    

    on top of the receive function to see if the receive function is called and which type is handed over..

    Troubleshooting

  • Node to node communication fails if gateway is not reachable
    H Heizelmann

    For me, node to node communication is a must have for a reliable secure home automation system. E.g. if a PIR sensor node detects motion, a lamp actuator on a different place should switch on the lamp quickly even if the gateway is off. May be mySensors is the wrong choice for this domain.

    Development

  • Node to node communication fails if gateway is not reachable
    H Heizelmann

    My scenario is as follows: A sensor node should report directly to a actuator node wether the gatway or any repeater are on or off. Both nodes should communicate bidirectonal to the gateway if available some different messages. Can anyone give me as an end user a simple example code for the both nodes?

    Development

  • Node to node communication fails if gateway is not reachable
    H Heizelmann

    @scalz Thanks for the info. I do not understand much of the software, but I would prefer the second solution as far as it will be integrated in the release. Using an internal API is unacceptable.
    But what about the case that the gateway is not reachable and the direct node also but a repeater inbetween could serve it?

    Development

  • Node to node communication fails if gateway is not reachable
    H Heizelmann

    Sorry, but this is too much complicated discussion for me. Is it possible or not with the current version for end users like me? If yes, I need a simple how to example.

    Development

  • Is there a way to check presence of a MySensors network, and proceed without if not found ?
    H Heizelmann

    @dbemowsk Search for node to node communication, you will find e.g.
    https://forum.mysensors.org/topic/8716/direct-pairing-of-two-nodes-implementation
    https://forum.mysensors.org/topic/826/node-to-node-communication and maybe some more.

    Development

  • 💬 Battery operated rain-gauge
    H Heizelmann

    @gohan As far as I can remember I used requestTime() on every wakeup which gets time from gateway. Basic implementation based on https://www.mysensors.org/build/rain.

    OpenHardware.io rain

  • 💬 Battery operated rain-gauge
    H Heizelmann

    My selfmade rain gauge uses the following algorithm:

    It collects amount of rain per day and stores it in eeprom ( with other values) every hour.
    If it is not raining, every hour it reports battery voltage and amount of rain per day (mm/day).
    If it is raining, it collects bucket tips and reports rain rate (l/h) every 5 minutes. It doesn't matter that the one hour sleep timer is resetted in this case and amount of rain and battery voltage is sent too.
    If it stops raining the bucket tip collector is reset to zero after a configurable amount of time, e.g. 1 minute.

    Using Arduino pro mini with 2 AA Batteries. Still have 2.9V after 9 month of operation.

    OpenHardware.io rain

  • nRF24Doctor
    H Heizelmann

    Very helpfull!

    My Project transmission delays compare modules power consumption radio quality doctor range gateway location diagnose nrf24 radio

  • nRf24L01+ connection quality meter
    H Heizelmann

    See further advanced project nRF24Doctor. Great thanks to @Technovation

    My Project

  • nrf24L01+ 1715AH versus 1452AB problem
    H Heizelmann

    @division can you please describe which concrete RF24 Library you took , which version of MySensors library you use, and how you integrate the RF24 library into MySensors?

    Hardware

  • nRf24L01+ connection quality meter
    H Heizelmann

    @AWI Thanks for this great tool. It helped me very much and I tried to implement some extended features.
    Here is my current result: It has now a menu interface with two buttons. You can change the pa level and the send repeat tries. Further you can measure the current of the radio module and reset the store. Configuration parameters are stored in EEPROM. See following code for more details.

    /*
      PROJECT: MySensors / Quality of radio transmission
      PROGRAMMER: AWI (MySensors libraries), modified by Heizelmann
      DATE: 20160529/ last update: 20171012
      FILE: AWI_Send.ino
      LICENSE: Public domain
    
      Hardware: ATMega328p board (e.g. Arduino pro nano) w/ NRF24l01
      and MySensors 2.1.1
    
      Special:
    
    
      Summary:
      Sends a radio message with counter each  x time to determine fault ratio with receiver
      Remarks:
      Fixed node-id & communication channel to other fixed node
    
      Change log:
      20160530 - added moving average on fail/ miss count, update to 2.0
      20171012 - extensions by @Heizelmann
               . added radio current measurement
               . added pa level switching
               . added send repeat option
               . added LCD Display with parallel interface
               . added two button to change pa level, send repeat count, reset store and display radio current
               . store config params in EEPROM
               . connect timeout with MY_TRANSPORT_WAIT_READY_MS
    
      @see https://forum.mysensors.org/topic/3984/nrf24l01-connection-quality-meter
    */
    
    //****  MySensors *****
    // Enable debug prints to serial monitor
    //#define MY_DEBUG
    #define MY_RADIO_NRF24                  // Enable and select radio type attached
    //#define MY_RF24_CHANNEL 80                // radio channel, default = 76
    
    // Set LOW transmit power level  if you have an amplified NRF-module
    // if power your radio separately with a good regulator you can turn up PA level.
    // MIN, LOW, HIGH, MAX
    #define MY_RF24_PA_LEVEL RF24_PA_MAX //default = MAX on nodes, LOW on gateway and repeater
    #define MY_NODE_ID 250
    #define NODE_TXT "Quality counter Q 250"
    // Init timeout for gateway not reachable
    #define MY_TRANSPORT_WAIT_READY_MS 20000 //ms; supported since MySensors V2.1 beta
    
    
    //#define MY_PARENT_NODE_ID 32              // fixed parent to controller when 0 (else comment out = AUTO)
    //#define MY_PARENT_NODE_IS_STATIC
    
    // #define MY_RF24_CE_PIN 7               // Ceech board, 3.3v (7,8)  (pin default 9,10)
    // #define MY_RF24_CS_PIN 8
    
    #define DESTINATION_NODE 0                // receiving fixed node id (default 0 = gateway)
    
    #define MY_BAUD_RATE 115200
    
    #include <SPI.h>
    #include <MySensors.h>
    //#include <LiquidCrystal_I2C.h>                // LCD display with I2C interface
    #include <LiquidCrystal.h>                      // LCD display with parallel interface
    #include <OneButton.h> //from https://github.com/mathertel/OneButton/blob/master/examples/TwoButtons/TwoButtons.ino
    
    // helpers
    #define LOCAL_DEBUG
    
    #ifdef LOCAL_DEBUG
    #define Sprint(a) (Serial.print(a))           // macro as substitute for print, enable if no print wanted
    #define Sprintln(a) (Serial.println(a))         // macro as substitute for println
    #else
    #define Sprint(a)                   // enable if no print wanted -or- 
    #define Sprintln(a)                   // enable if no print wanted
    #endif
    
    
    // MySensors sensor
    #define COUNTER_CHILD 0
    
    // send constants and variables
    int messageCounter = 0 ;
    const int messageCounterMax = 100 ;           // maximum message counter value
    const unsigned counterUpdateDelay = 500 ;       // send every x ms and sleep in between
    
    // receive constants and variables
    boolean failStore[messageCounterMax] ;          // moving average stores & pointers
    int failStorePointer = 0 ;
    boolean missedStore[messageCounterMax] ;
    int missedStorePointer = 0 ;
    int newMessage = 0 ;
    int lastMessage = -1 ;
    int missedMessageCounter = 0 ;              // total number of messages in range (messageCounterMax)
    int failMessageCounter = 0 ;              // total number of messages in range (messageCounterMax)
    uint8_t parent = 0 ;                  // parent node-id
    
    // Loop delays
    const unsigned long displayInterval = 1000UL ;      // display update in ms
    unsigned long lastDisplayUpdate = 0 ;         // last update for loop timers
    
    // standard messages
    MyMessage counterMsg(COUNTER_CHILD, V_PERCENTAGE);   // Send value
    
    // ***** LCD
    #define LCD_COLS 16
    #define LCD_ROWS 2
    //LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
    //LiquidCrystal_I2C lcd(0x27, 16, 2);  // Set the LCD I2C address
    LiquidCrystal lcd(8, 7, 6, 5, 4, 3); // LCD with paralell interface
    
    #define CURRENT_PIN A5
    #define BUTTON1_PIN A1
    #define BUTTON2_PIN A2
    OneButton button1(BUTTON1_PIN, true); //PullUp, Activelow
    OneButton button2(BUTTON2_PIN, true); //PullUp, Activelow
    
    // Options
    #define EEPROM_FLAG 0
    #define EEPROM_PA_LEVEL 1
    #define EEPROM_SEND_REPEATS 2
    
    #define LEVEL_ITEMS 4
    const char *paLevelNames[LEVEL_ITEMS] = { "MIN", "LOW", "HIGH", "MAX" };
    uint8_t rf24palevel = MY_RF24_PA_LEVEL;
    
    #define MIN_REPEAT_DELAY 50
    #define MAX_REPEAT_DELAY 200
    uint8_t sendRepeats = 3;
    
    // Current measurement
    #define CORRECTION 9.285
    int currentMa;
    
    // Menu
    #define MENU_TIMEOUT 10000
    enum mode { STATE_RUN, STATE_RUN2, STATE_PALEVEL, STATE_RESEND};
    mode opState = STATE_RUN;
    unsigned long lastClickedMillis;
    boolean dspRefresh = true;
    
    void before() {
      pinMode(CURRENT_PIN, INPUT);
      analogReference(INTERNAL);
    
      //  Wire.begin();  // I2C
      // ** LCD display **
      lcd.begin(LCD_COLS, LCD_ROWS);
      //lcd.setBacklight(HIGH);
      lcd.home();
      lcd.setCursor(0, 0);
      lcd.print("AWIQuality nRF24");
      lcd.setCursor(0, 1);
      lcd.print("Connect...");
    
      initStore();
      delay(1000);
    
      button1.attachClick(onButton1Pressed);
      button1.attachLongPressStart(onButton1LongPressed);
      button2.attachClick(onButton2Pressed);
    
      if (loadState(EEPROM_FLAG) == 0xFF) {
        rf24palevel = loadState(EEPROM_PA_LEVEL);
        sendRepeats = loadState(EEPROM_SEND_REPEATS);
      } else {
        saveState(EEPROM_FLAG, 0xFF);
        saveState(EEPROM_PA_LEVEL, rf24palevel);
        saveState(EEPROM_SEND_REPEATS, sendRepeats);
      }
    }
    
    void presentation() {
      present(COUNTER_CHILD, S_DIMMER, NODE_TXT) ;  // counter uses percentage from dimmer value
    }
    
    void loop() {
      button1.tick();
      button2.tick();
      if (opState != STATE_RUN && opState != STATE_RUN2 && millis() - lastClickedMillis > MENU_TIMEOUT) {
        Sprintln("Timeout");
        setRFLevel(rf24palevel);
        saveState(EEPROM_PA_LEVEL, rf24palevel);
        saveState(EEPROM_SEND_REPEATS, sendRepeats);
        opState = STATE_RUN;
      }
    
      if (dspRefresh) LCD_local_display();
    
      if ( opState == STATE_RUN ) {
        Sprint("count:") ; Sprintln(messageCounter++) ;
        missedStore[failStorePointer] = false  ;      // set slot to false (ack message needs to set) ;
        boolean success = failStore[failStorePointer] = resend(counterMsg.setDestination(DESTINATION_NODE).set(failStorePointer), sendRepeats);  // send to destination with ack
        currentMa = analogRead(CURRENT_PIN) / CORRECTION;
        if (!success) {
          failMessageCounter++ ;
          Sprint("Fail on message: ") ; Sprint(failStorePointer) ;
          Sprint(" # ") ; Sprintln(failMessageCounter);
        }
        failStorePointer++ ;
        if (failStorePointer >= messageCounterMax) {
          failStorePointer =  0 ;           // wrap counter
        }
        parent = getParentNodeId();             // get the parent node (0 = gateway)
    
        wait(counterUpdateDelay) ;              // wait for things to settle and ack's to arrive
        dspRefresh = true;
      }
    }
    
    void receive(const MyMessage &message) {          // Expect few types of messages from controller
      newMessage = message.getInt();            // get received value
      switch (message.type) {
        case V_PERCENTAGE:
          missedStore[newMessage] = true ;      // set corresponding flag to received.
          if (newMessage > lastMessage) {       // number of messages missed from lastMessage (kind of, faulty at wrap)
            Sprint("Missed messages: ") ; Sprintln( newMessage - lastMessage - 1) ;
            missedMessageCounter += newMessage - lastMessage - 1 ;
          }
          lastMessage = newMessage ;
          break ;
        default: break ;
      }
    }
    
    
    // calculate number of false values in array
    // takes a lot of time, but who cares...
    int getCount(boolean countArray[], int size) {
      int falseCount = 0 ;
      for (int i = 0 ; i < size ; i++) {
        falseCount += countArray[i] ? 0 : 1 ;
      }
      return falseCount ;
    }
    
    
    void initStore() {
      for (int i = 0 ; i <  messageCounterMax ; i++) { // init stores for moving averages
        failStore[i] = true ;
        missedStore[i] = true ;
      }
      missedMessageCounter = failMessageCounter = 0;
    }
    
    void setRFLevel(uint8_t rfLevel) {
      Sprint("Set RF Level to "); Sprintln(rf24palevel);
      uint8_t rfsetup = (((MY_RF24_DATARATE) & 0b10 ) << 4) | (((MY_RF24_DATARATE) & 0b01 ) << 3) | (((rfLevel << 1))) + 1; // +1 for Si24R1;
      RF24_setRFSetup(rfsetup);
    }
    
    boolean resend(MyMessage &msg, int repeats) {
      int repeat = 0;
      int repeatdelay = 0;
      boolean sendOK = false;
    
      while ((sendOK == false) and (repeat < repeats)) {
        if (send(msg, true)) { //send
          sendOK = true;
        } else {
          sendOK = false;
          repeatdelay += random(MIN_REPEAT_DELAY, MAX_REPEAT_DELAY);
        }
        repeat++;
        delay(repeatdelay);
      }
      return sendOK;
    }
    
    void onButton1Pressed() {
      dspRefresh = true;
      lcd.clear(); lcd.home();
      switch (opState) {
        case STATE_RUN:
          opState = STATE_PALEVEL;
          break;
        case STATE_RUN2:
          opState = STATE_RUN;
          break;
        case STATE_PALEVEL:
          opState = STATE_RESEND;
          break;
        case STATE_RESEND:
          setRFLevel(rf24palevel);
          saveState(EEPROM_PA_LEVEL, rf24palevel);
          saveState(EEPROM_SEND_REPEATS, sendRepeats);
          opState = STATE_RUN;
          break;
      }
      lastClickedMillis = millis();
    }
    
    void onButton2Pressed() {
      dspRefresh = true;
      lcd.clear(); lcd.home();
      switch (opState) {
        case STATE_RUN:
          opState = STATE_RUN2;
          break;
        case STATE_RUN2:
          opState = STATE_RUN;
          break;
        case STATE_PALEVEL:
          rf24palevel++; if (rf24palevel > 3) rf24palevel = 0;
          break;
        case STATE_RESEND:
          sendRepeats++; if (sendRepeats > 3) sendRepeats = 1;
          break;
      }
      lastClickedMillis = millis();
    }
    
    void onButton1LongPressed() {
      initStore();
    }
    
    
    void LCD_local_display(void) {
      dspRefresh = false;
      char buf[LCD_COLS + 1];                     // buffer for max 16 char display
    
      switch (opState) {
        case STATE_RUN:
          lcd.setCursor(0, 0);
          snprintf(buf, sizeof buf, "P%-3dFail%4d%3d%%", parent, failMessageCounter, getCount(failStore, messageCounterMax));
          lcd.print(buf);
          lcd.setCursor(0, 1);
          snprintf(buf, sizeof buf, "D%-3dMiss%4d%3d%%", DESTINATION_NODE , missedMessageCounter, getCount(missedStore, messageCounterMax));
          lcd.print(buf);
          break;
        case STATE_RUN2:
          lcd.setCursor(0, 0);
          snprintf(buf, sizeof buf, "PA Level = %s", paLevelNames[rf24palevel]);
          lcd.print(buf);
          lcd.setCursor(0, 1);
          snprintf(buf, sizeof buf, "Current = %dmA", currentMa);
          lcd.print(buf);
          break;
        case STATE_PALEVEL:
          lcd.setCursor(0, 0);
          snprintf(buf, sizeof buf, "PA Level = %s", paLevelNames[rf24palevel]);
          lcd.print(buf);
          break;
        case STATE_RESEND:
          lcd.setCursor(0, 0);
          snprintf(buf, sizeof buf, "Send repeats = %d", sendRepeats);
          lcd.print(buf);
          break;
      }
    }
    
    
    My Project

  • Rain sensor
    H Heizelmann

    https://forum.mysensors.org/topic/4821/rain-gauge

    My Project rainsensor

  • How to get time a sensor has slept
    H Heizelmann

    @rejoe2 For battery power saving you need sleep().

    Troubleshooting

  • How to get time a sensor has slept
    H Heizelmann

    @mfalkvidd said in How to get time a sensor has slept:

    There are a few tricks though. See these threads and see if any of the suggested solutions would work for you.
    https://forum.mysensors.org/post/71715

    That is exact the same issue .Thanks for pointing to this. I didn't found this.

    Troubleshooting

  • How to get time a sensor has slept
    H Heizelmann

    I would like to use sleep function with wakeup from interrupt or timeout. The function only returns the wakeup reason. Is there a possibility to get the time slept when the wakup came from interrupt? The reason is that I would like to process the inteerupt an then recall the sleep with only th remsing time from the inital sleep time.

    Troubleshooting

  • nrf24L01+ 1715AH versus 1452AB problem
    H Heizelmann

    Thanks, but that is too much discussion for me. Can't someone simply answer with some links where to buy genuine modules for sure or where someone recently bought some which works?

    Hardware

  • nrf24L01+ 1715AH versus 1452AB problem
    H Heizelmann

    @gohan said in nrf24L01+ 1715AH versus 1452AB problem:

    Usually it is most likely a bad Chinese clone. You can't do much about it, just get the genuine ones

    But how can I be sure to get the genuine ones?

    Hardware

  • nrf24L01+ 1715AH versus 1452AB problem
    H Heizelmann

    I have two sets of nearly the same modules. The only visible difference is this number above. The modules with chip NRF M, 24L01, 1452AB work without problem. The modules with chip NRF M, 24L01, 1715AH did not. I tested 5 new modules from each series with the same node hardware and software.

    Here the protocol of the not working 1715AH:

    0 MCO:BGN:INIT NODE,CP=RNNNA--,VER=2.1.1
    3 MCO:BGN:BFR
    BEFORE...
    5 TSM:INIT
    6 TSF:WUR:MS=0
    13 TSM:INIT:TSP OK
    15 TSM:INIT:STATID=50
    17 TSF:SID:OK,ID=50
    19 TSM:FPAR
    55 TSF:MSG:SEND,50-50-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    2062 !TSM:FPAR:NO REPLY
    2064 TSM:FPAR
    2100 TSF:MSG:SEND,50-50-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    4108 !TSM:FPAR:NO REPLY
    4110 TSM:FPAR
    4146 TSF:MSG:SEND,50-50-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    6154 !TSM:FPAR:NO REPLY
    6156 TSM:FPAR
    6192 TSF:MSG:SEND,50-50-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    8200 !TSM:FPAR:FAIL
    8201 TSM:FAIL:CNT=1
    8203 TSM:FAIL:PDT
    

    Hope someone can help. I saw a lot of topics concerning those modules on this forum but as a non-expert it is difficult to find the right answer.
    My non working module

    Hardware

  • Node communication without gateway
    H Heizelmann

    So it must be possible for one node to connect to two networks. Is this possible?

    General Discussion
  • Login

  • Don't have an account? Register

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