Advertisement
Boelle

emontx pulse count & control

Jun 4th, 2015
346
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.21 KB | None | 0 0
  1. /*
  2. emonTX V2 water pulse + ctrl of heating
  3.  
  4. An example sketch for the emontx module V2
  5.  
  6. Part of the openenergymonitor.org project
  7. Licence: GNU GPL V3
  8.  
  9. Authors: Glyn Hudson, Trystan Lea
  10.  
  11. Builds upon JeeLabs RF12 library and Arduino
  12.  
  13. emonTx documentation:   http://openenergymonitor.org/emon/modules/emontx/
  14. emonTx firmware code explination: http://openenergymonitor.org/emon/modules/emontx/firmware
  15. emonTx calibration instructions: http://openenergymonitor.org/emon/modules/emontx/firmware/calibration
  16.  
  17. THIS SKETCH REQUIRES:
  18.  
  19. Libraries in the standard arduino libraries folder:
  20.     - JeeLib        https://github.com/jcw/jeelib
  21.         - EmonLib       https://github.com/openenergymonitor/EmonLib.git
  22.  
  23. Other files in project directory (should appear in the arduino tabs above)
  24.     - emontx_lib.ino
  25.  
  26. ------------------------------------------------------------------------------------------------------------
  27. -ID-    -Node Type-
  28. 0   - Special allocation in JeeLib RFM12 driver - reserved for OOK use
  29. 1-4     - Control nodes
  30. 5-10    - Energy monitoring nodes
  31. 11-14   --Un-assigned --
  32. 15-16   - Base Station & logging nodes
  33. 17-30   - Environmental sensing nodes (temperature humidity etc.)
  34. 31  - Special allocation in JeeLib RFM12 driver - Node31 can communicate with nodes on any network group
  35. -------------------------------------------------------------------------------------------------------------
  36.  
  37. */
  38.  
  39. #define RF69_COMPAT 0                                                                                                                                         // set to 1 to use RFM69CW
  40. #include <JeeLib.h>                                                                                                                                           // make sure V12 (latest) is used if using RFM69CW
  41. #include <RTClib.h>                                                                                                                                           //https://github.com/jcw/rtclib - software RTC
  42. RTC_Millis RTC; DateTime future;
  43. #include <Wire.h>
  44. #include <avr/wdt.h>
  45.  
  46. #define network 210                                                                                                                                           // emonTx RFM12B wireless network group - needs to be same as on emoncms
  47. #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.
  48. #define myNodeID 6                                                                                                                                            // emonTx RFM12B node ID
  49.  
  50. //FAIL SAFE VARIABLES
  51. const int MaxHeatingTime =2;                                                                                                                                  //longest period heating can be on for in hrs
  52.  
  53. const int RelayPin=6;
  54. const int ledPin=9;
  55. const int RFM12Pi_nodeID=15;
  56.  
  57. const boolean debug=1;
  58. int unsigned long off_time;                                                      
  59.  
  60. boolean heating, last_heating_state,relay;
  61.  
  62. //emoncms RF structure
  63. typedef struct
  64. {
  65.   byte glcdspace;
  66.   byte hour;
  67.   byte minute;
  68.   byte second;
  69.   boolean heating;
  70.  
  71. } EmoncmsPayload;
  72. EmoncmsPayload emoncms;
  73.  
  74. //emontx RF structure
  75. typedef struct {
  76.       float flow;                                                                                                                                            // flowrate
  77.           int pulse;                                                                                                                                         // liters
  78.  
  79.  
  80. } Payload;
  81. Payload emontx;
  82.  
  83.  
  84.  
  85. // Pulse counting settings
  86. long pulseCount = 0;                                                                                                                                             // Number of pulses, or how many liters since meter has 1 click for each liter.
  87. unsigned long pulseTime,lastTime;                                                                                                                                // Used to measure flow rate.
  88.  
  89.  
  90. #define POLLINTERVAL 4000                                                                                                                                        // Polling interval  ->>>> how often to send water meter data to emoncms. Does not affect RX
  91.  
  92.  
  93. unsigned long lastpoll;                                                                                                                                          // last poll variable
  94.  
  95.  
  96.  
  97. void setup()
  98. {
  99.   pinMode(ledPin,OUTPUT);
  100.   digitalWrite(ledPin,HIGH);
  101.  
  102.    rf12_initialize(myNodeID,RF_freq,network);                                                                                                                     //Initialize RFM12 with settings defined above  
  103.   Serial.begin(9600);
  104.  
  105.   if (debug ==1) {
  106.     Serial.println("heating boiler relay controller - openenergymonitor.org");
  107.     Serial.print("Node: ");
  108.  Serial.print(myNodeID);
  109.  Serial.print(" Freq: ");
  110.  if (RF_freq == RF12_433MHZ) Serial.print("433Mhz");
  111.  if (RF_freq == RF12_868MHZ) Serial.print("868Mhz");
  112.  if (RF_freq == RF12_915MHZ) Serial.print("915Mhz");  
  113.  Serial.print(" Network: ");
  114.  Serial.println(network);
  115.   }
  116.   if (debug==0) Serial.end();
  117.  
  118.  delay(3000);
  119.  digitalWrite(ledPin,LOW);
  120.   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
  121.   wdt_enable(WDTO_8S);                                                                                                                                            // Enable hardware anti crash watchdog: max 8 seconds
  122. }
  123.  
  124.  
  125. void loop()
  126. {
  127.    DateTime now = RTC.now();  
  128.  
  129.   if (rf12_recvDone() && rf12_crc == 0 && (rf12_hdr & RF12_HDR_CTL) == 0)                                                                                        // when RF packet has been received
  130.   {
  131.     int node_id = (rf12_hdr & 0x1F);                                                                                                                             // Extract transmitter node ID
  132.    
  133.     if (node_id == RFM12Pi_nodeID)                                                                                                                               // Emoncms RFM12Pi node id is set to 15
  134.     {
  135.       // The packet data is contained in rf12_data, the *(EmoncmsPayload*) part tells the compiler
  136.       // what the format of the data is so that it can be copied correctly
  137.       emoncms = *(EmoncmsPayload*) rf12_data;
  138.      
  139.       RTC.adjust(DateTime(2013, 1, 1, rf12_data[1], rf12_data[2], rf12_data[3]));   //set software RTC based on time received from emoncms
  140.       DateTime now = RTC.now();
  141.      
  142.      heating = emoncms.heating;
  143.      
  144.       if (debug==1)
  145.       {
  146.         Serial.print(emoncms.glcdspace); Serial.print(" "); Serial.print(emoncms.hour); Serial.print(" "); Serial.print(emoncms.minute); Serial.print(" ");
  147.         Serial.print(emoncms.second);Serial.print(" "); Serial.println(emoncms.heating);
  148.        
  149.         Serial.print("Heating: "); Serial.print(heating); Serial.print(" ");  Serial.print("Relay: "); Serial.println(relay);
  150.         Serial.print("Now: "); Serial.print(now.get()); Serial.print(" ");  Serial.print("Off Time: "); Serial.println(off_time);
  151.        
  152.         Serial.println();
  153.        }
  154.        
  155.     }
  156.    
  157.            
  158.   } //end of RF receive
  159.  
  160.  
  161. if (relay==0) off_time = (now.get() + MaxHeatingTime * 3600L);
  162.  last_heating_state=relay;        //record last relay heating state
  163.  
  164.  if ( (heating==1) && (now.get() < off_time ) ) relay =1;          //if heating is turned on and fail safe checks are passed
  165. else relay =0;      
  166.  
  167.  
  168.  //control heating
  169. if (relay==0) //turn the heating off
  170. {
  171.   digitalWrite(RelayPin, LOW);
  172.  
  173. }
  174.  
  175. if (relay==1) //turn the heating on
  176.  {
  177.   digitalWrite(RelayPin, HIGH);
  178.  
  179.   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
  180.  }    
  181.  
  182.  
  183.  
  184. wdt_reset();           // Reset watchdog - this must be called every 8s - if not the ATmega328 will reboot
  185.  
  186.  
  187. if(millis() - lastpoll > POLLINTERVAL or lastpoll == 0) {                                                                     // check if it is time to do a poll
  188.  
  189.                                                                                                                                
  190.  
  191.                                                                                                                                 // update lastpoll
  192.     lastpoll = millis();
  193.  
  194.  
  195.    
  196.  
  197.  emontx.pulse = pulseCount; pulseCount=0;
  198.  
  199.  if (debug==1)
  200. {  
  201.   Serial.print(emontx.flow);
  202.   Serial.println(" Liter/h");
  203.   Serial.print(emontx.pulse);
  204.   Serial.println(" Liters since last poll");    
  205. }  
  206. delay(100);
  207.  
  208. send_rf_data();                                                                                                              // *SEND RF DATA* - see emontx_lib
  209.  
  210.   digitalWrite(ledPin, HIGH); delay(2); digitalWrite(ledPin, LOW);                                                             // flash LED
  211.  
  212. emontx.flow = 0;
  213.    
  214.  
  215.    
  216.   }
  217.  
  218.  
  219. }
  220.  
  221.                                                                                                                          // The interrupt routine - runs each time a falling edge of a pulse is detected
  222. void onPulse()                  
  223. {
  224.   lastTime = pulseTime;                                                                                                  //used to measure time between pulses.
  225.   pulseTime = millis();
  226.   pulseCount++;                                                                                                          //pulseCounter              
  227. emontx.flow = float((3600000 / (pulseTime - lastTime)));                                                      //Calculate flow
  228. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement