|
楼主 |
发表于 2014-9-1 15:35:31
|
显示全部楼层
本帖最后由 hi55234 于 2014-9-1 15:37 编辑
- /*
- 1、修正GPS未定时,1602上显示的内容
- 2、修改浇花时故障检测程序的运行方式,30秒检测,没水流的话,直接跳出程序
- 3、赋予串口控制命令与实体按钮相同的意义
- PS:特别注意,这个程序用的DS18B20库是改过的,读取耗时96ms的样子,原始的750ms,9600的GPS根本无法正常运行
- PS2:如果没有DHT11,就把相应的程序注释掉,否则,会非常耗时,以至于影响程序的正常运行
-
- 此程序最大特点为依赖gps的信号周期,已信号周期的发送完毕作为是否执行后续程序的唯一标准
- 换言之,就是离了gps这程序就不会动了,显然这不够科学,需要改进(浇花的程序已经不用GPS信号了)
-
- 2014-08-27 针对SRIF2, SRIF3 时间上的差异(2是秒百分位、3是千分位)导致纬度取不全,进行兼容性修正
-
- 剩余问题:在可用卫星数的表示上,SRIF3 为恒定2位,不足则补0,SRIF2 则只显示了一位,这个暂不修改
-
- 关于浇花部分,对Pin 16 Pin 17进行了复用,而模式切换按键Pin 14 同时也复用做了浇花的停止按钮
-
- */
- #include <MemoryFree.h>//剩余内存查询
- //////////////////////////////////////////////////////////////////////////////////////////////
- //GPS
- //////////////////////////////////////////////////////////////////////////////////////////////
-
- #include <SoftwareSerial.h>
- SoftwareSerial gps(8, 9); // RX, TX
- char temp1[450];//临时数组1,放gps数据的
- char temp2[135]="Time:2000/00/00 00:00:00#/latitude:00 00.0000 N#/longitude:000 00.0000 E#/weixingshu:00#/altitude: 000.0 M#/gp2y1010:0000 mV 77% 24C";
- char temp3[27];//1602显示(特定一行)输出的类容(因为 u8g.print没有换行符,所以用一个小的临时数组来搞定问题)
- //temp4为地面速率 + 地面航向
- char temp4[34]="speed:999.90 Knot#/course:359.90";
- char temp5[10];//接受蓝牙命令(没蓝牙的情况下,就通过串口助手直接发送命令)
-
- unsigned long x;//超级泛用酱油帝,X,主要就是1602显示时作为中间暂存值来用
-
- String jianyan="";//GPS数据包的ASCII异或校验
- int jsq1,jsq2,jsq3;//jsq3记录的是GPRMC中9第个逗号的前一个位置
- int jsq4,jsq5;//jsq4记录的是GPRMC中8第个逗号的前2个位置,jsq5记录的是GPRMC中7第个逗号的前2个位置,找出“地面速率”和“航向”
- int jsq6=0;//1602进行循环显示[暂时与蓝牙沟通]
- int jsq7=0;//gp2y1010利用gps每秒一次的数据做循环
- boolean jsq8=1;//这个布尔量决定蓝牙输出的gps nema-1803信息(作为蓝牙gps模块使用),还是输出检测信息(作为检测模块)
- int number1A,number2A,number3A,number4A;//$号的位置
- int number1B,number2B,number3B,number4B;//*号的位置
- int number5A,number6A,number7A,number8A;//$号的位置
- int number5B,number6B,number7B,number8B;//*号的位置
- int number9A,number10A,number11A,number12A;//$号的位置
- int number9B,number10B,number11B,number12B;//*号的位置
- int wanzhengdezushu;//完整的$-*组数
- int zifuweizhiA,zifuweizhiB;//字符位置,异或运算的时候用,A是$号的位置,B是*号的位置
- //布尔量0-24,最多表示12组完整的$--*字符串的存在
- boolean change0,change1,change2,change3,change4,change5,change6,change7,change8;
- boolean change9,change10,change11,change12,change13,change14,change15,change16,change17,change18;
- boolean change19,change20,change21,change22,change23,change24;
- boolean jiaoyanjieguo=0;//校验结果
- int yihuoyunsuan;//异或运算——校验结果
- int altitudeA,altitudeB;//海拔前逗号、海拔后逗号
- boolean altitudeC;
- boolean dingweiok;
- int weidubiaoji,jingdubiaoji;//经度标记、纬度标记
- //UTC +8(北京时间)时、分、秒、年、月、日
- int utc8s,utc8f,utc8m,utc8n,utc8y,utc8r;
- //小月的数组
- int xiaoyue[5]={4,6,9,11};
- //日进位,月进位,年进位,大小月判断值
- boolean rijinwei,yuejinwei,nianjinwei,xiaoyueok;
- unsigned long gpstimes;//gps计时器,如果超过一定时间10ms,则证明gps数据已经发送完毕
- //unsigned long quanjujishu;//全局计数,计算1秒之内,循环了多少次,这个次数在一定程度上表示了剩余性能
- boolean konghangpanduan;//空行判断,因为在读取串口数据后并没有延迟,完全依赖全局循环,那么,特定程序是否执行,就全靠布尔量来标记了
- //////////////////////////////////////////////////////////////////////////////////////////////
- //1602
- //////////////////////////////////////////////////////////////////////////////////////////////
-
- #include <LiquidCrystal.h>
-
- // initialize the library with the numbers of the interface pins
- LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
-
- byte quan0[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- //////////////////////////////////////////////////////////////////////////////////////////////
- //DS18B20 温度
- //////////////////////////////////////////////////////////////////////////////////////////////
- #include <OneWire.h>
- #include <DallasTemperature.h>
- OneWire oneWire(10);// 数字接口10
- DallasTemperature sensors(&oneWire);
- //////////////////////////////////////////////////////////////////////////////////////////////
- //DHT11 湿度
- //////////////////////////////////////////////////////////////////////////////////////////////
- #include <dht11.h>
- dht11 DHT11;
- #define DHT11PIN 11 //DHT11 PIN 11
- //////////////////////////////////////////////////////////////////////////////////////////////
- //ds1307
- //////////////////////////////////////////////////////////////////////////////////////////////
- #include <Wire.h>
- #include <RTClib.h>
- void printDateTime(DateTime dateTime);
- RTC_DS1307 RTC;//创建实例
- int nian,yue,ri,shi,fen,miao;
- boolean shoushiqidong;//布尔量,授时启动
- //////////////////////////////////////////////////////////////////////////////////////////////
- //MQ-2
- //////////////////////////////////////////////////////////////////////////////////////////////
- int MQ2Pin=1;//A1——粉尘电压
- int dustVal=0;
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- //浇花的一些定义
- //////////////////////////////////////////////////////////////////////////////////////////////
- int liuliangji=12;
- int diancifa=13;
- unsigned long meimiaoyilunhui=millis();//每秒一轮回
-
- boolean chongfupanduanA=0;//重复判定A
-
- int jsqLLx=0;
- float shishiliuliang=0;//实时流量
- float leijiliuliang=0;//累计流量
- int shedingjiaoguanliang=0;//设定浇灌量
-
- unsigned long guzhangjianceA=millis();//故障检测
- int guzhangjiancejsq;//故障检测计数器
- int tiaojieliang=5;//每次增减的 调节量 5L
-
-
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- //切换GPS(浇花模式),以及切换GPS显示画面(浇花设定流量)
- //////////////////////////////////////////////////////////////////////////////////////////////
- boolean anjianzuseA=0;
- boolean anjianzuseB=0;
- unsigned long time1=millis();
- unsigned long time2=millis();
-
- unsigned long timeX=millis();//timeX实际记录的是luanqizaoba()所用的时间,大概300ms,总体上gps 450ms ,空闲250ms
- //////////////////////////////////////////////////////////////////////////////////////////////
- /*-------------------------------------------------------------------------------------------*/
- //////////////////////////////////////////////////////////////////////////////////////////////
- void setup() {
- Serial.begin(9600);
- gps.begin(9600);
- //1602
- lcd.createChar(1, quan0); //全0
- lcd.begin(16, 2);
-
- pinMode(14,INPUT);//切换浇花与其他模式的控制角
- pinMode(16,INPUT); //切换jsq6++,注意复用
- pinMode(17,INPUT); //切换jsq6--,注意复用
-
- pinMode(liuliangji,INPUT); //流量计接12
- pinMode(diancifa, OUTPUT); //电磁阀接13
- digitalWrite(diancifa, HIGH); //控制继电器关(开)电磁阀,这个主要是由继电器的有效电频决定,电磁阀接继电器常开(本例中继电器LOW有效)
-
- //DS1307
- Wire.begin(); //初始化总线
- RTC.begin(); //初始化实时时钟
-
- //对temp2进行处理,把“#/”替换成 换行+回车
- for(int col=2;col<135;col++){
-
- if(temp2[col-1]=='#' && temp2[col]=='/'){
- temp2[col-1]=10;
- temp2[col]=13;
- }
- }
- //对temp4进行处理,把“#/”替换成 换行+回车
- for(int col=2;col<34;col++){
- if(temp4[col-1]=='#' && temp4[col]=='/'){
- temp4[col-1]=10;
- temp4[col]=13;
- }
- }
- }
-
- void loop() {
-
- if(jsq8){
-
- //无条件接受串口的字符,全都给临时数组temp1
- while (gps.available() > 0) {
- gpstimes=millis();//重置gpstimes为millis()
- konghangpanduan=0;//因为串口有数据,所以空行判断为0,即不空行
- temp1[jsq1] = gps.read();//软串口读取GPS数据,并保存在临时数组temp1中
- if(jsq6<3)Serial.write(temp1[jsq1]);//用硬件串口,把收到的GPS数据同步转发出去
-
- //做一个保险,保证数组不会溢出,同时也限制了最大字符串的长度(450)
- if(jsq1<449) jsq1++;
- else jsq1=449;
- }
-
-
- //如果连续10ms串口都没有收到新的数据,则说明一个周期内(1秒)的GPS数据发送已完毕
- //这个空行一个周期只做一次,所以同时加入布尔量konghangpanduan的判断
- if(millis()-gpstimes>10 && !konghangpanduan){
- timeX=millis();
- //此处millis()-gpstimes延迟550ms可过,证明数据转发后,余下的时间大于550ms
- konghangpanduan=1;
- Serial.println();
- Serial.println();
- //////////////////////////////////////////////////////////////
- //luanqizaoba系列其实就是主程序
- /////////////////////////////////////////////////////////////
- luanqizaobaA();//部分定义、赋值,目的是计算出究竟有多少组完整的$----*0C
- luanqizaobaB();//DS1307时间的取得,以及通过GPS对DS1307校时
- luanqizaobaC();//这玩意实际上是主程序
- jsq1=0;
- ///////////////////////////////////////////////1602输出部分
- lcd1602out();
- /////////////////////////////////////////////
- timeX=millis()-timeX;
- Serial.print("timeX=");
- Serial.println(timeX);
- }
-
- }else{
-
- //浇花主程序///////////////////////////////////////////////////////////
-
- jiaohuaA();//每秒频率测定,实时流量计算,累计流量叠加,1602显示
-
- jiaohuaB();//通过3秒的频率次数的累加,来判断是否停水了(防止电池阀在没水的时候长期运行)
-
-
- if(leijiliuliang < shedingjiaoguanliang) { //流量控制,流量超了就关了
- digitalWrite(diancifa, LOW);//累计流量小于设定流量,打开电磁阀
-
- }else{
- digitalWrite(diancifa, HIGH);//关闭电磁阀
- shedingjiaoguanliang=0;//清空设定浇灌量
- leijiliuliang=0;//清空累计流量
-
- }
-
- /*-------------------------end------------------------------*/
-
- }
-
-
- while (Serial.available() > 0) {
-
- temp5[0] = Serial.read();
- delayMicroseconds(1150);
-
- //做一个保险,保证数组不会溢出,同时也限制了最大字符串的长度(10)
- //if(jsq2<10) jsq2++;
- //else jsq2=10;
- if(temp5[0]=='A'){
- if(jsq8)jsq6++;
- else {
- shedingjiaoguanliang=shedingjiaoguanliang+tiaojieliang;
- if(shedingjiaoguanliang>99)shedingjiaoguanliang=99;//最多设定浇灌99L
- }
- anjianzuseB=!anjianzuseB;
- time2=millis();
- }
- if(temp5[0]=='B'){
- if(jsq8){
-
- if(jsq6>0)jsq6--;
- else jsq6=3;
-
- }else {
- shedingjiaoguanliang=shedingjiaoguanliang-tiaojieliang;
- if(shedingjiaoguanliang<0)shedingjiaoguanliang=0;//最少设定浇灌0L
- }
- anjianzuseB=!anjianzuseB;
- time2=millis();
- }
- if(temp5[0]=='G'){
- jsq8=!jsq8;
- anjianzuseA=!anjianzuseA;
- //切换模式之后,对浇花部分进行操作(即停止浇花)
- digitalWrite(diancifa, HIGH);//关闭电磁阀
- shedingjiaoguanliang=0;//清空设定浇灌量
- leijiliuliang=0;//清空累计流量
- guzhangjianceA=millis();//同时清空故障检测的时间,否则一开始就是故障状态
- time1=millis();
- }
- }
-
- //浇花程序的切换写在此处,主要由蓝牙的字符识别(退步)为按键的高低电平识别
-
- int qiehuandianpingA =digitalRead(14);//切换(GPS 与浇花之间)
- if(!anjianzuseA&&qiehuandianpingA == HIGH){ //高电平 就切换
- jsq8=!jsq8;
- anjianzuseA=!anjianzuseA;
- //切换模式之后,对浇花部分进行操作(即停止浇花)
- digitalWrite(diancifa, HIGH);//关闭电磁阀
- shedingjiaoguanliang=0;//清空设定浇灌量
- leijiliuliang=0;//清空累计流量
- guzhangjianceA=millis();//同时清空故障检测的时间,否则一开始就是故障状态
- time1=millis();
- }
-
- if(anjianzuseA && millis()-time1>1000)anjianzuseA=!anjianzuseA;//切换(GPS 与浇花之间)频率最大每秒一次
-
-
- //Pin16 Pin17 公用一套anjianzuseB(按键阻塞B)、时间间隔time2,以保证同一时刻只有一个键按下有效
-
- int qiehuandianpingB =digitalRead(17);//读取切换jsq6 OR 设定流量
- if(!anjianzuseB&&qiehuandianpingB == HIGH){ //高电平 就切换
- if(jsq8)jsq6++;
- else {
- shedingjiaoguanliang=shedingjiaoguanliang+tiaojieliang;
- if(shedingjiaoguanliang>99)shedingjiaoguanliang=99;//最多设定浇灌99L
- }
- anjianzuseB=!anjianzuseB;
- time2=millis();
- }
-
-
- int qiehuandianpingC =digitalRead(16);//读取切换jsq6 OR 设定流量
- if(!anjianzuseB&&qiehuandianpingC == HIGH){ //高电平 就切换
- if(jsq8){
-
- if(jsq6>0)jsq6--;
- else jsq6=3;
-
- }else {
- shedingjiaoguanliang=shedingjiaoguanliang-tiaojieliang;
- if(shedingjiaoguanliang<0)shedingjiaoguanliang=0;//最少设定浇灌0L
- }
- anjianzuseB=!anjianzuseB;
- time2=millis();
- }
-
- if(anjianzuseB && millis()-time2>1000)anjianzuseB=!anjianzuseB;//切换 jsq6 OR 设定流量 频率最大每秒一次
-
-
-
-
- }
-
-
-
- void luanqizaobaA()
- {
- //布尔量,授时启动
- shoushiqidong=0;
-
- //日进位,月进位
- rijinwei=0;
- yuejinwei=0;
- nianjinwei=0;
-
- //布尔量 1-24,2个一组,可以判断出12组$```*
- change0=1;//最开始的一个,必须置1
- change1=0;
- change2=0;
- change3=0;
- change4=0;
- change5=0;
- change6=0;
- change7=0;
- change8=0;
- change9=0;
- change10=0;
- change11=0;
- change12=0;
- change13=0;
- change14=0;
- change15=0;
- change16=0;
- change17=0;
- change18=0;
- change19=0;
- change20=0;
- change21=0;
- change22=0;
- change23=0;
- change24=0;
- //number 1-12,记录$号的位置,以便找出特定语句的开始
- number1A=0;
- number2A=0;
- number3A=0;
- number4A=0;
- number5A=0;
- number6A=0;
- number7A=0;
- number8A=0;
- number9A=0;
- number10A=0;
- number11A=0;
- number12A=0;
- //number 1-12,记录*号的位置,以便找出“校验码”,从而确定串口传输的完整性
- number1B=0;
- number2B=0;
- number3B=0;
- number4B=0;
- number5B=0;
- number6B=0;
- number7B=0;
- number8B=0;
- number9B=0;
- number10B=0;
- number11B=0;
- number12B=0;
- //海拔用的,起点位置,结束位置,布尔量充当开关
- altitudeA=0;
- altitudeB=0;
- altitudeC=0;
- weidubiaoji=0;//纬度标记
- jingdubiaoji=0;//经度标记
- //子程序数据处理1,计算出“完整的$-*组数”,以及每组的起始位置
- shujuchuli1();
- //根据不同个数的完整组,分别进行"校验码计算与对比",以确保有效性
- if(wanzhengdezushu>0){ //1
- zifuweizhiA=number1A;
- zifuweizhiB=number1B;
- shujuchuli2();
- shujuchuli3();
- }
- if(wanzhengdezushu>1){ //2
- zifuweizhiA=number2A;
- zifuweizhiB=number2B;
- shujuchuli2();
- shujuchuli3();
- }
- if(wanzhengdezushu>2){ //3
- zifuweizhiA=number3A;
- zifuweizhiB=number3B;
- shujuchuli2();
- shujuchuli3();
- }
- if(wanzhengdezushu>3){ //4
- zifuweizhiA=number4A;
- zifuweizhiB=number4B;
- shujuchuli2();
- shujuchuli3();
- }
- if(wanzhengdezushu>4){ //5
- zifuweizhiA=number5A;
- zifuweizhiB=number5B;
- shujuchuli2();
- shujuchuli3();
- }
- if(wanzhengdezushu>5){ //6
- zifuweizhiA=number6A;
- zifuweizhiB=number6B;
- shujuchuli2();
- shujuchuli3();
- }
- if(wanzhengdezushu>6){ //7
- zifuweizhiA=number7A;
- zifuweizhiB=number7B;
- shujuchuli2();
- shujuchuli3();
- }
- if(wanzhengdezushu>7){ //8
- zifuweizhiA=number8A;
- zifuweizhiB=number8B;
- shujuchuli2();
- shujuchuli3();
- }
- if(wanzhengdezushu>8){ //9
- zifuweizhiA=number9A;
- zifuweizhiB=number9B;
- shujuchuli2();
- shujuchuli3();
- }
- if(wanzhengdezushu>9){ //10
- zifuweizhiA=number10A;
- zifuweizhiB=number10B;
- shujuchuli2();
- shujuchuli3();
- }
- if(wanzhengdezushu>10){ //11
- zifuweizhiA=number11A;
- zifuweizhiB=number11B;
- shujuchuli2();
- shujuchuli3();
- }
- if(wanzhengdezushu>11){ //12
- zifuweizhiA=number12A;
- zifuweizhiB=number12B;
- shujuchuli2();
- shujuchuli3();
- }
- }
- void luanqizaobaB()
- {
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////时间部分
-
- //获取当前日期和时间
- DateTime now = RTC.now();
- //通过串口传送当前的日期和时间
- printDateTime(now);
- //尚缺一个部分,即授时的条件 授时启动(时间有偏差) + gps已经定位(gps时间本身可用),
- //////////////////////////////////////////////
- if(dingweiok){
- if(yue != utc8y) shoushiqidong=1;
- if(ri != utc8r) shoushiqidong=1;
- if(shi != utc8s) shoushiqidong=1;
- if(fen != utc8f) shoushiqidong=1;
- if(miao-utc8m>2 || utc8m-miao>2) shoushiqidong=1; //秒允许差3秒
- if(shoushiqidong){ //ds1307 重置时间
- shoushiqidong=0;
- //年
- RTC.set(RTC_YEAR, utc8n);
- //月
- RTC.set(RTC_MONTH, utc8y);
- //日
- RTC.set(RTC_DAY, utc8r);
- //时
- RTC.set(RTC_HOUR, utc8s);
- //分
- RTC.set(RTC_MINUTE, utc8f);
- //秒
- RTC.set(RTC_SECOND, utc8m);
- }
- }
-
- x=nian*0.1;
- x=x%10;
- temp2[7] = x+48, DEC;
- x=nian%10;
- temp2[8] = x+48, DEC;
-
-
- x=yue*0.1;
- temp2[10] = x+48, DEC;
- x=yue%10;
- temp2[11] = x+48, DEC;
-
-
- x=ri*0.1;
- temp2[13] = x+48, DEC;
- x=ri%10;
- temp2[14] = x+48, DEC;
-
- x=shi*0.1;
- temp2[16] = x+48, DEC;
- x=shi%10;
- temp2[17] = x+48, DEC;
-
- x=fen*0.1;
- temp2[19] = x+48, DEC;
- x=fen%10;
- temp2[20] = x+48, DEC;
-
-
- x=miao*0.1;
- temp2[22] = x+48, DEC;
- x=miao%10;
- temp2[23] = x+48, DEC;
- }
- void luanqizaobaC()
- {
-
- //////////////////////////////////////////// 温度、湿度部分
- //DS18B20 取温度
- sensors.requestTemperatures();
- int wendu=sensors.getTempCByIndex(0);
- //DHT11取湿度
- DHT11.read(DHT11PIN);
- int shidu=DHT11.humidity;
-
- x=shidu*0.1;
- temp2[125] = x+48;//湿度十位
- x=shidu%10;
- temp2[126] = x+48;//湿度个位
-
- x=wendu*0.1;
- temp2[129] = x+48;//温度十位
- x=wendu%10;
- temp2[130] = x+48;//温度个位
- //打印整个临时数组temp2
- if(jsq6==3){
- Serial.println(temp2);
- Serial.println(temp4);
- //Serial.println(temp1);
- Serial.print("freeMemory()=");
- Serial.println(freeMemory());
- }
-
-
-
-
-
- //清空临时数组temp1
- for(int col=0;col<450;col++)temp1[col]=0;
-
-
-
- }
- void fenchentou()
- {
-
- ////////////////////////
-
- dustVal=analogRead(MQ2Pin);
-
- x=dustVal*4.882*0.001;
- if(x==0) temp2[117] = 32;//空格
- else temp2[117] = x+48, DEC;//千
-
- x=dustVal*4.882*0.01;
- x=x%10;
- if(x==0 && temp2[117] == 32) temp2[118] = 32;//空格 ,在空气质量极好的地反,小于100mv的情况
- else temp2[118] = x+48, DEC;//百
- x=dustVal*4.882*0.1;
- x=x%10;
- temp2[119] = x+48, DEC;//十
-
- x=dustVal*4.882;
- x=x%10;
- temp2[120] = x+48, DEC;//个
-
-
-
- }
- //////////////////////////////////////////////////////////////////////////////////////
- //子程序数据处理1,计算出“完整的$-*组数”,以及每组的起始位置
- void shujuchuli1()
- {
- //这个是典型的先接受,后处理的程序,因为需要逐个检查,所以接收多少字符就要循环多少次
- //其主要目的是找出$、*的位置,以400个字节及手上模块(垃圾佬处买的洋垃圾破模块+自己暴力拆解)的表现,
- //此处最多出现四组,完整的最多2组(*后带校验码)
- //但完整的gps NMEA-0183应当有6+x($GPGSV有多组),正常都是9组以上数据,即使x不输出,也有6组数据
- //(个人观点)最有价值的是$GPGGA、$GPRMC
- for(int col=0;col<jsq1;col++){
- //$第一次
- if(temp1[col]=='$' && change0){
- change0=0;
- change1=1;
- number1A=col; //记录第一个$号的位置
- }
- //*第一次
- if(temp1[col]=='*' && change1){
- change1=0;
- change2=1;
- number1B=col; //记录第一个*号的位置
- }
- //////////////////////////////////////////////////////
- //$第二次
- if(temp1[col]=='$' && change2){
- change2=0;
- change3=1;
- number2A=col; //记录第2个$号的位置
- }
- //*第二次
- if(temp1[col]=='*' && change3){
- change3=0;
- change4=1;
- number2B=col; //记录第2个*号的位置
- }
-
- //////////////////////////////////////////////////////
- //$第三次
- if(temp1[col]=='$' && change4){
- change4=0;
- change5=1;
- number3A=col; //记录第3个$号的位置
- }
- //*第三次
- if(temp1[col]=='*' && change5){
- change5=0;
- change6=1;
- number3B=col; //记录第3个*号的位置
- }
-
- //////////////////////////////////////////////////////
- //$第四次
- if(temp1[col]=='$' && change6){
- change6=0;
- change7=1;
- number4A=col; //记录第4个$号的位置
- }
- //*第四次
- if(temp1[col]=='*' && change7){
- change7=0;
- change8=1;
- number4B=col; //记录第4个*号的位置
- }
-
- //////////////////////////////////////////////////////
- //$第5次
- if(temp1[col]=='$' && change8){
- change8=0;
- change9=1;
- number5A=col; //记录第5个$号的位置
- }
- //*第5次
- if(temp1[col]=='*' && change9){
- change9=0;
- change10=1;
- number5B=col; //记录第5个*号的位置
- }
-
- //////////////////////////////////////////////////////
- //$第6次
- if(temp1[col]=='$' && change10){
- change10=0;
- change11=1;
- number6A=col; //记录第5个$号的位置
- }
- //*第6次
- if(temp1[col]=='*' && change11){
- change11=0;
- change12=1;
- number6B=col; //记录第6个*号的位置
- }
-
- //////////////////////////////////////////////////////
- //$第7次
- if(temp1[col]=='$' && change12){
- change12=0;
- change13=1;
- number7A=col; //记录第7个$号的位置
- }
- //*第7次
- if(temp1[col]=='*' && change13){
- change13=0;
- change14=1;
- number7B=col; //记录第7个*号的位置
- }
-
- //////////////////////////////////////////////////////
- //$第8次
- if(temp1[col]=='$' && change14){
- change14=0;
- change15=1;
- number8A=col; //记录第8个$号的位置
- }
- //*第8次
- if(temp1[col]=='*' && change15){
- change15=0;
- change16=1;
- number8B=col; //记录第8个*号的位置
- }
- //////////////////////////////////////////////////////
- //$第9次
- if(temp1[col]=='$' && change16){
- change16=0;
- change17=1;
- number9A=col; //记录第9个$号的位置
- }
- //*第9次
- if(temp1[col]=='*' && change17){
- change17=0;
- change18=1;
- number9B=col; //记录第8个*号的位置
- }
- //////////////////////////////////////////////////////
- //$第10次
- if(temp1[col]=='$' && change18){
- change18=0;
- change19=1;
- number10A=col; //记录第10个$号的位置
- }
- //*第10次
- if(temp1[col]=='*' && change19){
- change19=0;
- change20=1;
- number10B=col; //记录第10个*号的位置
- }
-
- //////////////////////////////////////////////////////
- //$第11次
- if(temp1[col]=='$' && change20){
- change20=0;
- change21=1;
- number11A=col; //记录第11个$号的位置
- }
- //*第10次
- if(temp1[col]=='*' && change21){
- change21=0;
- change22=1;
- number11B=col; //记录第11个*号的位置
- }
-
- //////////////////////////////////////////////////////
- //$第12次
- if(temp1[col]=='$' && change22){
- change22=0;
- change23=1;
- number12A=col; //记录第12个$号的位置
- }
- //*第12次
- if(temp1[col]=='*' && change23){
- change23=0;
- change24=1;
- number12B=col; //记录第12个*号的位置
- }
-
-
- }
- //分别找出$、*的位置后,首先就要验证数据的可靠性
- //计算校验码,并与所收到的校验码对比
- //计算完整的$-*组数
- //Serial.print("wanzhengde $-*geshu=");
- if(change24){
- //完整的12组$--*
- wanzhengdezushu=12;
- }else if(change23 || change22){
- wanzhengdezushu=11;
- }else if(change21 || change20){
- wanzhengdezushu=10;
- }else if(change19 || change18){
- wanzhengdezushu=9;
- }else if(change17 || change16){
- wanzhengdezushu=8;
- }else if(change15 || change14){
- wanzhengdezushu=7;
- }else if(change13 || change12){
- wanzhengdezushu=6;
- }else if(change11 || change10){
- wanzhengdezushu=5;
- }else if(change9 || change8){
- wanzhengdezushu=4;
- /////////////////////////////////////////////////////////////////
- }else if(change7 || change6){
- //change7=1是第四组仅找到$,而没有*
- //change6=1只找到了完整的3组$--*
- wanzhengdezushu=3;
- //Serial.println(wanzhengdezushu);
- }else if(change5 || change4){
- //change5=1是第3组仅找到$,而没有*
- //change4=1只找到了完整的2组$--*
- wanzhengdezushu=2;
- //Serial.println(wanzhengdezushu);
- }else if(change3 || change2){
- //change3=1是第2组仅找到$,而没有*
- //change2=1只找到了完整的1组$--*
- wanzhengdezushu=1;
- //Serial.println(wanzhengdezushu);
- }else if(change1 || change0){
- //change1=1是第1组仅找到$,而没有*
- //change0=1连第一组的$都没找到,原始状态~~~啥玩意?
- wanzhengdezushu=0;
- //Serial.println(wanzhengdezushu);
- }
- }
- //子程序数据处理2,进行异或运算的处理(对比校验码)
- void shujuchuli2(){
- //zifuweizhiB-zifuweizhiA-1;*号本身不参与异或运算,所以差值还要减1
- for(int col=0;col<zifuweizhiB-zifuweizhiA-1;col++){
- if(col==0)yihuoyunsuan=temp1[col+zifuweizhiA+1];
- else yihuoyunsuan=yihuoyunsuan ^ temp1[col+zifuweizhiA+1];
- }
- //因为定义int的时候,yihuoyunsuan的结果是以10进制DEC表示的,所以需转换为16进制HEX
- //因为GPS校验数据0位也进行了传输,所以在转换的时候有必要将情况分类讨论
- //(yihuoyunsuan=0)/(0<yihuoyunsuan<17)/(17<yihuoyunsuan)
- if(yihuoyunsuan==0){
- //校验数10进制为0,直接填充字符串00
- jianyan="00";
- }else if(yihuoyunsuan>15){
- //此时转换为16进制以后,天然有2位,很理想,不用处理
- jianyan = String(yihuoyunsuan,HEX);
- }else{
- //校验数10进制为1-15时,转换为16进制就只有1位数,所以需要在前面填0
- jianyan = "0";
- jianyan += String(yihuoyunsuan,HEX);
- }
- //实践中发现,jianyan中的字符是以小写方式存在,虽然Serial.println(yihuoyunsuan,HEX)会以大写方式打印出来
- //但直接Serial.println(jianyan)就是小写的,这是啥情况?
- //将其字母转换为大写,否则与GPS传输的校验码对比时大小写问题校验失败(GPS传输的校验码为大写的)
- jianyan.toUpperCase();
- ///////////////////////////////////////////显示异或校验码,方便给GPS编程,虽然还没成功过
- //Serial.print("jianyan=");
- //Serial.println(jianyan);
- //与GPS传输的校验码进行对比
- if(jianyan[0]==temp1[zifuweizhiB+1] && jianyan[1]==temp1[zifuweizhiB+2]){
- //一致,则说明数据是有效的,输出校验结果
- jiaoyanjieguo=1;
- }else{
- //不一致
- jiaoyanjieguo=0;
- }
- //对校验数组进行清零
- jianyan="";
- }
- //子程序数据处理3,有效的字符串究竟是什么?以及相应的操作
- void shujuchuli3(){
- /*
- 常见的GPS发送字符串如下
- $GPGGA,
- $GPGLL,
- $GPGSA,
- $GPGST,
- $GPGSV,
- $GPRMC,
- $GPVTG,
- 鉴于最后2位不同,所以用判断$+4、$+5 两个位置的字符来判断所收到的究竟是什么信息
- */
- if(jiaoyanjieguo){
- jiaoyanjieguo=0;//使用后则置0,以免影响后续计算
- if(temp1[zifuweizhiA+4]=='G' && temp1[zifuweizhiA+5]=='A'){
- //$GPGGA C3-470B有
- for(int col=0;col<zifuweizhiB-zifuweizhiA-1;col++){
-
- if(temp1[zifuweizhiA+1+col]=='N' || temp1[zifuweizhiA+1+col]=='S')weidubiaoji=col;//纬度标记(纬度半球)
- if(temp1[zifuweizhiA+1+col]=='E' || temp1[zifuweizhiA+1+col]=='W')jingdubiaoji=col;//经度标记(经度半球)
- }
- if(temp1[zifuweizhiA+jingdubiaoji+3]=='1' || temp1[zifuweizhiA+jingdubiaoji+3]=='2'){ //检查gps状态位
- //1=非差分定位,2=差分定位,这种情况下,数据是有意义的
- dingweiok=1;//已经定位
- //Serial.print("UTC time:");
- //for(int col=0;col<10;col++) Serial.print(temp1[zifuweizhiA+7+col]);
- //Serial.println();
- //纬度
- memcpy(temp2+35,temp1+zifuweizhiA-9+weidubiaoji, 2);
- memcpy(temp2+38,temp1+zifuweizhiA-7+weidubiaoji, 7);
-
- memcpy(temp2+46,temp1+zifuweizhiA+1+weidubiaoji, 1);
- //经度
- memcpy(temp2+59,temp1+zifuweizhiA+weidubiaoji+3, 3);
- memcpy(temp2+63,temp1+zifuweizhiA+weidubiaoji+6, 7);
- memcpy(temp2+71,temp1+zifuweizhiA+1+jingdubiaoji, 1);
- //可用卫星数
- memcpy(temp2+85,temp1+zifuweizhiA+jingdubiaoji+5, 2);
-
-
- //海拔计算
- for(int col=0;col<13;col++) {
- if(temp1[zifuweizhiA+jingdubiaoji+8+col]==',' && !altitudeC){
- altitudeA=col;
- altitudeC=1;
- col++;
- }
-
- if(temp1[zifuweizhiA+jingdubiaoji+8+col]==',' && altitudeC){
- altitudeB=col;
- altitudeC=0;
- //结束循环
- col=13;
- }
- }
-
- //海拔-999.9--9999.9
- if(altitudeB-altitudeA-1==3){
- temp2[98]=32;//空格
- temp2[99]=32;
- temp2[99]=32;
- memcpy(temp2+101,temp1+zifuweizhiA+jingdubiaoji+9+altitudeA, 3);
- }else if(altitudeB-altitudeA-1==4){
- temp2[98]=32;//空格
- temp2[99]=32;
- memcpy(temp2+100,temp1+zifuweizhiA+jingdubiaoji+9+altitudeA, 4);
- }else if(altitudeB-altitudeA-1==5){
- temp2[98]=32;//空格
- memcpy(temp2+99,temp1+zifuweizhiA+jingdubiaoji+9+altitudeA, 5);
- }else if(altitudeB-altitudeA-1==6){
- memcpy(temp2+98,temp1+zifuweizhiA+jingdubiaoji+9+altitudeA, 6);
- }
- // memcpy(temp2+98,temp1+zifuweizhiA+jingdubiaoji+9+altitudeA, altitudeB-altitudeA-1);
- }else{
- //剩下的就是,未定位、正在估算,这2种情况都属于数据无意义,所以对输出数组的相应部分进行填充
- dingweiok=0;//没有定位
- temp2[35]=95;//下划线,纬度
- temp2[36]=95;
- temp2[38]=95;
- temp2[39]=95;
- temp2[41]=95;
- temp2[42]=95;
- temp2[43]=95;
- temp2[44]=95;
- temp2[46]=95;
- //////////////////////////////经度
- temp2[59]=95;
- temp2[60]=95;
- temp2[61]=95;
- temp2[63]=95;
- temp2[64]=95;
- temp2[66]=95;
- temp2[67]=95;
- temp2[68]=95;
- temp2[69]=95;
- temp2[71]=95;
- //////////////////////////////卫星数、海拔
- temp2[85]=95;
- temp2[86]=95;
- temp2[98]=95;
- temp2[99]=95;
- temp2[100]=95;
- temp2[101]=95;
- temp2[103]=95;
- }
- }else if(temp1[zifuweizhiA+4]=='L' && temp1[zifuweizhiA+5]=='L'){
- //$GPGLL
- }else if(temp1[zifuweizhiA+4]=='S' && temp1[zifuweizhiA+5]=='A'){
- //$GPGSA C3-470B有
- }else if(temp1[zifuweizhiA+4]=='S' && temp1[zifuweizhiA+5]=='T'){
- //$GPGST
- }else if(temp1[zifuweizhiA+4]=='S' && temp1[zifuweizhiA+5]=='V'){
- //$GPGSV C3-470B有
- }else if(temp1[zifuweizhiA+4]=='M' && temp1[zifuweizhiA+5]=='C'){
- //$GPRMC C3-470B有
- ///////////////////////////////////////////////////////////////////////////////////
- //$GPRMC,143716.000,A,2936.49838,N,10634.13016,E,0.1,273.6,120314,2.1,W,A*13
- //时间部分:UTC转为UTC+8,北京时间(时:分:秒)
- //时:
- jianyan = String(temp1[zifuweizhiA+7]);//复用jianyan这个数组来节约内存
- jianyan += temp1[zifuweizhiA+8];
- utc8s=jianyan.toInt()+8;
- if(utc8s>23)rijinwei=1;//提示后面程序换算为北京时间的时候,日要+1天
- utc8s=utc8s%24;//字符串转换为整数,参与运算
- //分:
- jianyan = String(temp1[zifuweizhiA+9]);//复用jianyan这个数组来节约内存
- jianyan += temp1[zifuweizhiA+10];
- utc8f=jianyan.toInt();//字符串转换为整数,参与运算
- //秒:
- jianyan = String(temp1[zifuweizhiA+11]);//复用jianyan这个数组来节约内存
- jianyan += temp1[zifuweizhiA+12];
- utc8m=jianyan.toInt();//字符串转换为整数,参与运算
- ////////////////////////////////////////////////
- //提取UTC日期(日、月、年),这个日期位于GPRMC第9个数据中,所以定位第九个逗号的位置即可
- jsq2=0;
- jsq3=0;
- jsq4=0;
- jsq5=0;
- for(int col=0;col<zifuweizhiB-zifuweizhiA-1;col++){
- if(temp1[zifuweizhiA+1+col]==',')jsq2++;
- if(jsq2==9){
- jsq3=col;//找到9第个逗号的前一个位置,循环0开始,0的时候就已经后推了一位置
- col=zifuweizhiB-zifuweizhiA;//找到9个逗号就跳出循环
- }
- if(jsq2<8){
- jsq4=col;//找到8第个逗号的前2个位置,即“地面速率(节)”的最后一位
- }
- if(jsq2<7){
- jsq5=col;//找到7第个逗号的前2个位置,即“经度标记”
- }
- }
- //日
- jianyan = String(temp1[zifuweizhiA+jsq3+2]);//复用jianyan这个数组来节约内存,9第个逗号前一位后推2个位置
- jianyan += temp1[zifuweizhiA+jsq3+3];
- utc8r=jianyan.toInt();//字符串转换为整数,参与运算
- //月
- jianyan = String(temp1[zifuweizhiA+jsq3+4]);//复用jianyan这个数组来节约内存
- jianyan += temp1[zifuweizhiA+jsq3+5];
- utc8y=jianyan.toInt();//字符串转换为整数,参与运算
- //年
- jianyan = String(temp1[zifuweizhiA+jsq3+6]);//复用jianyan这个数组来节约内存
- jianyan += temp1[zifuweizhiA+jsq3+7];
- utc8n=jianyan.toInt();//字符串转换为整数,参与运算
- // 地面速率(000.0~999.9节、地面航向(000.0~359.9度
- x=jsq4-jsq5-1;
- //Serial.print("jsq4-jsq5=");
- //Serial.println(x);
- if(x==6){
- memcpy(temp4+6,temp1+zifuweizhiA+jsq5+3, 6);//地面速率部分
- }else if(x==5){
- temp4[6]=32;//空格
- memcpy(temp4+7,temp1+zifuweizhiA+jsq5+3, 5);//地面速率部分
- }else if(x==4){
- temp4[6]=32;//空格
- temp4[7]=32;//空格
- memcpy(temp4+8,temp1+zifuweizhiA+jsq5+3, 4);//地面速率部分
- }else if(x==3){
- temp4[6]=32;//空格
- temp4[7]=32;//空格
- temp4[8]=32;//空格
- memcpy(temp4+9,temp1+zifuweizhiA+jsq5+3, 3);//地面速率部分
- }else {//没数据的情况
- temp4[6]=32;//空格
- temp4[7]=32;//空格
- temp4[8]=95;//空格
- temp4[9]=95;//_
- temp4[10]=46;//.
- temp4[11]=95;//_
- }
- x=jsq3-jsq4-2;
- //Serial.print("jsq3-jsq4=");
- //Serial.println(x);
- if(x==6){
- memcpy(temp4+26,temp1+zifuweizhiA+jsq4+3, 6);// 地面航向部分
- }else if(x==5){
- temp4[26]=32;//空格
- memcpy(temp4+27,temp1+zifuweizhiA+jsq4+3, 5);//地面速率部分
- }else if(x==4){
- temp4[26]=32;//空格
- temp4[27]=32;//空格
- memcpy(temp4+28,temp1+zifuweizhiA+jsq4+3, 4);//地面速率部分
- }else if(x==3){
- temp4[26]=32;//空格
- temp4[27]=32;//空格
- temp4[28]=32;//空格
- memcpy(temp4+29,temp1+zifuweizhiA+jsq4+3, 3);//地面速率部分
- }else {//没数据的情况
- temp4[26]=32;//空格
- temp4[27]=32;//空格
- temp4[28]=95;//空格
- temp4[29]=46;//.
- temp4[30]=95;//_
- temp4[31]=95;//_
- }
- jsq2=0; //防止以后会用,先行清零
- jsq3=0;
- jsq4=0;
- jsq5=0;
- //讨论日、月、年进位(大月、小月、平年、闰年的问题)
- if(rijinwei){
- //先讨论2月的问题
- if(utc8y==2 && utc8r==28){
- if(utc8n%4==0)utc8r=29;//闰年可加一天
- else {
- utc8r=1;
- yuejinwei=1;
- }
- }else{
- //判断大小月
- for(int col=0;col<4;col++){
- if(xiaoyue[col]==utc8y)xiaoyueok=1;
- }
- if(xiaoyueok && utc8r==30){ //小月最后一天
- utc8r=1;
- yuejinwei=1;
- }else if(!xiaoyueok && utc8r==31){ //大月最后一天
- utc8r=1;
- yuejinwei=1;
- }else{
- utc8r++;//剩下的情况自加1就可以了
- }
- }
- }
- if(yuejinwei && utc8y==12){ //最后一月
- utc8y=1;
- nianjinwei=1;
- }else if(yuejinwei){
- utc8y++;
- }
- if(nianjinwei)utc8n++;
- ////////////////
- //////////////////////////////////////////////////////////////////////////////////
- }else if(temp1[zifuweizhiA+4]=='T' && temp1[zifuweizhiA+5]=='G'){
- //$GPVTG
- }
- }
- }
- void printDateTime(DateTime dateTime) {
- //传送年份
- nian=dateTime.year(), DEC;
-
- //传送月份
- yue=dateTime.month(), DEC;
- //传送月份中的第几天
- ri=dateTime.day(), DEC;
- //传送小时
- shi=dateTime.hour(), DEC;
- //传送分钟
- fen=dateTime.minute(), DEC;
- //传送秒
- miao=dateTime.second(), DEC;
- }
-
-
- void lcd1602out(){
- jsq6=jsq6%4;
-
- //清空第一排的所有内容
- lcd.setCursor(0, 0);
- for(int col=0;col<16;col++){
- lcd.write(1);
- }
-
- lcd.setCursor(0, 0);//回归第一排,第一点
- for(int col=0;col<27;col++)temp3[col]=0;//清空1602打印数组,备用
-
- if(jsq8){
- //蓝牙gps模式
-
- if(jsq6==0){
-
- temp3[0]='G';
- temp3[1]='P';
- temp3[2]='S';
- temp3[3]=32;
- temp3[4]='O';
- temp3[5]='U';
- temp3[6]='T';
- temp3[7]=32;
- memcpy(temp3+8,temp2+16, 8);//时间部分(00/00 00:00:00)
-
- }else if(jsq6==1){
-
- if(dingweiok){ //已定位的情况下,显示纬度
-
- temp3[0]='G';
- temp3[1]='P';
- temp3[2]='S';
- temp3[3]=32;
- memcpy(temp3+4,temp2+35, 12);//纬度部分纯数字
- }else{
- //未定位的情况下,please wait
- temp3[0]=32;
- temp3[1]='l';
- temp3[2]='a';
- temp3[3]='t';
- temp3[4]='.';
- temp3[5]=32;
- temp3[6]='a';
- temp3[7]='n';
- temp3[8]='d';
- temp3[9]=32;
- temp3[10]='L';
- temp3[11]='O';
- temp3[12]='N';
- temp3[13]='G';
- temp3[14]='.';
-
- }
-
-
- }else if(jsq6==2){
-
-
- if(dingweiok){ //已定位的情况下,显示速度
-
- memcpy(temp3,temp4, 14);//速度部分(节)
-
- }else{
- //未定位的情况下,please wait
- temp3[0]='s';
- temp3[1]='p';
- temp3[2]='e';
- temp3[3]='e';
- temp3[4]='d';
- temp3[5]='&';
- temp3[6]='d';
- temp3[7]='i';
- temp3[8]='r';
- temp3[9]='e';
- temp3[10]='c';
- temp3[11]='t';
- temp3[12]='i';
- temp3[13]='o';
- temp3[14]='n';
-
- }
-
- }else if(jsq6==3){
-
-
- //空气质量检测模式
-
-
- memcpy(temp3,temp2+10, 14);//时间部分(00/00 00:00:00)
-
-
-
- jsq7++; //MQ-2的控制参数1,数秒
- jsq7=jsq7%10;//10秒循环一次
-
- if(jsq7==1)fenchentou();//十秒一轮回
-
- }
-
-
-
- }else{
-
- //浇花程序的1602第1行显示部分
-
- x=shishiliuliang*0.1; //实时流量的十位
- if(x==0) temp3[0]=32;
- else temp3[0]=x+48, DEC;
-
- x=shishiliuliang;
- x=x%10; //实时流量的个位
- temp3[1]=x+48, DEC;
-
- temp3[2]='.';//小数点
-
- x=(shishiliuliang*10); //实时流量的十分位
- x=x%10;
- temp3[3]=x+48, DEC;
-
- temp3[4]='L';
- temp3[5]='/';
- temp3[6]='m';
- temp3[7]='i';
- temp3[8]='n';
- temp3[9]=32;
-
- temp3[10]='S';
- temp3[11]='D';
- temp3[12]=':';
-
- x=shedingjiaoguanliang*0.1; //设定浇灌量的十位
- if(x==0) temp3[13]=32;
- else temp3[13]=x+48, DEC;
-
- x=shedingjiaoguanliang%10; //设定浇灌量的个位
- temp3[14]=x+48, DEC;
-
-
- temp3[15]='L';
-
-
- }
-
-
- lcd.print(temp3);
-
-
- //清空第2排的所有内容
- lcd.setCursor(0, 1);
- for(int col=0;col<16;col++){
- lcd.write(1);
- }
-
- lcd.setCursor(0, 1);//回归第2排,第一点
- for(int col=0;col<27;col++)temp3[col]=0;//清空1602打印数组,备用
-
-
-
- if(jsq8){
- //蓝牙gps模式
-
- if(jsq6==0){
-
- if(dingweiok){ //已定位的情况下,显示卫星、海拔
- temp3[0]='n';
- temp3[1]='u';
- temp3[2]='m';
-
- memcpy(temp3+3,temp2+84, 3);//卫星数部分(num:00)
- temp3[6]=32;
- temp3[7]=32;
- memcpy(temp3+8,temp2+98, 8);//海拔部分( 000.0 M)
- }else{
- //未定位的情况下,Search GPS ing..
- temp3[0]='S';
- temp3[1]='e';
- temp3[2]='a';
- temp3[3]='r';
- temp3[4]='c';
- temp3[5]='h';
- temp3[6]=32;
- temp3[7]='G';
- temp3[8]='P';
- temp3[9]='S';
- temp3[10]=32;
- temp3[11]='i';
- temp3[12]='n';
- temp3[13]='g';
- temp3[14]='.';
- temp3[15]='.';
-
- }
-
-
- }else if(jsq6==1){
-
- if(dingweiok){ //已定位的情况下,显示经度
-
- temp3[0]=32;
- temp3[1]=32;
- temp3[2]=32;
- memcpy(temp3+3,temp2+59, 13);//经度部分纯数字
-
- }else{
- //未定位的情况下,Search GPS ing..
-
- temp3[0]='S';
- temp3[1]='e';
- temp3[2]='a';
- temp3[3]='r';
- temp3[4]='c';
- temp3[5]='h';
- temp3[6]=32;
- temp3[7]='G';
- temp3[8]='P';
- temp3[9]='S';
- temp3[10]=32;
- temp3[11]='i';
- temp3[12]='n';
- temp3[13]='g';
- temp3[14]='.';
- temp3[15]='.';
-
- }
-
-
- }else if(jsq6==2){
-
-
- if(dingweiok){ //已定位的情况下,显示航向
-
- memcpy(temp3,temp4+19, 13);//航向部分
-
- }else{
- //未定位的情况下,Search GPS ing..
-
- temp3[0]='S';
- temp3[1]='e';
- temp3[2]='a';
- temp3[3]='r';
- temp3[4]='c';
- temp3[5]='h';
- temp3[6]=32;
- temp3[7]='G';
- temp3[8]='P';
- temp3[9]='S';
- temp3[10]=32;
- temp3[11]='i';
- temp3[12]='n';
- temp3[13]='g';
- temp3[14]='.';
- temp3[15]='.';
-
- }
-
- }else if(jsq6==3){
-
- //空气质量检测模式
-
- memcpy(temp3,temp2+125, 7);//湿度、温度;
- temp3[7]=32;
- memcpy(temp3+8,temp2+117, 7);//gp2y1010
-
-
- }
-
-
-
- }else{
-
- //浇花程序的1602第2行显示部分
-
- temp3[0]='T';
- temp3[1]='o';
- temp3[2]='t';
- temp3[3]='a';
- temp3[4]='l';
- temp3[5]=':';
-
- x=leijiliuliang*0.1; //累计流量的十位
- if(x==0) temp3[6]=32;
- else temp3[6]=x+48, DEC;
-
- x=leijiliuliang; //累计流量的个位
- x=x%10; //累计流量的个位
- temp3[7]=x+48, DEC;
-
- temp3[8]='.';
-
- x=leijiliuliang*10; //累计流量的十分位
- x=x%10; //累计流量的十分位
- temp3[9]=x+48, DEC;
-
-
- x=leijiliuliang*100; //累计流量的百分位
- x=x%10;
- temp3[10]=x+48, DEC;
-
- temp3[11]=32;
- temp3[12]='L';
-
- }
-
-
- lcd.print(temp3);
-
-
-
- }
-
-
- void jiaohuaA(){
-
- if(millis()-meimiaoyilunhui>1000) {
-
- meimiaoyilunhui=millis();//每一秒还原一次
- shishiliuliang=jsqLLx/7.5;//计算实时流量(公式:频率=7.5*流量(L/min))
- leijiliuliang=leijiliuliang+(shishiliuliang/60);//(每秒积分)计数累计流量
-
- lcd1602out();//每秒钟刷新显示类容
-
- guzhangjiancejsq=guzhangjiancejsq+jsqLLx;//累加频率的数量,来确定是否故障(停水了)
- jsqLLx=0;//清空每秒频率
-
- }else{
- int liuliangjidianping =digitalRead(liuliangji);//读取流量计的电平
-
- if(liuliangjidianping == HIGH && !chongfupanduanA){ //高电平 且 本次没计数,就计数
- jsqLLx++;
- chongfupanduanA=!chongfupanduanA;//本次已计数,则标记已计数
- }
-
- if(liuliangjidianping == LOW && chongfupanduanA)chongfupanduanA=!chongfupanduanA;//低电平,且 计数标记为1,则重置计数标记
- }
-
- }
-
- void jiaohuaB(){
-
- //停水状态的应急处理
- if(millis()-guzhangjianceA>30000) {
-
-
- if(guzhangjiancejsq<210){//3秒累计频率小于21,则说明流量小于1L/min,这个时候认定为停水了
- jsq8=!jsq8;//跳出浇花模式
- //切换模式之后,对浇花部分进行操作(即停止浇花)
- digitalWrite(diancifa, HIGH);//关闭电磁阀
- shedingjiaoguanliang=0;//清空设定浇灌量
- leijiliuliang=0;//清空累计流量
- guzhangjianceA=millis();//同时清空故障检测的时间,否则一开始就是故障状态
-
- }
-
- guzhangjiancejsq=0;//累计频率置0
-
-
- }
-
- }
复制代码 |
|