Navigation

    • Register
    • Login
    • Search
    • OpenHardware.io
    • Categories
    • Recent
    • Tags
    • Popular
    1. Home
    2. Heizelmann
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    Heizelmann

    @Heizelmann

    17
    Reputation
    59
    Posts
    705
    Profile views
    0
    Followers
    0
    Following
    Joined Last Online

    Heizelmann Follow

    Best posts made by Heizelmann

    • RE: Option non blocking registration at gateway

      @tekka OK unplugging the GW leads to a different behaviour.
      First the node didn't detect the failure as long it is not trying to send.
      When it tries to send it fails

      131268 !TSF:MSG:SEND,42-42-0-0,s=1,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=NACK:1
      

      and after some more failure this

      238494 !TSM:READY:UPL FAIL,SNP
      238497 TSM:FPAR
      238534 TSF:MSG:SEND,42-42-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=6,st=OK:
      238995 !TSF:SND:TNR
      240002 !TSF:SND:TNR
      240542 !TSM:FPAR:NO REPLY
      240544 TSM:FPAR
      240581 TSF:MSG:SEND,42-42-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
      246683 !TSM:FPAR:FAIL
      246685 TSM:FAIL:CNT=1
      246687 TSM:FAIL:PDT
      

      and after a while mostly only

      609748 !TSF:SND:TNR
      

      When gateway comes back a proper reinitialization takes place:

      620572 TSM:FAIL:RE-INIT
      620574 TSM:INIT
      620581 TSM:INIT:TSP OK
      620583 TSM:INIT:STATID=42
      620587 TSF:SID:OK,ID=42
      620589 TSM:FPAR
      620625 TSF:MSG:SEND,42-42-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
      Current: 0.00
      0:0:0
      Current: 0.00
      0:0:0
      621443 TSF:MSG:READ,0-0-42,s=255,c=3,t=8,pt=1,l=1,sg=0:0
      621448 TSF:MSG:FPAR OK,ID=0,D=1
      Current: 0.00
      0:0:0
      Current: 0.00
      0:0:0
      622633 TSM:FPAR:OK
      622635 TSM:ID
      622637 TSM:ID:OK
      622638 TSM:UPL
      622642 TSF:MSG:SEND,42-42-0-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
      622652 TSF:MSG:READ,0-0-42,s=255,c=3,t=25,pt=1,l=1,sg=0:1
      622657 TSF:MSG:PONG RECV,HP=1
      622660 TSM:UPL:OK
      622662 TSM:READY:ID=42,PAR=0,DIS=1
      

      From now the sensor can send again without errors. 😃
      So far my tests.
      Except the case where the radio of the sensor went off and causes a lot of logging all test cases where satisfactorily.
      I think this is really an edge case and not so serious.
      From this point of view I would welcome that this beta development version will be published.

      posted in Feature Requests
      Heizelmann
      Heizelmann
    • RE: How avoid endless loop when radio init fails?

      @mfalkvidd Thanks for the link to this thread. I didn't found this before. It is exactly my problem, so we can close this thread and continue discussing in thisone.

      @tekka Thank you for this outlook.

      For me this feature is essential and I am wondering if it is not implemented from the beginning. So I hope that it will be published soon.
      Anyway I like MySensors and the great developer community. Many thanks to all.

      posted in Troubleshooting
      Heizelmann
      Heizelmann
    • RE: nRf24L01+ connection quality meter

      @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;
        }
      }
      
      
      posted in My Project
      Heizelmann
      Heizelmann
    • RE: repeater node with sensor

      ... and to give the DHT sensor a chance on reading errors to retry and not to wait until next cycle which might be very long:

          for (unsigned int i = 0; i < DHT_MAX_TRIES; i ++) {
            float temperature = dht.getTemperature();
            if (isnan(temperature)) {
              Serial.println("Failed reading temperature from DHT");
              gw.wait(dht.getMinimumSamplingPeriod());
            } else if (temperature != lastTemp) {
              lastTemp = temperature;
              if (!metric) {
                temperature = dht.toFahrenheit(temperature);
              }
              gw.send(msgTemp.set(temperature, 1));
              Serial.print("T: ");
              Serial.println(temperature);
              break;
            }
          }
      

      Repeat the same for humidity of cause.

      posted in General Discussion
      Heizelmann
      Heizelmann
    • RE: Doorbell node

      Something like that:

      long ringSendtAt;
      boolean isRinging;
      void setup() {
        ringSendtAt = millis() - 10000;
        ...
      }
      
      
      void loop() {
        ...
        if ( isRinging && millis()- ringSendtAt > 10000)
          sendRingingMessage();
          ringSendtAt = millis();
        }
        ...
      
      posted in Development
      Heizelmann
      Heizelmann
    • RE: How to get longest battery life

      Here you find a sketch including battery report which I found best. Works also with your PIR I think. For a advanced sketch you can ckeck this.

      I use an arduino pro mini 3.3V with 2 AA batteries at 8 MHZ CPU speed.

      Most important is to remove the voltage regulator on the PIR and supply it directly with 3V. My battery lasts over month with this combination.

      There are different solutions for this. Most powersaving is to remove the regulator.
      The solution n the picture above has the advantage that the electrolytic capacitor downright is still in use. The additional blue capacitor 100nF is optional, should serve as noise filter.
      PIR modification

      posted in Troubleshooting
      Heizelmann
      Heizelmann
    • RE: Node communication without gateway

      @sigolhi I have a similar problem and started a thread about this a while ago. See here https://forum.mysensors.org/topic/6413/node-to-node-communication. It is still unclear how to do a node-to-node communication without a gateway. Even a repeater node will not help.

      posted in General Discussion
      Heizelmann
      Heizelmann
    • RE: Doorbell node

      Some optimization to check:

      • ringerdelay needs to be defined with a type
      • if condition in setup() not necessary initialize buttonpushed and ringSendAt unconditioned
      • normalize logic in if (timenu > buttonpushed && timenu > buttonpushed + ringerdelay) to if (timenu > buttonpushed + ringerdelay), it is the same
      • variable timenu not necessary use millis() directly: if (millis() > buttonpushed + ringerdelay)
      • on relay initialisation the two comments are wrong
      posted in Development
      Heizelmann
      Heizelmann
    • RE: How to get longest battery life

      @dbemowsk The picture shows the modified PIR. The right circle shows the place where the diode was. It is also removed and the contacts are bridged by soldering. The regulator was on position marked with the left circle. it is removed and the two upper contacts are bridged. The adde blue capacitor is contected from this point ( now 3.3V) input to the lower pad which is Ground. It is a 100nF ceramic capacitor.

      posted in Troubleshooting
      Heizelmann
      Heizelmann
    • RE: Is there a way to check presence of a MySensors network, and proceed without if not found ?

      @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.

      posted in Development
      Heizelmann
      Heizelmann

    Latest posts made by Heizelmann

    • RE: Node to node communication fails if gateway is not reachable

      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.

      posted in Development
      Heizelmann
      Heizelmann
    • RE: Node to node communication fails if gateway is not reachable

      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?

      posted in Development
      Heizelmann
      Heizelmann
    • RE: Node to node communication fails if gateway is not reachable

      @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?

      posted in Development
      Heizelmann
      Heizelmann
    • RE: Node to node communication fails if gateway is not reachable

      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.

      posted in Development
      Heizelmann
      Heizelmann
    • RE: Is there a way to check presence of a MySensors network, and proceed without if not found ?

      @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.

      posted in Development
      Heizelmann
      Heizelmann
    • RE: 💬 Battery operated rain-gauge

      @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.

      posted in OpenHardware.io
      Heizelmann
      Heizelmann
    • RE: 💬 Battery operated rain-gauge

      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.

      posted in OpenHardware.io
      Heizelmann
      Heizelmann
    • RE: nRF24Doctor

      Very helpfull!

      posted in My Project
      Heizelmann
      Heizelmann
    • RE: nRf24L01+ connection quality meter

      See further advanced project nRF24Doctor. Great thanks to @Technovation

      posted in My Project
      Heizelmann
      Heizelmann
    • RE: nrf24L01+ 1715AH versus 1452AB problem

      @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?

      posted in Hardware
      Heizelmann
      Heizelmann