极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 70964|回复: 28

使用乐为物联GPRS模块搭建远程环境监测系统

[复制链接]
发表于 2013-3-28 08:11:15 | 显示全部楼层 |阅读模式
本帖最后由 数字 于 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.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伏供电,背景灯可设开关。
  


4 程序
  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.    
  111.   duration = pulseIn(pin, LOW);
  112.   lowpulseoccupancy += duration;
  113.   endtime = millis();
  114.   if ((endtime-starttime) > sampletime_ms)
  115.   {
  116.     ratio = (lowpulseoccupancy-endtime+starttime + sampletime_ms)/(sampletime_ms*10.0);  // Integer percentage 0=>100
  117.     concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve
  118.     //Serial.print(lowpulseoccupancy);
  119.     // Serial.print(",");
  120.     //Serial.print(ratio);
  121. //    Serial.print("DSM501A:");
  122. //    Serial.println(concentration);
  123. //    Serial.print(";");
  124. //Serial.println(endtime-starttime);
  125. wuchaxiuzheng = (endtime-starttime-30000)/30000.0;
  126. //Serial.println(wuchaxiuzheng);
  127. concentration = (1.00-wuchaxiuzheng)*concentration;
  128. //Serial.println(concentration);

  129.     lcd.setCursor(6, 0);
  130.     lcd.print(concentration);
  131.     lcd.print("pcs/0.01cf");
  132. //    lowpulseoccupancy = 0;
  133. //    starttime = millis();
  134.   }
  135.   sensorValue = analogRead(analogInPin);    // read the analog in value:
  136.   delay(10);  
  137.   R_Data=sensorValue*5/1024.0;
  138.   //Serial.print("R_Data = " );                       
  139.   //Serial.print(R_Data);   
  140.   for(i=0;i<111;i++){
  141.      if(R_Data>4.67)
  142.      {
  143.        TEMPRATURE =-30;//对应-30℃
  144.       }
  145.      else if(R_Data<0.62)
  146.      {
  147.       TEMPRATURE=80; //对应80℃      
  148.       }
  149.      else if(R_Data<U_data[i]&&R_Data>U_data[i+1])
  150.      {
  151.       TEMPRATURE=int(i-30-3);
  152.       }
  153. }
  154. //     Serial.print("T:" );
  155. //     Serial.print(TEMPRATURE);
  156. //     Serial.print(";" );
  157.      delay(10);
  158.       
  159.    
  160.     lcd.setCursor(0, 0);
  161.     lcd.print("PM2.5=");
  162.     lcd.setCursor(0, 1);
  163.     lcd.print("T=     ");
  164.     //lcd.write(1);
  165.     lcd.print("   RH=  %");
  166. //     lcd.setCursor(0, 1);
  167. //     lcd.print("T=     ");
  168. //    //lcd.write(1);
  169. //    lcd.print("   RH=  %");
  170.      lcd.setCursor(2, 1);
  171.      lcd.print(TEMPRATURE);
  172.      lcd.write(1);
  173.     lcd.print("C");
  174.      Fout=(16000000.0 / divider[prescaler] / count);  
  175.      //Serial.print("Vsensor=" );                       
  176.      //Serial.print(sensorValue);      
  177.      //Serial.print(", " );
  178.      //Serial.print("Freq=");
  179.      //Serial.print(Fout);
  180. //    Serial.print("   ");
  181. //    Serial.print(int(divider));
  182. //    Serial.print("   ");
  183. //    Serial.print(prescaler);
  184. //    Serial.print("   ");
  185. //    Serial.println(count);
  186. if (Fout<8115)
  187. {
  188. RH=100;
  189. //      Serial.print("RH:100");
  190. //      Serial.println(";");
  191.       lcd.setCursor(13, 1);
  192.       lcd.print("H.");
  193. }
  194. else if(Fout>9595)
  195. {
  196. RH=0;
  197.   //   Serial.print("RH:0");
  198. //   Serial.println(";");
  199.    lcd.setCursor(13, 1);
  200.    lcd.print("L.");
  201. }
  202. else
  203. {

  204. RH=(9595-Fout)/14.8;
  205. // Serial.print("RH:");
  206. // Serial.print(RH);
  207. // Serial.println(";");
  208. lcd.setCursor(13, 1);
  209. lcd.print(RH);
  210. }
  211.     if (prescaler > 1)
  212.     {
  213.         prescaler--;
  214.         delay(200);
  215.     }

  216. //if(  flag )//
  217. //  {
  218. //    Serial.print( BH1750() );
  219. //    Serial.println("[lux]");
  220. //   
  221. //    flag = 0;//归零,等着定时中断重新赋值
  222. //  }
  223. delay(2000);

  224.    if(tempconcentration!=concentration)
  225.    {
  226.     tempconcentration=concentration;
  227.     BH=BH1750();
  228.     // read the state of the jiangyu value:
  229.   buttonState = digitalRead(buttonPin);
  230.     // check if the jiangyu is low.
  231.   // if it is, the buttonState is LOW:
  232.   if (buttonState == LOW) {     
  233.     Rain=0;
  234.     }
  235.   else {
  236.     Rain=1;
  237.     }
  238. //lewei ouput by computer tools  
  239. //     Serial.print("D:");
  240. //     Serial.print(concentration);
  241. //     Serial.print(";");
  242. //     Serial.print("T:" );
  243. //     Serial.print(TEMPRATURE);
  244. //     Serial.print(";" );
  245. //     Serial.print("R:");
  246. //     Serial.print(RH);
  247. //     Serial.print(";" );
  248. //     Serial.print("B:" );
  249. //     Serial.print(BH);
  250. //     Serial.print(";" );
  251. //     Serial.print("W:");
  252. //     Serial.print(Rain);
  253. //     Serial.println(";");
  254.    
  255. //lewei ouput by GPRS   
  256.    
  257.     lcd.setCursor(0, 1);
  258.     lcd.print("                ");
  259.     lcd.setCursor(0, 1);
  260.     lcd.print(BH);
  261.     lcd.print("LUX");
  262.     //delay(5000);

  263.     String tempstring="@uploading(01,D,";
  264.     String tempstring1=")";
  265.     Serial.print(tempstring);
  266.     Serial.print(int(concentration));
  267.     Serial.println(tempstring1);
  268. //    delay(12000); min transtime
  269. delay(30000);
  270.    
  271.     String tempstring2="@uploading(01,T,";
  272.     String tempstring3=")";
  273.     Serial.print(tempstring2);
  274.     Serial.print(TEMPRATURE);
  275.     Serial.println(tempstring3);
  276. //    delay(12000);
  277. delay(30000);
  278.    
  279.     String tempstring4="@uploading(01,R,";
  280.     String tempstring5=")";
  281.     Serial.print(tempstring4);
  282.     Serial.print(RH);
  283.     Serial.println(tempstring5);
  284. //    delay(15000);
  285.     delay(30000);

  286.     String tempstring6="@uploading(01,B,";
  287.     String tempstring7=")";
  288.     Serial.print(tempstring6);
  289.     Serial.print(int(BH));
  290.     Serial.println(tempstring7);
  291. //    delay(2000);
  292. delay(30000);

  293.     String tempstring8="@uploading(01,W,";
  294.     String tempstring9=")";
  295.     Serial.print(tempstring8);
  296.     Serial.print(Rain);
  297.     Serial.println(tempstring9);
  298. delay(30000);

  299.     lowpulseoccupancy = 0;
  300.     starttime = millis();
  301.      
  302.     }
  303.    
  304. }

  305. double BH1750() //BH1750设备操作
  306. {
  307.   int i=0;
  308.   double  val=0;
  309.   //开始I2C读写操作
  310.   Wire.beginTransmission(BH1750address);
  311.   Wire.write(0x10);//1lx reolution 120ms//发送命令
  312.   Wire.endTransmission();  

  313.   delay(200);
  314.   //读取数据
  315.   Wire.beginTransmission(BH1750address);
  316.   Wire.requestFrom(BH1750address, 2);
  317.   while(Wire.available()) //
  318.   {
  319.     buff[i] = Wire.read();  // receive one byte
  320.     i++;
  321.   }
  322.   Wire.endTransmission();
  323.   if(2==i)
  324.   {
  325.    val=((buff[0]<<8)|buff[1])/1.2;
  326.   }
  327.   if(val<0) val=56134+val;
  328.   return val;
  329. }
