极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 31203|回复: 28

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

[复制链接]
发表于 2013-3-28 08:11:15 | 显示全部楼层 |阅读模式
本帖最后由 数字 于 2013-3-28 11:06 编辑

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

1 目的
    试验基于Arduino硬件平台,采用乐为物联GPRS模块监控不具备有线网络接入条件的山区环境,可以用于农业、林业数据采集。
2 实验条件
    硬件设备列表:
1)        Arduino Nano约50RMB,
arduino nano.jpg
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。
GPRS.JPG

2)        DSM501A,本次只使用2、3、5脚,2脚为Vout 2 output (PWM)接Arduino D8, 3脚为Vcc接电源5伏,5脚为GND接地。
501a.JPG DSM501A.JPG

3)        HTF3223LF模块,使用1、2、3、4脚,1脚为NTC输出端,接Arduino A0,2脚为GND接地,3脚为湿度频率输出,接Arduino D2,4脚为Vcc接电源5伏。
3223.jpg
4)        BH1750模块为5脚,I2C接口,本次不用接ADD脚,VCC接电源5伏,SCL接Arduino A5,SDA接Arduino A4,GND接地。
1750.jpg
5)        降雨传感器为4脚,逻辑输出接Arduino D10,VCC接电源5伏,GND接地。
下雨传感器.jpg
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,程序中的问题还请大家批评指正。



上几张照片看看
IMAG1326.jpg
IMAG1327.jpg
IMAG1328.jpg
IMAG1329.jpg
IMAG1330.jpg
IMAG1331.jpg
IMAG1332.jpg
IMAG1333.jpg
回复

使用道具 举报

发表于 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|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2020-9-21 21:38 , Processed in 0.059788 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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