使用樂為物聯GPRS模塊搭建遠程環境監測系統

本帖最後由 數字 於 2013-3-28 11:06 編輯 使用樂為物聯GPRS模塊搭建遠程環境監測系統1 目的 試驗基於Arduino硬體平台,採用樂為物聯GPRS模塊監控不具備有線網路接入條件的山區環境,可以用於農業、林業數據採集。2 實驗條件 硬體設備列表:1) Arduino Nano約50RMB,

2) 樂為物聯GPRS模塊為測試版(必要的GPRS資費SIM卡),3) DSM501A模塊約30RMB,顆粒物感測器,目的在於監測花粉濃度,PWM輸出,4) HTF3223LF模塊23RMB,用於監測空氣溫濕度,NTC溫度輸出(試驗採用10k上拉),濕度頻率輸出,5) BH1750模塊13RMB,監測光照強度,I2C輸出,6) 降雨感測器,大約10元,用於監測降雨情況,邏輯電平輸出,7) LCD1602,大約10元, 數據系統平台:樂聯網http://www.lewei50.com3 硬體連線1) 樂為物聯GPRS模塊為6腳,本次只用1、2、3、4腳,1腳為Vcc接電源5-12伏輸入,2腳為接地,3腳為TTL電平TX,4腳為TTL電平RX。

2) DSM501A,本次只使用2、3、5腳,2腳為Vout 2 output (PWM)接Arduino D8, 3腳為Vcc接電源5伏,5腳為GND接地。

3) HTF3223LF模塊,使用1、2、3、4腳,1腳為NTC輸出端,接Arduino A0,2腳為GND接地,3腳為濕度頻率輸出,接Arduino D2,4腳為Vcc接電源5伏。

4) BH1750模塊為5腳,I2C介面,本次不用接ADD腳,VCC接電源5伏,SCL接Arduino A5,SDA接Arduino A4,GND接地。

5) 降雨感測器為4腳,邏輯輸出接Arduino D10,VCC接電源5伏,GND接地。

