兰州理工大学后花园盐渍土参数-Arduino中文社区 - Powered by Discuz! Archiver

王大富 发表于 2021-8-3 10:25

兰州理工大学后花园盐渍土参数

本帖最后由 王大富 于 2021-8-7 04:24 编辑

主程序
#include <ESP8266WiFi.h>                         //esp8266wifi模块库
#include <ESP8266WiFiMulti.h>                  //自动链接最强wifi库
#include <DNSServer.h>                           //WiFiManager库要用的
#include <PubSubClient.h>                        //MQTT协议中的库
#include <Ticker.h>                              //时间记录库
#include <ArduinoJson.h>                         //调用Json数据库
#include <Wire.h>
//#include <WiFiManager.h>                         //WiFiManager库
#include "DHTesp.h"                              //温度DHT11模块函数库
#include "FastLED.h"                           //FastLED库用于调用随机函数库
#include <stdlib.h>                              //接收数据的转化
#include <stdio.h>

#include "JXBS.h"                              //土壤湿度库
#define debugSerial Serial1


#define PRODUCT_ID ""//Onenote产品名(需修改)
#define API_KEY    ""//产品密钥(需修改)
#define DEVICE_ID""                   //设备名(需修改),与开发板没有关系,由平台生成的
const char* mqttServer = "183.230.40.39";      //onenet地址(不修改)
const uint16_t mqttPort = 6002;                  //mqtt接口端口(不修改)
#define TOPIC      "ceshitopic1"               //订阅主题



#define LED1 D2
#define LED2 D3
#define LVDT_pin A0

ESP8266WiFiMulti wifiMulti;                      //自动链接wifi
DHTesp dht;                                    //温度
WiFiClient wifiClient;                           //
PubSubClient mqttClient(wifiClient);             //
Ticker ticker;                                 //用于记录时间

int count=0,aa =0,bt=0;                               //定义参数变量
char msgJson;//msgJson数据长度
char msg_buf;//
char dataTemplate[] = "{\"RH5\":%.2f,\"T5\":%.2f,\"EC5\":%.2f,\"pH5\":%.2f}";//char dataTemplate[] = "{\"temp\":%.2f,\"hum\":%.2f,\"rand\":%d,\"sin\":%.2f,\"butt\":%2d}";
extern floatT2 = 0.0, RH2 = 0.0, EC2 = 0.0,pH2=0.0, T4 = 0.0, RH4 = 0.0, EC4 = 0.0,pH4=0.0;                                       


void setup() {                                  //里面的函数只执行一次
JXBSInit();
debugSerial.begin(9600);

wifiMulti.addAP("CMCC-PbWq","9bf07201");//添加多个wifi网络
wifiMulti.addAP("4G-UFI-19DE","seuseucyd");
wifiMulti.addAP("esp8266","esp82661");
wifiMulti.addAP("4G-UFI-5FD6","onenetesp8266");
      

WiFi.mode(WIFI_STA);                        //设置wifi模式
// dht.setup(D4, DHTesp::DHT11);               //温湿度模块DHT11初始化,D4脚位
connectWifi();                              //链接Wifi函数
mqttClient.setServer(mqttServer, mqttPort);   //mqttServer是onenet地址,mqtt接口端口mqttPort
mqttClient.setCallback(receiveCallback);      //设置MQTT订阅回调,函数
connectMQTTServer();                        //链接MQTT服务器函数
ticker.attach(1, tickerCount);
}

void loop() {                                 //里面的函数无限循环执行
if (mqttClient.connected()) {               //如果开发板成功连接服务器                                       
      pubMQTTmsg();                           //调用pubMQTTmsg()函数发送数据到云端
      delay(3000);
      mqttClient.loop();
} else {                                    //如果开发板未能成功连接服务器
    connectMQTTServer();                        //则尝试连接服务器
}
}

int tickerCount() {
count++;
}
void connectMQTTServer() {                     //通过MQTT协议链接Onenet
String clientId = DEVICE_ID;
String productId = PRODUCT_ID;
String apiKey = API_KEY;
if (mqttClient.connect(clientId.c_str(), productId.c_str(), apiKey.c_str())) {//连接MQTT服务器
//    Serial.println("MQTT Server Connected.");
//    Serial.println("Server Address: ");
//    Serial.println(mqttServer);
//    Serial.println("ClientId:");
//    Serial.println(clientId);
    subscribeTopic();                        //订阅指定主题
} else {
    //Serial.print("MQTT Server Connect Failed. Client State:");
   // Serial.println(mqttClient.state());
    delay(3000);
}
}
                                             
