Navigation

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

    flopp

    @flopp

    123
    Reputation
    591
    Posts
    2318
    Profile views
    2
    Followers
    0
    Following
    Joined Last Online

    flopp Follow

    Best posts made by flopp

    • Solar Powered Soil Moisture Sensor

      I have build an Solar panel-powered Soil moisture sensor.

      Photos

      I bought the lamps on Jula.
      Lamp1 Battery 2/3 AAA 100 mAh, 10 SEK, 1 euro
      Lamp2 Battery 2/3 AA 200 mAh, 5 SEK, 0,5 euro
      Lamp3 Battery LR44 40 mAh, 10 SEK, 1 euro, NOT TESTED YET

      I removed all the electronic on the PCB and used the PCB as a connection board.
      The solar panel gives around 1,4 V during a very sunny day.
      I had to add a step-up(0,8->3,3V) to be able to run a ATMEGA. My first idea was to connect 2 batteries in series, but that was too much work. Now everything fits in the parts that is included.

      Lamp1 is using a Pro Mini(fake), glued soil sensor on "arrow"
      Lamp2 is using my designed PCB with ATMEGA328p, soil sensor just put in soil, not glued at all.
      Both MCU are using Optiboot, https://forum.mysensors.org/topic/3018/tutorial-how-to-burn-1mhz-8mhz-bootloader-using-arduino-ide-1-6-5-r5.
      Pro Mini:Power-on LED removed and also step-down. Activity-LED is still in use.
      My designed PCB:https://oshpark.com/shared_projects/F7esJEMY, also with LED for startup and send OK

      I am using @mfalkvidd sketch, thank you. I have only add a few rows(LED and resend function)
      It sends data(Humidity/Volt/VoltPercent every 10 second, just for testing the hardware later on I will send maybe twice an hour or once an hour.
      I am measuring the battery voltage on a analog input.

      #include <SPI.h>
      #include <MySensor.h>
      
      #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
      #define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
      
      #define CHILD_ID_MOISTURE 0
      #define CHILD_ID_BATTERY 1
      #define SLEEP_TIME 10000 // Sleep time between reads (in milliseconds)
      #define THRESHOLD 1.1 // Only make a new reading with reverse polarity if the change is larger than 10%.
      #define STABILIZATION_TIME 1000 // Let the sensor stabilize before reading
      default BOD settings.
      const int SENSOR_ANALOG_PINS[] = {A4, A5}; // Sensor is connected to these two pins. Avoid A3 if using ATSHA204. A6 and A7 cannot be used because they don't have pullups.
      
      MySensor gw;
      MyMessage msg(CHILD_ID_MOISTURE, V_HUM);
      MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE);
      long oldvoltage = 0;
      byte direction = 0;
      int oldMoistureLevel = -1;
      float batteryPcnt;
      float batteryVolt;
      int LED = 5;
      
      void setup()
      {
        pinMode(LED, OUTPUT);
        digitalWrite(LED, HIGH);
        delay(200);
        digitalWrite(LED, LOW);
        delay(200);
        digitalWrite(LED, HIGH);
        delay(200);
        digitalWrite(LED, LOW);
        
        gw.begin();
      
        gw.sendSketchInfo("Plant moisture w solar", "1.0");
      
        gw.present(CHILD_ID_MOISTURE, S_HUM);
        delay(250);
        gw.present(CHILD_ID_BATTERY, S_MULTIMETER);
        for (int i = 0; i < N_ELEMENTS(SENSOR_ANALOG_PINS); i++) {
          pinMode(SENSOR_ANALOG_PINS[i], OUTPUT);
          digitalWrite(SENSOR_ANALOG_PINS[i], LOW);
        }
      }
      
      void loop()
      {
        int moistureLevel = readMoisture();
      
        // Send rolling average of 2 samples to get rid of the "ripple" produced by different resistance in the internal pull-up resistors
        // See http://forum.mysensors.org/topic/2147/office-plant-monitoring/55 for more information
        if (oldMoistureLevel == -1) { // First reading, save current value as old
          oldMoistureLevel = moistureLevel;
        }
        if (moistureLevel > (oldMoistureLevel * THRESHOLD) || moistureLevel < (oldMoistureLevel / THRESHOLD)) {
          // The change was large, so it was probably not caused by the difference in internal pull-ups.
          // Measure again, this time with reversed polarity.
          moistureLevel = readMoisture();
        }
        gw.send(msg.set((moistureLevel + oldMoistureLevel) / 2.0 / 10.23, 1));
        oldMoistureLevel = moistureLevel;
        
        int sensorValue = analogRead(A0);
        Serial.println(sensorValue);
        float voltage=sensorValue*(3.3/1023);
        Serial.println(voltage);
        batteryPcnt = (sensorValue - 248) * 0.72;
        batteryVolt = voltage;
        gw.sendBatteryLevel(batteryPcnt);
        resend((voltage_msg.set(batteryVolt, 3)), 10);
      
        digitalWrite(LED, HIGH);
        delay(200);
        digitalWrite(LED, LOW);
        
        gw.sleep(SLEEP_TIME);
      }
      
      void resend(MyMessage &msg, int repeats)
      {
        int repeat = 1;
        int repeatdelay = 0;
        boolean sendOK = false;
      
        while ((sendOK == false) and (repeat < repeats)) {
          if (gw.send(msg)) {
            sendOK = true;
          } else {
            sendOK = false;
            Serial.print("Error ");
            Serial.println(repeat);
            repeatdelay += 500;
          } repeat++; delay(repeatdelay);
        }
      }
      
      
      int readMoisture() {
        pinMode(SENSOR_ANALOG_PINS[direction], INPUT_PULLUP); // Power on the sensor
        analogRead(SENSOR_ANALOG_PINS[direction]);// Read once to let the ADC capacitor start charging
        gw.sleep(STABILIZATION_TIME);
        int moistureLevel = (1023 - analogRead(SENSOR_ANALOG_PINS[direction]));
      
        // Turn off the sensor to conserve battery and minimize corrosion
        pinMode(SENSOR_ANALOG_PINS[direction], OUTPUT);
        digitalWrite(SENSOR_ANALOG_PINS[direction], LOW);
      
        direction = (direction + 1) % 2; // Make direction alternate between 0 and 1 to reverse polarity which reduces corrosion
        return moistureLevel;
      }
      
      

      0_1465299264398_IMG_1337.JPG
      0_1465928822164_SolarPanel (2).png

      posted in My Project
      flopp
      flopp
    • RE: Merry X-mas and Happy New 2018

      Merry Christmas and a Happy New Year and as thank you I donated some money to you.

      posted in Announcements
      flopp
      flopp
    • LUA, send email when device has not report

      I had lots of problem for my nodes that they sometimes didn't send data and I could never know when, I wanted to know when it happen just to know if I did something with Domoticz or something else I did.
      This script will read when the Device sent data last time and if it is more than 30 minutes Domoticz will send me an email, when the Device has sent within 30 minutes it send a new email. I now have 100% control when it is not working.
      I also add a function to write to a file, so I could see if it stopped working on same time of day or it was something else.
      I have written the file content to be possible to view in a PHP file, to see the OK and NOT OK easier

      PHP file looks like this

      <html>
      <head>
      <title>Title</title>
      <body bgcolor="white">
      <meta http-equiv="Content-Type" content="text/html;charset=utf-8" / >
      </head>
      
      <?php
          $myfilename = "c:\progra~2\domoticz\sensor.txt";
          if(file_exists($myfilename)){
            echo file_get_contents($myfilename);
          }
      ?>
      </html>
      

      picture how it looks in PHP
      0_1466712672460_sensor.png

      Translation first row
      YYYY-MM-DD HH:MM:SS No data for 40 minutes from "device", last data was YYYY-MM-DD HH:MM:SS
      Translation seconds row
      Data from "device" is OK again, last data YYYY-MM-DD HH:MM:SS

      In Domoticz create a new Event, LUA and Device as trigger
      You also need to create a Variable(integer) with the same name as the Device, value=0
      Name your device a unique name, like "flopp" 🙂 when it works you can rename it
      LUA code

      commandArray = {}
      local function update(cmd)
      vari = "Variable:"  .. cmd --add Variable: before device
      t1 = os.time() --get date/time right now in seconds
      t3  = os.date("%Y-%m-%d %H:%M:%S") --get date/time right now in normal format
      s = otherdevices_lastupdate[cmd] --read last date/time for device
      --print(cmd)
      --print(s)
      year = string.sub(s, 1, 4)
      month = string.sub(s, 6, 7)
      day = string.sub(s, 9, 10)
      hour = string.sub(s, 12, 13)
      minutes = string.sub(s, 15, 16)
      seconds = string.sub(s, 18, 19)
      
      t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
      difference = (os.difftime (t1, t2)) --compare right now with device
      
      if (difference > 2400) and (uservariables[cmd] == 0) then --if device date/time is more than 30 minutes
          file = io.open("sensor.txt", "a") -- Opens a file named sensor.txt(stored under Domoticz folder) in append mode
          commandArray['SendEmail']=''..cmd..' äldre än 40 min#'..s..' är senaste tid#abc@hotmail.com' --send mail
          commandArray[vari] = "1" --set variable to 1
          --write to opened file
          file:write(t3 .. " Ingen data på 40 min från ")
          file:write("<font color=red>")
          file:write(cmd .."</font>")
          file:write(", senaste data " .. s .."<br>","\n")
          file:close() --closes the open file
          
      elseif (difference < 2400) and (uservariables[cmd] == 1) then --if device date/time is less than 30 minutes
          file = io.open("sensor.txt", "a")
          commandArray[vari] = "0"
          commandArray['SendEmail']=''..cmd..' ok igen#'..s..' är senaste tid#abc@hotmail.com'
          file:write(t3 .. " Data från ")
          file:write("<font color=blue>")
          file:write(cmd .."</font>")
          file:write(" är OK igen, senaste data " .. s .. "<br>","\n")
          file:close()
      end 
      
      end
      
      update ('Ute_V') --device name can be temperature or voltage
      update ('AppleTV')
      update ('PS3')
      update ('Stereo')
      update ('Captest')
      update ('Captest_V')
      
      return commandArray
      
      posted in Domoticz
      flopp
      flopp
    • IKEA Spöke/Spoke(ghost)

      I have rebuilt IKEA Spöke(ghost) to be used with MyS and Pro Mini 5V
      I replaced LED with 4 pcs WS2812B LED's.
      Removed all components on POWER PCB, I only use the PCB to get 5V.
      Button is removed.
      No battery is used, only power from 5v adapter. To drive nRF I used step-down 5->3.3V
      When you solder the Ground pin on the PCB, check carefully from where you take the GND, when the plug is inserted you will NOT get GND from all GND spots/places.
      If you will build this think about this/next version:
      Use more LED's, maybe 6 or 8. Change in sketch!!
      Remove LED on step-down and LED on Pro Mini, will light up alot during night if lamp is off
      Add function for button, so you can start it without access to your controller
      Add Repeater function, why not it is on power all the time

      Video: https://youtu.be/sNSBahc-79s
      Link to IKEA Spoke http://www.ikea.com/gb/en/products/childrens-ikea-products/children-3-7/childrens-lighting/spöka-led-night-light-animal-white-turquoise-art-00150985/

      I use the color to tell my kids when it is OK to wake up :), sometimes they wake up at 6 am!!. When time is ok to go up from bed it shows green otherwise it shows red/purple light during whole night.

      To put the silicon back I forst used a lot of power, then I tried with alcohol it was a piece of cake. The alcohol will vaporize.
      This is the sketch

      /*PROJECT: MySensors / RGB test for Light & Sensor
       PROGRAMMER: AWI/GizMoCuz
       DATE: september 27, 2015/ last update: October 10, 2015
       FILE: AWI_RGB.ino
       LICENSE: Public domain
      
       Hardware: Nano and MySensors 1.5
          
       Special:
        uses Fastled library with NeoPixel (great & fast RBG/HSV universal library)       https://github.com/FastLED/FastLED
       
       Remarks:
        Fixed node-id
        Added option to request/apply last light state from gateway
        
       Domoticz typicals - 2015 10 10:
        - Domoticz is using HUE values internally, there might be a slight difference then using direct RGB colors.
      */
      
      #include <MySensor.h>
      #include <SPI.h>
      #include <FastLED.h>
      
      
      const int stripPin = 4 ;                  // pin where 2812 LED strip is connected
      
      const int numPixel = 4 ;                  // set to number of pixels
      
      #define NODE_ID 254                       // fixed MySensors node id
      
      #define CHILD_ID 0                  // Child Id's
      
      CRGB leds[numPixel];
      
      char actRGBvalue[] = "000000";               // Current RGB value
      uint16_t actRGBbrightness = 0xFF ;         // Controller Brightness 
      int actRGBonoff=0;                        // OnOff flag
      
      MySensor gw;
      
      MyMessage lastColorStatusMsg(CHILD_ID,V_VAR1);
      
      void setup() {
        FastLED.addLeds<NEOPIXEL, stripPin >(leds, numPixel); // initialize led strip
      
        gw.begin(incomingMessage, AUTO, false);      // initialize MySensors
        gw.sendSketchInfo("AWI RGB Light", "1.1");
        gw.present(CHILD_ID, S_RGB_LIGHT);        // present to controller
      
        // Flash the "hello" color sequence: R, G, B, black. 
        colorBars();
      
        //Request the last stored colors settings
        gw.request(CHILD_ID, V_VAR1);
      }
      
      void loop() {
        gw.process();                       // wait for incoming messages
      }
      
      void colorBars()
      {
        SendColor2AllLEDs( CRGB::Red );   FastLED.show(); delay(500);
        SendColor2AllLEDs( CRGB::Green ); FastLED.show(); delay(500);
        SendColor2AllLEDs( CRGB::Blue );  FastLED.show(); delay(500);
        SendColor2AllLEDs( CRGB::Black ); FastLED.show(); delay(500);
      } 
      
      void SendColor2AllLEDs(const CRGB lcolor)
      {
        for(int i = 0 ; i < numPixel ; i++) {
          leds[i] = lcolor;
        }
      }
      
      void SendLastColorStatus()
      {
        String cStatus=actRGBvalue+String("&")+String(actRGBbrightness)+String("&")+String(actRGBonoff);
        gw.send(lastColorStatusMsg.set(cStatus.c_str()));
      }
      
      String getValue(String data, char separator, int index)
      {
       int found = 0;
        int strIndex[] = {0, -1};
        int maxIndex = data.length()-1;
        for(int i=0; i<=maxIndex && found<=index; i++){
        if(data.charAt(i)==separator || i==maxIndex){
        found++;
        strIndex[0] = strIndex[1]+1;
        strIndex[1] = (i == maxIndex) ? i+1 : i;
        }
       }
        return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
      }
      
      void incomingMessage(const MyMessage &message) {
        if (message.type == V_RGB) {            // check for RGB type
          actRGBonoff=1;
          strcpy(actRGBvalue, message.getString());    // get the payload
          SendColor2AllLEDs(strtol(actRGBvalue, NULL, 16));
          SendLastColorStatus();
        }
        else if (message.type == V_DIMMER) {           // if DIMMER type, adjust brightness
          actRGBonoff=1;
          actRGBbrightness = map(message.getLong(), 0, 100, 0, 255);
          FastLED.setBrightness( actRGBbrightness );
          SendLastColorStatus();
        }
        else if (message.type == V_STATUS) {           // if on/off type, toggle brightness
          actRGBonoff = message.getInt();
          FastLED.setBrightness((actRGBonoff == 1)?actRGBbrightness:0);
          SendLastColorStatus();
        }
        else if (message.type==V_VAR1) {            // color status
          String szMessage=message.getString();
          strcpy(actRGBvalue, getValue(szMessage,'&',0).c_str());
          actRGBbrightness=atoi(getValue(szMessage,'&',1).c_str());
          actRGBonoff=atoi(getValue(szMessage,'&',2).c_str());
          SendColor2AllLEDs(strtol(actRGBvalue, NULL, 16));
          FastLED.setBrightness((actRGBonoff == 1)?actRGBbrightness:0);
        }
        FastLED.show();
      }
      
      

      0_1485641197144_IMG_3696.JPG
      0_1485641206076_IMG_3698.JPG
      0_1485641215595_IMG_3694.JPG

      posted in My Project
      flopp
      flopp
    • nRF24L01+ long range, learn from my mistake

      If you would like to buy a new nRF24L01+ so you can get more range, don't do like I did. I will tell you what i did.
      I bought this(link below) and was waiting and waiting and today finally it arrives, yeah. Kids had gone to bed and I was going around my house checking range before change.
      Changed the nRF24L01+ with standard PCB antenna to new NRF(link), checked mA and the new NRF was 1 mA below!!!, I have heard that long range NRF should draw much more that you need external power source. Not this one!!! 😟
      PCB antenna ~13 mA, long range 60 mA maybe?
      I walked around my house again and still same range like old NRF, strange. Went in to this forum and found my mistake.
      I had bought a normal NRF but with an SMA antenna, WHAT???😡 Like always I am so excite to order quickly so I didn't see that this is NOT PA and NOT LNA.

      So before you order check that the NRF is PA and LNA. Sometimes I order same item but from 2 different sellers and sometimes even from 2 different placed like ebay and aliexpress, if the item disappear or take extra long time to arrive. I checked my second order and that was a PA and LNA, yeah, so now i am back to wait until it arrives. Puhh

      Good luck😃

      http://www.ebay.com/itm/281962954019?_trksid=p2060353.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

      posted in Hardware
      flopp
      flopp
    • RE: Merry Christmas and Happy New Year

      Replying to an old topic.

      Happy christmas everyone.

      Please donate to mysensors project, so this very good project gets even better.

      posted in General Discussion
      flopp
      flopp
    • RE: Raspberry Pi2 GPIO interface for NRF24L01+

      @mfalkvidd said:

      @flopp feeding the nrf with 5V is a bad idea. It wants 3.3V.

      I was not clear enough. I have edit my text.
      Thanks

      posted in OpenHardware.io
      flopp
      flopp
    • LUA, send email when Temperature is high

      I am using this script to detect if the drawer is open for my "TV-electronics". My kids start PS3 but forget to open the drawer. That's why I made this 🙂

      Create a user variable named "AppleTVVarm", of course you can name it to what you like but use my names first then after you tested it and it works you can change the names. Device name must be change to your device name If variable is 1 it means that the temperature has reached its limit.
      If the temperature get above 35 it will send me an email and when it goes below 30 it will send a new email, so I know it gets cooled down.
      Varm means Warm
      Sval means cool

      commandArray = {}
      
      local function update(cmd)
      if devicechanged[cmd] then
          local vari = "Variable:"  .. cmd .. "Varm" --add Varibale: before device and Varm after device
          local varm = cmd .. "Varm" --add Varm after device
          --print(cmd)
          --print(varm)
          --print(vari)
      
          temperature = tonumber(devicechanged[''..cmd..'_Temperature']) --read temperature from device, if device have more than only temperature
          if (temperature > 35) and (uservariables[varm] == 0) then --if temperature is above 35 for the first time
              commandArray['SendEmail']=''..cmd..' varm#""#abc@hotmail.com' --send email
              commandArray[vari] = "1" --set variable to 1
          end
          if (temperature < 30) and (uservariables[varm] == 1) then --if temperature is below 30
              commandArray['SendEmail']=''..cmd..' sval#""#abc@hotmail.com' --send email
              commandArray[vari] = "0" --set variable to 0
          end
      end
      
      end
      
      update ('AppleTV') --device to read temperature from
      update ('PS3')
      update ('Stereo')
      
      return commandArray
      

      copy the code and create a new script in Domoticz, select LUA and Device otherwise it will not work

      posted in Domoticz
      flopp
      flopp
    • RE: Power external sensors on demand

      That I am also using.

      Read here https://forum.mysensors.org/topic/2147/office-plant-monitoring/64 and here https://forum.mysensors.org/topic/4045/solar-powered-soil-moisture-sensor/45

      posted in Hardware
      flopp
      flopp
    • RE: MySensors protocol page improvement recommendation

      also found typo
      V_STATUS missing S_BINARY, S_WATER_QUALITY
      V_LIGHT missing S_BINARY
      V_WATT missing S_BINARY, S_RGB_LIGHT, S_RGBW_LIGHT
      V_PERCENTAGE missing S_COVER
      V_TEMP missing S_WATER_QUALITY
      S_HEATER missing V_STATUS, V_HVAC_SETPOINT_HEAT
      S_HVAC missing V_STATUS, V_TEMP, V_HVAC_SPEED

      V_HVAC_SETPOINT_COLD is missing

      posted in General Discussion
      flopp
      flopp

    Latest posts made by flopp

    • S_Heater

      Home Assistant 2022.12.6
      Supervisor 2022.11.2
      Operating System 9.4
      Frontend 20221213.0 - latest

      I know that S_Heater is not supported.

      Are there any plans to support it?

      I get this error:

      WARNING (MainThread) [homeassistant.components.mysensors.helpers] Child type 14 is not supported
      
      posted in Home Assistant
      flopp
      flopp
    • Selling: Temp, Hum Si7021

      I have some self designed Circuit boards with NRF and Si7021.
      I do not use them anymore.
      Battery is CR123 used in Visonic alarm.
      When I replaced the battery on the IR sensor I continued to use it in these sensors.

      Contact me if you are interested so I can tel you more about it.

      48BFD28A-EF1B-48CF-A391-1BD9A1DAAC27.jpeg DEDAE29B-12E7-4CAD-A050-0B940B43AF03.jpeg

      posted in Hardware
      flopp
      flopp
    • RE: How To - Doorbell Automation Hack

      @flopp
      Found one mistake. I wrote some Serial.print to see where in the code my problem was and I wrote in a wrong place, so the code was looping on a wrong way.

      When that was corrected I found out that my relay needed to get 1 when it was off, so I just changed to below and now I don't get a green light as soon as I power on the arduino

      #define RELAY_ON 0
      #define RELAY_OFF 1
      
      posted in My Project
      flopp
      flopp
    • RE: How To - Doorbell Automation Hack

      Very long time ago this was active.

      I tried the code for MySensors 2.0 but it triggers my relay all the time.

      When I press simulate a button-press the relay goes off, then on and then stays on.

      I have the stuff on my desk so it is not connected to my button.

      Only differene is that I am using a Arduino nano, so the signal from PIN 4 is 5 volt.

      I think the micro is only giving 3.3 volt out on pins?

      posted in My Project
      flopp
      flopp
    • RE: Error: Serial Port closed!... Error: End of file..

      I tried to reprogram the Arduino Nano but that didn't helped.
      Changed com port on computer and that seems to solve my problem

      posted in Troubleshooting
      flopp
      flopp
    • RE: Error: Serial Port closed!... Error: End of file..

      To which unit did you add the 5->3.3v?
      Gateway or Motion?

      posted in Troubleshooting
      flopp
      flopp
    • Shunt motor/valve

      My heating system was not putting out any heated water to our radiators. A friend gave the idea to put an accelerator-meter to the pin.

      This is what I made.
      MySensors - Shunt motor valve – 00:27
      — Daniel Nilsson

      On the monitor you see 2666, that is the raw value from the sensor, below that you see how much the shunt is opened in percent.

      Grapg from Grafana, top graph shows raw value from accelerator-meter, bottom graph with percent opened and outdoor temp:
      0_1557840289633_db87a8e8-79cb-4596-8661-3f5019c8e26f-image.png

      The code I am using:

      // I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class
      // 10/7/2011 by Jeff Rowberg <jeff@rowberg.net>
      // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
      //
      // Changelog:
      //      2013-05-08 - added multiple output formats
      //                 - added seamless Fastwire support
      //      2011-10-07 - initial release
      
      /* ============================================
      I2Cdev device library code is placed under the MIT license
      Copyright (c) 2011 Jeff Rowberg
      
      Permission is hereby granted, free of charge, to any person obtaining a copy
      of this software and associated documentation files (the "Software"), to deal
      in the Software without restriction, including without limitation the rights
      to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      copies of the Software, and to permit persons to whom the Software is
      furnished to do so, subject to the following conditions:
      
      The above copyright notice and this permission notice shall be included in
      all copies or substantial portions of the Software.
      
      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      THE SOFTWARE.
      ===============================================
      */
      
      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2015 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
      */
      
      // Enable and select radio type attached
      #define MY_RADIO_RF24
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      
      #include <SPI.h>
      #include <MySensors.h>
      #include <Wire.h>
      
      #define CHILD_SHUNT 0
      #define CHILD_SHUNTDATA 1
      
      #define CHILD_FAILS 250
      #define CHILD_PARENT 251
      #define CHILD_DISTANCE 252
      
      //NRF
      int Fails = 0;
      int OldFails = -1;
      int FailsLoopCount = 10;
      int OldParentNode = -1;
      int ParentNodeLoopCount = 10;
      int OldDistanceNode = -1;
      int DistanceLoopCount = 10;
      
      MyMessage msgShunt(CHILD_SHUNT, V_WATT);
      MyMessage msgShuntData(CHILD_SHUNTDATA, V_WATT);
      
      MyMessage msgFails(CHILD_FAILS, V_VA);
      MyMessage msgParent(CHILD_PARENT, V_VA);
      MyMessage msgDistance(CHILD_DISTANCE, V_VA);
      
      // I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
      // for both classes must be in the include path of your project
      #include "I2Cdev.h"
      #include "MPU6050.h"
      
      // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
      // is used in I2Cdev.h
      #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
          #include "Wire.h"
      #endif
      
      // class default I2C address is 0x68
      // specific I2C addresses may be passed as a parameter here
      // AD0 low = 0x68 (default for InvenSense evaluation board)
      // AD0 high = 0x69
      MPU6050 accelgyro;
      //MPU6050 accelgyro(0x69); // <-- use for AD0 high
      
      int16_t ax, count;
      long axx;
      
      
      
      // uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
      // list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
      // not so easy to parse, and slow(er) over UART.
      #define OUTPUT_READABLE_ACCELGYRO
      
      // uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit
      // binary, one right after the other. This is very fast (as fast as possible
      // without compression or data loss), and easy to parse, but impossible to read
      // for a human.
      //#define OUTPUT_BINARY_ACCELGYRO
      
      void setup() {
          // join I2C bus (I2Cdev library doesn't do this automatically)
          #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
              Wire.begin();
          #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
              Fastwire::setup(400, true);
          #endif
      
          // initialize serial communication
          // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
          // it's really up to you depending on your project)
          //Serial.begin(38400);
      
          // initialize device
          Serial.println("Initializing I2C devices...");
          accelgyro.initialize();
      
          // verify connection
          Serial.println("Testing device connections...");
          Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
      
          // use the code below to change accel/gyro offset values
          /*
          Serial.println("Updating internal sensor offsets...");
          // -76	-2359	1688	0	0	0
          Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
          Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
          Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
          Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
          Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
          Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
          Serial.print("\n");
          accelgyro.setXGyroOffset(220);
          accelgyro.setYGyroOffset(76);
          accelgyro.setZGyroOffset(-85);
          Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
          Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
          Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
          Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
          Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
          Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
          Serial.print("\n");
          */
      
      }
      
      void presentation() {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Shuntventil", "20190505");
        // Register all sensors to gateway (they will be created as child devices)
        present(CHILD_SHUNT, S_POWER, "Procent");
        present(CHILD_SHUNTDATA, S_POWER, "ShuntData");  
        present(CHILD_FAILS, S_POWER, "Fails");
        present(CHILD_PARENT, S_POWER, "Parent");
        present(CHILD_DISTANCE, S_POWER, "Distance");  
      }
      
      void loop() {
          for (count = 0 ; count < 10 ; count++) {
          
          // read raw accel/gyro measurements from device
          //accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
      
          // these methods (and a few others) are also available
          //accelgyro.getAcceleration(&ax, &ay, &az);
          //accelgyro.getRotation(&gx, &gy, &gz);
          ax = accelgyro.getAccelerationX();
          #ifdef OUTPUT_READABLE_ACCELGYRO
              // display tab-separated accel/gyro x/y/z values
              //Serial.print("a/g:\t");
              //Serial.print(ax);// Serial.print("\t");
              //Serial.println(axa);// Serial.print("\t");
              //Serial.print(az); Serial.print("\t");
              //Serial.print(gx); Serial.print("\t");
              //Serial.print(gy); Serial.print("\t");
              //Serial.println(gz);
          #endif
      
          
          axx = axx + ax;  
         
          }
          axx = axx / 10;
          //Serial.println(axx);
          resend((msgShuntData.set(axx)),3);
          long y = map(axx,-12300,12500,0,100);
          //Serial.println(y);
          resend((msgShunt.set(y)),3);
          axx = 0;
      
          if ((OldParentNode != _transportConfig.parentNodeId) | (ParentNodeLoopCount >= 10))
        {
          resend((msgParent.set(_transportConfig.parentNodeId)),3);
          OldParentNode = _transportConfig.parentNodeId;
          ParentNodeLoopCount = 0;
        }
          
        if ((OldDistanceNode != _transportConfig.distanceGW) | (DistanceLoopCount >= 10))
        {
          resend((msgDistance.set(_transportConfig.distanceGW)),3);
          OldDistanceNode = _transportConfig.distanceGW;
          DistanceLoopCount = 0;
        }
      
        if ((OldFails != Fails) | (FailsLoopCount >= 3))
        {
          failsend((msgFails.set(Fails)),3);
          OldFails = Fails;
          FailsLoopCount = 0;
        }
           
        ParentNodeLoopCount++;
        DistanceLoopCount++;
        FailsLoopCount++;
      
          sleep(30000);
      }
      
      //skicka axx(som är delat på 10) till DZ, så man kan kalibrera värden
      
      
      void resend(MyMessage & msg, int repeats) {
        int repeat = 0;
        int repeatdelay = 0;
        boolean sendOK = false;
        while ((sendOK == false) and(repeat < repeats))
        {
          if (send(msg))
          {
            sendOK = true;
          }
          else
          {
            Fails++;
            sendOK = false;
            Serial.print("Error ");
            Serial.println(repeat);
            repeatdelay += 250;
            repeat++;
            sleep(repeatdelay);
          }
        }
      }
      
      void failsend(MyMessage &msg, int repeats) {
        int repeat = 1;
        int repeatdelay = 0;
        boolean sendOK = false;
      
        while ((sendOK == false) and (repeat < repeats)) {
          if (send(msg))
          {
            Fails = 0;
            sendOK = true;
          }
          else
          {
            Fails++;
            sendOK = false;
            Serial.print("Error ");
            Serial.println(repeat);
            repeatdelay += 250;
            repeat++;
            sleep(repeatdelay);
          }
        }
      }
      
      posted in My Project
      flopp
      flopp
    • RE: Repeater getting NACK

      Thanks for all answers.

      Node 25 send its value every 30 second (before I said every 2 minutes)

      So my conclusion is that GW is not sending ACK back to my repeater.

      value 96637 has already been sent before so GW will not send ACK

      7957760 TSF:MSG:READ,25-25-0,s=0,c=1,t=24,pt=5,l=4,sg=0:96637
      7957766 TSF:MSG:REL MSG
      7957806 !TSF:MSG:SEND,25-7-0-0,s=0,c=1,t=24,pt=5,l=4,sg=0,ft=0,st=NACK:96637
      

      30 seconds later, now Node 25 sends new values(96638) that is different since last send, so this time GW will send ACK

      7987763 TSF:MSG:READ,25-25-0,s=0,c=1,t=34,pt=7,l=5,sg=0:0.01
      7987768 TSF:MSG:REL MSG
      7987808 TSF:MSG:SEND,25-7-0-0,s=0,c=1,t=34,pt=7,l=5,sg=0,ft=1,st=OK:0.01
      7987819 TSF:MSG:READ,25-25-0,s=0,c=1,t=35,pt=7,l=5,sg=0:96.638
      7987825 TSF:MSG:REL MSG
      7987829 TSF:MSG:SEND,25-7-0-0,s=0,c=1,t=35,pt=7,l=5,sg=0,ft=0,st=OK:96.638
      

      30 seconds later, same values so GW will not send ACK

      8017766 TSF:MSG:READ,25-25-0,s=0,c=1,t=24,pt=5,l=4,sg=0:96638
      8017771 TSF:MSG:REL MSG
      8017811 !TSF:MSG:SEND,25-7-0-0,s=0,c=1,t=24,pt=5,l=4,sg=0,ft=0,st=NACK:96638
      

      30 seconds later, same values so GW will not send ACK

      8047768 TSF:MSG:READ,25-25-0,s=0,c=1,t=24,pt=5,l=4,sg=0:96638
      8047774 TSF:MSG:REL MSG
      8047813 !TSF:MSG:SEND,25-7-0-0,s=0,c=1,t=24,pt=5,l=4,sg=0,ft=1,st=NACK:96638
      

      or can it be that when it sends two values it will be ACK fro GW?

      look at 7987763, this value is water flow
      at 8017766 it is only the incremental value for my water meter, no flow is sent

      posted in Domoticz
      flopp
      flopp
    • RE: Repeater getting NACK

      This is a water counter node.
      It will send the value every 2 minutes, even if there isn’t a new value.
      But when we use water it will be a increased value, then I get OK from Controller.

      posted in Domoticz
      flopp
      flopp
    • RE: Repeater getting NACK

      @mfalkvidd said in Repeater getting NACK:

      @flopp said in Repeater getting NACK:

      Is looks like when the value is same as already sent, Gateway or controller is not accepting the value

      I can't see anything in the posted log that supports this conclusion. Could you elaborate?

      Node 7 can send and gets OK, but when Node 25 send its values it gets NACK.
      When the value is new from Node 25 it gets OK

      Could you grab a log from the repeater and node25 at the same time?

      I will try

      Could you post the sketch for node25?

      Is node25 sending more data immediately after sending the meter reading? Maybe a second send causes a collision with the the message sent by the repeater.

      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2015 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
       *
       * REVISION HISTORY
       * Version 1.0 - Henrik Ekblad
       * Version 1.1 - GizMoCuz
       *
       * DESCRIPTION
       * Use this sensor to measure volume and flow of your house watermeter.
       * You need to set the correct pulsefactor of your meter (pulses per m3).
       * The sensor starts by fetching current volume reading from gateway (VAR 1).
       * Reports both volume and flow back to gateway.
       *
       * Unfortunately millis() won't increment when the Arduino is in
       * sleepmode. So we cannot make this sensor sleep if we also want
       * to calculate/report flow.
       * http://www.mysensors.org/build/pulse_water
       */
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      //#define MY_RADIO_NRF5_ESB
      //#define MY_RADIO_RFM69
      //#define MY_RADIO_RFM95
      
      #include <MySensors.h>
      
      #define DIGITAL_INPUT_SENSOR 2                  // The digital input you attached your sensor.  (Only 2 and 3 generates interrupt!)
      
      #define PULSE_FACTOR 1000                       // Nummber of blinks per m3 of your meter (One rotation/liter)
      
      #define SLEEP_MODE false                        // flowvalue can only be reported when sleep mode is false.
      
      #define MAX_FLOW 40                             // Max flow (l/min) value to report. This filters outliers.
      
      #define CHILD_ID 0                              // Id of the sensor child
      
      uint32_t SEND_FREQUENCY =
          30000;           // Minimum time between send (in milliseconds). We don't want to spam the gateway.
      
      MyMessage flowMsg(CHILD_ID,V_FLOW);
      MyMessage volumeMsg(CHILD_ID,V_VOLUME);
      MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
      
      double ppl = ((double)PULSE_FACTOR)/1000;        // Pulses per liter
      
      volatile uint32_t pulseCount = 0;
      volatile uint32_t lastBlink = 0;
      volatile double flow = 0;
      bool pcReceived = false;
      uint32_t oldPulseCount = 0;
      uint32_t newBlink = 0;
      double oldflow = 0;
      double volume =0;
      double oldvolume =0;
      uint32_t lastSend =0;
      uint32_t lastPulse =0;
      
      void setup()
      {
      	// initialize our digital pins internal pullup resistor so one pulse switches from high to low (less distortion)
      	pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);
      
      	pulseCount = oldPulseCount = 0;
      
      	// Fetch last known pulse count value from gw
      	request(CHILD_ID, V_VAR1);
      
      	lastSend = lastPulse = millis();
      
      	attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), onPulse, FALLING);
      }
      
      void presentation()
      {
      	// Send the sketch version information to the gateway and Controller
      	sendSketchInfo("Water Meter", "1.0");
      
      	// Register this device as Waterflow sensor
      	present(CHILD_ID, S_WATER);
      }
      
      void loop()
      {
      	uint32_t currentTime = millis();
      
      	// Only send values at a maximum frequency or woken up from sleep
      	if (SLEEP_MODE || (currentTime - lastSend > SEND_FREQUENCY)) {
      		lastSend=currentTime;
      
      		if (!pcReceived) {
      			//Last Pulsecount not yet received from controller, request it again
      			request(CHILD_ID, V_VAR1);
      			return;
      		}
      
      		if (!SLEEP_MODE && flow != oldflow) {
      			oldflow = flow;
      
      			Serial.print("l/min:");
      			Serial.println(flow);
      
      			// Check that we dont get unresonable large flow value.
      			// could hapen when long wraps or false interrupt triggered
      			if (flow<((uint32_t)MAX_FLOW)) {
      				send(flowMsg.set(flow, 2));                   // Send flow value to gw
      			}
      		}
      
      		// No Pulse count received in 2min
      		if(currentTime - lastPulse > 120000) {
      			flow = 0;
      		}
      
      		// Pulse count has changed
      		if ((pulseCount != oldPulseCount)||(!SLEEP_MODE)) {
      			oldPulseCount = pulseCount;
      
      			Serial.print("pulsecount:");
      			Serial.println(pulseCount);
      
      			send(lastCounterMsg.set(pulseCount));                  // Send  pulsecount value to gw in VAR1
      
      			double volume = ((double)pulseCount/((double)PULSE_FACTOR));
      			if ((volume != oldvolume)||(!SLEEP_MODE)) {
      				oldvolume = volume;
      
      				Serial.print("volume:");
      				Serial.println(volume, 3);
      
      				send(volumeMsg.set(volume, 3));               // Send volume value to gw
      			}
      		}
      	}
      	if (SLEEP_MODE) {
      		sleep(SEND_FREQUENCY);
      	}
      }
      
      void receive(const MyMessage &message)
      {
      	if (message.type==V_VAR1) {
      		uint32_t gwPulseCount=message.getULong();
      		pulseCount += gwPulseCount;
      		flow=oldflow=0;
      		Serial.print("Received last pulse count from gw:");
      		Serial.println(pulseCount);
      		pcReceived = true;
      	}
      }
      
      void onPulse()
      {
      	if (!SLEEP_MODE) {
      		uint32_t newBlink = micros();
      		uint32_t interval = newBlink-lastBlink;
      
      		if (interval!=0) {
      			lastPulse = millis();
      			if (interval<500000L) {
      				// Sometimes we get interrupt on RISING,  500000 = 0.5sek debounce ( max 120 l/min)
      				return;
      			}
      			flow = (60000000.0 /interval) / ppl;
      		}
      		lastBlink = newBlink;
      	}
      	pulseCount++;
      }
      
      posted in Domoticz
      flopp
      flopp