数字 发表于 2013-3-28 08:11:15

使用乐为物联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.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 程序
#include<string.h>
//#include <SoftwareSerial.h>
#include <Wire.h>
#include <math.h>
//#include <MsTimer2.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 4, 5, 6, 7);
//* LCD RS pin to digital pin 12
// * LCD Enable pin to digital pin 11
// * LCD D4 pin to digital pin 4
// * LCD D5 pin to digital pin 5
// * LCD D6 pin to digital pin 6
// * LCD D7 pin to digital pin 7
// * LCD R/W pin to ground
// * 10K resistor:
// * ends to +5V and ground
// * wiper to LCD VO pin (pin 3)
//SoftwareSerial mySerial(9, 10); // RX, TX
//String inputString = "";
const int buttonPin = 10;   //the number of the jiangyu input pin
int buttonState = 0;         // variable for reading the jiangyu status
int Rain = 1;
int BH1750address = 0x23;//BH1750 I2C地址
byte buff;
float BH = 0;
const int analogInPin = A0;// Analog input pin that the potentiometer is attached to//*//Freqinput pin D2
int pin = 8;//DSM501A input D8
float wuchaxiuzheng = 0;
unsigned long duration;
unsigned long starttime;
unsigned long endtime;
unsigned long sampletime_ms = 30000;
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;
float tempconcentration=0;
int sensorValue = 0;      // value read from the NTC
int TEMPRATURE=0;
int i=0;
float R_Data=0;
float U_data ={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电表格
int divider = {0, 1, 8, 64, 256, 1024};//read RH use interrupt get F
int prescaler = 5;
double count = 0;
double middle = 0;
char x = 0;
int Fout=0;
int RH=0;
byte du={
B00111,
B00101,
B00111,
B00000,
B00000,
B00000,
B00000,
};//define 1602 char
ISR(TIMER1_OVF_vect)
{
    if (prescaler < 4)
    {
      prescaler++;
    }
}
void interrupt()
{
    if (!x)
    {
      count = TCNT1;
      TCNT1 = 0x000;
      TCCR1B = prescaler;
      attachInterrupt(0, interrupt, FALLING);
    }
    else
    {
      middle = TCNT1;
      attachInterrupt(0, interrupt, RISING);
    }
    x = ~x;
}
void setup()
{
Wire.begin();
Serial.begin(9600);
//mySerial.begin(9600);
//inputString.reserve(200);
//MsTimer2::set(2000, timer); //定时器设置,每2秒触发一次timer函数操作
//MsTimer2::start();
//pinMode(buttonPin, INPUT);
analogReference(DEFAULT);//INTERNAL
    lcd.createChar(1,du);
    lcd.begin(16, 2);
    lcd.clear();
//    lcd.setCursor(0, 0);
//    lcd.print("PM2.5=");
//    lcd.setCursor(0, 1);
//    lcd.print("T=   ");
//    //lcd.write(1);
//    lcd.print("   RH=%");
//    Serial.begin(9600);
    pinMode(buttonPin, INPUT);
    pinMode(8,INPUT);
    TIMSK1 = 0x01;
    TCCR1A = 0x00;
    attachInterrupt(0, interrupt, RISING);
    starttime = millis();
}
void loop()
{
   
duration = pulseIn(pin, LOW);
lowpulseoccupancy += duration;
endtime = millis();
if ((endtime-starttime) > sampletime_ms)
{
    ratio = (lowpulseoccupancy-endtime+starttime + sampletime_ms)/(sampletime_ms*10.0);// Integer percentage 0=>100
    concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve
    //Serial.print(lowpulseoccupancy);
    // Serial.print(",");
    //Serial.print(ratio);
//    Serial.print("DSM501A:");
//    Serial.println(concentration);
//    Serial.print(";");
//Serial.println(endtime-starttime);
wuchaxiuzheng = (endtime-starttime-30000)/30000.0;
//Serial.println(wuchaxiuzheng);
concentration = (1.00-wuchaxiuzheng)*concentration;
//Serial.println(concentration);

    lcd.setCursor(6, 0);
    lcd.print(concentration);
    lcd.print("pcs/0.01cf");
//    lowpulseoccupancy = 0;
//    starttime = millis();
}
sensorValue = analogRead(analogInPin);    // read the analog in value:
delay(10);
R_Data=sensorValue*5/1024.0;
//Serial.print("R_Data = " );                     
//Serial.print(R_Data);   
for(i=0;i<111;i++){
   if(R_Data>4.67)
   {
       TEMPRATURE =-30;//对应-30℃
      }
   else if(R_Data<0.62)
   {
      TEMPRATURE=80; //对应80℃      
      }
   else if(R_Data<U_data&&R_Data>U_data)
   {
      TEMPRATURE=int(i-30-3);
      }
}
//   Serial.print("T:" );
//   Serial.print(TEMPRATURE);
//   Serial.print(";" );
   delay(10);
      
   
    lcd.setCursor(0, 0);
    lcd.print("PM2.5=");
    lcd.setCursor(0, 1);
    lcd.print("T=   ");
    //lcd.write(1);
    lcd.print("   RH=%");
//   lcd.setCursor(0, 1);
//   lcd.print("T=   ");
//    //lcd.write(1);
//    lcd.print("   RH=%");
   lcd.setCursor(2, 1);
   lcd.print(TEMPRATURE);
   lcd.write(1);
    lcd.print("C");
   Fout=(16000000.0 / divider / count);
   //Serial.print("Vsensor=" );                     
   //Serial.print(sensorValue);      
   //Serial.print(", " );
   //Serial.print("Freq=");
   //Serial.print(Fout);
//    Serial.print("   ");
//    Serial.print(int(divider));
//    Serial.print("   ");
//    Serial.print(prescaler);
//    Serial.print("   ");
//    Serial.println(count);
if (Fout<8115)
{
RH=100;
//      Serial.print("RH:100");
//      Serial.println(";");
      lcd.setCursor(13, 1);
      lcd.print("H.");
}
else if(Fout>9595)
{
RH=0;
//   Serial.print("RH:0");
//   Serial.println(";");
   lcd.setCursor(13, 1);
   lcd.print("L.");
}
else
{

RH=(9595-Fout)/14.8;
// Serial.print("RH:");
// Serial.print(RH);
// Serial.println(";");
lcd.setCursor(13, 1);
lcd.print(RH);
}
    if (prescaler > 1)
    {
      prescaler--;
      delay(200);
    }

//if(flag )//
//{
//    Serial.print( BH1750() );
//    Serial.println("");
//   
//    flag = 0;//归零,等着定时中断重新赋值
//}
delay(2000);

   if(tempconcentration!=concentration)
   {
    tempconcentration=concentration;
    BH=BH1750();
    // read the state of the jiangyu value:
buttonState = digitalRead(buttonPin);
    // check if the jiangyu is low.
// if it is, the buttonState is LOW:
if (buttonState == LOW) {   
    Rain=0;
    }
else {
    Rain=1;
    }
//lewei ouput by computer tools
//   Serial.print("D:");
//   Serial.print(concentration);
//   Serial.print(";");
//   Serial.print("T:" );
//   Serial.print(TEMPRATURE);
//   Serial.print(";" );
//   Serial.print("R:");
//   Serial.print(RH);
//   Serial.print(";" );
//   Serial.print("B:" );
//   Serial.print(BH);
//   Serial.print(";" );
//   Serial.print("W:");
//   Serial.print(Rain);
//   Serial.println(";");
   
//lewei ouput by GPRS   
   
    lcd.setCursor(0, 1);
    lcd.print("                ");
    lcd.setCursor(0, 1);
    lcd.print(BH);
    lcd.print("LUX");
    //delay(5000);

    String tempstring="@uploading(01,D,";
    String tempstring1=")";
    Serial.print(tempstring);
    Serial.print(int(concentration));
    Serial.println(tempstring1);
//    delay(12000); min transtime
delay(30000);
   
    String tempstring2="@uploading(01,T,";
    String tempstring3=")";
    Serial.print(tempstring2);
    Serial.print(TEMPRATURE);
    Serial.println(tempstring3);
//    delay(12000);
delay(30000);
   
    String tempstring4="@uploading(01,R,";
    String tempstring5=")";
    Serial.print(tempstring4);
    Serial.print(RH);
    Serial.println(tempstring5);
//    delay(15000);
    delay(30000);

    String tempstring6="@uploading(01,B,";
    String tempstring7=")";
    Serial.print(tempstring6);
    Serial.print(int(BH));
    Serial.println(tempstring7);
//    delay(2000);
delay(30000);

    String tempstring8="@uploading(01,W,";
    String tempstring9=")";
    Serial.print(tempstring8);
    Serial.print(Rain);
    Serial.println(tempstring9);
delay(30000);

    lowpulseoccupancy = 0;
    starttime = millis();
   
    }
   
}

double BH1750() //BH1750设备操作
{
int i=0;
doubleval=0;
//开始I2C读写操作
Wire.beginTransmission(BH1750address);
Wire.write(0x10);//1lx reolution 120ms//发送命令
Wire.endTransmission();

delay(200);
//读取数据
Wire.beginTransmission(BH1750address);
Wire.requestFrom(BH1750address, 2);
while(Wire.available()) //
{
    buff = Wire.read();// receive one byte
    i++;
}
Wire.endTransmission();
if(2==i)
{
   val=((buff<<8)|buff)/1.2;
}
if(val<0) val=56134+val;
return val;
}


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 08:53:10

{:soso_e103:}都上GRPS模块了。。。好强

℡Li_筅鉎 发表于 2013-3-28 09:13:53

不错吗,这个要用在什么地方上的

honyfox 发表于 2013-3-28 10:00:49

数据远传噻,发短信拨电话

数字 发表于 2013-3-28 11:08:05

℡Li_筅鉎 发表于 2013-3-28 09:13 static/image/common/back.gif
不错吗,这个要用在什么地方上的

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

luhuaneda 发表于 2013-3-28 16:18:22

还穿雨衣呢:lol:lol

laoliu1982 发表于 2013-3-29 10:50:49

这个也不错

韋編弎絕 发表于 2013-3-29 20:14:01

帅呆了!很喜欢你这个装置的外壳。

davidce 发表于 2013-3-29 20:22:14

传感器又便宜了

8200 发表于 2013-5-21 22:40:14

兄弟是在哪的?现在的温度才16.000 ℃?感觉好冷呀。

wskyhorse 发表于 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两个变量。

jh7086 发表于 2013-6-27 15:19:44

好厉害,学习了
请问gprs模块怎么买,多少钱?

数字 发表于 2013-7-3 10:05:04

gprs模块请与乐联网联系。

nust_奔跑 发表于 2013-8-6 13:36:05

乐为物联GPRS模块多少钱?求购买连接~谢谢~
页: [1] 2
查看完整版本: 使用乐为物联GPRS模块搭建远程环境监测系统