6) LCD1602,本次採用4數據線連接法,RS 接Arduino D12,Enable接Arduino D11, LCD D4接Arduino D4,LCD D5接Arduino D5,LCD D6接Arduino D6,LCD D7接Arduino D7,LCD R/W 接地,LCD V0接10k可調電阻,LCD使用5伏供電,背景燈可設開關。4 程序ARDUINO 代碼複製列印

  1. #include<string.h>
  2. //#include <SoftwareSerial.h>
  3. #include <Wire.h>
  4. #include <math.h>
  5. //#include <MsTimer2.h>
  6. #include <LiquidCrystal.h>
  7. LiquidCrystal lcd(12, 11, 4, 5, 6, 7);
  8. //* LCD RS pin to digital pin 12
  9. // * LCD Enable pin to digital pin 11
  10. // * LCD D4 pin to digital pin 4
  11. // * LCD D5 pin to digital pin 5
  12. // * LCD D6 pin to digital pin 6
  13. // * LCD D7 pin to digital pin 7
  14. // * LCD R/W pin to ground
  15. // * 10K resistor:
  16. // * ends to +5V and ground
  17. // * wiper to LCD VO pin (pin 3)
  18. //SoftwareSerial mySerial(9, 10); // RX, TX
  19. //String inputString = "";
  20. const int buttonPin = 10; //the number of the jiangyu input pin
  21. int buttonState = 0; // variable for reading the jiangyu status
  22. int Rain = 1;
  23. int BH1750address = 0x23;//BH1750 I2C地址
  24. byte buff[2];
  25. float BH = 0;
  26. const int analogInPin = A0;// Analog input pin that the potentiometer is attached to//*//Freqinput pin D2
  27. int pin = 8;//DSM501A input D8
  28. float wuchaxiuzheng = 0;
  29. unsigned long duration;
  30. unsigned long starttime;
  31. unsigned long endtime;
  32. unsigned long sampletime_ms = 30000;
  33. unsigned long lowpulseoccupancy = 0;
  34. float ratio = 0;
  35. float concentration = 0;
  36. float tempconcentration=0;
  37. int sensorValue = 0; // value read from the NTC
  38. int TEMPRATURE=0;
  39. int i=0;
  40. float R_Data=0;
  41. float U_data [111]={4.67,4.65,4.64,4.62,4.60,4.57,4.55,4.53,4.51,4.48,4.46,4.43,4.40,4.38,4.35,4.32,4.28,4.25,4.22,4.19,4.15,4.11,4.08,4.04,4.00,3.96,3.92,3.88,3.83,3.79,3.75,3.70,3.65,3.61,3.56,3.51,3.47,3.42,3.37,3.32,3.27,3.22,3.17,3.11,3.06,3.01,2.96,2.91,2.86,2.81,2.75,2.70,2.65,2.60,2.54,2.50,2.44,2.39,2.34,2.29,2.24,2.20,2.15,2.10,2.06,2.01,1.96,1.92,1.87,1.83,1.78,1.74,1.70,1.66,1.62,1.58,1.54,1.50,1.47,1.43,1.39,1.36,1.32,1.29,1.25,1.22,1.19,1.15,1.12,1.09,1.06,1.04,1.01,0.98,0.96,0.93,0.91,0.88,0.86,0.84,0.81,0.79,0.77,0.75,0.73,0.713,0.69,0.67,0.66,0.64,0.62};//溫度對應NTC電錶格
  42. int divider[6] = {0, 1, 8, 64, 256, 1024};//read RH use interrupt get F
  43. int prescaler = 5;
  44. double count = 0;
  45. double middle = 0;
  46. char x = 0;
  47. int Fout=0;
  48. int RH=0;
  49. byte du[8]={
  50. B00111,
  51. B00101,
  52. B00111,
  53. B00000,
  54. B00000,
  55. B00000,
  56. B00000,
  57. };//define 1602 char
  58. ISR(TIMER1_OVF_vect)
  59. {
  60. if (prescaler < 4)
  61. {
  62. prescaler++;
  63. }
  64. }
  65. void interrupt()
  66. {
  67. if (!x)
  68. {
  69. count = TCNT1;
  70. TCNT1 = 0x000;
  71. TCCR1B = prescaler;
  72. attachInterrupt(0, interrupt, FALLING);
  73. }
  74. else
  75. {
  76. middle = TCNT1;
  77. attachInterrupt(0, interrupt, RISING);
  78. }
  79. x = ~x;
  80. }
  81. void setup()
  82. {
  83. Wire.begin();
  84. Serial.begin(9600);
  85. //mySerial.begin(9600);
  86. //inputString.reserve(200);
  87. //MsTimer2::set(2000, timer); //定時器設置,每2秒觸發一次timer函數操作
  88. //MsTimer2::start();
  89. //pinMode(buttonPin, INPUT);
  90. analogReference(DEFAULT);//INTERNAL
  91. lcd.createChar(1,du);
  92. lcd.begin(16, 2);
  93. lcd.clear();
  94. // lcd.setCursor(0, 0);
  95. // lcd.print("PM2.5=");
  96. // lcd.setCursor(0, 1);
  97. // lcd.print("T= ");
  98. // //lcd.write(1);
  99. // lcd.print(" RH=%");
  100. // Serial.begin(9600);
  101. pinMode(buttonPin, INPUT);
  102. pinMode(8,INPUT);
  103. TIMSK1 = 0x01;
  104. TCCR1A = 0x00;
  105. attachInterrupt(0, interrupt, RISING);
  106. starttime = millis();
  107. }
  108. void loop()
  109. {
  110. duration = pulseIn(pin, LOW);
  111. lowpulseoccupancy += duration;
  112. endtime = millis();
  113. if ((endtime-starttime) > sampletime_ms)
  114. {
  115. ratio = (lowpulseoccupancy-endtime+starttime + sampletime_ms)/(sampletime_ms*10.0);// Integer percentage 0=>100
  116. concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve
  117. //Serial.print(lowpulseoccupancy);
  118. // Serial.print(",");
  119. //Serial.print(ratio);
  120. // Serial.print("DSM501A:");
  121. // Serial.println(concentration);
  122. // Serial.print(";");
  123. //Serial.println(endtime-starttime);
  124. wuchaxiuzheng = (endtime-starttime-30000)/30000.0;
  125. //Serial.println(wuchaxiuzheng);
  126. concentration = (1.00-wuchaxiuzheng)*concentration;
  127. //Serial.println(concentration);
  128. lcd.setCursor(6, 0);
  129. lcd.print(concentration);
  130. lcd.print("pcs/0.01cf");
  131. // lowpulseoccupancy = 0;
  132. // starttime = millis();
  133. }
  134. sensorValue = analogRead(analogInPin); // read the analog in value:
  135. delay(10);
  136. R_Data=sensorValue*5/1024.0;
  137. //Serial.print("R_Data = " );
  138. //Serial.print(R_Data);
  139. for(i=0;i<111;i++){
  140. if(R_Data>4.67)
  141. {
  142. TEMPRATURE =-30;//對應-30℃
  143. }
  144. else if(R_Data<0.62)
  145. {
  146. TEMPRATURE=80; //對應80℃
  147. }
  148. else if(R_Data<U_data[i]&&R_Data>U_data[i+1])
  149. {
  150. TEMPRATURE=int(i-30-3);
  151. }
  152. }
  153. // Serial.print("T:" );
  154. // Serial.print(TEMPRATURE);
  155. // Serial.print(";" );
  156. delay(10);
  157. lcd.setCursor(0, 0);
  158. lcd.print("PM2.5=");
  159. lcd.setCursor(0, 1);
  160. lcd.print("T= ");
  161. //lcd.write(1);
  162. lcd.print(" RH=%");
  163. // lcd.setCursor(0, 1);
  164. // lcd.print("T= ");
  165. // //lcd.write(1);
  166. // lcd.print(" RH=%");
  167. lcd.setCursor(2, 1);
  168. lcd.print(TEMPRATURE);
  169. lcd.write(1);
  170. lcd.print("C");
  171. Fout=(16000000.0 / divider[prescaler] / count);
  172. //Serial.print("Vsensor=" );
  173. //Serial.print(sensorValue);
  174. //Serial.print(", " );
  175. //Serial.print("Freq=");
  176. //Serial.print(Fout);
  177. // Serial.print(" ");
  178. // Serial.print(int(divider));
  179. // Serial.print(" ");
  180. // Serial.print(prescaler);
  181. // Serial.print(" ");
  182. // Serial.println(count);
  183. if (Fout<8115)
  184. {
  185. RH=100;
  186. // Serial.print("RH:100");
  187. // Serial.println(";");
  188. lcd.setCursor(13, 1);
  189. lcd.print("H.");
  190. }
  191. else if(Fout>9595)
  192. {
  193. RH=0;
  194. // Serial.print("RH:0");
  195. // Serial.println(";");
  196. lcd.setCursor(13, 1);
  197. lcd.print("L.");
  198. }
  199. else
  200. {
  201. RH=(9595-Fout)/14.8;
  202. // Serial.print("RH:");
  203. // Serial.print(RH);
  204. // Serial.println(";");
  205. lcd.setCursor(13, 1);
  206. lcd.print(RH);
  207. }
  208. if (prescaler > 1)
  209. {
  210. prescaler--;
  211. delay(200);
  212. }
  213. //if(flag )//
  214. //{
  215. // Serial.print( BH1750() );
  216. // Serial.println("[lux]");
  217. //
  218. // flag = 0;//歸零,等著定時中斷重新賦值
  219. //}
  220. delay(2000);
  221. if(tempconcentration!=concentration)
  222. {
  223. tempconcentration=concentration;
  224. BH=BH1750();
  225. // read the state of the jiangyu value:
  226. buttonState = digitalRead(buttonPin);
  227. // check if the jiangyu is low.
  228. // if it is, the buttonState is LOW:
  229. if (buttonState == LOW) {
  230. Rain=0;
  231. }
  232. else {
  233. Rain=1;
  234. }
  235. //lewei ouput by computer tools
  236. // Serial.print("D:");
  237. // Serial.print(concentration);
  238. // Serial.print(";");
  239. // Serial.print("T:" );
  240. // Serial.print(TEMPRATURE);
  241. // Serial.print(";" );
  242. // Serial.print("R:");
  243. // Serial.print(RH);
  244. // Serial.print(";" );
  245. // Serial.print("B:" );
  246. // Serial.print(BH);
  247. // Serial.print(";" );
  248. // Serial.print("W:");
  249. // Serial.print(Rain);
  250. // Serial.println(";");
  251. //lewei ouput by GPRS
  252. lcd.setCursor(0, 1);
  253. lcd.print(" ");
  254. lcd.setCursor(0, 1);
  255. lcd.print(BH);
  256. lcd.print("LUX");
  257. //delay(5000);
  258. String tempstring="@uploading(01,D,";
  259. String tempstring1=")";
  260. Serial.print(tempstring);
  261. Serial.print(int(concentration));
  262. Serial.println(tempstring1);
  263. // delay(12000); min transtime
  264. delay(30000);
  265. String tempstring2="@uploading(01,T,";
  266. String tempstring3=")";
  267. Serial.print(tempstring2);
  268. Serial.print(TEMPRATURE);
  269. Serial.println(tempstring3);
  270. // delay(12000);
  271. delay(30000);
  272. String tempstring4="@uploading(01,R,";
  273. String tempstring5=")";
  274. Serial.print(tempstring4);
  275. Serial.print(RH);
  276. Serial.println(tempstring5);
  277. // delay(15000);
  278. delay(30000);
  279. String tempstring6="@uploading(01,B,";
  280. String tempstring7=")";
  281. Serial.print(tempstring6);
  282. Serial.print(int(BH));
  283. Serial.println(tempstring7);
  284. // delay(2000);
  285. delay(30000);
  286. String tempstring8="@uploading(01,W,";
  287. String tempstring9=")";
  288. Serial.print(tempstring8);
  289. Serial.print(Rain);
  290. Serial.println(tempstring9);
  291. delay(30000);
  292. lowpulseoccupancy = 0;
  293. starttime = millis();
  294. }
  295. }
  296. double BH1750() //BH1750設備操作
  297. {
  298. int i=0;
  299. doubleval=0;
  300. //開始I2C讀寫操作
  301. Wire.beginTransmission(BH1750address);
  302. Wire.write(0x10);//1lx reolution 120ms//發送命令
  303. Wire.endTransmission();
  304. delay(200);
  305. //讀取數據
  306. Wire.beginTransmission(BH1750address);
  307. Wire.requestFrom(BH1750address, 2);
  308. while(Wire.available()) //
  309. {
  310. buff[i] = Wire.read();// receive one byte
  311. i++;
  312. }
  313. Wire.endTransmission();
  314. if(2==i)
  315. {
  316. val=((buff[0]<<8)|buff[1])/1.2;
  317. }
  318. if(val<0) val=56134+val;
  319. return val;
  320. }

