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);
        }
      }
    }
    

 

166
Online

8.7k
Users

9.5k
Topics

99.9k
Posts