【爱好者】Arduino+GPRS 的环境监控方案




本实采用的硬件,除了一个串口模块以外(约200元),其他均可以从taobo上面找到标准产品

发帖子不是为了买模块,如果不愿意用gprs的可以用w5100(以太网)替代,见帖子  http://www.lewei50.com/dev/doc/94  

比较有意思的地方:可以通过手机app,微信随时掌控监测数据的情况。

------------------------------------------------------------------------万恶的分界线------------------------------------------------------------------------------------
使用乐为物联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.com

3 硬件连线

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伏供电,背景灯可设开关。

 

XML/HTML代码
  1. #include<string.h>  
  2.    
  3. //#include <SoftwareSerial.h>  
  4.    
  5. #include <Wire.h>  
  6.    
  7. #include <math.h>  
  8.    
  9. //#include <MsTimer2.h>  
  10.    
  11. #include <LiquidCrystal.h>  
  12.    
  13. LiquidCrystal lcd(12, 11, 4, 5, 6, 7);  
  14.    
  15. //* LCD RS pin to digital pin 12  
  16.    
  17. // * LCD Enable pin to digital pin 11  
  18.    
  19. // * LCD D4 pin to digital pin 4  
  20.    
  21. // * LCD D5 pin to digital pin 5  
  22.    
  23. // * LCD D6 pin to digital pin 6  
  24.    
  25. // * LCD D7 pin to digital pin 7  
  26.    
  27. // * LCD R/W pin to ground  
  28.    
  29. // * 10K resistor:  
  30.    
  31. // * ends to +5V and ground  
  32.    
  33. // * wiper to LCD VO pin (pin 3)  
  34.    
  35. //SoftwareSerial mySerial(9, 10); // RX, TX  
  36.    
  37. //String inputString = "";  
  38.    
  39. const int buttonPin = 10;     //the number of the jiangyu input pin  
  40.    
  41. int buttonState = 0;         // variable for reading the jiangyu status  
  42.    
  43. int Rain = 1;  
  44.    
  45. int BH1750address = 0x23;//BH1750 I2C地址  
  46.    
  47. byte buff[2];  
  48.    
  49. float BH = 0;  
  50.    
  51. const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to//*//Freqinput pin D2  
  52.    
  53. int pin = 8;//DSM501A input D8  
  54.    
  55. float wuchaxiuzheng = 0;  
  56.    
  57. unsigned long duration;  
  58.    
  59. unsigned long starttime;  
  60.    
  61. unsigned long endtime;  
  62.    
  63. unsigned long sampletime_ms = 30000;  
  64.    
  65. unsigned long lowpulseoccupancy = 0;  
  66.    
  67. float ratio = 0;  
  68.    
  69. float concentration = 0;  
  70.    
  71. float tempconcentration=0;  
  72.    
  73. int sensorValue = 0;        // value read from the NTC  
  74.    
  75. int TEMPRATURE=0;  
  76.    
  77. int i=0;  
  78.    
  79. float R_Data=0;  
  80.    
  81. 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电表格  
  82.    
  83. int divider[6] = {0, 1, 8, 64, 256, 1024};//read RH use interrupt get F  
  84.    
  85. int prescaler = 5;  
  86.    
  87. double count = 0;  
  88.    
  89. double middle = 0;  
  90.    
  91. char x = 0;  
  92.    
  93. int Fout=0;  
  94.    
  95. int RH=0;  
  96.    
  97. byte du[8]={  
  98.    
  99. B00111,  
  100.    
  101. B00101,  
  102.    
  103. B00111,  
  104.    
  105. B00000,  
  106.    
  107. B00000,  
  108.    
  109. B00000,  
  110.    
  111. B00000,  
  112.    
  113. };//define 1602 char   
  114. ISR(TIMER1_OVF_vect)  
  115.    
  116. {  
  117.    
  118.     if (prescaler < 4)  
  119.    
  120.     {  
  121.    
  122.         prescaler++;  
  123.    
  124.     }  
  125.    
  126. }  
  127.    
  128. void interrupt()  
  129.    
  130. {  
  131.    
  132.     if (!x)  
  133.    
  134.     {  
  135.    
  136.         count = TCNT1;  
  137.    
  138.         TCNT1 = 0x000;  
  139.    
  140.         TCCR1B = prescaler;  
  141.    
  142.         attachInterrupt(0, interrupt, FALLING);  
  143.    
  144.     }  
  145.    
  146.     else  
  147.    
  148.     {  
  149.    
  150.         middle = TCNT1;  
  151.    
  152.         attachInterrupt(0, interrupt, RISING);  
  153.    
  154.     }  
  155.    
  156.     x = ~x;  
  157.    
  158. }  
  159.    
  160. void setup()  
  161.    
  162. {  
  163.    
  164. Wire.begin();  
  165.    
  166.   Serial.begin(9600);  
  167.    
  168. //  mySerial.begin(9600);  
  169.    
  170. //  inputString.reserve(200);  
  171.    
  172. //  MsTimer2::set(2000, timer); //定时器设置,每2秒触发一次timer函数操作  
  173.    
  174. //  MsTimer2::start();  
  175.    
  176.   //  pinMode(buttonPin, INPUT);    
  177.    
  178.   analogReference(DEFAULT);//INTERNAL  
  179.    
  180.     lcd.createChar(1,du);  
  181.    
  182.     lcd.begin(16, 2);    
  183.    
  184.     lcd.clear();  
  185.    
  186. //    lcd.setCursor(0, 0);  
  187.    
  188. //    lcd.print("PM2.5=");  
  189.    
  190. //    lcd.setCursor(0, 1);  
  191.    
  192. //    lcd.print("T=     ");  
  193.    
  194. //    //lcd.write(1);  
  195.    
  196. //    lcd.print("   RH=  %");  
  197.    
  198. //    Serial.begin(9600);  
  199.    
  200.     pinMode(buttonPin, INPUT);  
  201.    
  202.     pinMode(8,INPUT);  
  203.    
  204.     TIMSK1 = 0x01;  
  205.    
  206.     TCCR1A = 0x00;  
  207.    
  208.     attachInterrupt(0, interrupt, RISING);  
  209.    
  210.     starttime = millis();   
  211. }  
  212.    
  213. void loop()  
  214.    
  215. {  
  216.    
  217.   
  218.   duration = pulseIn(pin, LOW);  
  219.    
  220.   lowpulseoccupancy += duration;  
  221.    
  222.   endtime = millis();  
  223.    
  224.   if ((endtime-starttime) > sampletime_ms)  
  225.    
  226.   {  
  227.    
  228.     ratio = (lowpulseoccupancy-endtime+starttime + sampletime_ms)/(sampletime_ms*10.0);  // Integer percentage 0=>100  
  229.    
  230.     concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve  
  231.    
  232.     //Serial.print(lowpulseoccupancy);  
  233.    
  234.     // Serial.print(",");  
  235.    
  236.     //Serial.print(ratio);  
  237.    
  238. //    Serial.print("DSM501A:");  
  239.    
  240. //    Serial.println(concentration);  
  241.    
  242. //    Serial.print(";");  
  243.    
  244. //Serial.println(endtime-starttime);  
  245.    
  246. wuchaxiuzheng = (endtime-starttime-30000)/30000.0;  
  247.    
  248. //Serial.println(wuchaxiuzheng);  
  249.    
  250. concentration = (1.00-wuchaxiuzheng)*concentration;  
  251.    
  252. //Serial.println(concentration);  
  253.    
  254.   
  255.     lcd.setCursor(6, 0);  
  256.    
  257.     lcd.print(concentration);  
  258.    
  259.     lcd.print("pcs/0.01cf");  
  260.    
  261. //    lowpulseoccupancy = 0;  
  262.    
  263. //    starttime = millis();  
  264.    
  265.   }  
  266.    
  267.   sensorValue = analogRead(analogInPin);    // read the analog in value:   
  268.   delay(10);    
  269.    
  270.   R_Data=sensorValue*5/1024.0;  
  271.    
  272.   //Serial.print("R_Data = " );                         
  273.    
  274.   //Serial.print(R_Data);     
  275.    
  276.   for(i=0;i<111;i++){  
  277.    
  278.      if(R_Data>4.67)  
  279.    
  280.      {  
  281.    
  282.        TEMPRATURE =-30;//对应-30℃  
  283.    
  284.       }  
  285.    
  286.      else if(R_Data<0.62)  
  287.    
  288.      {  
  289.    
  290.       TEMPRATURE=80; //对应80℃        
  291.    
  292.       }  
  293.    
  294.      else if(R_Data<U_data[i]&&R_Data>U_data[i+1])  
  295.    
  296.      {  
  297.    
  298.       TEMPRATURE=int(i-30-3);   
  299.       }  
  300.    
  301. }  
  302.    
  303. //     Serial.print("T:" );  
  304.    
  305. //     Serial.print(TEMPRATURE);  
  306.    
  307. //     Serial.print(";" );  
  308.    
  309.      delay(10);  
  310.    
  311.   
  312.   
  313.     lcd.setCursor(0, 0);  
  314.    
  315.     lcd.print("PM2.5=");  
  316.    
  317.     lcd.setCursor(0, 1);  
  318.    
  319.     lcd.print("T=     ");  
  320.    
  321.     //lcd.write(1);  
  322.    
  323.     lcd.print("   RH=  %");  
  324.    
  325. //     lcd.setCursor(0, 1);  
  326.    
  327. //     lcd.print("T=     ");  
  328.    
  329. //    //lcd.write(1);  
  330.    
  331. //    lcd.print("   RH=  %");  
  332.    
  333.      lcd.setCursor(2, 1);  
  334.    
  335.      lcd.print(TEMPRATURE);  
  336.    
  337.      lcd.write(1);  
  338.    
  339.     lcd.print("C");  
  340.    
  341.      Fout=(16000000.0 / divider[prescaler] / count);    
  342.    
  343.      //Serial.print("Vsensor=" );                         
  344.    
  345.      //Serial.print(sensorValue);        
  346.    
  347.      //Serial.print(", " );   
  348.      //Serial.print("Freq=");  
  349.    
  350.      //Serial.print(Fout);  
  351.    
  352. //    Serial.print("   ");  
  353.    
  354. //    Serial.print(int(divider));  
  355.    
  356. //    Serial.print("   ");  
  357.    
  358. //    Serial.print(prescaler);  
  359.    
  360. //    Serial.print("   ");  
  361.    
  362. //    Serial.println(count);  
  363.    
  364. if (Fout<8115)  
  365.    
  366. {  
  367.    
  368. RH=100;  
  369.    
  370. //      Serial.print("RH:100");  
  371.    
  372. //      Serial.println(";");  
  373.    
  374.       lcd.setCursor(13, 1);  
  375.    
  376.       lcd.print("H.");  
  377.    
  378. }  
  379.    
  380. else if(Fout>9595)  
  381.    
  382. {  
  383.    
  384. RH=0;  
  385.    
  386.   //   Serial.print("RH:0");  
  387.    
  388. //   Serial.println(";");  
  389.    
  390.    lcd.setCursor(13, 1);  
  391.    
  392.    lcd.print("L.");  
  393.    
  394. }  
  395.    
  396. else  
  397.    
  398. {  
  399.    
  400.   
  401. RH=(9595-Fout)/14.8;  
  402.    
  403. // Serial.print("RH:");  
  404.    
  405. // Serial.print(RH);  
  406.    
  407. // Serial.println(";");  
  408.    
  409. lcd.setCursor(13, 1);  
  410.    
  411. lcd.print(RH);  
  412.    
  413. }  
  414.    
  415.     if (prescaler > 1)  
  416.    
  417.     {  
  418.    
  419.         prescaler--;  
  420.    
  421.         delay(200);  
  422.    
  423.     }  
  424.    
  425.   
  426. //if(  flag )//  
  427.    
  428. //  {  
  429.    
  430. //    Serial.print( BH1750() );  
  431.    
  432. //    Serial.println("[lux]");  
  433.    
  434. //      
  435. //    flag = 0;//归零,等着定时中断重新赋值  
  436.    
  437. //  }  
  438.    
  439. delay(2000);  
  440.    
  441.   
  442.    if(tempconcentration!=concentration)  
  443.    
  444.    {  
  445.    
  446.     tempconcentration=concentration;  
  447.    
  448.     BH=BH1750();  
  449.    
  450.     // read the state of the jiangyu value:  
  451.    
  452.   buttonState = digitalRead(buttonPin);  
  453.    
  454.     // check if the jiangyu is low.  
  455.    
  456.   // if it is, the buttonState is LOW:  
  457.    
  458.   if (buttonState == LOW) {       
  459.    
  460.     Rain=0;  
  461.    
  462.     }   
  463.   else {  
  464.    
  465.     Rain=1;  
  466.    
  467.     }  
  468.    
  469. //lewei ouput by computer tools    
  470.    
  471. //     Serial.print("D:");  
  472.    
  473. //     Serial.print(concentration);  
  474.    
  475. //     Serial.print(";");  
  476.    
  477. //     Serial.print("T:" );  
  478.    
  479. //     Serial.print(TEMPRATURE);  
  480.    
  481. //     Serial.print(";" );  
  482.    
  483. //     Serial.print("R:");  
  484.    
  485. //     Serial.print(RH);  
  486.    
  487. //     Serial.print(";" );  
  488.    
  489. //     Serial.print("B:" );  
  490.    
  491. //     Serial.print(BH);  
  492.    
  493. //     Serial.print(";" );  
  494.    
  495. //     Serial.print("W:");  
  496.    
  497. //     Serial.print(Rain);  
  498.    
  499. //     Serial.println(";");  
  500.    
  501.   
  502. //lewei ouput by GPRS     
  503.    
  504.   
  505.     lcd.setCursor(0, 1);  
  506.    
  507.     lcd.print("                ");  
  508.    
  509.     lcd.setCursor(0, 1);  
  510.    
  511.     lcd.print(BH);  
  512.    
  513.     lcd.print("LUX");  
  514.    
  515.     //delay(5000);   
  516.   
  517.     String tempstring="@uploading(01,D,";  
  518.    
  519.     String tempstring1=")";  
  520.    
  521.     Serial.print(tempstring);  
  522.    
  523.     Serial.print(int(concentration));  
  524.    
  525.     Serial.println(tempstring1);   
  526. //    delay(12000); min transtime  
  527.    
  528. delay(30000);  
  529.    
  530.   
  531.     String tempstring2="@uploading(01,T,";  
  532.    
  533.     String tempstring3=")";  
  534.    
  535.     Serial.print(tempstring2);  
  536.    
  537.     Serial.print(TEMPRATURE);  
  538.    
  539.     Serial.println(tempstring3);   
  540. //    delay(12000);  
  541.    
  542. delay(30000);  
  543.    
  544.   
  545.     String tempstring4="@uploading(01,R,";  
  546.    
  547.     String tempstring5=")";  
  548.    
  549.     Serial.print(tempstring4);  
  550.    
  551.     Serial.print(RH);  
  552.    
  553.     Serial.println(tempstring5);   
  554. //    delay(15000);  
  555.    
  556.     delay(30000);  
  557.    
  558.   
  559.     String tempstring6="@uploading(01,B,";  
  560.    
  561.     String tempstring7=")";  
  562.    
  563.     Serial.print(tempstring6);  
  564.    
  565.     Serial.print(int(BH));  
  566.    
  567.     Serial.println(tempstring7);   
  568. //    delay(2000);  
  569.    
  570. delay(30000);  
  571.    
  572.   
  573.     String tempstring8="@uploading(01,W,";  
  574.    
  575.     String tempstring9=")";  
  576.    
  577.     Serial.print(tempstring8);  
  578.    
  579.     Serial.print(Rain);  
  580.    
  581.     Serial.println(tempstring9);   
  582. delay(30000);  
  583.    
  584.   
  585.     lowpulseoccupancy = 0;  
  586.    
  587.     starttime = millis();  
  588.    
  589.   
  590.     }  
  591.    
  592.   
  593. }  
  594.    
  595.   
  596. double BH1750() //BH1750设备操作  
  597.    
  598. {  
  599.    
  600.   int i=0;  
  601.    
  602.   double  val=0;  
  603.    
  604.   //开始I2C读写操作  
  605.    
  606.   Wire.beginTransmission(BH1750address);  
  607.    
  608.   Wire.write(0x10);//1lx reolution 120ms//发送命令  
  609.    
  610.   Wire.endTransmission();    
  611.    
  612.   
  613.   delay(200);  
  614.    
  615.   //读取数据  
  616.    
  617.   Wire.beginTransmission(BH1750address);  
  618.    
  619.   Wire.requestFrom(BH1750address, 2);  
  620.    
  621.   while(Wire.available()) //  
  622.    
  623.   {  
  624.    
  625.     buff[i] = Wire.read();  // receive one byte  
  626.    
  627.     i++;  
  628.    
  629.   }  
  630.    
  631.   Wire.endTransmission();  
  632.    
  633.   if(2==i)  
  634.    
  635.   {  
  636.    
  637.    val=((buff[0]<<8)|buff[1])/1.2;  
  638.    
  639.   }  
  640.    
  641.   if(val<0val=56134+val;  
  642.    
  643.   return val;  
  644.    
  645. }  

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