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

markcame

@markcame
About
Posts
11
Topics
1
Shares
0
Groups
0
Followers
0
Following
0

Posts

Recent Best Controversial

  • 💬 Heatpump / airconditioner controller
    M markcame

    First , I started to build an arduino pro version of the sensors but i have some trouble, it seems that the code sended over ir is not stable using an arduino as decoder i see that sometims one ore more bit is delayed or not send and accordingly the heatpump does not start... there are settings that i have to change for the PWM on an arduino pro mini ?
    Second if someone is interested i decoded the ir codes of my heatpump a mitsubishi not supported on the provided library on the forum, i can share the reverse of the protocol if someone is interested

    OpenHardware.io mysensors infrared heatpump contest2016

  • Molgan and Emengency Light
    M markcame

    Ok, how can assign a fixed id ?

    My Project

  • Molgan and Emengency Light
    M markcame

    @AWI
    Sketch

    /**
     * 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
     *
     * DESCRIPTION
     * Motion Sensor example using HC-SR501
     * http://www.mysensors.org/build/motion
     *
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_SIGNING_SOFT //Enable software Signing
    //#define MY_SIGNING_REQUEST_SIGNATURES //Enable signature on gateway
    //#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 //Randomize pin leave unconnected
    
    #include <MySensors.h>
    
    
    #define SENSOR_SLEEP_TIME_MS (24UL*60UL*60UL*1000UL) // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define CHILD_ID 1   // Id of motion sensor child
    
    #define DIGITAL_OUTPUT_LED 4 //Digital Output driving led mosfet
    #define LED_CHILD_ID 2 // Id of motion sensor child
    #define VOLTAGE_CHILD_ID 3
    
    // define values for the battery measurement
    #define R1  1e6
    #define R2  470e3
    #define VMIN  3.5
    #define VMAX  4.5
    #define ADC_PRECISION  1024
    #define VREF 3.3
    
    
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point   
    int oldBatteryPcnt = 200;
    bool ledstatus = 0;
    bool response =0;
    bool tripped =0;
    float batteryvoltreport=0;
    
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    MyMessage led(LED_CHILD_ID,V_STATUS);
    MyMessage voltageMsg(VOLTAGE_CHILD_ID, V_VOLTAGE);
    
    
    
    void setup()
    {
        // use the 3.3 V  reference
    
        analogReference(DEFAULT);
       
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
        pinMode(DIGITAL_OUTPUT_LED, OUTPUT);
        digitalWrite(DIGITAL_OUTPUT_LED, 0);
        send(led.set(0));
     
    
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Motion Sensor and EMO Light", "1.0");
    
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_MOTION, "Motion Molgan ",true);
        wait(500);
        present(LED_CHILD_ID, S_BINARY, "LED Molgan ",true);
        wait(500);
        present(VOLTAGE_CHILD_ID, S_MULTIMETER, "Battery level" );
        
    }
    
    void loop()
    {
        // Read digital motion value
        tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
        
        Serial.print("Motion State:");
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
       
        request(LED_CHILD_ID, V_STATUS);
        response=wait(5000, C_SET, V_STATUS);
        Serial.print("Controller Response:");
        Serial.println(response);
    
        int batteryPcnt=getBatteryPercentage();
    
            if (batteryPcnt < oldBatteryPcnt  ) {
            // Power up radio after sleep
            sendBatteryLevel(batteryPcnt);
            oldBatteryPcnt = batteryPcnt;
            send(voltageMsg.set(batteryvoltreport,2)); //send battery in Volt 2 decimal places
        }
    
        
         
        // Sleep until interrupt comes in on motion sensor if gateway is responsive othervise prevent to sleep adn turn on led
        //if (response==1)
        //{
        //Serial.print("Going to sleep");
        sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SENSOR_SLEEP_TIME_MS);
        //return;
        //}
        //else  
        //        {
        //          if (response==0){
        //          digitalWrite(DIGITAL_OUTPUT_LED, 1);
        //          }
        //      return;
        //      }    
    }
    
    
    void receive(const MyMessage &message)
    {
        
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_STATUS) {
            // Change led state
            ledstatus=message.getBool();
            //tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
            if (ledstatus==1){
            digitalWrite(DIGITAL_OUTPUT_LED, tripped);
            }
            else {
              
                    if(ledstatus==0)
                      {
                          digitalWrite(DIGITAL_OUTPUT_LED, 0);
                      }
                  }
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(ledstatus);
        }
    
    
    
    }
    
    int getBatteryPercentage() {
    
      // read analog pin value
      int inputValue = analogRead(BATTERY_SENSE_PIN);
      
      // calculate the max possible value and therefore the range and steps
      float voltageDividerFactor = 3.225622776;
      float maxValue = voltageDividerFactor * VREF;
      float voltsPerBit = maxValue / ADC_PRECISION;
      
      int batteryVoltage = (voltsPerBit * inputValue)*1000;
      batteryvoltreport=(voltsPerBit * inputValue);
      
      //Serial.print("Battery Voltage:");
      //Serial.println(batteryVoltage);
      
      //int batteryPercentage = ((batteryVoltage-VMIN)/(VMAX-VMIN))*100;
      int batteryPercentage = min(map(batteryVoltage, 3500, 4500, 0, 100),100);
    
      //Serial.print("Battery Percentage:");
      //Serial.println(batteryPercentage);
    
      return batteryPercentage;
    }
    

    Serial Debug

    4242 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=OK:0100
    4371 TSF:MSG:READ,0-0-6,s=255,c=3,t=15,pt=6,l=2,sg=0:0100
    4378 TSF:MSG:SEND,6-6-0-0,s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=OK:2.1.1
    4386 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:0
    5599 TSF:MSG:READ,0-0-6,s=255,c=3,t=6,pt=0,l=1,sg=0:M
    5609 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=11,pt=0,l=25,sg=0,ft=0,st=OK:Motion Sensor and EMO Lig
    5619 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=OK:1.0
    5628 TSF:MSG:SEND,6-6-0-0,s=1,c=0,t=1,pt=0,l=14,sg=0,ft=0,st=OK:Motion Molgan 
    5946 TSF:MSG:READ,0-0-6,s=1,c=0,t=1,pt=0,l=14,sg=0:Motion Molgan 
    5951 TSF:MSG:ACK
    6140 TSF:MSG:SEND,6-6-0-0,s=2,c=0,t=3,pt=0,l=11,sg=0,ft=0,st=OK:LED Molgan 
    6246 TSF:MSG:READ,0-0-6,s=2,c=0,t=3,pt=0,l=11,sg=0:LED Molgan 
    6252 TSF:MSG:ACK
    6652 TSF:MSG:SEND,6-6-0-0,s=3,c=0,t=30,pt=0,l=13,sg=0,ft=0,st=OK:Battery level
    6660 MCO:REG:REQ
    6666 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2
    6804 TSF:MSG:READ,0-0-6,s=255,c=3,t=27,pt=1,l=1,sg=0:1
    6808 MCO:PIM:NODE REG=1
    6811 MCO:BGN:STP
    6814 TSF:MSG:SEND,6-6-0-0,s=2,c=1,t=2,pt=2,l=2,sg=0,ft=0,st=OK:0
    6820 MCO:BGN:INIT OK,TSP=1
    Motion State:0
    6824 TSF:MSG:SEND,6-6-0-0,s=1,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=OK:0
    6865 !TSF:MSG:SEND,6-6-0-0,s=2,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=NACK:
    Controller Response:0
    11874 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=1,st=OK:100
    11891 TSF:MSG:SEND,6-6-0-0,s=3,c=1,t=38,pt=7,l=5,sg=0,ft=0,st=OK:4.88
    11897 MCO:SLP:MS=86400000,SMS=0,I1=1,M1=1,I2=255,M2=255
    11902 MCO:SLP:TPD
    11905 MCO:SLP:WUP=1
    Motion State:1
    11909 TSF:MSG:SEND,6-6-0-0,s=1,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=OK:1
    11916 TSF:MSG:SEND,6-6-0-0,s=2,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=OK:
    Controller Response:0
    16922 MCO:SLP:MS=86400000,SMS=0,I1=1,M1=1,I2=255,M2=255
    16928 MCO:SLP:TPD
    16930 MCO:SLP:WUP=1
    Motion State:0
    16936 TSF:MSG:SEND,6-6-0-0,s=1,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=OK:0
    16944 TSF:MSG:SEND,6-6-0-0,s=2,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=OK:
    Controller Response:0
    21950 MCO:SLP:MS=86400000,SMS=0,I1=1,M1=1,I2=255,M2=255
    21956 MCO:SLP:TPD```
    
    
    

    Gateway

    0;255;3;0;14;Gateway startup complete.
    0;255;0;0;18;2.1.1
    0;255;3;0;2;2.1.1
    0;255;3;0;22;188673920
    0;255;3;0;22;188683854
    6;255;0;0;17;2.1.1
    6;255;3;0;6;0
    6;255;3;0;11;Motion Sensor and EMO Lig
    6;255;3;0;12;1.0
    6;1;0;0;1;Motion Molgan 
    6;2;0;0;3;LED Molgan 
    6;3;0;0;30;Battery level
    6;2;1;0;2;0
    6;1;1;0;16;0
    6;2;2;0;2;
    0;255;3;0;22;188693888
    6;255;3;0;0;100
    6;3;1;0;38;4.88
    0;255;3;0;22;188703923
    6;1;1;0;16;1
    6;2;2;0;2;
    6;1;1;0;16;0
    6;2;2;0;2;
    
    My Project

  • Molgan and Emengency Light
    M markcame

    I've tryed everything but seems that the request does not return a value, seems that domoticz does not expose the value but only send status update at the moment of the switch, request on V_VAR1... ecc. ec... instead always works but they are not exposed to the user...

    My Project

  • Molgan and Emengency Light
    M markcame

    Ok i will try with the modification suggested.
    I have at the moment some comunication problems with th radio so i've rewired my ESP8266 gateway and adding some capacitors.
    what type use S-BINARY , i have had some problems retriving the status from domoticz , i don't know if it is related to the lastest beta...

    My Project

  • Molgan and Emengency Light
    M markcame

    I started play with an ikea molgan to make a a motion sensor for domoticz I want also have the possibility to use the onboard led as emergency light in case of black out so i've started with the standard motion sensor sketch trying to add the funcionality but i encountred some problems.

    Basically what i want is

    Normal state (motion sensor)
    Emergency light triggered on and off by pir (if at first motion triggering if cannot contact the gateway or if in domoticz a switch status is on )

    for the hardware i've connected che gate control to a digital i/o of arduino, but for the software i sill have problem.

    Sometimes the status is not correctly recived from controller in an acceptable time and i didn't have at the moment an efficient method to know if the gateway is alive.
    any suggest ?

    here the sketch used

    *
     * 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
     *
     * DESCRIPTION
     * Motion Sensor example using HC-SR501
     * http://www.mysensors.org/build/motion
     *
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_SIGNING_SOFT //Enable software Signing
    //#define MY_SIGNING_REQUEST_SIGNATURES //Enable signature on gateway
    //#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 //Randomize pin leave unconnected
    
    #include <MySensors.h>
    
    
    #define SENSOR_SLEEP_TIME_MS (24UL*60UL*60UL*1000UL) // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define CHILD_ID 1   // Id of motion sensor child
    
    #define DIGITAL_OUTPUT_LED 4 //Digital Output driving led mosfet
    #define LED_CHILD_ID 2 // Id of motion sensor child
    
    // define values for the battery measurement
    #define R1  1e6
    #define R2  470e3
    #define VMIN  3.5
    #define VMAX  4.5
    #define ADC_PRECISION  1024
    #define VREF 3.306
    
    
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point   
    int oldBatteryPcnt = 0;
    bool ledstatus = 0;
    bool response =0;
    bool tripped =0;
    
    
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    MyMessage led(LED_CHILD_ID,V_TEXT);
    
    
    
    void setup()
    {
        // use the 3.3 V  reference
    
        analogReference(DEFAULT);
       
     
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
        pinMode(DIGITAL_OUTPUT_LED, OUTPUT);
        
        digitalWrite(DIGITAL_OUTPUT_LED, 0);
        send(led.set(0));
     
    
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Motion Sensor and EMO Light", "1.0");
    
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_MOTION, "Motion Molgan ",true);
        wait(500);
        present(LED_CHILD_ID, S_INFO, "LED Molgan ",true);
        
        
    }
    
    void loop()
    {
        // Read digital motion value
        tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
        
        Serial.print("Motion State:");
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
       
        request(LED_CHILD_ID, V_TEXT);
        response=wait(5000, 2, V_TEXT);
        Serial.print("Controller Response:");
        Serial.println(response);
    
        int batteryPcnt=getBatteryPercentage();
    
            if (oldBatteryPcnt != batteryPcnt) {
            // Power up radio after sleep
            sendBatteryLevel(batteryPcnt);
            oldBatteryPcnt = batteryPcnt;
        }
    
        
         
        // Sleep until interrupt comes in on motion sensor if gateway is responsive othervise prevent to sleep adn turn on led
        //if (response==1)
        //{
        Serial.print("Going to sleep");
        sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SENSOR_SLEEP_TIME_MS);
        //return;
        //}
        //else  
        //        {
        //          if (response==0){
        //          digitalWrite(DIGITAL_OUTPUT_LED, 1);
        //          }
        //      return;
        //      }    
    }
    
    
    void receive(const MyMessage &message)
    {
        
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_TEXT) {
            // Change led state
            ledstatus=message.getBool();
            //tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
            if (ledstatus==1){
            digitalWrite(DIGITAL_OUTPUT_LED, tripped);
            }
            else {
              
                    if(ledstatus==0)
                      {
                          digitalWrite(DIGITAL_OUTPUT_LED, 0);
                      }
                  }
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(ledstatus);
        }
    
    
    
    }
    
    int getBatteryPercentage() {
    
      // read analog pin value
      int inputValue = analogRead(BATTERY_SENSE_PIN);
      
      // calculate the max possible value and therefore the range and steps
      float voltageDividerFactor = 3.225622776;
      float maxValue = voltageDividerFactor * VREF;
      float voltsPerBit = maxValue / ADC_PRECISION;
      
      int batteryVoltage = (voltsPerBit * inputValue)*1000;
      
      Serial.print("Battery Voltage:");
      Serial.println(batteryVoltage);
      
      //int batteryPercentage = ((batteryVoltage-VMIN)/(VMAX-VMIN))*100;
      int batteryPercentage = min(map(batteryVoltage, 3500, 4500, 0, 100),100);
    
      Serial.print("Battery Percentage:");
      Serial.println(batteryPercentage);
    
      return batteryPercentage;
    }
    
    My Project

  • Gas Meter Reading Using a Magnetometer
    M markcame

    @dpcr Yes I use var1 for pulse count Var2 for Top and Var3 for bottom

    if the retrieve of value from Gw/Controller is fine get the last Top and Bottom otherwise if retrieve fails after power cycle use locally hard coded, if the retrieve is 0 for TOP and BOTTOM starts auto-detect (gas must be flow) this happens on first run or if you want to manually starts a recalculation.

    I think that the problem of spike... maybe related to a non triggering of top or bottom after magnetic field change due to temperature so pulse count going up until new top and bottom was recalculated and applied, there are a control over max pulse for cycle ?

    for the count up probably there are a part of code time spending and the reading jump ?

    on version V3.6304 of domoticz m3/h are displayed fine if you select gas type counter .... for flow maybe is still water flow reported.

    for the pulse count i meaning looking at the code that you take a period then divide in division and trigger a pulse for every division is passed but i didn't understand if the metodology for counting pulse changed on the old and on the new code

    here the code i have modified is a mix of old and new code you have posted plus the support to store on controller and a chek for not count more than todividers on rising or falling , i want to test if i can improve the count or not...

    /*
     * 
     * 
     * 
     * 
     * Currently the autoDetectMaxMin in set to true which will find the TOP and BOTTOM of the wave, however if you want 
     * to use it the gas must be flowing.
     */
    
    
    
    #define MY_DEBUG
    #define MY_RADIO_NRF24
    
    #include <MySensors.h>                  
    #include <Wire.h>                       //I2C Arduino Library
    
    #define CHILD_ID 1                      //ID of the sensor child
    #define SLEEP_MODE false                //prevent sensor from sleeping
    #define address 0x1E                    //0011110b, I2C 7bit address of HMC5883
    
    int TOP = 0;                            //highest magnetic field registered from meter (Ga)Initialize low if using AutoDetectMaxMin
    int BOTTOM = 0;                         //lowest magnetic field registered from meter (Ga) Initialize high if using AutoDetectMaxMin
    int NewTop=-9000;
    int NewBottom=9000;
    int tol = 50;
    unsigned long SEND_FREQUENCY = 30000;   // Minimum time between send (in milliseconds). We don't want to spam the gateway.
    
    bool metric = true;                     //sets units to Metric or English
    bool autoDetectMaxMin = false;           //lets Arduino decide the values for TOP and BOTTOM
    bool pcReceived = false;                //whether or not the gw has sent us a pulse count
    bool rising = true;                     //whether or not a pulse has been triggered
    bool inside = true;                     //whether the magnetic field is within TOP and BOTTOM limits
    unsigned long pulsecount = 0;           //total number of pulses measured ever
    unsigned long oldPulseCount = 0;        //old total
    double vpp = 0.12;                      //Volume of gas per pulse
    unsigned long lastSend = 0;             //time since last transmission - msec
    double volume = 0;                      //Cumulative amount of gas measured
    const int len = 3;                      //number of flow rate measurements to save
    double flow [len];                      //array of previous gas flow rate measurements
    double avgFlow = 0;                     //average of all elements in flow array
    double oldAvgFlow = 0;                  //previous average flow
    int divider = 1;                        //Current divider
    int totDividers = 10;                    //Number of dividers
    int increment = (TOP - BOTTOM) / totDividers;   //space b/w dividers
    int newTop = -9000;                     //potential new Top
    int newBottom = 9000;                   //potential new Bottom
    int counter=0;
    
    MyMessage flowMsg(CHILD_ID,V_FLOW);
    MyMessage volumeMsg(CHILD_ID,V_VOLUME);
    MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
    MyMessage lastTopMsg(CHILD_ID,V_VAR2);
    MyMessage lastBottomMsg(CHILD_ID,V_VAR3);
    
    void setup(){
      //Initialize Serial and I2C communications
      Serial.begin(115200);
      Wire.begin();
    
      // Fetch last known pulse count , TOP and BOTTOM value from gw
      request(CHILD_ID, V_VAR1);
      request(CHILD_ID, V_VAR2);
      request(CHILD_ID, V_VAR3);
      
      // Wait until timeout of 2 seconds for message from gw
      wait(2000, 2, V_VAR1);
      wait(2000, 2, V_VAR2);
      wait(2000, 2, V_VAR3);
    
      
      //Put the HMC5883 IC into the correct operating mode
      Wire.beginTransmission(address); //open communication with HMC5883
      Wire.write(0x02); //select mode register
      Wire.write(0x00); //continuous measurement mode
      Wire.endTransmission();
      
      int y = 0;
      int oldy = 0;
    
      //WARNING: MAKE SURE GAS IS RUNNING IF USING THIS OPTION!!!
      if(TOP==0 && BOTTOM==0){
      autoDetectMaxMin = true;
        //determine max and min magnetic field strength over a few minutes
        lastSend = millis();
        
        while(millis() - lastSend < 120000){
          y = readMag();
          if(y > TOP){
            TOP = y;                        //update TOP if new max has been detected
          }
          else if(y < BOTTOM){
            BOTTOM = y;                     //update BOTTOM if new min has been detected
          }
        }
        
        TOP -= tol;                         //nudge TOP and BOTTOM so that they have a chance of being triggered
        BOTTOM += tol;
    
        increment = (TOP - BOTTOM) / totDividers;    //recalculate increment to match new TOP and BOTTOM
        autoDetectMaxMin = false;           //finished determining TOP and BOTTOM
       
      Serial.println("Store on Controller TOP and BOTTOM found");
      send(lastTopMsg.set(TOP));
      send(lastBottomMsg.set(BOTTOM));
      
      }
      increment = (TOP - BOTTOM) / totDividers;    //recalculate increment to match new TOP and BOTTOM
      Serial.print("Increment = ");
      Serial.println(increment);
      
      oldy = readMag();
      y = readMag();
      while(abs(y - oldy) < increment / 2){ //wait until difference b/w y and oldy is greater than half an increment
        y = readMag();
      }
      rising = (y > oldy);
      Serial.println(rising ? "Magnetic field is rising" : "Magnetic field is falling");
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Gas Meter", "0.4");
    
        // Register this device as Gas sensor
        present(CHILD_ID, S_GAS);
    }
    
    void loop(){
      if (!pcReceived) {
        //Last Pulsecount not yet received from controller, request it again
        request(CHILD_ID, V_VAR1);
        return;
      }
      //detecting magnetic pulses - Fractional Simple Method
      while(millis() - lastSend < SEND_FREQUENCY){
        int y = readMag();
      
      if(y >NewTop ){
            NewTop = y;                        //update TOP if new max has been detected
          }
          else if(y < NewBottom){
            NewBottom = y;                     //update BOTTOM if new min has been detected
          }
    
        if(inside && rising && y > BOTTOM + divider * increment && divider < totDividers+1){
          divider++;
          pulsecount++;
        }
        else if(inside && !rising && y < TOP - divider * increment &&  divider < totDividers+1){
          divider++;
          pulsecount++;
        }
    
        if(inside && (y > TOP || y < BOTTOM )){        //switch directions once TOP or BOTTOM divider has been reached
          inside = false;                 //keep this from happening multiple times once signal exceeds TOP or BOTTOM
          Serial.println("OUTSIDE");
        }
        else if(!inside && (y < TOP - increment / 2 && y > BOTTOM + increment / 2)){
          rising = !rising;
          divider = 1;
          inside = true;
          Serial.println("INSIDE");
        } 
      }
      
    counter += (pulsecount - oldPulseCount);      //update counter
        if(counter >= ((totDividers + 1) * 2)){
        if ( (abs(TOP-NewTop)) > tol || (abs(BOTTOM-NewBottom)) >tol){
          TOP=NewTop-tol;
          BOTTOM=NewBottom+tol;
          increment = (TOP - BOTTOM) / totDividers;    //recalculate increment to match new TOP and BOTTOM
    
          //Send Top and Bottom to gateway
          send(lastTopMsg.set(TOP));                  
          send(lastBottomMsg.set(BOTTOM));
          
          //reset newTop and newBottom
          newTop = -9000;
          newBottom = 9000;
          counter = 0;
          //display new bounds
          Serial.println("NEW BOUNDARIES SET:");
          Serial.print("Top = ");
          Serial.println(TOP);
          Serial.print("Bottom = ");
          Serial.println(BOTTOM);
          Serial.print("Increment = ");
          Serial.println(increment);
        }
      }
      
    
      //shift all flow array elements to the right by 1, ignore last element
      for(int idx = len - 1; idx > 0; idx--){
        flow[idx] = flow[idx - 1];
      }
      //calculate newest flow reading and store it as first element in flow array
      flow[0] = (double)(pulsecount - oldPulseCount) * (double)vpp * 60000.0 / (double)SEND_FREQUENCY;
      //display flow array state
      Serial.print("Flow Array State: [");
      for(int idx = 0; idx < len - 1; idx++){
        Serial.print(flow[idx]);
        Serial.print("|");
      }
      Serial.print(flow[len - 1]);
      Serial.println("]");
      //calculate average flow
      avgFlow = 0;                                //reset avgFlow
      for(int idx = 0; idx < len; idx++){         //calculate weighted sum of all elements in flow array
        avgFlow += (flow[idx] * (len - idx));
      }
      avgFlow /= (len * (len + 1) / 2);           //divide by triangle number of elements to get linear weighted average
      Serial.print("Average flow: ");             //display average flow
      Serial.println(avgFlow);
      //send flow message if avgFlow has changed
      if(avgFlow != oldAvgFlow){
        oldAvgFlow = avgFlow;
        send(flowMsg.set(avgFlow, 2));
      }
    
      //send updated cumulative pulse count and volume data, if necessary
      if(pulsecount != oldPulseCount){
        oldPulseCount = pulsecount;              //update old total
        
        //calculate volume
        volume = (double)oldPulseCount * (double)vpp / 1000.0;
    
        //send pulse count and volume data to gw
        send(lastCounterMsg.set(pulsecount));
        send(volumeMsg.set(volume, 3));
      }
    
      lastSend = millis();
      
    }
    
    void receive(const MyMessage &message)
    {
      if (message.type==V_VAR1) {
        unsigned long gwPulseCount=message.getULong();
        pulsecount = gwPulseCount;
        oldPulseCount = pulsecount;
        Serial.print("Received last pulse count from gw:");
        Serial.println(pulsecount);
        pcReceived = true;
        lastSend = millis();
      }
      if (message.type==V_VAR2) {
        int gwStoredTOP=message.getInt();
        TOP = gwStoredTOP;
        Serial.print("Received stored TOP value from gw:");
        Serial.println(TOP);
      }
      if (message.type==V_VAR3) {
        int gwStoredBOTTOM=message.getInt();
        BOTTOM = gwStoredBOTTOM;
        Serial.print("Received stored BOTTOM value from gw:");
        Serial.println(BOTTOM);
      }
    }
    int readMag(){
      int x = 0, y = 0, z = 0;
      
      //Tell the HMC5883 where to begin reading data
      Wire.beginTransmission(address);
      Wire.write(0x03); //select register 3, X MSB register - was called Wire.send but the compiler had an error and said to rename to to Wire.write
      Wire.endTransmission();
    
      //Read data from each axis, 2 registers per axis
      Wire.requestFrom(address, 6);
      if(6<=Wire.available()){
        x = Wire.read()<<8; //X msb
        x |= Wire.read(); //X lsb
        z = Wire.read()<<8; //Z msb
        z |= Wire.read(); //Z lsb
        y = Wire.read()<<8; //Y msb
        y |= Wire.read(); //Y lsb
      }
    
      if(!autoDetectMaxMin){
        //show real-time magnetic field, pulse count, and pulse count total
        Serial.print("y: ");
        Serial.print(y);
        Serial.print(rising ? "  Rising, " : "  Falling, ");
        Serial.print("next pulse at: ");
        Serial.print(rising ? BOTTOM + divider * increment : TOP - divider * increment);
        Serial.print("  Current Number of Pulses: ");
        Serial.print(pulsecount - oldPulseCount);
        Serial.print("  Last Total Pulse Count Sent to GW: ");
        Serial.println(oldPulseCount);
      }
      else{
        //show real-time magnetic field, TOP, BOTTOM, and time left in auto-detect mode
        Serial.print("y: ");
        Serial.print(y);
        Serial.print("  TOP: ");
        Serial.print(TOP);
        Serial.print("  BOTTOM: ");
        Serial.print(BOTTOM);
        unsigned long remainingTime = 120000 + lastSend - millis();
        Serial.print("  Time remaining: ");
        Serial.print(remainingTime / 60000);
        Serial.print(":");
        remainingTime = (remainingTime % 60000) / 1000;
        if(remainingTime >= 10){
          Serial.println(remainingTime);
        }
        else{
          Serial.print("0");
          Serial.println(remainingTime);
        }
        
      }
      
      return y;
     
    }
    
    
    

    I have another little problem that after a while the node stop to work i don't know but on the serial stop to print data and no more message is sent to the gateway if i close and re-open the serial monitor the data readed by magnetometer is displayed again but no data is sent,
    Can be related to radio issue ? or overbuffering serial ? do you have experienced similar problem?

    My Project

  • Gas Meter Reading Using a Magnetometer
    M markcame

    @dpcr They find corect top and bottom, and start to pulse but after first recalculation of bounds they statrs to count a pulse for every readings.

    My Project

  • Gas Meter Reading Using a Magnetometer
    M markcame

    I've try to analyze the program on the old sketch everything are good except the flow rate, I've found an error when you perform the shift of the element on an index this is the reason because the number reported wrong to the gateway.

    I want to use the new sketch but i have two question, the first is that i didn't understand the pulse count

    while(millis() - lastSend < SEND_FREQUENCY){
       //check if the signal has significantly increased/decreased
       if(abs(oldy - y) > increment){
         pulsecount ++;
         //increment or decrement oldy by oInsert Code Herene increment based on direction
         oldy += rising ? increment : -1 * increment;     
         safe = false;             //reset safe now that oldy has updated     
       }
       //check if the signal has recently switched directions
       else if(safe){                  //first make sure y has moved a significant distance from oldy
         if((rising && y <= oldy) || (!rising && y >= oldy)){
           pulsecount ++;              //add one extra pulse
           rising = !rising;           //update direction
           safe = false;
         }
       }
       
       //take another reading
       y = readMag();Insert Code Here
       //check if y has moved a significant distance from oldy
       if(abs(y - oldy) > tol / 2){Insert Code Here
         safe = true;Insert Code Here
       }
       
       //update newTop and newBottom
       detectMaxMin();                
     }
    

    and the second is about the initialization of variables retrieved from the FRAM , i i have understand to start the "calibration" you need to put 50 and -50 on the memory otherwise the right condition was not triggered right ?
    i didn't use the FRAM but I've coded to retrieve form the controller

     //get Top and Bottom from controller***********************
     Serial.println("Ask for top value @ controller");
     //Get Last top
     request(CHILD_ID, V_VAR2);
        
     Serial.println("Ask for bottom value @ controller");
     //Get Last bottom
     request(CHILD_ID, V_VAR3);
     
     wait(2000, 2, V_VAR1);
     wait(2000, 2, V_VAR2);
     wait(2000, 2, V_VAR3);
     Serial.println("Variables Succesfully Retrived from GW");
     //************************************************************  
    
    My Project

  • Gas Meter Reading Using a Magnetometer
    M markcame

    @dpcr I've tried the sketch but seems something is wrong, I've modified it for using my controller to store the top and bottom values and this function very well I'm able to check on the serial that the values are correctly retrieved and stored, but during the running after some cycles start counting pulse at every reading of magnetic field

    My Project

  • Gas Meter Reading Using a Magnetometer
    M markcame

    Dear All,
    I've tried to make a gas meter sensor using the magnetometer because I've started only few weeks ago approaching mysensor setup so be patient with me...

    I've now two problems , the first is regarding the accuracy of the measure, it seems that after I've count the number of cycles Vs the gas measured of the meter and found the value of vpp (I've used the scketch posted by dpcr) afther a while the values measured drift from the real
    The second problem is that I'm not able to measure the flow... it gave me values very high (1249225088.00 l/min)
    Someone have ideas what's happen ?

    Thanks a lot

    My Project
  • Login

  • Don't have an account? Register

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