void subscribeTopic() {//订阅指定主题,主题名称以Taichi-Maker-Sub为前缀,后面添加设备的MAC地址
String topicString = "temperature"+ WiFi.macAddress();
char subTopic;
strcpy(subTopic, topicString.c_str());       //                                                
if (mqttClient.subscribe(subTopic)){         //通过串口监视器输出是否成功订阅主题以及订阅的主题名称
    //Serial.println("Subscrib Topic:");
    //Serial.println(subTopic);
} else {
    //Serial.print("Subscribe Fail...");
}
}

void receiveCallback(char* topic, byte* payload, unsigned int length) {//反调函数用于接收平台下发的消息
//Serial.print("Message Received [");
// Serial.print(topic);
//Serial.print("]");               
for (int i = 0; i < length; i++){//按字符一个一个输出
   // Serial.print((char)payload);
}
//Serial.println("");
// Serial.print("Message Length(Bytes)");
// Serial.println(length);
payload = '\0'; // 添加一个空值使其转化为字符数组
String payload1=(char *)payload;
int aNumber = atoi((char *)payload);//将字符数组转化为整型数组
//analogWrite(LED2, aNumber);
if (payload1 == "21"){//测试下发数据,如果收到的信息以“1”为开始
    //digitalWrite(LED2, HIGH);// 点亮LED。
//Serial.println("LED ON");
} else if (payload1 == "20"){
   // digitalWrite(LED2, LOW);//熄灭LED。
   // Serial.println("LED OFF");
}   
}                                                               
                                                                           
void pubMQTTmsg() {                              //onenet数据点上传系统主题
String topicString = "$dp";
char publishTopic;
strcpy(publishTopic, topicString.c_str());   //c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同,json数据转换为数组

////////////////////////////////////////////////////////////

readJXBS20();
delay(1000);
JXBSListen20();
RH2=RH_2*0.1;   
T2=temper_2*0.1;

delay(1000);

readJXBS21();
delay(1000);
JXBSListen21();
EC2=EC_2;

delay(1000);

readJXBS22();
delay(1000);
JXBSListen22();
pH2=pH_2*0.01;
////////////////////////////////////////////////


snprintf(msgJson, 130, dataTemplate,RH2,T2,EC2,pH2);//将模拟温湿度数据套入dataTemplate模板中, 生成的字符串传给msgJson
int json_len = strlen(msgJson);                //msgJson的长度
msg_buf = char(0x03);                     //要发送的数据必须按照ONENET的要求发送, 根据要求,数据第一位是3
msg_buf = char(json_len >> 8);            //数据第二位是要发送的数据长度的高八位
msg_buf = char(json_len & 0xff);            //数据第三位是要发送数据的长度的低八位
memcpy(msg_buf + 3, msgJson, strlen(msgJson)); //从msg_buf的第四位开始,放入要传的数据msgJson
msg_buf = 0;            //添加一个0作为最后一位, 这样要发送的msg_buf准备好了
//Serial.print("public message:");Serial.println(msgJson);//向串口发送订阅信息
mqttClient.publish("$dp", (uint8_t *)msg_buf, 3 + strlen(msgJson)); //发送数据到主题$dp
// Serial.println(strlen(msgJson));
}

void connectWifi() {                              //wifi连接函数
//Serial.print("Connecting...");
//WiFiManager wifiManager;// 建立WiFiManager对象
//wifiManager.resetSettings();// 清除ESP8266所存储的WiFi连接信息以便测试WiFiManager工作效果
//wifiManager.autoConnect("AutoConnectAP");// 自动连接WiFi。以下语句的参数是连接ESP8266时的WiFi名称
int ii=0;
while (wifiMulti.run() != WL_CONNECTED) {         //等待WiFi连接,成功连接后输出成功信息
delay(1000);
//Serial.print("ii++");Serial.print(" ");
}
//Serial.println('\n');                     // WiFi连接成功后
//Serial.print("Connected to ");            // NodeMCU将通过串口监视器输出。
//Serial.println(WiFi.SSID());            // 连接的WiFI名称
//Serial.print("IP address:\t");            // 以及IP
//Serial.println(WiFi.localIP());         // NodeMCU的IP地址
}子程序

#define MYADRESS2 0x05//485地址

//const unsigned charreadcmd20={MYADRESS2,0x03,0x00,0x12,0x00,0x02,0x64,0x0E}; //读取温湿度指令
//const unsigned charreadcmd21={MYADRESS2,0x03,0x00,0x15,0x00,0x01,0x95,0xCE}; //读取电导率指令
//const unsigned charreadcmd22={MYADRESS2,0x03,0x00,0x06,0x00,0x01,0x64,0x0B}; //读取pH指令

//const unsigned charreadcmd20={MYADRESS2,0x03,0x00,0x12,0x00,0x02,0x64,0x3D}; //读取温湿度指令
//const unsigned charreadcmd21={MYADRESS2,0x03,0x00,0x15,0x00,0x01,0x95,0xFD}; //读取电导率指令
//const unsigned charreadcmd22={MYADRESS2,0x03,0x00,0x06,0x00,0x01,0x64,0x38}; //读取pH指令
//
//const unsigned charreadcmd20={MYADRESS2,0x03,0x00,0x12,0x00,0x02,0x65,0xEC}; //读取温湿度指令
//const unsigned charreadcmd21={MYADRESS2,0x03,0x00,0x15,0x00,0x01,0x94,0x2C}; //读取电导率指令
//const unsigned charreadcmd22={MYADRESS2,0x03,0x00,0x06,0x00,0x01,0x65,0xE9}; //读取pH指令
//
//const unsigned charreadcmd20={MYADRESS2,0x03,0x00,0x12,0x00,0x02,0x64,0x5B}; //读取温湿度指令
//const unsigned charreadcmd21={MYADRESS2,0x03,0x00,0x15,0x00,0x01,0x95,0x9B}; //读取电导率指令
//const unsigned charreadcmd22={MYADRESS2,0x03,0x00,0x06,0x00,0x01,0x64,0x5E}; //读取pH指令
//
const unsigned charreadcmd20={MYADRESS2,0x03,0x00,0x12,0x00,0x02,0x65,0x8A}; //读取温湿度指令
const unsigned charreadcmd21={MYADRESS2,0x03,0x00,0x15,0x00,0x01,0x94,0x4A}; //读取电导率指令
const unsigned charreadcmd22={MYADRESS2,0x03,0x00,0x06,0x00,0x01,0x65,0x8F}; //读取pH指令


unsigned int RH_2=0,temper_2=0,EC_2=0,pH_2=0.0,RH_4=0,temper_4=0,EC_4=0,pH_4=0.0;//湿度

void JXBSInit()
{Serial.begin(9600);}

unsigned char com_buf; //接收数据缓存变量
bool rec_flag=false;
bool rec_flag1=false;
bool receive_success_flag=false;
bool receive_success_flag1=false;

//////////////////////////////////////////////////////////////////////////////////
void readJXBS20()
{Serial.write(readcmd20,8);//发射数据
}

void JXBSListen20()
{unsigned char com_num = 0;
while (Serial.available())
   {char inChar = (char)Serial.read();
    com_buf = inChar;
    com_num++;
    delay(2);
   }
    if(com_buf==MYADRESS2 && com_buf==0x03)
       {RH_2=com_buf*256+com_buf;
       temper_2=com_buf*256+com_buf;
       if (temper_2>32768){temper_2=temper_2-65536;}
       }
}

//---------------------------------------------------
void readJXBS21()
{Serial.write(readcmd21,8);//发射数据
}

void JXBSListen21()
{unsigned char com_num = 0;
while (Serial.available())
    {char inChar = (char)Serial.read();//接收数据
   com_buf = inChar;
   com_num++;
   delay(2);
    }
if(com_buf==MYADRESS2 && com_buf==0x03)
   {EC_2=com_buf*256+com_buf;
   }   
}
//---------------------------------------------------
void readJXBS22()
{Serial.write(readcmd22,8);//发射数据
}

void JXBSListen22()
{unsigned char com_num = 0;
while (Serial.available())
    {char inChar = (char)Serial.read();//接收数据
   com_buf = inChar;
   com_num++;
   delay(2);
    }
if(com_buf==MYADRESS2 && com_buf==0x03)
   {pH_2=com_buf*256+com_buf;
   }   
} 实物图

frankhan747 发表于 2021-8-3 15:09

···于是乎?

hdku18 发表于 2021-9-18 10:06

:D:D感谢分享!!!
页: [1]
查看完整版本: 兰州理工大学后花园盐渍土参数