Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- emonTX V2 water pulse + ctrl of heating
- An example sketch for the emontx module V2
- Part of the openenergymonitor.org project
- Licence: GNU GPL V3
- Authors: Glyn Hudson, Trystan Lea
- Builds upon JeeLabs RF12 library and Arduino
- emonTx documentation: http://openenergymonitor.org/emon/modules/emontx/
- emonTx firmware code explination: http://openenergymonitor.org/emon/modules/emontx/firmware
- emonTx calibration instructions: http://openenergymonitor.org/emon/modules/emontx/firmware/calibration
- THIS SKETCH REQUIRES:
- Libraries in the standard arduino libraries folder:
- - JeeLib https://github.com/jcw/jeelib
- - EmonLib https://github.com/openenergymonitor/EmonLib.git
- Other files in project directory (should appear in the arduino tabs above)
- - emontx_lib.ino
- ------------------------------------------------------------------------------------------------------------
- -ID- -Node Type-
- 0 - Special allocation in JeeLib RFM12 driver - reserved for OOK use
- 1-4 - Control nodes
- 5-10 - Energy monitoring nodes
- 11-14 --Un-assigned --
- 15-16 - Base Station & logging nodes
- 17-30 - Environmental sensing nodes (temperature humidity etc.)
- 31 - Special allocation in JeeLib RFM12 driver - Node31 can communicate with nodes on any network group
- -------------------------------------------------------------------------------------------------------------
- */
- #define RF69_COMPAT 0 // set to 1 to use RFM69CW
- #include <JeeLib.h> // make sure V12 (latest) is used if using RFM69CW
- #include <RTClib.h> //https://github.com/jcw/rtclib - software RTC
- RTC_Millis RTC; DateTime future;
- #include <Wire.h>
- #include <avr/wdt.h>
- #define network 210 // emonTx RFM12B wireless network group - needs to be same as on emoncms
- #define RF_freq RF12_868MHZ // Frequency of RF12B module can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.
- #define myNodeID 6 // emonTx RFM12B node ID
- //FAIL SAFE VARIABLES
- const int MaxHeatingTime =2; //longest period heating can be on for in hrs
- const int RelayPin=6;
- const int ledPin=9;
- const int RFM12Pi_nodeID=15;
- const boolean debug=1;
- int unsigned long off_time;
- boolean heating, last_heating_state,relay;
- //emoncms RF structure
- typedef struct
- {
- byte glcdspace;
- byte hour;
- byte minute;
- byte second;
- boolean heating;
- } EmoncmsPayload;
- EmoncmsPayload emoncms;
- //emontx RF structure
- typedef struct {
- float flow; // flowrate
- int pulse; // liters
- } Payload;
- Payload emontx;
- // Pulse counting settings
- long pulseCount = 0; // Number of pulses, or how many liters since meter has 1 click for each liter.
- unsigned long pulseTime,lastTime; // Used to measure flow rate.
- #define POLLINTERVAL 4000 // Polling interval ->>>> how often to send water meter data to emoncms. Does not affect RX
- unsigned long lastpoll; // last poll variable
- void setup()
- {
- pinMode(ledPin,OUTPUT);
- digitalWrite(ledPin,HIGH);
- rf12_initialize(myNodeID,RF_freq,network); //Initialize RFM12 with settings defined above
- Serial.begin(9600);
- if (debug ==1) {
- Serial.println("heating boiler relay controller - openenergymonitor.org");
- Serial.print("Node: ");
- Serial.print(myNodeID);
- Serial.print(" Freq: ");
- if (RF_freq == RF12_433MHZ) Serial.print("433Mhz");
- if (RF_freq == RF12_868MHZ) Serial.print("868Mhz");
- if (RF_freq == RF12_915MHZ) Serial.print("915Mhz");
- Serial.print(" Network: ");
- Serial.println(network);
- }
- if (debug==0) Serial.end();
- delay(3000);
- digitalWrite(ledPin,LOW);
- attachInterrupt(1, onPulse, FALLING); // KWH interrupt attached to IRQ 1 = pin3 - hardwired to emonTx pulse jackplug. For connections see: http://openenergymonitor.org/emon/node/208
- wdt_enable(WDTO_8S); // Enable hardware anti crash watchdog: max 8 seconds
- }
- void loop()
- {
- DateTime now = RTC.now();
- if (rf12_recvDone() && rf12_crc == 0 && (rf12_hdr & RF12_HDR_CTL) == 0) // when RF packet has been received
- {
- int node_id = (rf12_hdr & 0x1F); // Extract transmitter node ID
- if (node_id == RFM12Pi_nodeID) // Emoncms RFM12Pi node id is set to 15
- {
- // The packet data is contained in rf12_data, the *(EmoncmsPayload*) part tells the compiler
- // what the format of the data is so that it can be copied correctly
- emoncms = *(EmoncmsPayload*) rf12_data;
- RTC.adjust(DateTime(2013, 1, 1, rf12_data[1], rf12_data[2], rf12_data[3])); //set software RTC based on time received from emoncms
- DateTime now = RTC.now();
- heating = emoncms.heating;
- if (debug==1)
- {
- Serial.print(emoncms.glcdspace); Serial.print(" "); Serial.print(emoncms.hour); Serial.print(" "); Serial.print(emoncms.minute); Serial.print(" ");
- Serial.print(emoncms.second);Serial.print(" "); Serial.println(emoncms.heating);
- Serial.print("Heating: "); Serial.print(heating); Serial.print(" "); Serial.print("Relay: "); Serial.println(relay);
- Serial.print("Now: "); Serial.print(now.get()); Serial.print(" "); Serial.print("Off Time: "); Serial.println(off_time);
- Serial.println();
- }
- }
- } //end of RF receive
- if (relay==0) off_time = (now.get() + MaxHeatingTime * 3600L);
- last_heating_state=relay; //record last relay heating state
- if ( (heating==1) && (now.get() < off_time ) ) relay =1; //if heating is turned on and fail safe checks are passed
- else relay =0;
- //control heating
- if (relay==0) //turn the heating off
- {
- digitalWrite(RelayPin, LOW);
- }
- if (relay==1) //turn the heating on
- {
- digitalWrite(RelayPin, HIGH);
- if (last_heating_state==0) off_time = (now.get() + MaxHeatingTime * 3600L); //record start time and calculate failsafe off-time, calculate a time which is MaxHeatingTime hrs in the future
- }
- wdt_reset(); // Reset watchdog - this must be called every 8s - if not the ATmega328 will reboot
- if(millis() - lastpoll > POLLINTERVAL or lastpoll == 0) { // check if it is time to do a poll
- // update lastpoll
- lastpoll = millis();
- emontx.pulse = pulseCount; pulseCount=0;
- if (debug==1)
- {
- Serial.print(emontx.flow);
- Serial.println(" Liter/h");
- Serial.print(emontx.pulse);
- Serial.println(" Liters since last poll");
- }
- delay(100);
- send_rf_data(); // *SEND RF DATA* - see emontx_lib
- digitalWrite(ledPin, HIGH); delay(2); digitalWrite(ledPin, LOW); // flash LED
- emontx.flow = 0;
- }
- }
- // The interrupt routine - runs each time a falling edge of a pulse is detected
- void onPulse()
- {
- lastTime = pulseTime; //used to measure time between pulses.
- pulseTime = millis();
- pulseCount++; //pulseCounter
- emontx.flow = float((3600000 / (pulseTime - lastTime))); //Calculate flow
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement