Advertisement
Guest User

Untitled

a guest
Apr 9th, 2019
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.33 KB | None | 0 0
  1. #include <SPI.h>
  2. #include <Ethernet.h> // Arduino Uno Ethernet Shield "W5100"
  3. //#include <UIPEthernet.h> // Arduino Nano Ethernet Shield "ENC28j60"
  4. #include <PubSubClient.h>
  5.  
  6. #define vers "Water Meter V1.0"
  7. #define debug true
  8. #define dhcp true
  9. byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xE1};
  10. //IPAddress ip(192, 168, 1, 200);
  11. //IPAddress gw(192, 168, 1, 1);
  12. //IPAddress mask(255, 255, 255, 0);
  13.  
  14. // MQTT Network Settings
  15. const char* mqtt_server = "192.168.1.10";
  16. const int mqtt_port = 1883;
  17. const char* mqtt_id = "ardnano_water_meter";
  18. const char* mqtt_topic_rx = "control/water_meter";
  19. const char* mqtt_topic_tx = "sensors/water_meter";
  20. const char* mqtt_topic_lwt = "status/water_meter";
  21. const char* mqtt_user = "super_secret_username";
  22. const char* mqtt_pass = "super_secret_password";
  23.  
  24. String rx;
  25. String tx_msg;
  26. int rxLength = 0;
  27. byte sensorInterrupt = 0;
  28. float calibrationFactor = 4.8; // F = 4.8 * Q (L / Min) (for my sensor, FL-808 model, 1" hall effect, 1-60 L/Min)
  29. volatile byte pulseCount;
  30. float flowRate;
  31. float pressure;
  32. unsigned int flowMilliLitres;
  33. unsigned long totalMilliLitres;
  34. unsigned long oldTime;
  35.  
  36. EthernetClient client;
  37. PubSubClient mqttClient(mqtt_server, mqtt_port, client);
  38.  
  39. void setup()
  40. {
  41. pinMode(2, INPUT); // water flow hall effect pulse
  42. pinMode(A0, INPUT); // pressure sensor
  43. digitalWrite(2, HIGH);
  44. Ethernet.begin(mac); // DHCP
  45. //Ethernet.begin(mac, ip, gw, mask); // Static IP
  46. #if debug
  47. Serial.begin(115200);
  48. while (!Serial) {
  49. ;
  50. }
  51. #endif
  52.  
  53. #if debug
  54. Serial.print("Version: ");
  55. Serial.println(vers);
  56. Serial.print("My IP address: ");
  57. Serial.println(Ethernet.localIP());
  58. #endif
  59.  
  60. reconnect();
  61.  
  62. pulseCount = 0;
  63. flowRate = 0.0;
  64. flowMilliLitres = 0.0;
  65. totalMilliLitres = 0.0;
  66. oldTime = 0;
  67. pressure = 0.0;
  68. attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
  69. }
  70.  
  71. void loop()
  72. {
  73. if ((millis() - oldTime) > 1000)
  74. {
  75. detachInterrupt(sensorInterrupt);
  76. if (!mqttClient.loop() && mqttClient.state() != 0) {
  77. reconnect();
  78. }
  79. flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor; // Flow rate in liters per minute
  80. pressure = analogRead(A0);
  81. double volts = pressure * (5.0 / 1023.0);
  82. oldTime = millis();
  83. flowMilliLitres = (flowRate / 60) * 1000;
  84. totalMilliLitres += flowMilliLitres;
  85. tx_msg = "{\"gpm\":";
  86. tx_msg.concat(int(flowRate) * 0.2641721); // convert liters per minute to gallons per minute
  87. tx_msg.concat(",\"lpm\":");
  88. tx_msg.concat(int(flowRate)); // liters per minute
  89. tx_msg.concat(",\"gal\":");
  90. tx_msg.concat(totalMilliLitres * 0.0002641721); // convert milliliters to gallons usage
  91. tx_msg.concat(",\"mil\":");
  92. tx_msg.concat(totalMilliLitres); // milliliters usage since last reset/clear
  93. tx_msg.concat(",\"psi\":");
  94. tx_msg.concat((((pressure - 103) / 819) * 100)); // actual psi reading, calibrate the voltage to match sensor range (my sensor = 0-100 psi, 0.5-4.5v linear scale, 0 psi = 0.5v, 50 psi = 2.5v, 100 psi = 4.5v)
  95. // 103 = 0.5v on the analog pin, 819 = 4.5v (roughly), scale is 0-1023 (10 bit resolution)
  96. tx_msg.concat(",\"volts\":");
  97. tx_msg.concat(volts); // DC voltage of pin A0 (0-5v)
  98. tx_msg.concat("}");
  99. tx_msg.trim();
  100. byte tx_buf[tx_msg.length()+1];
  101. tx_msg.getBytes(tx_buf, tx_msg.length()+1);
  102. if(!mqttClient.publish(mqtt_topic_tx, tx_buf, tx_msg.length())) {
  103. Serial.println("Publish FAILED!");
  104. delay(500);
  105. reconnect();
  106. }
  107. #if debug
  108. Serial.print("TX: ");
  109. Serial.print((char *)tx_buf);
  110. Serial.print(" [");
  111. Serial.print(tx_msg.length()+1);
  112. Serial.println("]");
  113. #endif
  114.  
  115. pulseCount = 0;
  116. attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
  117. }
  118. }
  119.  
  120. void pulseCounter()
  121. {
  122. pulseCount++;
  123. }
  124.  
  125. // MQTT reconnection function
  126. void reconnect() {
  127. while (mqttClient.state() != 0) {
  128. #if debug
  129. Serial.println("Attempting MQTT connection...");
  130. #endif
  131. //mqttClient.setServer(mqtt_server, mqtt_port);
  132. mqttClient.setCallback(callback);
  133. if (mqttClient.connect(mqtt_id, mqtt_user, mqtt_pass, mqtt_topic_lwt, 0, 1, "offline")) {
  134. mqttClient.subscribe(mqtt_topic_rx);
  135. //mqttClient.subscribe(mqtt_topic_rx2);
  136. mqttClient.publish(mqtt_topic_lwt, "online", true);
  137. }
  138. else {
  139. #if debug
  140. Serial.print("failed, rc= ");
  141. Serial.println(mqttClient.state());
  142. Serial.println("try again in 5 seconds");
  143. #endif
  144. delay(5000);
  145. }
  146. }
  147. }
  148.  
  149. void(* resetFunc) (void) = 0;
  150.  
  151. // MQTT received data callback function
  152. void callback(char* topic, byte* payload, unsigned int length) {
  153. #if debug
  154. Serial.print("RX: ");
  155. #endif
  156. rx = String((char *)payload);
  157. rxLength = rx.length();
  158. for (int i = length; i <= rxLength; i++) {
  159. rx.setCharAt(i, ' ');
  160. }
  161. rx.trim();
  162. #if debug
  163. Serial.println(rx);
  164. //Serial.print(" - ");
  165. //Serial.println((char *)payload);
  166. //rx = String((char *)payload);
  167. //Serial.println(rx);
  168. //Serial.println();
  169. #endif
  170. if(rx == "clear") {
  171. totalMilliLitres = 0.0;
  172. #if debug
  173. Serial.println("CLEAR REQUESTED!"); // an automation publishes to this topic nightly at midnight to reset daily usage
  174. #endif
  175. }
  176. if (rx == "reboot") {
  177. #if debug
  178. Serial.println("REBOOT REQUESTED!"); // if the clear command (above) fails, an automation resets the device to force a clear
  179. #endif
  180. resetFunc();
  181. }
  182. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement