Navigation

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

    markcame

    @markcame

    0
    Reputation
    11
    Posts
    365
    Profile views
    0
    Followers
    0
    Following
    Joined Last Online

    markcame Follow

    Best posts made by markcame

    This user hasn't posted anything yet.

    Latest posts made by markcame

    • RE: 💬 Heatpump / airconditioner controller

      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

      posted in OpenHardware.io
      markcame
      markcame
    • RE: Molgan and Emengency Light

      Ok, how can assign a fixed id ?

      posted in My Project
      markcame
      markcame
    • RE: Molgan and Emengency Light

      @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;
      
      posted in My Project
      markcame
      markcame
    • RE: Molgan and Emengency Light

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

      posted in My Project
      markcame
      markcame
    • RE: Molgan and Emengency Light

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

      posted in My Project
      markcame
      markcame
    • Molgan and Emengency Light

      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;
      }
      
      posted in My Project
      markcame
      markcame
    • RE: Gas Meter Reading Using a Magnetometer

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

      posted in My Project
      markcame
      markcame
    • RE: Gas Meter Reading Using a Magnetometer

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

      posted in My Project
      markcame
      markcame
    • RE: Gas Meter Reading Using a Magnetometer

      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");
       //************************************************************  
      
      posted in My Project
      markcame
      markcame
    • RE: Gas Meter Reading Using a Magnetometer

      @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

      posted in My Project
      markcame
      markcame