链接:https://pan.baidu.com/s/1QVC2_gi0j_5BEunNYNmJOQ?pwd=tldq
提取码:tldq
--来自百度网盘超级会员V4的分享
arduino-stm32
//#include <SoftwareSerial.h>
//============1_串口定义=================
//1_wifi串口
//SoftwareSerial mySerial(2, 3); // RX, TX
#define mySerial Serial2 //A3-RX->d2 A2-TX->d1
//所有串口初始化函数
void Serial_Int(){
Serial.begin(9600);
while (!Serial) {
}
//Serial.println("Goodnight moon!");
mySerial.begin(9600);
//mySerial.println("Hello, world?");
}
//============2_引脚和传感器定义=================
//1_模拟引脚-
int pin_turang= PA4;
int pin_light= PA1;
//2_数字引脚-
#include <DS18B20.h>
int pin_dbs180=PB8;//温度
DS18B20 ds(pin_dbs180);
int pin_dd=PB9;//蜂鸣器
//3_电机
int pin_JD1=PB6;
int pin_JD2=PB7;
//所有按键引脚和传感器初始化
void Pin_Int(){
pinMode(pin_turang, INPUT_ANALOG);//模拟引脚初始化
pinMode(pin_light, INPUT_ANALOG);//数字引脚初始化
//pinMode(pin_dbs180, INPUT);//数字引脚初始化
pinMode(pin_dd, OUTPUT);//数字引脚初始化
digitalWrite(pin_dd,LOW);
pinMode(pin_JD1, OUTPUT);//数字引脚初始化
digitalWrite(pin_JD1,LOW);
pinMode(pin_JD2, OUTPUT);//数字引脚初始化
digitalWrite(pin_JD2,LOW);
}
//============解析函数=================
//分割结果
#define sleng 3 //数组大小 比实际多一个
String split_result[sleng];//手动动态调整数组大小,保证数组可以满足容量
/*字符串分割
输入参数
String zifuchuan, 输入字符串
String fengefu, 分隔符号-可以是多个
String result[] 输出结果
*/
void Split(String zifuchuan,String fengefu,String result[])
{
int weizhi; //找查的位置
String temps;//临时字符串
int i=0;
do
{
weizhi = zifuchuan.indexOf(fengefu);//找到位置
if(weizhi != -1)//如果位置不为空
{
temps=zifuchuan.substring(0,weizhi);//打印取第一个字符
zifuchuan = zifuchuan.substring(weizhi+fengefu.length(), zifuchuan.length());
//分隔后只取后面一段内容 以方便后面找查
}
else
{ //上面实在找不到了就把最后的 一个分割值赋值出来以免遗漏
if(zifuchuan.length() > 0)
temps=zifuchuan;
}
result[i++]=temps;
//Serial.println(result[i-1]);//在这里执行分割出来的字符下面不然又清空了
temps="";
}
while(weizhi >=0);
}
// 根据消息解析,并生成指令返回
String DoWork_Response(String SensorName,String SensorAction){
// 根据命令做控制
// 解析1-传感器sensor_all 命令GetData 返回所有的数据
if(SensorName=="sensor_all" && SensorAction=="GetData"){
//1读取模拟引脚
int pin_turang_Value = analogRead(pin_turang);
pin_turang_Value=(4095-pin_turang_Value);
int pin_light_Value = analogRead(pin_light);
//2读取数字引脚红外
//int pin_red_Value=digitalRead(pin_red);
//3读取温湿度
int TemperatureC=20;
if (ds.hasAlarm()) {
TemperatureC=int(ds.getTempC());
}
else{
TemperatureC=20;
}
String AlramMsg="工作中...";
if (TemperatureC>23)
{
AlramMsg=AlramMsg+"高温报警,开启报警";
digitalWrite(pin_dd,HIGH);
digitalWrite(pin_JD1,LOW);
digitalWrite(pin_JD2,HIGH);
}
if (pin_turang_Value<1000)
{
AlramMsg=AlramMsg+",干旱报警,自动开启浇水";
digitalWrite(pin_dd,HIGH);
digitalWrite(pin_JD1,LOW);
digitalWrite(pin_JD2,HIGH);
}
//json 格式打包数据 网页端解析
String ResMsg=String("{")
+String("\"turang\":")
+String(pin_turang_Value)+","
+String("\"light\":")
+String(pin_light_Value)+","
+String("\"tem\":")
+String(TemperatureC)+","
+String("\"AlramMsg\":")
+"\""+AlramMsg+"\""
+"};";
Serial.print("Reponse_esp: "); Serial.println(ResMsg);
return ResMsg;
}
// 解析2-传感器sensor_jidianqi 继电器控制操作
else if(SensorName=="sensor_jidianqi"){
//命令open1 打开第一个
if(SensorAction=="open1"){
digitalWrite(pin_JD1,LOW);
digitalWrite(pin_JD2,HIGH);
}
else if(SensorAction=="close1"){
digitalWrite(pin_JD1,LOW);
digitalWrite(pin_JD2,LOW);
}
else if(SensorAction=="open2"){
digitalWrite(pin_dd,HIGH);
}
else if(SensorAction=="close2"){
digitalWrite(pin_dd,LOW);
}
String ResMsg=SensorName+" anction ok!";
Serial.print("Reponse_esp: "); Serial.println(ResMsg);
return ResMsg;
}
// 解析n-传感器xxxx 未识别 不做任何处理
else{
String ResMsg="Anction unkown...";
Serial.print("Reponse_esp: "); Serial.println(ResMsg);
return ResMsg;
}
}
String comdata="";
void setup()
{
//1_串口初始化
Serial_Int();
//2_所有引脚和传感器初始化
Pin_Int();
}
void loop()
{
/*
if (mySerial.available()){
comdata =mySerial.readStringUntil(';');
Serial.println(comdata);
}
if(Serial.available()>0){
comdata =Serial.readStringUntil(';');
mySerial.println(comdata);
}
*/
//收到串口命令
if (mySerial.available()){
//1 =========从串口获取命令 ;结尾 例子: sensor-on;
String split_input =mySerial.readStringUntil(';');
Serial.print("Recive_esp: ");Serial.println(split_input);
//2 ========解析命令
//2-0解析数据 sensor-on
Split(split_input,"-",split_result);//分割调用
//2-1打印消息 0-sensor 1-on
for(int i=0;i<sleng;i++)
{
if(split_result[i]!="")
{
//Serial.println(String(i)+"-"+split_result[i]);
}
}
String SensorName=split_result[0];//传感器类型/命令类型
String SensorAction=split_result[1];//具体指令/要干什么
//Serial.print(SensorName);Serial.print(" "); Serial.println(SensorAction);
//3===========修改对象,根据命令做动作 生成返回报文
String ResMsg=DoWork_Response(SensorName,SensorAction);
//4 串口返回消息
mySerial.println(ResMsg);// 换行符号影响下一次解析
//不加 \n 会导致连续发送两行积累 所以解析段必须去除 \n 字符
}
}
esp
#include <SoftwareSerial.h>
SoftwareSerial portOne(D1, D2);//rx tx
//SoftwareSerial portTwo(D8, D7);// rx tx
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>
ESP8266WebServer server (80);
//连接或者要辐射的wifi信息
//String wifiName = ("ESPWIFI_"+(String)ESP.getChipId()); // 2 设置WIFI名称
String wifiName = "love1"; // 2 设置WIFI名称
String password ="love123456"; // 需要连接的wifi热点密码
//登录账号密码
String LoginName="admin";
String LoginPwd="admin";
//工作模式
String work_mode="AP";// AP 自己辐射wifi STA 链接wifi
//本机ip 会自动修改
String LocaIP="192.168.1.1";//跳转使用
int CanPost=1;//记录本次请求是否处理完毕
/**
* 网页系统API
* 根据文件后缀获取html协议的返回内容类型
*/
String getContentType(String filename){
if(server.hasArg("download")) return "application/octet-stream";
else if(filename.endsWith(".htm")) return "text/html";
else if(filename.endsWith(".html")) return "text/html";
else if(filename.endsWith(".css")) return "text/css";
else if(filename.endsWith(".js")) return "application/javascript";
else if(filename.endsWith(".png")) return "image/png";
else if(filename.endsWith(".gif")) return "image/gif";
else if(filename.endsWith(".jpg")) return "image/jpeg";
else if(filename.endsWith(".ico")) return "image/x-icon";
else if(filename.endsWith(".xml")) return "text/xml";
else if(filename.endsWith(".pdf")) return "application/x-pdf";
else if(filename.endsWith(".zip")) return "application/x-zip";
else if(filename.endsWith(".gz")) return "application/x-gzip";
return "text/plain";
}
/* NotFound处理
* 用于处理没有注册的请求地址
*/
void handleNotFound() {
String path = server.uri();
Serial.print("load url:");
Serial.println(path);
String contentType = getContentType(path);
String pathWithGz = path + ".gz";
if(SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)){
if(SPIFFS.exists(pathWithGz))
path += ".gz";
File file = SPIFFS.open(path, "r");
size_t sent = server.streamFile(file, contentType);
file.close();
return;
}
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for ( uint8_t i = 0; i < server.args(); i++ ) {
message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
}
server.send ( 404, "text/plain", message );
}
/* 引脚更改处理
* 访问地址为htp://192.162.xxx.xxx/ 返回主页面
*/
void handleMain() {
/* 返回信息给浏览器(状态码,Content-type, 内容)
* 这里是访问当前设备ip直接返回一个String
*/
Serial.print("handleMain");
File file = SPIFFS.open("/index.html", "r");
size_t sent = server.streamFile(file, "text/html");
file.close();
return;
}
//获取数据打包
String SensorData_Produce(int temperatureNum,int humidityNum){
// 定义温度变量名
String temperature = "\"temperature\":";
// 获取温度
//temperatureNum=(float)60.0;
// 定义湿度变量名
String humidity = "\"humidity\":";
// 获取湿度
//humidityNum=(float)30.0;
String dataRes="{"+temperature+temperatureNum+","+humidity+humidityNum+"}";
return dataRes;
}
// 本机处理网页数据请求 ESP直接对接网页 不做单片机转换
/// Get_SensorData?action=all&sensor=all
void handle_SensorDataGet()
{
//解析命令
if(server.hasArg("action") && server.hasArg("sensor")) { // 请求中是否包含有a的参数
String action = server.arg("action"); // 获得动作
String sensor = server.arg("sensor"); // 获得传感器型号
String ShowMsg =String()+"sensor-"+ sensor+"-action-"+action+";";
Serial.println (ShowMsg); //电脑串口打印
//获取所有传感器数据
if(sensor=="all"&& sensor=="all"){
//String REC_comdata=SensorData_Produce(56,98);//数据打包
//消息打包生成
ShowMsg =String()+ sensor+"-"+action+";";
while(portOne.read() >= 0){}//清空缓存
//转发给单片机处理
portOne.print(ShowMsg);
//等待单片机回应消息
String REC_comdata;
if (portOne.available()){
REC_comdata =portOne.readStringUntil(';');
Serial.print("Rec_arduino:");Serial.println(REC_comdata);
}
Serial.println (REC_comdata); //电脑串口打印
server.send ( 200, "text/html", REC_comdata);
return; // 返回数据
}
}
else{
server.send ( 200, "text/html", "请求参数不匹配");
}
server.send ( 200, "text/html", "action no found");
}
//控制页面-本机处理函数
void handle_PinControl_DoMySelf(String action_)
{
}
String REC_comdata="{\"turang\":0,\"light\":0,\"tem\":0,\"AlramMsg\":\"工作中...\"}";
// 控制页面请求函数处理 ESP数据给单片机,由单片机处理后返回数据
///Get_SensorData?action=all&sensor=all
void handle_PinControl() {
if(CanPost==1)
{
CanPost=0;
}
else
{
server.send ( 200, "text/html", REC_comdata);
return;
}
if(server.hasArg("action") && server.hasArg("sensor")) { // 请求中是否包含有a的参数
String action = server.arg("action"); // 获得动作
String sensor = server.arg("sensor"); // 获得传感器型号
String ShowMsg =String()+"sensor-"+ sensor+"-action-"+action+";";
Serial.println (ShowMsg); //电脑串口打印
//根据传感器型号进行控制
//本机处理
if(sensor=="sensor_ESP"){
handle_PinControl_DoMySelf(action);//调用本机函数处理
server.send ( 200, "text/html", "消息本机处理:"+ShowMsg); // 返回数据
CanPost=1;
return;
}//转发单片机处理
else{ //其他设备控制
//消息打包生成
ShowMsg =String()+ sensor+"-"+action+";";
//转发给单片机处理
portOne.print(ShowMsg);
//等待单片机回应消息
//String REC_comdata;
if (portOne.available()){
//发送端是加了换行符发送的 不加 \n 会导致连续发送两行积累 所以解析段必须去除 \n 字符
REC_comdata =portOne.readStringUntil(';');
//REC_comdata=REC_comdata.replace("\n","");
Serial.print("Rec_arduino:");Serial.println(REC_comdata);
}
server.send ( 200, "text/html", REC_comdata);
CanPost=1;
return;
}
}
else{
server.send ( 200, "text/html", "action no found");
}
}
//用来跳转页面
String GoUrl(String urlName){
String ALLHtml=String("")+
"<HTML>"+
"<HEAD>"+
"<meta HTTP-EQUIV=\'REFRESH\' content=\'0; url="+urlName+"\'/>"+
"<TITLE>Success</TITLE>"+
"</HEAD>"+
"<BODY>"+
"Success"+
"</BODY>"+
"</HTML>";
return ALLHtml;
}
void handle_Login(){
if(server.hasArg("config")) { // 请求中是否包含有a的参数
String config = server.arg("config"); // 获得a参数的值
String RecLoginName;
String RecLoginPwd;
if(config == "on") { // a=on
if(server.hasArg("name")) { // 请求中是否包含有a的参数
RecLoginName = server.arg("name"); // 获得a参数的值
}
else{
String backtxt= "请输入用户名" ;
server.send ( 200, "text/html", backtxt);
return;
}
if(server.hasArg("pwd")) { // 请求中是否包含有a的参数
RecLoginPwd = server.arg("pwd"); // 获得a参数的值
}
if(RecLoginName==LoginName && RecLoginPwd==LoginPwd){
String backtxt= "成功登录! 名称:"+ RecLoginName +" 密码:"+ RecLoginPwd ;
Serial.print("handleMain");
backtxt=GoUrl("http://"+LocaIP+"/index1_control.html");
server.send ( 200, "text/html", backtxt);
return;
}
else{
String backtxt= "失败登录,账号和密码错误!\n 名称:"+ RecLoginName +" 密码:"+ RecLoginPwd ;
server.send ( 200, "text/html", backtxt);
return;
}
}
server.send ( 200, "text/html", "unknown action"); return;
}
server.send ( 200, "text/html", "action no found");
}
//工作模式1 自身建立wifi等待连接
void Int_SetWIfi(String wifiName_,String password_){
//LocaIP="192.168.1.1";
IPAddress softLocal(192,168,1,1); // 1 设置内网WIFI IP地址
IPAddress softGateway(192,168,1,1);
IPAddress softSubnet(255,255,255,0);
WiFi.softAPConfig(softLocal, softGateway, softSubnet);
//String wifiName = ("ESPWIFI_"+(String)ESP.getChipId()); // 2 设置WIFI名称
const char *softAPName = wifiName_.c_str();
WiFi.softAP(softAPName, password_); // 3创建wifi 名称 +密码 adminadmin
IPAddress myIP = WiFi.softAPIP(); // 4输出创建的WIFI IP地址
Serial.print("AP IP address: ");
LocaIP=myIP.toString().c_str();
Serial.println(LocaIP);
Serial.print("softAPName: "); // 5输出WIFI 名称
Serial.println(wifiName_);
}
//工作模式2 连接到wifi 获取ip访问
void Int_wificonnect(String wifiName,String password){
int connectCount = 0;
WiFi.begin ( wifiName.c_str(), password.c_str() );
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 1000 );
Serial.print ( "." );
if(connectCount > 30) {
Serial.println( "Connect fail!" );
break;
}
connectCount += 1;
}
if(WiFi.status() == WL_CONNECTED) {
Serial.println ( "" );
Serial.print ( "Connected to " );
Serial.println ( wifiName );
Serial.print ( "IP address: " );
//Serial.println ( WiFi.localIP() );
LocaIP=WiFi.localIP().toString().c_str();
Serial.println ( LocaIP );
connectCount = 0;
}
}
void setup() {
// 日常初始化网络
pinMode(2, OUTPUT);
Serial.begin ( 9600 );
portOne.begin(9600);//软串口1 单片机之间过高导致解析出错
//portTwo.begin(9600);//软串口2 红外模块串口通信默认115200
SPIFFS.begin();
if(work_mode=="STA"){
Int_wificonnect(wifiName,password);
}
else{
Int_SetWIfi(wifiName,password);
}
server.on ("/", handleMain); // 绑定‘/’地址到handleMain方法处理 默认返回登陆网页
server.on ("/login", HTTP_GET, handle_Login); // 处理登陆请求是否正确,然后跳转控制页面
server.on ("/Control_SensorPin", HTTP_GET, handle_PinControl); //处理控制页面的按键和滑动条请求
server.on ("/Get_SensorData", HTTP_GET, handle_SensorDataGet); //处理请求数据页面请求,返回传感器数据给网页
server.onNotFound ( handleNotFound ); // NotFound处理 默认会返回登陆页面
server.begin();
Serial.println ( "HTTP server started" );
}
void loop() {
/* 循环处理,因为ESP8266的自带的中断已经被系统占用,
* 只能用过循环的方式来处理网络请求
*/
server.handleClient();
}
手机一定要关闭上网流量