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
Posts made by markcame
-
RE: 💬 Heatpump / airconditioner controller
-
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;
-
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...
-
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... -
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; }
-
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? -
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.
-
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"); //************************************************************
-
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
-
RE: Gas Meter Reading Using a Magnetometer
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