Advertisement
seston

easyiot bmp180 v0.2

Jan 27th, 2016
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.66 KB | None | 0 0
  1. /*
  2. V1.0 - first version
  3.  
  4. Created by Igor Jarc <igor.jarc1@gmail.com>
  5. See http://iot-playground.com for details
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. version 2 as published by the Free Software Foundation.
  10. */
  11. #include <Esp8266EasyIoT.h>
  12. #include <SFE_BMP180.h>
  13. #include <Wire.h>
  14. #ifndef HAVE_HWSERIAL1
  15. #include "SoftwareSerial.h"
  16. SoftwareSerial Serial1(10, 11); // RX, TX
  17. #endif
  18.  
  19.  
  20. #define ALTITUDE 13.0 // Altitude of my home
  21. #define ESP_RESET_PIN 12
  22.  
  23. #define MILS_IN_MIN 60000
  24.  
  25. #define CHILD_ID_TEMP 0
  26. #define CHILD_ID_BARO 1
  27.  
  28.  
  29. int minuteCount = 0;
  30. double pressureSamples[9][6];
  31. double pressureAvg[9];
  32. double dP_dt;
  33.  
  34. const char *weather[] = {
  35. "stable","sunny","cloudy","unstable","thunderstorm","unknown"};
  36.  
  37. int forecast = 5;
  38.  
  39. unsigned long startTime;
  40.  
  41. SFE_BMP180 bmp180;
  42. Esp8266EasyIoT esp;
  43.  
  44.  
  45. Esp8266EasyIoTMsg msgTemp(CHILD_ID_TEMP, V_TEMP);
  46. Esp8266EasyIoTMsg msgPress(CHILD_ID_BARO, V_PRESSURE);
  47. Esp8266EasyIoTMsg msgForec(CHILD_ID_BARO, V_FORECAST);
  48.  
  49. void setup()
  50. {
  51. Serial1.begin(9600); // ESP
  52. Serial.begin(115200); // debug
  53.  
  54. if (bmp180.begin())
  55. Serial.println("BMP180 init success");
  56. else
  57. {
  58. // Oops, something went wrong, this is usually a connection problem,
  59. // see the comments at the top of this sketch for the proper connections.
  60.  
  61. Serial.println("BMP180 init fail\n\n");
  62. while(1); // Pause forever.
  63. }
  64.  
  65. startTime = -1;
  66.  
  67. esp.begin(NULL, ESP_RESET_PIN, &Serial1, &Serial);
  68.  
  69. esp.present(CHILD_ID_TEMP, S_TEMP);
  70. esp.present(CHILD_ID_BARO, S_BARO);
  71. }
  72.  
  73.  
  74. void loop()
  75. {
  76.  
  77. for(int i =0; i<10;i++)
  78. {
  79. if (esp.process())
  80. break;
  81. }
  82.  
  83.  
  84. if (IsTimeout())
  85. {
  86. char status;
  87. double T,P,p0,a;
  88.  
  89. // Loop here getting pressure readings every 60 seconds.
  90.  
  91. // If you want sea-level-compensated pressure, as used in weather reports,
  92. // you will need to know the altitude at which your measurements are taken.
  93. // We're using a constant called ALTITUDE in this sketch:
  94.  
  95. // If you want to measure altitude, and not pressure, you will instead need
  96. // to provide a known baseline pressure. This is shown at the end of the sketch.
  97.  
  98. // You must first get a temperature measurement to perform a pressure reading.
  99.  
  100. // Start a temperature measurement:
  101. // If request is successful, the number of ms to wait is returned.
  102. // If request is unsuccessful, 0 is returned.
  103.  
  104. status = bmp180.startTemperature();
  105. if (status != 0)
  106. {
  107. // Wait for the measurement to complete:
  108. delay(status);
  109.  
  110. // Retrieve the completed temperature measurement:
  111. // Note that the measurement is stored in the variable T.
  112. // Function returns 1 if successful, 0 if failure.
  113.  
  114. status = bmp180.getTemperature(T);
  115. if (status != 0)
  116. {
  117. // Print out the measurement:
  118. Serial.print("temperature: ");
  119. Serial.print(T,2);
  120. Serial.print(" deg C, ");
  121. //Serial.print((9.0/5.0)*T+32.0,2);
  122. //Serial.println(" deg F");
  123.  
  124.  
  125. static int lastSendTempInt;
  126. int temp = round(T *10);
  127.  
  128. if (temp != lastSendTempInt)
  129. {
  130. lastSendTempInt = temp;
  131. esp.send(msgTemp.set((float)T, 1));
  132. }
  133.  
  134. // Start a pressure measurement:
  135. // The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
  136. // If request is successful, the number of ms to wait is returned.
  137. // If request is unsuccessful, 0 is returned.
  138.  
  139. status = bmp180.startPressure(3);
  140. if (status != 0)
  141. {
  142. // Wait for the measurement to complete:
  143. delay(status);
  144.  
  145. // Retrieve the completed pressure measurement:
  146. // Note that the measurement is stored in the variable P.
  147. // Note also that the function requires the previous temperature measurement (T).
  148. // (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
  149. // Function returns 1 if successful, 0 if failure.
  150.  
  151. status = bmp180.getPressure(P,T);
  152. if (status != 0)
  153. {
  154. // The pressure sensor returns abolute pressure, which varies with altitude.
  155. // To remove the effects of altitude, use the sealevel function and your current altitude.
  156. // This number is commonly used in weather reports.
  157. // Parameters: P = absolute pressure in mb, ALTITUDE = current altitude in m.
  158. // Result: p0 = sea-level compensated pressure in mb
  159.  
  160. p0 = bmp180.sealevel(P,ALTITUDE); // we're at 1655 meters (Boulder, CO)
  161. Serial.print(F("relative (sea-level) pressure: "));
  162. Serial.print(p0,2);
  163. Serial.print(" mb, ");
  164. Serial.print(p0*0.0295333727,2);
  165. Serial.println(" inHg");
  166.  
  167.  
  168. static int lastSendPresInt;
  169. int pres = round(p0 *10);
  170.  
  171. if (pres != lastSendPresInt)
  172. {
  173. lastSendPresInt = pres;
  174. esp.send(msgPress.set((float)p0, 1));
  175. }
  176.  
  177. forecast = calculateForecast(p0);
  178. static int lastSendForeInt = -1;
  179.  
  180.  
  181. if (forecast != lastSendForeInt)
  182. {
  183. lastSendForeInt = forecast;
  184. esp.send(msgForec.set(weather[forecast]));
  185. }
  186. }
  187. else Serial.println(F("error retrieving pressure measurement\n"));
  188. }
  189. else Serial.println(F("error starting pressure measurement\n"));
  190. }
  191. else Serial.println(F("error retrieving temperature measurement\n"));
  192. }
  193. else Serial.println(F("error starting temperature measurement\n"));
  194.  
  195. startTime = millis();
  196. }
  197.  
  198. //delay(5000); // Pause for 5 seconds.
  199. }
  200.  
  201. boolean IsTimeout()
  202. {
  203. unsigned long now = millis();
  204. if (startTime <= now)
  205. {
  206. if ( (unsigned long)(now - startTime ) < MILS_IN_MIN )
  207. return false;
  208. }
  209. else
  210. {
  211. if ( (unsigned long)(startTime - now) < MILS_IN_MIN )
  212. return false;
  213. }
  214.  
  215. return true;
  216. }
  217.  
  218.  
  219. int calculateForecast(double pressure) {
  220. //From 0 to 5 min.
  221. if (minuteCount <= 5){
  222. pressureSamples[0][minuteCount] = pressure;
  223. }
  224. //From 30 to 35 min.
  225. else if ((minuteCount >= 30) && (minuteCount <= 35)){
  226. pressureSamples[1][minuteCount - 30] = pressure;
  227. }
  228. //From 60 to 65 min.
  229. else if ((minuteCount >= 60) && (minuteCount <= 65)){
  230. pressureSamples[2][minuteCount - 60] = pressure;
  231. }
  232. //From 90 to 95 min.
  233. else if ((minuteCount >= 90) && (minuteCount <= 95)){
  234. pressureSamples[3][minuteCount - 90] = pressure;
  235. }
  236. //From 120 to 125 min.
  237. else if ((minuteCount >= 120) && (minuteCount <= 125)){
  238. pressureSamples[4][minuteCount - 120] = pressure;
  239. }
  240. //From 150 to 155 min.
  241. else if ((minuteCount >= 150) && (minuteCount <= 155)){
  242. pressureSamples[5][minuteCount - 150] = pressure;
  243. }
  244. //From 180 to 185 min.
  245. else if ((minuteCount >= 180) && (minuteCount <= 185)){
  246. pressureSamples[6][minuteCount - 180] = pressure;
  247. }
  248. //From 210 to 215 min.
  249. else if ((minuteCount >= 210) && (minuteCount <= 215)){
  250. pressureSamples[7][minuteCount - 210] = pressure;
  251. }
  252. //From 240 to 245 min.
  253. else if ((minuteCount >= 240) && (minuteCount <= 245)){
  254. pressureSamples[8][minuteCount - 240] = pressure;
  255. }
  256.  
  257.  
  258. if (minuteCount == 5) {
  259. // Avg pressure in first 5 min, value averaged from 0 to 5 min.
  260. pressureAvg[0] = ((pressureSamples[0][0] + pressureSamples[0][1]
  261. + pressureSamples[0][2] + pressureSamples[0][3]
  262. + pressureSamples[0][4] + pressureSamples[0][5]) / 6);
  263. }
  264. else if (minuteCount == 35) {
  265. // Avg pressure in 30 min, value averaged from 0 to 5 min.
  266. pressureAvg[1] = ((pressureSamples[1][0] + pressureSamples[1][1]
  267. + pressureSamples[1][2] + pressureSamples[1][3]
  268. + pressureSamples[1][4] + pressureSamples[1][5]) / 6);
  269. float change = (pressureAvg[1] - pressureAvg[0]);
  270. dP_dt = change / 5;
  271. }
  272. else if (minuteCount == 65) {
  273. // Avg pressure at end of the hour, value averaged from 0 to 5 min.
  274. pressureAvg[2] = ((pressureSamples[2][0] + pressureSamples[2][1]
  275. + pressureSamples[2][2] + pressureSamples[2][3]
  276. + pressureSamples[2][4] + pressureSamples[2][5]) / 6);
  277. float change = (pressureAvg[2] - pressureAvg[0]);
  278. dP_dt = change / 10;
  279. }
  280. else if (minuteCount == 95) {
  281. // Avg pressure at end of the hour, value averaged from 0 to 5 min.
  282. pressureAvg[3] = ((pressureSamples[3][0] + pressureSamples[3][1]
  283. + pressureSamples[3][2] + pressureSamples[3][3]
  284. + pressureSamples[3][4] + pressureSamples[3][5]) / 6);
  285. float change = (pressureAvg[3] - pressureAvg[0]);
  286. dP_dt = change / 15;
  287. }
  288. else if (minuteCount == 125) {
  289. // Avg pressure at end of the hour, value averaged from 0 to 5 min.
  290. pressureAvg[4] = ((pressureSamples[4][0] + pressureSamples[4][1]
  291. + pressureSamples[4][2] + pressureSamples[4][3]
  292. + pressureSamples[4][4] + pressureSamples[4][5]) / 6);
  293. float change = (pressureAvg[4] - pressureAvg[0]);
  294. dP_dt = change / 20;
  295. }
  296. else if (minuteCount == 155) {
  297. // Avg pressure at end of the hour, value averaged from 0 to 5 min.
  298. pressureAvg[5] = ((pressureSamples[5][0] + pressureSamples[5][1]
  299. + pressureSamples[5][2] + pressureSamples[5][3]
  300. + pressureSamples[5][4] + pressureSamples[5][5]) / 6);
  301. float change = (pressureAvg[5] - pressureAvg[0]);
  302. dP_dt = change / 25;
  303. }
  304. else if (minuteCount == 185) {
  305. // Avg pressure at end of the hour, value averaged from 0 to 5 min.
  306. pressureAvg[6] = ((pressureSamples[6][0] + pressureSamples[6][1]
  307. + pressureSamples[6][2] + pressureSamples[6][3]
  308. + pressureSamples[6][4] + pressureSamples[6][5]) / 6);
  309. float change = (pressureAvg[6] - pressureAvg[0]);
  310. dP_dt = change / 30;
  311. }
  312. else if (minuteCount == 215) {
  313. // Avg pressure at end of the hour, value averaged from 0 to 5 min.
  314. pressureAvg[7] = ((pressureSamples[7][0] + pressureSamples[7][1]
  315. + pressureSamples[7][2] + pressureSamples[7][3]
  316. + pressureSamples[7][4] + pressureSamples[7][5]) / 6);
  317. float change = (pressureAvg[7] - pressureAvg[0]);
  318. dP_dt = change / 35;
  319. }
  320. else if (minuteCount == 245) {
  321. // Avg pressure at end of the hour, value averaged from 0 to 5 min.
  322. pressureAvg[8] = ((pressureSamples[8][0] + pressureSamples[8][1]
  323. + pressureSamples[8][2] + pressureSamples[8][3]
  324. + pressureSamples[8][4] + pressureSamples[8][5]) / 6);
  325. float change = (pressureAvg[8] - pressureAvg[0]);
  326. dP_dt = change / 40; // note this is for t = 4 hour
  327.  
  328. minuteCount -= 30;
  329. pressureAvg[0] = pressureAvg[1];
  330. pressureAvg[1] = pressureAvg[2];
  331. pressureAvg[2] = pressureAvg[3];
  332. pressureAvg[3] = pressureAvg[4];
  333. pressureAvg[4] = pressureAvg[5];
  334. pressureAvg[5] = pressureAvg[6];
  335. pressureAvg[6] = pressureAvg[7];
  336. pressureAvg[7] = pressureAvg[8];
  337. }
  338.  
  339. minuteCount++;
  340.  
  341. if (minuteCount < 36) //if time is less than 35 min
  342. return 5; // Unknown, more time needed
  343. else if (dP_dt < (-0.25))
  344. return 4; // Quickly falling LP, Thunderstorm, not stable
  345. else if (dP_dt > 0.25)
  346. return 3; // Quickly rising HP, not stable weather
  347. else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
  348. return 2; // Slowly falling Low Pressure System, stable rainy weather
  349. else if ((dP_dt > 0.05) && (dP_dt < 0.25))
  350. return 1; // Slowly rising HP stable good weather
  351. else if ((dP_dt > (-0.05)) && (dP_dt < 0.05))
  352. return 0; // Stable weather
  353. else
  354. return 5; // Unknown
  355. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement