Battery Tank level node and Openhab



  • Hi All,
    I am a bit confused again (its not hard..) I am trying to combine a previous sketch from @Boots33 with battery reporting to openhab. The tank sketch works great (Thanks Boots!) but I can not figure out how to send the battery level. Here is my adapted sketch-:

    /*
      Sketch to read level of water in a round tank and  then send data back to controller
      uses MySensors V2 .
    
      Libraries used
      MySensors          https://www.mysensors.org/
      NewPing            https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home
      SPI                 installed with arduino IDE
    
    */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    // Enabled repeater feature for this node
    //#define MY_REPEATER_FEATURE
    
    //#define MY_RF24_CHANNEL 84    // channel of nrf network
    
    #include <MySensors.h>
    #include <SPI.h>
    #include <NewPing.h>
    
    #define MY_NODE_ID 3    // comment out this line if you use dynamic id's
    #define CHILD_ID_WATER 1
    #define CHILD_ID_PERCENT 2
    
    
    // newping settings
    #define TRIGGER_PIN  6                  // Arduino pin 6 connected to trigger pin on the ultrasonic sensor.
    #define ECHO_PIN     7                  // Arduino pin 7 connected to echo pin on the ultrasonic sensor.
    #define MAX_DISTANCE 240                // Maximum distance we want to ping for (in centimeters). you should set this to be 
    // a bit more than fullHeight + sensHeight.
    
    /*------change these to suit your tank setup-----*/
    const int tankRad = 170;                // Radius of tank in cm
    const int fullHeight = 198;             // Height of water when tank full in cm
    const int sensHeight = 30;              // height of sensor above full water mark in cm
    const int outletHeight = 7;             // height of water when tank reading will show empty in cm
    /*----------------------------------------------*/
    
    int BATTERY_SENSE_PIN = A0;             // select the input pin for the battery sense point
    int oldBatteryPcnt = 0;
    unsigned long lastSent;
    unsigned long heartbeatDelay = 15;     // how often the heartbeat will be sent, in minutes
    //unsigned long lastHeartbeat = millis(); // holder for last time heartbeat was sent
    uint32_t SLEEP_TIME = 10000;           // 900000=15 mins sleep time between reads (seconds * 1000 milliseconds)
    unsigned long pingHeight;               // holds total height from ultrasonic sender to current water height
    unsigned int waterAvail;                // holds current water available in litres
    
    byte oldWaterPercent;
    byte waterPercent = 0 ;                 // used to hold the tank water level percentage
    
    // NewPing setup of pins and maximum distance.
    NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
    
    MyMessage msgVolume(CHILD_ID_WATER, V_LEVEL);              // water available in litres
    MyMessage msgPercent(CHILD_ID_PERCENT, V_LEVEL);           // water percentsge available
    
    void setup() {
    
      pinMode(5, OUTPUT);
      analogReference(INTERNAL);
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Tank Level", "1.4");
    
      // Register all sensors to gateway (they will be created as child devices)
      present(CHILD_ID_WATER, S_DUST, "Water Available");
      present(CHILD_ID_PERCENT, S_DUST, "Water Percentage Available");
    }
    
    
    void loop()
    {
    // get the battery Voltage
    int sensorValue = analogRead(BATTERY_SENSE_PIN);
    #ifdef MY_DEBUG
    Serial.println(sensorValue);
    #endif
    
    // 1M, 470K divider across battery and using internal ADC ref of 1.1V
    // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
    // ((2.2e6+330e3)/330e3)*1.1 = Vmax = 8.4 Volts
    // 8.4/1023 = Volts per bit = 0.001075275
    
    int batteryPcnt = sensorValue / 10;
    
    #ifdef MY_DEBUG
    //float batteryV  = sensorValue * 0.001075275;
    float batteryV = sensorValue * 9.17 / 1023;
    
    Serial.print("Battery Voltage: ");
    Serial.print(batteryV);
    Serial.println(" V");
    
    Serial.print("Battery percent: ");
    Serial.print(batteryPcnt);
    Serial.println(" %");
    #endif
    
    if (oldBatteryPcnt != batteryPcnt) {
      // Power up radio after sleep
      sendBatteryLevel(batteryPcnt);
      oldBatteryPcnt = batteryPcnt;
    }
    {
      Serial.println("Waking out of sleep");
      digitalWrite(5, HIGH);
      Serial.println("Ultrasonic module ON");
      delay (1000);
    
      data_calc();      // perform calculations to get water remaining etc.
    
    
      if (oldWaterPercent != waterPercent) {        //check to see if new water data is available
        send(msgVolume.set(waterAvail));
        send(msgPercent.set(waterPercent));
        oldWaterPercent = waterPercent;
        lastSent = millis();
      }
    
      heartbeatCheck();                                    // call heartbeat function
      digitalWrite(5, LOW);
      Serial.println("Ultrasonic module OFF");
    
      Serial.println("Entering Sleep");
      sleep(SLEEP_TIME);
    
    }
    }
    /*-------------------------start of functions-------------------*/
    
    void heartbeatCheck() {
      unsigned long millisNow = millis();           // get the current time
      if ((millisNow - lastSent) > (heartbeatDelay * 60000)) {
        send(msgVolume.set(waterAvail));
        send(msgPercent.set(waterPercent));
        lastSent = millisNow;
      }
    
      /*if ((millisNow - lastHeartbeat) > (heartbeatDelay*60000)) {
        sendHeartbeat();
        wait(5);
        // sendBatteryLevel(100);
        lastHeartbeat = millis();
        #ifdef MY_DEBUG
          Serial.println("Heartbeat Sent" );
        #endif
        } */
    }
    
    void data_calc() {
      pingHeight = sonar.ping_median(5);             //- Do multiple (5) pings and return median
      pingHeight = sonar.convert_cm(pingHeight);     // then convert to cm
    #ifdef MY_DEBUG
      Serial.print("Ping Height raw in cm: ");
      Serial.println(pingHeight);
    #endif
      pingHeight  = constrain(pingHeight, sensHeight, (fullHeight - outletHeight) + sensHeight); // keep pingHeight within the expected values
      waterPercent = map(pingHeight, sensHeight, (fullHeight - outletHeight) + sensHeight, 100, 0);   // calculate the percentage of water available
      waterAvail = PI * pow(tankRad, 2) * (((fullHeight - outletHeight) + sensHeight) - pingHeight) / 1000; // calculate water available in litres
    
      // Write some debug info
    #ifdef MY_DEBUG
      Serial.print("Ping Height constrained in cm: ");
      Serial.println(pingHeight);
      Serial.print("Percentage Available: ");
      Serial.println(waterPercent);
      Serial.print("Litres Available: ");
      Serial.println(waterAvail);
    #endif
    }
    

    I am trying to figure out how the sketch sends the battery info to openhab and how I view it. Any tips or pointers would be most appreciated. Do I have to add another line in the void presentation for the voltage? And should Openhab discover the voltage data as another Thing?

    Cheers
    Crumpy



  • @crumpy10 Just looking over your sketch, I see on line 108 you have a call to a method named sendBatteryLevel(). I do not see that method defined anywhere in your sketch. I don't know if it is part of one of your included libraries, but if it is not, you need to define that.



  • @dbemowsk Hi, Thanks for the reply. I am very new to Mysensors and not a programmer. I think the sendbatteryLevel is part of the included libraries but not fully sure. I am seeing both voltage and percent in the serial monitor but just cant work out how to send it through the gateway to the controller (openhab). I just cant work out what extra I need in the sketch to do this?



  • @Crumpy10 The sendBatteryLevel is a method included in the library.
    How do you connect MySensors to OpenHAB? Do you use the serial GW or MQTT? What binding do you use on the OH-side?
    I am using MQTT myself so I am not that much at home with serial or with the MySensors binding for OH.



  • @bgunnarb thanks for the reply. That’s what I thought, that the battery monitor is included in the library. I just don’t know how that part gets the info through to openHAB. I am using the Ethernet gateway by the way. I have managed to get the info through using the multimeter function but I think there is a better way for battery level!



  • I do not know openhab, but in Domoticz this info ( battery and radio level ) I can see only in all devices list tab. Not like special sensor.


Log in to reply
 

Suggested Topics

  • 22
  • 2
  • 135
  • 3
  • 19
  • 10

0
Online

11.2k
Users

11.1k
Topics

112.5k
Posts