复制代码


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,程序中的问题还请大家批评指正。



上几张照片看看








本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2013-3-28 08:53:10 | 显示全部楼层
{:soso_e103:}都上GRPS模块了。。。好强
回复 支持 反对

使用道具 举报

发表于 2013-3-28 09:13:53 | 显示全部楼层
不错吗,这个要用在什么地方上的
回复 支持 反对

使用道具 举报

发表于 2013-3-28 10:00:49 | 显示全部楼层
数据远传噻,发短信拨电话
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-3-28 11:08:05 | 显示全部楼层
℡Li_筅鉎 发表于 2013-3-28 09:13
不错吗,这个要用在什么地方上的

放在农村,看看环境变化,可以作为农业种植或者旅游的参考。
回复 支持 反对

使用道具 举报

发表于 2013-3-28 16:18:22 | 显示全部楼层
还穿雨衣呢
回复 支持 反对

使用道具 举报

发表于 2013-3-29 10:50:49 | 显示全部楼层
这个也不错
回复 支持 反对

使用道具 举报

发表于 2013-3-29 20:14:01 | 显示全部楼层
帅呆了!很喜欢你这个装置的外壳。
回复 支持 反对

使用道具 举报

发表于 2013-3-29 20:22:14 | 显示全部楼层
传感器又便宜了
回复 支持 反对

使用道具 举报

发表于 2013-5-21 22:40:14 | 显示全部楼层
兄弟是在哪的?现在的温度才16.000 ℃?感觉好冷呀。
回复 支持 反对

使用道具 举报

发表于 2013-5-31 10:10:15 | 显示全部楼层
请问楼主:第116行“   ratio = (lowpulseoccupancy-endtime+starttime + sampletime_ms)/(sampletime_ms*10.0);  // Integer percentage 0=>100”看不明白, (lowpulseoccupancy-endtime+starttime + sampletime_ms)是否有误?谢谢
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-5-31 12:47:03 | 显示全部楼层
这段是抄的,原作者是为了修正计算时间的误差增加了endtime、starttime两个变量。
回复 支持 反对

使用道具 举报

发表于 2013-6-27 15:19:44 | 显示全部楼层
好厉害,学习了
请问gprs模块怎么买,多少钱?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-3 10:05:04 | 显示全部楼层
gprs模块请与乐联网联系。
回复 支持 反对

使用道具 举报

发表于 2013-8-6 13:36:05 | 显示全部楼层
乐为物联GPRS模块多少钱?求购买连接~谢谢~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-29 22:10 , Processed in 0.055643 second(s), 30 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表