5 總結 樂為gprs模塊使用非常簡單,但是要注意供電問題,我用5v1.5a開關電源有時會出現初始化無法通過的問題,後來改用12v1.5a開關電源一切正常。樂為gprs命令非常簡單,通常可以先用串口連接PC設置key,使用串口工具發送@key=你的key值,模塊返回key=你的key值,然後就可以當作黑盒子使用了。因為數據操作通常只使用上傳命令@uploading(a,b,c),a為網關標識(2位數字),b 設備標識(1-8位字元),c 為上傳數值(如果是負數,請在數值前加『-』號),簡單情況下根本不需要考慮交互反饋的判斷條件,只需要等待適當的延時就可以了。希望今後可以考慮簡訊控制的輸出協議,便於同時使用簡訊操作Arduino,也希望能將GPRS模塊協議與樂聯網串口工具協議保持一致,便於程序調試的兼容。試驗結果可以訪問http://open.lewei50.com/home/gatewaystatus/361初學Arduino,程序中的問題還請大家批評指正。上幾張照片看看

2013-3-28 11:05 上傳下載附件 (53.49 KB)


推薦閱讀:

建設霧霾監測系統實現霧霾實時監測隨筆
環保部通報2015年典型環境違法案件
DR-801D橋樑採樣器
水質自動採樣器-自密封作用到底有多重要?
水質自動採樣器簡介

TAG:環境 | 環境監測 | 系統 | 模塊 | 監測 | GPRS |