本实采用的硬件,除了一个串口模块以外(约200元),其他均可以从taobo上面找到标准产品
比较有意思的地方:可以通过手机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元,
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代码
- #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[2];
-
- 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 [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电表格
-
- int divider[6] = {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[8]={
-
- 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[i]&&R_Data>U_data[i+1])
-
- {
-
- 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[prescaler] / 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("[lux]");
-
- //
- // 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;
-
- double val=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[i] = Wire.read(); // receive one byte
-
- i++;
-
- }
-
- Wire.endTransmission();
-
- if(2==i)
-
- {
-
- val=((buff[0]<<8)|buff[1])/1.2;
-
- }
-
- if(val<0) val=56134+val;
-
- return val;
-
- }