INSERT INTO `WisdomPreview` (`id`, `tid`, `title`, `content`, `imgtext`, `user`) VALUES
(7963, 344, 'golang 爬虫 ', 'package main\r\n\r\nimport (\r\n	"bufio"\r\n	"fmt"\r\n	"gotest/models"\r\n	"io"\r\n	"os"\r\n	"strconv"\r\n	"strings"\r\n\r\n	"time"\r\n\r\n	"github.com/gocolly/colly"\r\n)\r\n\r\nvar OneErr bool\r\n\r\nfunc main() {\r\n	url := "https://p.jisuts.com:999/hls/152/20231112/2054932/plist"\r\n	mc := MyColly{}\r\n	mc.Init()\r\n	mc.Heby(mc.Path+"/video/", mc.Path+"/"+time.Now().Format("05")+".mp4", "cUw5NVBRN0hJRmxTZE5FdA==")\r\n	return\r\n	// mc.ReVisit()\r\n	// return\r\n	//mc.Heby(mc.Path+"/video/", mc.Path+"/"+time.Now().Format("05")+".mp4")\r\n	//return\r\n\r\n	// 开始爬取的起始点\r\n	for i := 0; i < 10; i++ {\r\n		strName := ""\r\n		if i < 10 {\r\n			//strName = "0" + fmt.Sprintf("%d", i)\r\n			strName = fmt.Sprintf("%d", i)\r\n		} else {\r\n			strName = fmt.Sprintf("%d", i)\r\n		}\r\n		gotoUrl := url + strName + ".ts"\r\n		fmt.Println(gotoUrl)\r\n		err := mc.Colly.Visit(gotoUrl)\r\n		if err != nil {\r\n			fmt.Println("抓取 失败1次")\r\n			err1 := mc.Colly.Visit(gotoUrl)\r\n			if err1 != nil {\r\n				fmt.Println("抓取 失败2次" + gotoUrl)\r\n				errr := mc.Colly.Visit(gotoUrl)\r\n				if errr != nil {\r\n					fmt.Println("抓取 失败3次保存错误记录" + gotoUrl)\r\n					OneErr = true\r\n					mc.ErrorSave(gotoUrl)\r\n				}\r\n\r\n			}\r\n		}\r\n	}\r\n\r\n	fmt.Println("完成")\r\n	if !OneErr {\r\n		fmt.Println("没有错误执行合并")\r\n		mc.Heby(mc.Path+"/video/", mc.Path+"/"+time.Now().Format("05")+".mp4", "cUw5NVBRN0hJRmxTZE5FdA==")\r\n	} else {\r\n		fmt.Println("筛选错误抓取")\r\n		mc.ReVisit()\r\n	}\r\n}\r\n\r\ntype MyColly struct {\r\n	Colly *colly.Collector\r\n	Path  string\r\n}\r\n\r\nfunc (these *MyColly) Init() *MyColly {\r\n	these.Path, _ = os.Getwd()\r\n	fmt.Println(these.Path)\r\n	these.Colly = colly.NewCollector()\r\n	these.Colly.AllowURLRevisit = true //可以重复访问\r\n	//在发起请求前被调用\r\n	these.Colly.OnRequest(func(r *colly.Request) {\r\n		r.Headers.Set("Accept", "*/*")\r\n		r.Headers.Set("Accept-Encoding", "gzip, deflate, br")\r\n		r.Headers.Set("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2")\r\n		r.Headers.Set("Connection", "keep-alive")\r\n		r.Headers.Set("DNT", "1")\r\n		r.Headers.Set("Host", "p.jisuts.com:999")\r\n		r.Headers.Set("Origin", "http://yidian68.com")\r\n		r.Headers.Set("Referer", "http://yidian68.com/")\r\n\r\n		r.Headers.Set("Sec-Fetch-Dest", "empty")\r\n		r.Headers.Set("Sec-Fetch-Mode", "cors")\r\n		r.Headers.Set("Sec-Fetch-Site", "cross-site")\r\n		r.Headers.Set("UserAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0")\r\n	})\r\n	//请求过程中如果发生错误被调用\r\n	these.Colly.OnError(func(r *colly.Response, err error) {\r\n		fmt.Println("请求过程中如果发生错误被调用" + r.FileName())\r\n	})\r\n	//收到回复后被调用\r\n	these.Colly.OnResponse(func(r *colly.Response) {\r\n		fname := r.FileName()\r\n		if tmp := strings.LastIndex(fname, "."); tmp != -1 {\r\n			s := fname[tmp-3:]\r\n			s = strings.ReplaceAll(s, ".ts", "")\r\n			// 使用strings包中的ContainsAny函数也可以判断字符串中是否包含字母\r\n			if !strings.ContainsAny(s, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") {\r\n				is, _ := strconv.Atoi(s)\r\n				isS := fmt.Sprintf("%d", is)\r\n				if is < 10 {\r\n					isS = "0" + s\r\n				}\r\n				err := r.Save(these.Path + "\\\\video\\\\" + isS + ".ts")\r\n				if err != nil {\r\n					fmt.Println(err.Error())\r\n					return\r\n				}\r\n				fmt.Println(isS + ".ts ok 100数")\r\n			} else {\r\n				//fmt.Println("字符串中包含字母")\r\n				s = s[1:]\r\n				fmt.Println(s)\r\n				if !strings.ContainsAny(s, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") {\r\n					is, _ := strconv.Atoi(s)\r\n					err := r.Save(these.Path + "\\\\video\\\\" + fmt.Sprintf("%d", is) + ".ts")\r\n					if err != nil {\r\n						fmt.Println(err.Error())\r\n						return\r\n					}\r\n					fmt.Println(s + ".ts ok 10数")\r\n				} else {\r\n					isS := "0" + s[1:]\r\n					err := r.Save(these.Path + "\\\\video\\\\" + isS + ".ts")\r\n					if err != nil {\r\n						fmt.Println(err.Error())\r\n						return\r\n					}\r\n					fmt.Println(isS + ".ts ok 个数")\r\n				}\r\n			}\r\n\r\n		}\r\n\r\n	})\r\n	//在OnResponse之后被调用，如果收到的内容是HTML\r\n	these.Colly.OnHTML("title", func(h *colly.HTMLElement) {\r\n\r\n	})\r\n	these.Colly.OnHTML("body", func(h *colly.HTMLElement) {\r\n		//h.ChildAttr() 获取一个元素属性\r\n		//h.ChildAttrs() 获取全部元素属性 返回切片\r\n	})\r\n	these.Colly.OnHTML("a[href]", func(h *colly.HTMLElement) {\r\n\r\n	})\r\n	//在OnHTML之后被调用\r\n	these.Colly.OnScraped(func(r *colly.Response) {\r\n\r\n	})\r\n	//线程数量限制 超时时间\r\n	these.Colly.Limit(&colly.LimitRule{\r\n		Parallelism: 1,\r\n		Delay:       60 * time.Second,\r\n	})\r\n	return these\r\n}\r\n\r\nfunc (these *MyColly) ErrorSave(str string) {\r\n	// 打开文件，如果文件不存在则创建，以追加模式打开\r\n	file, err := os.OpenFile("error.txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)\r\n	if err != nil {\r\n		fmt.Println("打开文件失败:", err)\r\n		return\r\n	}\r\n	defer file.Close()\r\n\r\n	// 要追加的内容\r\n	content := str + "\\n"\r\n\r\n	// 将内容追加到文件中\r\n	_, err = file.WriteString(content)\r\n	if err != nil {\r\n		fmt.Println("追加内容失败:", err)\r\n		return\r\n	}\r\n	fmt.Println("内容追加成功！")\r\n}\r\n\r\nfunc (these *MyColly) Heby(filePath, result, key string) bool {\r\n	folderPath := these.Path + "/video/"\r\n	// 获取文件夹下的所有文件\r\n	files, err := os.ReadDir(folderPath)\r\n	if err != nil {\r\n		fmt.Println("读取文件夹失败:", err)\r\n		return false\r\n	}\r\n\r\n	// 计数文件数量\r\n	fileCount := 0\r\n	for _, file := range files {\r\n		if !file.IsDir() {\r\n			fileCount++\r\n		}\r\n	}\r\n\r\n	for i := 0; i < fileCount; i++ {\r\n		tn := ""\r\n		if i < 10 {\r\n			tn = filePath + "0" + fmt.Sprintf("%d", i)\r\n		} else {\r\n			tn = filePath + fmt.Sprintf("%d", i)\r\n		}\r\n		// 打开源视频文件\r\n\r\n		sourceFile, err := os.Open(tn + ".ts")\r\n		if err != nil {\r\n			fmt.Println("打开源视频文件失败:", err)\r\n			these.ErrorSave("打开源视频文件失败:" + tn)\r\n			return false\r\n		}\r\n		defer sourceFile.Close()\r\n		// 打开目标视频文件，如果文件不存在则创建，以追加模式打开\r\n		targetFile, err := os.OpenFile(result, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)\r\n		if err != nil {\r\n			fmt.Println("打开目标视频文件失败:", err)\r\n			return false\r\n		}\r\n		defer targetFile.Close()\r\n		if key == "" {\r\n			// 将源视频文件的内容追加到目标视频文件中\r\n			_, err = io.Copy(targetFile, sourceFile)\r\n			if err != nil {\r\n				fmt.Println("追加视频文件内容失败:", err)\r\n				return false\r\n			}\r\n\r\n			fmt.Println("视频文件追加成功！")\r\n		} else {\r\n			bs, err := io.ReadAll(sourceFile)\r\n			if err != nil {\r\n				fmt.Println("视频文件转byte失败:", err)\r\n				return false\r\n			}\r\n			en := models.Encryption{}\r\n			strs := en.AesDecrypt(string(bs), key)\r\n			_, err = io.Copy(targetFile, strings.NewReader(strs))\r\n			if err != nil {\r\n				fmt.Println("追加视频文件内容失败:", err)\r\n				return false\r\n			}\r\n		}\r\n	}\r\n	os.RemoveAll(these.Path + "/video/")\r\n	return true\r\n}\r\nfunc (these *MyColly) TxtToList() []string {\r\n	strs := []string{}\r\n	// 打开txt文件\r\n	file, err := os.Open("error.txt")\r\n	if err != nil {\r\n		fmt.Println("打开文件失败:", err)\r\n		return nil\r\n	}\r\n	defer file.Close()\r\n\r\n	// 创建一个Scanner来读取文件内容\r\n	scanner := bufio.NewScanner(file)\r\n\r\n	// 逐行读取文件内容\r\n	for scanner.Scan() {\r\n		line := scanner.Text()\r\n		strs = append(strs, line)\r\n	}\r\n\r\n	// 检查是否有错误发生\r\n	if err := scanner.Err(); err != nil {\r\n		fmt.Println("读取文件失败:", err)\r\n\r\n		return nil\r\n	}\r\n	return strs\r\n}\r\nfunc (these *MyColly) ReVisit() {\r\n	result := []string{}\r\n	strs := these.TxtToList()\r\n	if len(strs) != 0 {\r\n		os.RemoveAll("error.txt")\r\n		for _, v := range strs {\r\n			err := these.Colly.Visit(v)\r\n			if err != nil {\r\n				result = append(result, v)\r\n			} else {\r\n				fmt.Println("重新抓取成功" + v)\r\n			}\r\n		}\r\n		if len(result) != 0 {\r\n			for _, v := range result {\r\n				these.ErrorSave(v)\r\n			}\r\n\r\n		}\r\n	}\r\n}\r\n', '', 'webserver'),
(7964, 344, 'golang txt文本文件换行追加', '	fileName := "errordh.txt"\r\n	// 打开文件，如果不存在则创建\r\n	file, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\r\n	if err != nil {\r\n		fmt.Println(err)\r\n		return\r\n	}\r\n	defer file.Close()\r\n\r\n	// 追加内容到文件\r\n	_, err = file.WriteString(str + "\\n")\r\n	if err != nil {\r\n		fmt.Println(err)\r\n		return\r\n	}', '', 'webserver'),
(7965, 344, 'golang 绘图', 'package main\r\n\r\nimport (\r\n	"fmt"\r\n	"os"\r\n\r\n	"github.com/vicanso/go-charts/v2"\r\n)\r\n\r\nfunc main() {\r\n\r\n	values := [][]float64{\r\n		{\r\n			2.0,\r\n			4.9,\r\n			7.0,\r\n			23.2,\r\n			25.6,\r\n			76.7,\r\n			135.6,\r\n			162.2,\r\n			32.6,\r\n			20.0,\r\n			6.4,\r\n			3.3,\r\n		},\r\n		{\r\n			// snip...\r\n		},\r\n	}\r\n\r\n	p, err := charts.BarRender(\r\n		values,\r\n		charts.XAxisDataOptionFunc([]string{\r\n			"Jan",\r\n			"Feb",\r\n			"Mar",\r\n			"Apr",\r\n			"May",\r\n			"Jun",\r\n			"Jul",\r\n			"Aug",\r\n			"Sep",\r\n			"Oct",\r\n			"Nov",\r\n			"Dec",\r\n		}),\r\n		charts.LegendLabelsOptionFunc([]string{\r\n			"Rainfall",\r\n			"Evaporation",\r\n		}, charts.PositionRight),\r\n		charts.MarkLineOptionFunc(0, charts.SeriesMarkDataTypeAverage),\r\n		charts.MarkPointOptionFunc(0, charts.SeriesMarkDataTypeMax,\r\n			charts.SeriesMarkDataTypeMin),\r\n		//custom option func\r\n		// func(opt *charts.ChartOption) {\r\n		// 	opt.SeriesList[0].MarkPoint = charts.NewMarkPoint(\r\n		// 		charts.SeriesMarkDataTypeMax,\r\n		// 		charts.SeriesMarkDataTypeMin,\r\n		// 	)\r\n		// 	opt.SeriesList[0].MarkLine = charts.NewMarkLine(\r\n		// 		charts.SeriesMarkDataTypeAverage,\r\n		// 	)\r\n		// },\r\n	)\r\n	if err != nil {\r\n		panic(err)\r\n	}\r\n\r\n	buf, err := p.Bytes()\r\n	if err != nil {\r\n		panic(err)\r\n	}\r\n	f, err := os.OpenFile("bar.jpg", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)\r\n	if err != nil {\r\n		fmt.Println("创建文件失败")\r\n	}\r\n	defer f.Close()\r\n\r\n	f.Write(buf)\r\n}\r\n', '', 'webserver'),
(7968, 20, '网络音响 ', '#include <Arduino.h>\r\n#include <WiFi.h>\r\n#include <WiFiClientSecure.h>\r\n#include <HTTPClient.h>\r\n#include <WebServer.h>\r\n#include <FS.h>\r\n#include "SPIFFS.h"\r\n#include "ESPmDNS.h"\r\n#include <Ticker.h>\r\n#include <Audio.h>\r\n\r\nTicker myTicker;\r\n//被读取的文件位置和名称\r\nString flash_wifi = "/wifi.txt";\r\nWebServer webServer(80);  // 创建网络服务器对象，HTTP服务的标准端口为：80\r\nString ssid = "";\r\nString passwd = "";\r\nString html;\r\nString espIp;\r\nString localServerIP;\r\n\r\nWiFiClient client;\r\nString localserver;\r\n// Digital I/O used\r\n#define I2S_DOUT 25\r\n#define I2S_BCLK 26\r\n#define I2S_LRC 27\r\nAudio audio;\r\nvoid hexdump(const void *mem, uint32_t len, uint8_t cols = 16) {\r\n  const uint8_t *src = (const uint8_t *)mem;\r\n  Serial.printf("\\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);\r\n  for (uint32_t i = 0; i < len; i++) {\r\n    if (i % cols == 0) {\r\n      Serial.printf("\\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);\r\n    }\r\n    Serial.printf("%02X ", *src);\r\n    src++;\r\n  }\r\n  Serial.printf("\\n");\r\n}\r\n\r\nvoid setup() {\r\n  Serial.begin(115200);\r\n  //Serial.setDebugOutput(true);\r\n  if (FlashConnetWifi() == false) {\r\n    HtmlSetWifi();\r\n  }\r\n  localserver = "http://" + localServerIP + "/apiview/everyday5english";\r\n  audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);\r\n  audio.setVolume(19);  // 0...21   音量大小\r\n  String ttmps1 = HttpPost(localserver, "MusicId=0");\r\n  String tmps1 = "http://" + localServerIP + "/" + ttmps1;\r\n  //Serial.println(tmps1);\r\n  audio.connecttohost(tmps1.c_str());\r\n  delay(500);\r\n}\r\n\r\nvoid loop() {\r\n  audio.loop();\r\n}\r\n\r\nString HttpPost(String url, String postStr) {\r\n  HTTPClient http;\r\n  String response;\r\n  http.begin(client, url);\r\n  http.setTimeout(2000);\r\n  //需要传输的数据\r\n  char dataBuff[postStr.length()];\r\n  strcpy(dataBuff, postStr.c_str());\r\n  //头信息，需要的反注释就可以\r\n  http.addHeader("Content-Type", "application/x-www-form-urlencoded");\r\n  int httpCode = http.POST(dataBuff);\r\n  if (httpCode == 200) {\r\n    response = http.getString();\r\n    return response;\r\n  } else {\r\n    return "";\r\n  }\r\n  http.end();\r\n}\r\nvoid HtmlSetWifi() {\r\n  WifiScan();\r\n  ApOpen();\r\n  delay(1000);\r\n  Serial.println("启动网页");\r\n  //5分后重启 防止停电后复电，路由器连接WIFI速度慢于ESP导致ESP连接不到路由器进入无限AP模式，所以这里只让AP激活5分钟后就重启\r\n  myTicker.once(300, EspRestart);\r\n  delay(200);\r\n  WebServerOpen();\r\n  while (1) {\r\n    webServer.handleClient();  // 检查网络服务请求并处理\r\n  }\r\n}\r\n\r\nvoid EspRestart() {\r\n  ESP.restart();\r\n}\r\n//扫描附件WIFI\r\nvoid WifiScan() {\r\n  WiFi.disconnect();\r\n  Serial.begin(115200);\r\n  WiFi.mode(WIFI_STA);\r\n  delay(100);\r\n  int n = WiFi.scanNetworks();\r\n  if (n > 0) {\r\n    Serial.println(n);\r\n    String a = "附近WiFi <select id=\\"ssid\\">";\r\n    for (int i = 0; i < n; i++) {\r\n      Serial.println(WiFi.SSID(i));\r\n      a = a + "<option value=\\"" + WiFi.SSID(i) + "\\">" + WiFi.SSID(i) + "</option>";\r\n      delay(50);\r\n    }\r\n    String HtmlStart = String("") + "<!DOCTYPE html>" + "<html>" + "<head>" + "<meta charset=\\"utf-8\\">" + "<meta name=\\"viewport\\" content=\\"width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\\" />" + "<title>设置WiFi</title>" + "<link rel=\\"stylesheet\\" href=\\"\\">" + "</head>" + "<script>" + "onload  = function() {" + "document.getElementById(\\"up\\").onclick = function(){" + "var ssida=document.getElementById(\\"ssid\\").value;" + "var ssid=ssida.replace(/\\\\s+/g, \\" \\");" + "var passwda=document.getElementsByTagName(''input'')[0].value;" + "var passwd=passwda.replace(/\\\\s+/g, \\" \\");" + "xhr = new XMLHttpRequest();" + "xhr.open(\\"POST\\",\\"./SetWifi\\",true);" + "var posts = (\\"ssid=\\"+ssid+\\"&passwd=\\"+ passwd);" + "xhr.setRequestHeader(\\"Content-Type\\",\\"application/x-www-form-urlencoded\\");" + "xhr.send(posts);" + "xhr.onreadystatechange = function(){" + "if(this.readyState == 4 && this.status == 200){" + "alert(this.responseText);" + "}" + "}" + "}" + "}" + "</script>" + "<body>";\r\n    String HtmlEnd = String("") + "<p>WiFi密码<input type=\\"text\\" id=\\"passwd\\"></p>" + "<input type=\\"submit\\" id=\\"up\\" value=\\"设 置\\">" + "<hr/>" + "<div>如果附近WiFi没有显示到自己的WIFI<div>" + "<div>请重启或离信号近点</div>" + "<div>连接成功AP热点退出转WIFI_STA</div>" + "</body>" + "</html>";\r\n    a = a + "</select>";\r\n    html = HtmlStart + a + HtmlEnd;\r\n  } else {\r\n    html = "扫描不到网络";\r\n    Serial.println("扫描不到网络");\r\n  }\r\n}\r\nvoid SetWifi() {\r\n  ssid = webServer.arg(0);\r\n  passwd = webServer.arg(1);\r\n  const char *Ssid = ssid.c_str();\r\n  const char *Passwd = passwd.c_str();\r\n  String sp = ssid + "&" + passwd;\r\n\r\n  Serial.println(sp);\r\n  Serial.begin(115200);\r\n  delay(500);\r\n  WiFi.begin(Ssid, Passwd);\r\n  WiFi.mode(WIFI_STA);\r\n  delay(200);\r\n  Serial.println("wifi_connet");\r\n  int ii = 0;\r\n  for (ii; ii < 20; ii++) {\r\n    delay(500);\r\n    Serial.print(".");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      webServer.send(200, "text/plane", "Wifi密码正确，ESP准备重启");\r\n      webServer.close();\r\n      delay(500);\r\n      WiFi.disconnect();\r\n      delay(500);\r\n      //写入数据\r\n      SPIFFS.format();\r\n      delay(500);\r\n      SPIFFS.begin();\r\n      File dataFile = SPIFFS.open(flash_wifi, "w");\r\n      dataFile.println(sp);\r\n      dataFile.close();\r\n      Serial.println("HTML连接成功");\r\n      delay(1000);\r\n      ESP.restart();\r\n    }\r\n  }\r\n  webServer.send(200, "text/plane", "Wifi密码错误，请重新输入");\r\n  //HtmlSetWifi();\r\n}\r\n//------- 展示页面-------\r\nvoid handleRoot() {\r\n  webServer.send(500, "text/html", html);\r\n}\r\nvoid handleNotFound(void) {\r\n  webServer.send(404, "text/plain", "404-The page is not Found!");\r\n}\r\n\r\n\r\nvoid ApOpen() {\r\n  Serial.begin(115200);\r\n  WiFi.mode(WIFI_AP);\r\n  IPAddress local_IP(192, 168, 168, 2);\r\n  IPAddress gateway(192, 168, 168, 1);\r\n  IPAddress subnet(255, 255, 255, 0);\r\n  WiFi.softAPConfig(local_IP, gateway, subnet);\r\n\r\n  //启动AP模式，并设置账号和密码\r\n  boolean result = WiFi.softAP("192.168.168.2", "192.168.168.2");\r\n  if (result) {\r\n    //输出 soft-ap ip地址\r\n    Serial.println(String("Soft-AP IP address = ") + WiFi.softAPIP());\r\n  }\r\n}\r\nvoid WebServerOpen() {\r\n  //-----------------启动webserver网络服务--------------------\r\n  webServer.begin();              // 启用网络服务\r\n  webServer.on("/", handleRoot);  // / 在HTTP中，表示请求首页服务，\r\n  webServer.on("/SetWifi", SetWifi);\r\n  webServer.onNotFound(handleNotFound);  // 当服务器没找到所需的服务，调用404函数\r\n  Serial.println("webserver started");\r\n}\r\n\r\nbool FlashConnetWifi() {\r\n  Serial.begin(115200);\r\n  delay(500);\r\n  //是否存在数据\r\n  SPIFFS.begin();\r\n  if (SPIFFS.exists(flash_wifi) == false) {\r\n    Serial.print(flash_wifi);\r\n    Serial.println(" NOT FOUND");\r\n    return false;\r\n  }\r\n\r\n  File dateFile = SPIFFS.open(flash_wifi, "r");\r\n  String result;\r\n  for (int i = 0; i < dateFile.size(); i++) {\r\n    //Serial.print((char)dateFile.read());\r\n    result += (char)dateFile.read();\r\n  }\r\n  //去除前后空格\r\n  result.trim();\r\n  Serial.println(result);\r\n  int i = result.indexOf("&");\r\n\r\n  String wifiname = result.substring(0, i);\r\n  String wifipw = result.substring(i + 1);\r\n  const char *WifiName = wifiname.c_str();\r\n  const char *WifiPw = wifipw.c_str();\r\n  Serial.println(WifiName);\r\n  Serial.println(WifiPw);\r\n  WiFi.begin(WifiName, WifiPw);\r\n  delay(500);\r\n  WiFi.mode(WIFI_STA);\r\n  Serial.println("FlashConnetWifi->connet");\r\n  int ii = 0;\r\n  for (ii; ii < 20; ii++) {\r\n    delay(500);\r\n    Serial.print(" . ");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      Serial.println("FlashConnetWifi 闪存配置连接成功");\r\n      espIp = WiFi.localIP().toString();\r\n      localServerIP = espIp.substring(0, espIp.lastIndexOf(".")) + ".254";\r\n      return true;\r\n    }\r\n  }\r\n  Serial.println("FlashConnetWifi->false");\r\n  return false;\r\n}\r\n// optional\r\nvoid audio_info(const char *info) {\r\n  // Serial.print("info        "); Serial.println(info);\r\n  String str = info;\r\n  if (str.indexOf("End of webstream") != -1) {\r\n    delay(900);\r\n    String ttmps = HttpPost(localserver, "MusicId=next");\r\n    String tmps2 = "http://" + localServerIP + "/" + ttmps;\r\n    audio.connecttohost(tmps2.c_str());\r\n  }\r\n}\r\nvoid audio_id3data(const char *info) {  //id3 metadata\r\n  Serial.print("id3data     ");\r\n  Serial.println(info);\r\n}\r\nvoid audio_eof_mp3(const char *info) {  //end of file\r\n  Serial.print("eof_mp3     ");\r\n  Serial.println(info);\r\n}\r\nvoid audio_showstation(const char *info) {\r\n  Serial.print("station     ");\r\n  Serial.println(info);\r\n}\r\nvoid audio_showstreamtitle(const char *info) {\r\n  Serial.print("streamtitle ");\r\n  Serial.println(info);\r\n}\r\nvoid audio_bitrate(const char *info) {\r\n  Serial.print("bitrate     ");\r\n  Serial.println(info);\r\n}\r\nvoid audio_commercial(const char *info) {  //duration in sec\r\n  Serial.print("commercial  ");\r\n  Serial.println(info);\r\n}\r\nvoid audio_icyurl(const char *info) {  //homepage\r\n  Serial.print("icyurl      ");\r\n  Serial.println(info);\r\n}\r\nvoid audio_lasthost(const char *info) {  //stream URL played\r\n  Serial.print("lasthost    ");\r\n  Serial.println(info);\r\n}', '', 'webserver'),
(7969, 529, 'redis window版下载地址', 'https://github.com/MicrosoftArchive/redis/releases', '', 'webserver'),
(7970, 321, 'windows redis使用与设置密码 ', 'redis 根目录\r\n修改redis.windows-service.conf\r\nappendonly yes\r\nrequirepass qq282246101\r\n\r\n', '', 'webserver'),
(7971, 344, 'golang 生成二维码库 读取二维码库', 'package main\r\n\r\nimport "github.com/skip2/go-qrcode"\r\n\r\nfunc main() {\r\n	qrcode.WriteFile("http://jyan.360xyz.cn/api/date", qrcode.Medium, 256, "./qrcode.png")\r\n}\r\n\r\npackage main\r\n\r\nimport (\r\n	"fmt"\r\n	"os"\r\n\r\n	"github.com/tuotoo/qrcode"\r\n)\r\n\r\nfunc main() {\r\n	fi, err := os.Open("./qrcode.png")\r\n	if err != nil {\r\n		fmt.Println(err.Error())\r\n		return\r\n	}\r\n	defer fi.Close()\r\n	qrmatrix, err := qrcode.Decode(fi)\r\n	if err != nil {\r\n		fmt.Println(err.Error())\r\n		return\r\n	}\r\n	fmt.Println(qrmatrix.Content)\r\n}\r\n', '', 'webserver'),
(7972, 344, '自动下载', '		//合成完成自动下载\r\n		ctx.Writer.WriteHeader(http.StatusOK)\r\n		ctx.Header("Content-Disposition", "attachment; filename=qrcode.png")\r\n		ctx.Header("Content-Type", "application/text/plain")\r\n		ctx.Header("Accept-Length", fmt.Sprintf("%d", len(bs)))\r\n		ctx.Writer.Write(bs)', '', 'webserver'),
(7974, 20, '点灯科技遥控大门 ', '#define BLINKER_WIFI\r\n#include <Blinker.h>\r\n#include <OneWire.h>\r\n#include <DallasTemperature.h>\r\n#include <DHT.h>\r\n#include <DHT_U.h>\r\n#include <Adafruit_Sensor.h>\r\n#include <SoftwareSerial.h>\r\n#include <ESP8266WiFi.h>\r\n#include <ESP8266HTTPClient.h>\r\nWiFiClient wificlient;\r\n//#include <ArduinoJson.h>\r\nchar auth[] = "f71c23621ed1";\r\nchar ssid[] = "webserver";\r\nchar pswd[] = "www.360xyz.cn";\r\n//几个全局变量\r\n//DynamicJsonDocument jsonBuffer(100);\r\n//JsonObject root;\r\n// 新建组件对象\r\nBlinkerButton Button1("btn-z2f");  //上升\r\nBlinkerButton Button2("btn-biu");  //停止\r\nBlinkerButton Button3("btn-3l9");  //下降\r\nBlinkerButton Button4("btn-wmf");  //刷新温度湿度\r\nBlinkerButton Button5("btn-u8w");  //广告开关\r\n\r\n\r\nBlinkerNumber Number1("num-du7");  //温度\r\nBlinkerNumber Number2("num-0j1");  //湿度\r\n\r\nBlinkerText Text1("tex-je9");\r\nBlinkerText Text2("tex-08u");  //广告牌状态\r\n#define DHTPIN 13              // 数字引脚连接DHT传感器\r\n// Feather HUZZAH ESP8266 note: use pins 3, 4, 5, 12, 13 or 14 --\r\n#define DHTTYPE DHT11  // DHT 11\r\nDHT_Unified dht(DHTPIN, DHTTYPE);\r\n// 温度输入脚接开发板数字引脚13\r\n#define d7 13\r\nOneWire oneWire(d7);\r\nDallasTemperature sensors(&oneWire);\r\nint open = 5;\r\nint close = 4;\r\n\r\nint d0 = 16;\r\nint d5 = 14;\r\nint d6 = 12;\r\n//广告牌定时开关输出电平脚 D4脚 2 不能使用 使为低电平时WIFI芯片灯会一直亮\r\nint d8 = 15;\r\n\r\n//开关状态 10为上升上限  0为下降上限 5为可以上升可降\r\nint state1 = 5;\r\n//此时执行中的状态  0关门  1开门  2停止 9什么也不代表\r\nint exec_status = 9;\r\nint humidity = 0;\r\nfloat temperature = 0;\r\nString hus;\r\nString tes;\r\n//最近操作物联用户相关信息\r\n\r\n\r\n//ggb为false代表没有开灯箱 true为已开启灯箱\r\nbool ggb = false;\r\n// 按下按键即会执行该函数\r\n//上升\r\nvoid button1_callback(const String& state) {\r\n  BLINKER_LOG("get button state: ", state);\r\n  //限位开关导通为低电平 表明还没有达到限位,并且没有达到上升最大限制 能正常上升,断开为高电平表明达到限位了\r\n  if (digitalRead(d5) == LOW && state1 != 10) {\r\n    //主电源接通\r\n    digitalWrite(d0, HIGH);\r\n\r\n    delay(200);\r\n    //开 上升\r\n    digitalWrite(close, LOW);\r\n\r\n    delay(200);\r\n    digitalWrite(open, HIGH);\r\n    exec_status = 1;\r\n    Text1.print("正在上升");\r\n  } else {\r\n    Text1.print("上升限制");\r\n  }\r\n}\r\n//停止\r\nvoid button2_callback(const String& state) {\r\n  BLINKER_LOG("get button state: ", state);\r\n  //如果已经在上限或下限时只更新响应时间\r\n  Text1.print("停止");\r\n  if (digitalRead(d5) == LOW && digitalRead(d6) == LOW) {\r\n    state1 = 5;\r\n  }\r\n  CloseAll();\r\n}\r\n//下降\r\nvoid button3_callback(const String& state) {\r\n  BLINKER_LOG("get button state: ", state);\r\n  //限位开关导通时为低电平表明还没有达到限位,并且没到达到下降最大限制  能正常下降,断开为高电平表明达到限位了\r\n  if (digitalRead(d6) == LOW && state1 != 0) {\r\n    //主电源接通\r\n    digitalWrite(d0, HIGH);\r\n    delay(200);\r\n    //关 下降\r\n\r\n    digitalWrite(open, LOW);\r\n    delay(200);\r\n    digitalWrite(close, HIGH);\r\n    Text1.print("正在下降");\r\n    exec_status = 0;\r\n  } else {\r\n    Text1.print("下降限制");\r\n  }\r\n}\r\nvoid button4_callback(const String& state) {\r\n  BLINKER_LOG("get button state: ", state);\r\n  // 获取温度事件并打印其值.\r\n  sensors_event_t event;\r\n  dht.temperature().getEvent(&event);\r\n  if (isnan(event.temperature)) {\r\n    Serial.println(F("Error reading temperature!"));\r\n  } else {\r\n    temperature = event.temperature;\r\n    if (temperature < -10) {\r\n      tes = "防冻";\r\n    }\r\n    if (temperature >= -10 && temperature < 18) {\r\n      tes = "寒冷";\r\n    }\r\n    if (temperature >= 18 && temperature <= 25) {\r\n      tes = "舒适";\r\n    }\r\n    if (temperature > 25 && temperature <= 36) {\r\n      tes = "炎热";\r\n    }\r\n    if (temperature > 36) {\r\n      tes = "防暑";\r\n    }\r\n  }\r\n  delay(500);\r\n  // Get humidity event and print its value.\r\n  dht.humidity().getEvent(&event);\r\n  if (isnan(event.relative_humidity)) {\r\n    Serial.println(F("Error reading humidity!"));\r\n  } else {\r\n    humidity = event.relative_humidity;\r\n    if (humidity < 40) {\r\n      hus = "干燥";\r\n    }\r\n    if (humidity >= 40 && humidity <= 70) {\r\n      hus = "舒适";\r\n    }\r\n    if (humidity > 70) {\r\n      hus = "潮湿";\r\n    }\r\n  }\r\n  Number1.print(temperature);\r\n  Number2.print(humidity);\r\n}\r\n// 如果未绑定的组件被触发，则会执行其中内容\r\n\r\nvoid button5_callback(const String& state) {\r\n  BLINKER_LOG("get button state: ", state);\r\n  if (ggb == false) {\r\n    digitalWrite(d8, HIGH);\r\n    ggb = true;\r\n    Text2.print("开");\r\n  } else {\r\n    digitalWrite(d8, LOW);\r\n    ggb = false;\r\n    Text2.print("关");\r\n  }\r\n  //限位开关导通时为低电平表明还没有达到限位,并且没到达到下降最大限制  能正常下降,断开为高电平表明达到限位了\r\n}\r\n\r\n\r\nvoid setup() {\r\n  // 初始化串口\r\n  Serial.begin(115200);\r\n  BLINKER_DEBUG.stream(Serial);\r\n  BLINKER_DEBUG.debugAll();\r\n\r\n  pinMode(open, OUTPUT);\r\n  pinMode(close, OUTPUT);\r\n  pinMode(d0, OUTPUT);\r\n  pinMode(d8, OUTPUT);\r\n  //pinMode(stop, OUTPUT);\r\n  pinMode(d5, INPUT_PULLUP);\r\n  pinMode(d6, INPUT_PULLUP);\r\n\r\n  digitalWrite(open, LOW);\r\n  digitalWrite(close, LOW);\r\n  digitalWrite(d0, LOW);\r\n  digitalWrite(d8, LOW);\r\n\r\n  // 初始化blinker\r\n  Blinker.begin(auth, ssid, pswd);\r\n\r\n  //Blinker.attachData(dataRead);\r\n\r\n  Button1.attach(button1_callback);\r\n  Button2.attach(button2_callback);\r\n  Button3.attach(button3_callback);\r\n  Button4.attach(button4_callback);\r\n  Button5.attach(button5_callback);\r\n  if (ggb == false) {\r\n    Text2.print("关");\r\n  } else {\r\n    Text2.print("开");\r\n  }\r\n\r\n  //防止 电源重启,门达到上限了,没有把状态改正,在这进行验证一下\r\n  if (digitalRead(d5) == HIGH) {\r\n    state1 = 10;\r\n  }\r\n  if (digitalRead(d6) == HIGH) {\r\n    state1 = 0;\r\n  }\r\n  String tmpDate = myHttpGet("http://jyan.360xyz.cn/api/Hour");\r\n  int dateL = tmpDate.toInt();\r\n  if (dateL > 6 && dateL < 18) {\r\n    ggb = true;\r\n    digitalWrite(d8, HIGH);\r\n    Text2.print("开");\r\n  }\r\n}\r\n\r\nvoid loop() {\r\n  Blinker.run();\r\n  //操作运行时 上升达到限位了,并且上次状态不是上升上限, 并且执行状态是上升 限位开关断开\r\n  if (digitalRead(d5) == HIGH && state1 != 10 && exec_status == 1) {\r\n    //关闭所有开关\r\n    digitalWrite(open, LOW);\r\n    digitalWrite(close, LOW);\r\n    delay(200);\r\n    //断开电源接通\r\n    digitalWrite(d0, LOW);\r\n    Text1.print("开门达到上限");\r\n    state1 = 10;\r\n\r\n    //执行状态为空\r\n    exec_status = 9;\r\n\r\n    String tmpDate = myHttpGet("http://jyan.360xyz.cn/api/Hour");\r\n    int dateL = tmpDate.toInt();\r\n    if (dateL > 6 && dateL < 18) {\r\n      ggb = true;\r\n      digitalWrite(d8, HIGH);\r\n      Text2.print("开");\r\n    }\r\n  }\r\n  //操作运行时 下降达到限位了,并且上次状态不是下降上限 并且执行状态是下降  限位开关开路\r\n  if (digitalRead(d6) == HIGH && state1 != 0 && exec_status == 0) {\r\n    digitalWrite(open, LOW);\r\n    digitalWrite(close, LOW);\r\n    delay(200);\r\n    //断开电源接通\r\n    digitalWrite(d0, LOW);\r\n    Text1.print("关门达到上限");\r\n    state1 = 0;\r\n\r\n    //执行状态为空\r\n    exec_status = 9;\r\n\r\n    //关门就把广告灯箱关了\r\n    digitalWrite(d8, LOW);\r\n    //告诉服务器让其知道灯箱现在是关闭状态\r\n\r\n    delay(500);\r\n  }\r\n  //即没有上限也没有下限状态\r\n  if (digitalRead(d5) == LOW && digitalRead(d6) == LOW && state1 != 5) {\r\n    state1 = 5;\r\n  }\r\n}\r\nString myHttpGet(String string) {\r\n  HTTPClient http;\r\n  String response;\r\n  http.begin(wificlient, string);\r\n  http.setTimeout(3000);\r\n  int httpCode = http.GET();\r\n  if (httpCode == 200) {\r\n    response = http.getString();\r\n    return response;\r\n  } else {\r\n    return "";\r\n  }\r\n  http.end();\r\n}\r\n//关闭上升,下降,变压器主电源\r\nvoid CloseAll() {\r\n  digitalWrite(open, LOW);\r\n  digitalWrite(close, LOW);\r\n  delay(200);\r\n  //断开电源接通\r\n  digitalWrite(d0, LOW);\r\n}\r\n', '', 'webserver'),
(7975, 20, '点灯科技遥控大门01s ', '#define BLINKER_WIFI\r\n#include <Blinker.h>\r\nchar auth[] = "f71c23621ed1";\r\nchar ssid[] = "webserver";\r\nchar pswd[] = "www.360xyz.cn";\r\nint dgxd = 0;\r\n\r\nBlinkerButton Button1("btn-z2f");  //上升\r\nBlinkerButton Button2("btn-biu");  //停止\r\nBlinkerButton Button3("btn-3l9");  //下降\r\nBlinkerButton Button4("btn-wmf");  //刷新温度湿度\r\nBlinkerButton Button5("btn-u8w");  //广告开关\r\n\r\nBlinkerNumber Number1("num-du7");  //温度\r\nBlinkerNumber Number2("num-0j1");  //湿度\r\n\r\nBlinkerText Text1("tex-je9");\r\nBlinkerText Text2("tex-08u");  //广告牌状态\r\n//上升\r\nvoid button1_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  Text1.print("上升");\r\n  String tstr = "mydoor1.↑";\r\n  Serial.write(tstr.c_str(), tstr.length());\r\n}\r\n//停止\r\nvoid button2_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  //如果已经在上限或下限时只更新响应时间\r\n  Text1.print("停止");\r\n  String tstr = "mydoor1.■";\r\n  Serial.write(tstr.c_str(), tstr.length());\r\n}\r\n//下降\r\nvoid button3_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  Text1.print("下降");\r\n  String tstr = "mydoor1.↓";\r\n  Serial.write(tstr.c_str(), tstr.length());\r\n}\r\nvoid button4_callback(const String& state) {\r\n // BLINKER_LOG("get button state: ", state);\r\n  // 获取温度事件并打印其值.\r\n  String tstr = "mydoor1.温湿度";\r\n  Serial.write(tstr.c_str(), tstr.length());\r\n  //Number1.print(temperature);\r\n  //Number2.print(humidity);\r\n}\r\nvoid button5_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  if (dgxd == 0) {\r\n    Text2.print("开");\r\n    String tstr = "mydoor1.灯箱开";\r\n    Serial.write(tstr.c_str(), tstr.length());\r\n  } else {\r\n    Text2.print("关");\r\n    String tstr = "mydoor1.灯箱关";\r\n    Serial.write(tstr.c_str(), tstr.length());\r\n  }\r\n  //限位开关导通时为低电平表明还没有达到限位,并且没到达到下降最大限制  能正常下降,断开为高电平表明达到限位了\r\n}\r\n\r\nvoid setup() {\r\n  // 初始化串口\r\n  Serial.begin(115200);\r\n  //BLINKER_DEBUG.stream(Serial);\r\n  //BLINKER_DEBUG.debugAll();\r\n  // 初始化blinker\r\n  Blinker.begin(auth, ssid, pswd);\r\n\r\n  //Blinker.attachData(dataRead);\r\n  Button1.attach(button1_callback);\r\n  Button2.attach(button2_callback);\r\n  Button3.attach(button3_callback);\r\n  Button4.attach(button4_callback);\r\n  Button5.attach(button5_callback);\r\n}\r\n\r\nvoid loop() {\r\n  Blinker.run();\r\n  if (Serial.available()) {                // 检查是否有可用的数据\r\n    String message = Serial.readString();  // 读取接收到的字符串\r\n    if (message.indexOf("°C") != -1) {\r\n      String temperature = message.substring(0, 4);\r\n      Number1.print(temperature.toFloat());\r\n      String humidity = message.substring(9);\r\n      Number2.print(humidity.toInt());\r\n    } else {\r\n      if (message.indexOf("灯箱") != -1) {\r\n        if (message.indexOf("灯箱开") != -1) {\r\n          dgxd = 1;\r\n          Text1.print(message);\r\n        } else {\r\n          dgxd = 0;\r\n          Text1.print(message);\r\n        }\r\n      }\r\n\r\n      Text1.print(message);\r\n    }\r\n    Serial.println("Received: " + message);  // 打印接收到的字符串\r\n  }\r\n}\r\n', '', 'webserver'),
(7977, 20, '超声波智能垃圾桶 ', '#include <Arduino.h>\r\n#include <ESP32Servo.h>\r\nconst int trigPin = 4;\r\nconst int echoPin = 16;\r\nServo servo1;\r\nint pos = 0;\r\nbool bl;\r\nint minUs = 500;   //0度是脉宽,单位us\r\nint maxUs = 2500;  //180度脉宽,单位us\r\nint servo1Pin = 15;\r\nvoid setup() {\r\n  // put your setup code here, to run once:\r\n  Serial.begin(115200);\r\n  delay(200);\r\n  pinMode(trigPin, OUTPUT);\r\n  pinMode(echoPin, INPUT);\r\n  ESP32PWM::allocateTimer(0);  //指定使用的硬件定时器 esp32有4个\r\n  ESP32PWM::allocateTimer(1);\r\n  ESP32PWM::allocateTimer(2);\r\n  ESP32PWM::allocateTimer(3);\r\n  servo1.setPeriodHertz(50);  //指定PWM频率\r\n  servo1.attach(servo1Pin, minUs, maxUs);\r\n // servo1.write(0);  //转到指定角度(0-180);\r\n  //servo1.detach();  //不需要的时候将引脚和ledc分离\r\n}\r\n\r\nvoid loop() {\r\n  // put your main code here, to run repeatedly:\r\n  digitalWrite(trigPin, HIGH);\r\n  delayMicroseconds(15);  //us 间隔15微秒的脉冲信号供应给超声波HC-SR04\r\n  digitalWrite(trigPin, LOW);\r\n\r\n  auto t = pulseIn(echoPin, HIGH);\r\n  double dis = t * 0.01715;  //cm 通过接收超声波返回的时间差计算距离 单位厘米\r\n  Serial.println(dis);\r\n  if (dis < 27) {\r\n    bl = true;\r\n  } else {\r\n    if (bl == true) {  //离开垃圾桶后触发 如果一直在感应区 bl 一直是true,首次是true得下次false触发\r\n      Serial.println("打开盖子到特定角度..........例如140度后停止............5秒后关闭盖子........................");\r\n      servo1.write(140);  //转到指定角度(0-180);\r\n      //servo1.detach();    //不需要的时候将引脚和ledc分离\r\n      delay(5000);\r\n      servo1.write(0);  //转到指定角度(0-180);\r\n     // servo1.detach();  //不需要的时候将引脚和ledc分离\r\n      Serial.println("5秒了关闭盖子中.....................舵机恢复到0角度后停止...................................");\r\n    }\r\n    bl = false;\r\n  }\r\n  delay(200);\r\n}\r\n', '', 'webserver'),
(7979, 20, '点灯科技自动手动温控加热加水断电记忆', '#define BLINKER_WIFI\r\n#include <OneWire.h>\r\n#include <DallasTemperature.h>\r\n#include <Blinker.h>\r\n#include <FS.h>\r\n\r\nString flash_file = "/false.txt";  //被读取的文件位置和名称\r\nString flash_bl = "/bl.txt";\r\nbool flash_bool = false;\r\n\r\nchar auth[] = "b07664fc1910";\r\nchar ssid[] = "webserver";\r\nchar pswd[] = "www.360xyz.cn";\r\nbool heating = false;  //加热状态  true 正在加热  false 加热关闭\r\nbool water = false;    //加水状态  true 正在加水  false 加水关闭\r\nfloat waterT = 0.01;   //预设定水温\r\n\r\n// 定义数据线引脚 D1\r\n#define ONE_WIRE_BUS 5\r\n#define D5 14  //加热开关\r\n#define D6 12  //上水开关\r\n\r\n// 初始化 OneWire 总线对象\r\nOneWire oneWire(ONE_WIRE_BUS);\r\n\r\n// 初始化 DallasTemperature 对象\r\nDallasTemperature sensors(&oneWire);\r\n\r\nBlinkerNumber Number1("num-8sr");  //水温\r\nBlinkerButton Button1("btn-x2p");  //刷新水温\r\n\r\nBlinkerNumber Number2("num-yc4");  //预热水温\r\nBlinkerButton Button2("btn-s73");  //刷新预热水温\r\n\r\nBlinkerButton Button3("btn-8ft");  //手动加热开关\r\nBlinkerButton Button4("btn-bx8");  //上水开关\r\n\r\nBlinkerButton Button5("btn-4dx");  //刷新手动开关状态\r\nBlinkerButton Button6("btn-ems");  //刷新上水开关状态\r\n\r\nBlinkerText Text1("tex-qyx");  //显示加热开关或上水 状态\r\n\r\nvoid setup(void) {\r\n  pinMode(D5, OUTPUT);\r\n  pinMode(D6, OUTPUT);\r\n  digitalWrite(D5, LOW);\r\n  digitalWrite(D6, LOW);\r\n  Serial.begin(115200);\r\n  Blinker.begin(auth, ssid, pswd);\r\n  Button1.attach(button1_callback);  //刷新水温\r\n  Button2.attach(button2_callback);  //刷新预热水温\r\n  Button3.attach(button3_callback);  //手动加热开关\r\n  Button4.attach(button4_callback);  //上水开关\r\n  Button5.attach(button5_callback);  //刷新手动开关状态\r\n  Button6.attach(button6_callback);  //刷新上水开关状态\r\n  Blinker.attachData(dataRead);\r\n\r\n  SPIFFS.begin();\r\n  //是否存在数据\r\n  if (SPIFFS.exists(flash_file) == false) {\r\n    File dataFile = SPIFFS.open(flash_file, "w");\r\n    dataFile.println("27.00");\r\n    waterT = 27.00;\r\n    dataFile.close();\r\n  } else {\r\n    SPIFFS.begin();\r\n    File dataFile = SPIFFS.open(flash_file, "r");\r\n    String result = dataFile.readString();\r\n    result.trim();  //清理字符两边的空格\r\n    waterT = result.toFloat();\r\n  }\r\n\r\n  if (SPIFFS.exists(flash_bl) == false) {\r\n    File dataFile = SPIFFS.open(flash_bl, "w");\r\n    dataFile.println("false");\r\n    dataFile.close();\r\n  } else {\r\n    SPIFFS.begin();\r\n    File dataFile = SPIFFS.open(flash_bl, "r");\r\n    String result = dataFile.readString();\r\n    result.trim();  //清理字符两边的空格\r\n    if (result == "true") {\r\n      digitalWrite(D5, HIGH);\r\n      heating = true;\r\n      flash_bool = true;\r\n    }\r\n  }\r\n\r\n  // 初始化DS18B20传感器\r\n  sensors.begin();\r\n}\r\n\r\nvoid loop(void) {\r\n  Blinker.run();\r\n\r\n  // 获取温度数据\r\n  sensors.requestTemperatures();\r\n  // 读取温度\r\n  float temperature = sensors.getTempCByIndex(0);\r\n  if (temperature >= waterT) {\r\n    digitalWrite(D5, LOW);\r\n    heating = false;\r\n    if (flash_bool == false) {\r\n      SPIFFS.begin();\r\n      File dataFile = SPIFFS.open(flash_bl, "w");\r\n      dataFile.println("false");\r\n      dataFile.close();\r\n      flash_bool = true;\r\n    }\r\n\r\n    Serial.println("达到设定温度 关闭加热");\r\n  }\r\n\r\n  delay(1000);\r\n}\r\n//刷新水温\r\nvoid button1_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  sensors.requestTemperatures();\r\n  float temperature = sensors.getTempCByIndex(0);\r\n  Number1.print(temperature);\r\n  Text1.print(temperature);\r\n}\r\n//刷新预热水温\r\nvoid button2_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  SPIFFS.begin();\r\n  File dataFile = SPIFFS.open(flash_file, "r");\r\n  String result = dataFile.readString();\r\n  result.trim();  //清理字符两边的空格\r\n  Number2.print(result.toFloat());\r\n  Serial.print(result);\r\n}\r\n//手动加热开关\r\nvoid button3_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  SPIFFS.begin();\r\n  if (heating == false) {\r\n    heating = true;\r\n    digitalWrite(D5, HIGH);\r\n    if (flash_bool == false) {\r\n      File dataFile = SPIFFS.open(flash_bl, "w");\r\n      dataFile.println("true");\r\n      dataFile.close();\r\n      flash_bool = true;\r\n    }\r\n\r\n    Text1.print("正在加热...");\r\n    Button3.color("#00FF00");\r\n    Button3.text("开");\r\n  } else {\r\n    heating = false;\r\n    digitalWrite(D5, LOW);\r\n\r\n    if (flash_bool == true) {\r\n      File dataFile = SPIFFS.open(flash_bl, "w");\r\n      dataFile.println("false");\r\n      dataFile.close();\r\n      flash_bool = false;\r\n    }\r\n\r\n    Text1.print("加热已经关闭");\r\n\r\n    Button3.color("#000000");\r\n    Button3.text("关");\r\n  }\r\n  Button3.print();\r\n}\r\n//上水开关\r\nvoid button4_callback(const String& state) {\r\n  // BLINKER_LOG("get button state: ", state);\r\n  if (water == false) {\r\n    water = true;\r\n    digitalWrite(D6, HIGH);\r\n    Text1.print("正在加水...");\r\n\r\n    Button4.color("#00FF00");\r\n    Button4.text("开");\r\n  } else {\r\n    water = false;\r\n    digitalWrite(D6, LOW);\r\n    Text1.print("加水已经关闭");\r\n\r\n    Button4.color("#000000");\r\n    Button4.text("关");\r\n  }\r\n  Button4.print();\r\n}\r\n//刷新手动加热开关状态\r\nvoid button5_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  if (heating == true) {\r\n\r\n    Text1.print("正在加热...");\r\n    Button3.color("#00FF00");\r\n    Button3.text("开");\r\n  } else {\r\n    Button3.color("#000000");\r\n    Button3.text("关");\r\n    Text1.print("加热已经关闭");\r\n  }\r\n  Button3.print();\r\n}\r\n//刷新上水开关状态\r\nvoid button6_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  if (water == true) {\r\n    Button4.color("#00FF00");\r\n    Button4.text("开");\r\n    Text1.print("正在加水...");\r\n  } else {\r\n    Button4.color("#000000");\r\n    Button4.text("关");\r\n    Text1.print("加水已经关闭");\r\n  }\r\n  Button4.print();\r\n}\r\n\r\n// 如果未绑定的组件被触发，则会执行其中内容\r\nvoid dataRead(const String& data) {\r\n  BLINKER_LOG("Blinker readString: ", data);\r\n  float tmp = data.toFloat();\r\n\r\n  if (tmp == 0) {\r\n    Text1.print("失败,只能数字");\r\n  } else {\r\n    File dataFile = SPIFFS.open(flash_file, "w");\r\n    dataFile.println(data);\r\n    waterT = tmp;\r\n    dataFile.close();\r\n    Text1.print("预制温度 " + data);\r\n  }\r\n}\r\n', '', 'webserver'),
(7980, 7, '电脑电源单独检测好坏', '24口插脚凸面朝下,右下开始数第4根绿线短接随意黑线,\r\n电源风扇转动就是好的\r\n', '', 'webserver'),
(7981, 4, '波轮洗衣机进水关不紧', '更换进水电磁阀开关', '', 'webserver'),
(7982, 7, '在不拆机状态下查看主板型号', 'Win+R 组合键\r\nmsinfo32 回车', '', 'webserver'),
(7983, 20, '巴法云 get post控制设备', '获取设备是否在线\r\nhttps://apis.bemfa.com/va/online?uid=07b120062a7972cf9831d7d9bc8012bc&topic=nobiggie01&type=1\r\n返回 \r\n{\r\n    "code": 0,  //0代表 成功\r\n    "message": "OK",\r\n    "data": false //true 为在线\r\n}\r\n获取设备所有主题\r\nhttps://apis.bemfa.com/va/alltopic?uid=07b120062a7972cf9831d7d9bc8012bc&type=1\r\n{\r\n    "code": 0,\r\n    "message": "OK",\r\n    "data": [\r\n        {\r\n            "topic": "nobiggie01",\r\n            "msg": "",\r\n            "name": "",\r\n            "room": "",\r\n            "online": false, //是否在线\r\n            "tid": "",\r\n            "sid": "", //如果是分享设备，此字段是分享者密钥\r\n            "time": "2023-12-15 17:58:05", //消息发送的时间，时区UTC/GMT+08:00\r\n            "unix": 1702634285 //消息发送的时间戳\r\n        }\r\n    ]\r\n}\r\n\r\n获取主题消息，支持GET协议\r\nhttps://apis.bemfa.com/va/getmsg?uid=07b120062a7972cf9831d7d9bc8012bc&topic=nobiggie01&type=1\r\n\r\n{\r\n    "code": 0,\r\n    "message": "OK",\r\n    "data": [\r\n        {\r\n            "msg": "啊哈哈哈哈",\r\n            "time": "2023-12-18 11:09:04",\r\n            "unix": 1702868944\r\n        }\r\n    ]\r\n}\r\n\r\n\r\n向主题推送消息，支持POST协议\r\nhttps://apis.bemfa.com/va/postmsg\r\n\r\nuid=07b120062a7972cf9831d7d9bc8012bc&topic=nobiggie01&type=1&msg=on&wemsg=on\r\n\r\n\r\n定时控制\r\n添加定时+删除定时 采用POST接口\r\n\r\n数据类型 "Content-Type": "application/x-www-form-urlencoded"\r\nhttps://api.bemfa.com/cloud/settime/v1/\r\nuid=07b120062a7972cf9831d7d9bc8012bc&topic=nobiggie01&type=1&msg=on&time=12:00:00&action=add    //add添加定时  del删除定时\r\n返回\r\n{"code":4003013,"status":"add ok"}  //成功\r\n删除 code:4003014 表示删除成功\r\n', '', 'webserver');
INSERT INTO `WisdomPreview` (`id`, `tid`, `title`, `content`, `imgtext`, `user`) VALUES
(7984, 20, 'ESP32物联遥控大门与智能播报', '#include <WiFi.h>\r\n#include <PubSubClient.h>\r\n#include <WebServer.h>\r\n#include <HTTPClient.h>\r\n#include <FS.h>\r\n#include "SPIFFS.h"\r\n#include "ESPmDNS.h"\r\n#include <Ticker.h>\r\n#include <DHT.h>\r\nconst char* mqttServer = "bemfa.com";\r\nconst int mqttPort = 9501;\r\nconst char* mqttUser = "door1";\r\nconst char* mqttPassword = "abcdefg";\r\nconst char* mqttClientId = "07b120062a7972cf9831d7d9bc8012bc";\r\nconst char* mqttTopic = "door1";\r\n\r\nint botelu = 19200;\r\nTicker myTicker;\r\n//被读取的文件位置和名称\r\nString flashWifi = "/wifi.txt";\r\nWebServer webServer(80);  // 创建网络服务器对象，HTTP服务的标准端口为：80\r\nString ssid = "";\r\nString passwd = "";\r\nString html;\r\n\r\nWiFiClient espClient;\r\nPubSubClient client(espClient);\r\n\r\nbool dx = false;  //灯箱状态 默认关\r\n\r\n#define doorTop 16     //升限位\r\n#define doorBottom 17  //降限位\r\n//由于中断处理函数是异步执行的，所以我们需要使用 volatile 关键字来声明中断标志，以确保在多线程环境下的可靠性\r\nvolatile bool flagTop = false;     // 第一个中断标志\r\nvolatile bool flagBottom = false;  // 第二个中断标志\r\n\r\n#define echoPin35 35  //超声距离感应echo脚\r\n#define trigPin32 32  //超声距离感应trig脚\r\n#define billboard 33  //广告牌\r\n#define doorOpen 25   //升\r\n#define doorClose 26  //降\r\n#define dhtPin 27     //温湿度传感器\r\n#define DHTTYPE DHT11  // DHT 11\r\nDHT_Unified dht(dhtPin, DHTTYPE);\r\n#define doorPower 14  //电源总开关\r\n#define broadcast 12  //播报电源开关\r\n\r\n//开关状态 10为上升上限  0为下降上限 5为可以上升可降\r\nint state = 5;\r\n\r\nint minUs = 500;    //0度是脉宽,单位us\r\nint maxUs = 2500;   //180度脉宽,单位us\r\nbool sr04 = false;  //默认不开启\r\nvoid setup() {\r\n  pinMode(trigPin32, OUTPUT);\r\n  pinMode(echoPin35, INPUT);\r\n\r\n  pinMode(doorTop, INPUT_PULLUP);                                         // 配置第一个中断引脚为输入模式，启用内部上拉电阻\r\n  pinMode(doorBottom, INPUT_PULLUP);                                      // 配置第二个中断引脚为输入模式，启用内部上拉电阻\r\n  attachInterrupt(digitalPinToInterrupt(doorTop), isrTop, CHANGE);        // 注册第一个中断处理函数，当引脚状态变化时触发\r\n  attachInterrupt(digitalPinToInterrupt(doorBottom), isrTottom, CHANGE);  // 注册第二个中断处理函数，当引脚状态变化时触发\r\n\r\n  pinMode(billboard, OUTPUT);\r\n  pinMode(doorOpen, OUTPUT);\r\n  pinMode(doorClose, OUTPUT);\r\n  pinMode(doorPower, OUTPUT);\r\n  pinMode(broadcast, OUTPUT);\r\n\r\n  digitalWrite(billboard, LOW);\r\n  digitalWrite(doorOpen, LOW);\r\n  digitalWrite(doorClose, LOW);\r\n  digitalWrite(doorPower, LOW);\r\n  digitalWrite(broadcast, LOW);\r\n\r\n  Serial.begin(botelu);\r\n  if (FlashConnetWifi() == false) {\r\n    HtmlSetWifi();\r\n  }\r\n  Serial.println("连接WIFIi成功");\r\n  client.setServer(mqttServer, mqttPort);\r\n  client.setCallback(callback);\r\n  while (!client.connected()) {\r\n    Serial.println("正在连接MQTT");\r\n    if (client.connect(mqttClientId, mqttUser, mqttPassword)) {\r\n      Serial.println("正在连接MQTT成功");\r\n      client.subscribe(mqttTopic);\r\n    } else {\r\n      Serial.println("正在连接MQTT失败");\r\n      delay(5000);\r\n    }\r\n  }\r\n}\r\nvoid loop() {\r\n  if (!client.connected()) {\r\n    reconnect();\r\n  }\r\n  client.loop();\r\n  if (flagTop) {\r\n    Serial.println("Interrupt 1 occurred!");\r\n\r\n    // flagTop = false;\r\n  }\r\n\r\n  if (flagBottom) {\r\n    Serial.println("Interrupt 2 occurred!");\r\n\r\n    //flagTottom = false;\r\n  }\r\n\r\n  if (sr04) {\r\n    digitalWrite(trigPin32, HIGH);\r\n    delayMicroseconds(15);  //us 间隔15微秒的脉冲信号供应给超声波HC-SR04\r\n    digitalWrite(trigPin32, LOW);\r\n\r\n    auto t = pulseIn(echoPin35, HIGH);\r\n    double dis = t * 0.01715;  //cm 通过接收超声波返回的时间差计算距离 单位厘米\r\n    Serial.println(dis);\r\n    if (dis < 150) {\r\n      sr04 = false;\r\n    }\r\n  }\r\n}\r\n\r\n// 第一个中断处理函数\r\nvoid isrTop() {\r\n  closeAll();\r\n  state = 10;\r\n  flagTop = true;\r\n  Serial.println("开门达到限制");\r\n}\r\n\r\n// 第二个中断处理函数\r\nvoid isrTottom() {\r\n  closeAll();\r\n  state = 0;\r\n  flagBottom = true;\r\n  Serial.println("关门达到限值");\r\n}\r\nvoid closeAll() {\r\n  digitalWrite(doorOpen, LOW);\r\n  digitalWrite(doorClose, LOW);\r\n  delay(200);\r\n  //断开电源接通\r\n  digitalWrite(doorPower, LOW);\r\n  //取消定时状态\r\n  myTicker.detach();\r\n  Serial.println("变压器电源已断开");\r\n}\r\n\r\nvoid callback(char* topic, byte* payload, unsigned int length) {\r\n  //Serial.println(topic);\r\n  String msg = "";\r\n  for (int i = 0; i < length; i++) {\r\n    msg += (char)payload[i];\r\n  }\r\n  Serial.print("Msg:");\r\n  Serial.println(msg);\r\n  if (msg == "■") {\r\n    closeAll();\r\n    sr04 = false;\r\n    String tmp = "";\r\n    if (dx == true) {\r\n      tmp = "灯箱状态 开";\r\n    } else {\r\n      tmp = "灯箱状态 关";\r\n    }\r\n    tmp = "停止 " + tmp;\r\n    client.publish(mqttTopic, tmp.c_str());\r\n    return;\r\n  }\r\n  if (msg == "↑") {\r\n    sr04 = false;\r\n    if (state != 10) {\r\n      client.publish(mqttTopic, "开门中...");\r\n      digitalWrite(doorOpen, HIGH);\r\n    } else {\r\n      client.publish(mqttTopic, "上限,指令无效");\r\n    }\r\n\r\n    return;\r\n  }\r\n  if (msg == "↓") {\r\n    sr04 = false;\r\n    if (state != 0) {\r\n      client.publish(mqttTopic, "关门中...");\r\n      digitalWrite(doorClose, HIGH);\r\n    } else {\r\n      client.publish(mqttTopic, "下限,指令无效");\r\n    }\r\n    return;\r\n  }\r\n  if (msg == "温湿度") {\r\n    // 获取温度事件并打印其值.\r\n    sensors_event_t event;\r\n    dht.temperature().getEvent(&event);\r\n    if (isnan(event.temperature)) {\r\n      Serial.println(F("Error reading temperature!"));\r\n    } else {\r\n      temperature = event.temperature;\r\n    }\r\n    delay(500);\r\n    // Get humidity event and print its value.\r\n    dht.humidity().getEvent(&event);\r\n    if (isnan(event.relative_humidity)) {\r\n      Serial.println(F("Error reading humidity!"));\r\n    } else {\r\n      humidity = event.relative_humidity;\r\n    }\r\n    String wfud = String(temperature) + "°C" + " " + String(humidity);\r\n   // Serial1.write(wfud.c_str(), wfud.length());\r\n    return;\r\n    client.publish(mqttTopic, wfud);\r\n  }\r\n  if (msg == "灯箱开") {\r\n    digitalWrite(billboard, HIGH);\r\n    dx = true;\r\n    client.publish(mqttTopic, "灯箱已开");\r\n  }\r\n  if (msg == "灯箱关") {\r\n    digitalWrite(billboard, LOW);\r\n    dx = false;\r\n    client.publish(mqttTopic, "灯箱已关");\r\n  }\r\n  if (msg.indexOf("温馨提示") != -1) {\r\n    if (state == 0 || state == 10) {\r\n      digitalWrite(broadcast, HIGH);\r\n      delay(2000);\r\n      String data = msg.substring(msg.indexOf("温馨提示"), msg.length());\r\n      data = data.substring(12);\r\n      data.replace(" ", "");\r\n      //String data = "020104C0";\r\n      //这里长度记得除下2    使用前校验一下String的长度是否正确\r\n      byte byteArray[data.length() / 2] = { 0 };\r\n      hexCharacterStringToBytes(byteArray, data.c_str());\r\n      //两个参数，第一个接收byte的数组,第二个要String.c_str()\r\n      Serial.write(byteArray, data.length() / 2);\r\n      delay(25000);\r\n      digitalWrite(broadcast, LOW);\r\n      return;\r\n    }\r\n  }\r\n  msg = "";\r\n}\r\n\r\nvoid reconnect() {\r\n  // Loop until we''re reconnected\r\n  while (!client.connected()) {\r\n    Serial.print("Attempting MQTT connection...");\r\n    // Attempt to connect\r\n    if (client.connect(mqttClientId)) {\r\n      Serial.println("connected");\r\n      Serial.print("subscribe:");\r\n      Serial.println(mqttTopic);\r\n      //订阅主题，如果需要订阅多个主题，可发送多条订阅指令client.subscribe(topic2);client.subscribe(topic3);\r\n      client.subscribe(mqttTopic);\r\n    } else {\r\n      Serial.print("failed, rc=");\r\n      Serial.print(client.state());\r\n      Serial.println(" try again in 5 seconds");\r\n      // Wait 5 seconds before retrying\r\n      delay(5000);\r\n    }\r\n  }\r\n}\r\n\r\n\r\nvoid HtmlSetWifi() {\r\n  WifiScan();\r\n  apStart();\r\n  delay(1000);\r\n  Serial.println("启动网页");\r\n  //5分后重启 防止停电后复电，路由器连接WIFI速度慢于ESP导致ESP连接不到路由器进入无限AP模式，所以这里只让AP激活5分钟后就重启\r\n  myTicker.once(300, EspReboot);\r\n  delay(200);\r\n  webserverStart();\r\n  while (1) {\r\n    webServer.handleClient();  // 检查网络服务请求并处理\r\n  }\r\n}\r\n\r\n//扫描附件WIFI\r\nvoid WifiScan() {\r\n  Serial.begin(botelu);\r\n  WiFi.mode(WIFI_STA);\r\n  delay(100);\r\n  int n = WiFi.scanNetworks();\r\n  if (n > 0) {\r\n    Serial.println(n);\r\n    String a = "附近WiFi <select id=\\"ssid\\">";\r\n    for (int i = 0; i < n; i++) {\r\n      Serial.println(WiFi.SSID(i));\r\n      a = a + "<option value=\\"" + WiFi.SSID(i) + "\\">" + WiFi.SSID(i) + "</option>";\r\n      delay(50);\r\n    }\r\n    String HtmlStart = String("") + "<!DOCTYPE html>" + "<html>" + "<head>" + "<meta charset=\\"utf-8\\">" + "<meta name=\\"viewport\\" content=\\"width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\\" />" + "<title>设置WiFi</title>" + "<link rel=\\"stylesheet\\" href=\\"\\">" + "</head>" + "<script>" + "onload  = function() {" + "document.getElementById(\\"up\\").onclick = function(){" + "var ssida=document.getElementById(\\"ssid\\").value;" + "var ssid=ssida.replace(/\\\\s+/g, \\" \\");" + "var passwda=document.getElementsByTagName(''input'')[0].value;" + "var passwd=passwda.replace(/\\\\s+/g, \\" \\");" + "xhr = new XMLHttpRequest();" + "xhr.open(\\"POST\\",\\"./setWifi\\",true);" + "var posts = (\\"ssid=\\"+ssid+\\"&passwd=\\"+ passwd);" + "xhr.setRequestHeader(\\"Content-Type\\",\\"application/x-www-form-urlencoded\\");" + "xhr.send(posts);" + "xhr.onreadystatechange = function(){" + "if(this.readyState == 4 && this.status == 200){" + "alert(this.responseText);" + "}" + "}" + "}" + "}" + "</script>" + "<body>";\r\n    String HtmlEnd = String("") + "<p>WiFi密码<input type=\\"text\\" id=\\"passwd\\"></p>" + "<input type=\\"submit\\" id=\\"up\\" value=\\"设 置\\">" + "<hr/>" + "<div>如果附近WiFi没有显示到自己的WIFI<div>" + "<div>请重启或离信号近点</div>" + "<div>连接成功AP热点退出转WIFI_STA</div>" + "</body>" + "</html>";\r\n    a = a + "</select>";\r\n    html = HtmlStart + a + HtmlEnd;\r\n  } else {\r\n    html = "扫描不到网络";\r\n    Serial.println("扫描不到网络");\r\n  }\r\n}\r\nvoid setWifi() {\r\n  ssid = webServer.arg(0);\r\n  passwd = webServer.arg(1);\r\n  const char* Ssid = ssid.c_str();\r\n  const char* Passwd = passwd.c_str();\r\n  String sp = ssid + "&" + passwd;\r\n\r\n  Serial.println(sp);\r\n  Serial.begin(botelu);\r\n  delay(500);\r\n  WiFi.begin(Ssid, Passwd);\r\n  WiFi.mode(WIFI_STA);\r\n  delay(200);\r\n  Serial.println("wifi_connet");\r\n  int ii = 0;\r\n  for (ii; ii < 20; ii++) {\r\n    delay(500);\r\n    Serial.print(".");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      webServer.send(200, "text/plane", "Wifi密码正确,ESP准备重启");\r\n      webServer.close();\r\n      delay(500);\r\n      WiFi.disconnect();\r\n      delay(500);\r\n      //写入数据\r\n      SPIFFS.format();\r\n      delay(500);\r\n      SPIFFS.begin();\r\n      File dataFile = SPIFFS.open(flashWifi, "w");\r\n      dataFile.println(sp);\r\n      dataFile.close();\r\n      Serial.println("HTML连接成功");\r\n      delay(1000);\r\n      ESP.restart();\r\n    }\r\n  }\r\n  webServer.send(200, "text/plane", "Wifi密码错误,请重新输入");\r\n  //HtmlSetWifi();\r\n}\r\n//------- 展示页面-------\r\nvoid handleRoot() {\r\n  webServer.send(500, "text/html", html);\r\n}\r\nvoid handleNotFound(void) {\r\n  webServer.send(404, "text/plain", "404-The page is not Found!");\r\n}\r\n\r\n\r\nvoid apStart() {\r\n  Serial.begin(botelu);\r\n  WiFi.mode(WIFI_AP);\r\n  IPAddress local_IP(192, 168, 168, 2);\r\n  IPAddress gateway(192, 168, 168, 1);\r\n  IPAddress subnet(255, 255, 255, 0);\r\n  WiFi.softAPConfig(local_IP, gateway, subnet);\r\n\r\n  //启动AP模式，并设置账号和密码\r\n  boolean result = WiFi.softAP("192.168.168.2", "192.168.168.2");\r\n  if (result) {\r\n    //输出 soft-ap ip地址\r\n    //Serial.println(String("Soft-AP IP address = ") + WiFi.softAPIP());\r\n  }\r\n}\r\nvoid webserverStart() {\r\n  //-----------------启动webserver网络服务--------------------\r\n  webServer.begin();              // 启用网络服务\r\n  webServer.on("/", handleRoot);  // / 在HTTP中，表示请求首页服务，\r\n  webServer.on("/setWifi", setWifi);\r\n  webServer.onNotFound(handleNotFound);  // 当服务器没找到所需的服务，调用404函数\r\n  Serial.println("webserver started");\r\n}\r\n\r\nbool FlashConnetWifi() {\r\n  Serial.begin(botelu);\r\n  delay(500);\r\n  //是否存在数据\r\n  SPIFFS.begin();\r\n  if (SPIFFS.exists(flashWifi) == false) {\r\n    Serial.print(flashWifi);\r\n    Serial.println(" NOT FOUND");\r\n    return false;\r\n  }\r\n\r\n  File dateFile = SPIFFS.open(flashWifi, "r");\r\n  String result;\r\n  for (int i = 0; i < dateFile.size(); i++) {\r\n    //Serial.print((char)dateFile.read());\r\n    result += (char)dateFile.read();\r\n  }\r\n  //去除前后空格\r\n  result.trim();\r\n  Serial.println(result);\r\n  int i = result.indexOf("&");\r\n\r\n  String wifiname = result.substring(0, i);\r\n  String wifipw = result.substring(i + 1);\r\n  const char* WifiName = wifiname.c_str();\r\n  const char* WifiPw = wifipw.c_str();\r\n  Serial.println(WifiName);\r\n  Serial.println(WifiPw);\r\n  WiFi.begin(WifiName, WifiPw);\r\n  delay(500);\r\n  WiFi.mode(WIFI_STA);\r\n  Serial.println("FlashConnetWifi->connet");\r\n  int ii = 0;\r\n  for (ii; ii < 20; ii++) {\r\n    delay(500);\r\n    Serial.print(" . ");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      Serial.println("FlashConnetWifi 闪存配置连接成功");\r\n      return true;\r\n    }\r\n  }\r\n  Serial.println("FlashConnetWifi->false");\r\n  return false;\r\n}\r\nvoid EspReboot() {\r\n  ESP.restart();\r\n}\r\n\r\nvoid hexCharacterStringToBytes(byte* byteArray, const char* hexString) {\r\n  bool oddLength = strlen(hexString) & 1;\r\n\r\n  byte currentByte = 0;\r\n  byte byteIndex = 0;\r\n\r\n  for (byte charIndex = 0; charIndex < strlen(hexString); charIndex++) {\r\n    bool oddCharIndex = charIndex & 1;\r\n\r\n    if (oddLength) {\r\n      // If the length is odd\r\n      if (oddCharIndex) {\r\n        // odd characters go in high nibble\r\n        currentByte = nibble(hexString[charIndex]) << 4;\r\n      } else {\r\n        // Even characters go into low nibble\r\n        currentByte |= nibble(hexString[charIndex]);\r\n        byteArray[byteIndex++] = currentByte;\r\n        currentByte = 0;\r\n      }\r\n    } else {\r\n      // If the length is even\r\n      if (!oddCharIndex) {\r\n        // Odd characters go into the high nibble\r\n        currentByte = nibble(hexString[charIndex]) << 4;\r\n      } else {\r\n        // Odd characters go into low nibble\r\n        currentByte |= nibble(hexString[charIndex]);\r\n        byteArray[byteIndex++] = currentByte;\r\n        currentByte = 0;\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\nbyte nibble(char c) {\r\n  if (c >= ''0'' && c <= ''9'')\r\n    return c - ''0'';\r\n\r\n  if (c >= ''a'' && c <= ''f'')\r\n    return c - ''a'' + 10;\r\n\r\n  if (c >= ''A'' && c <= ''F'')\r\n    return c - ''A'' + 10;\r\n\r\n  return 0;  // Not a valid hexadecimal character\r\n}', '', 'webserver'),
(7985, 20, 'esp8266 巴法云OTA方法', '#include <ESP8266WiFi.h>\r\n#include <ESP8266httpUpdate.h>\r\n/******需要修改的地方****************/\r\n#define wifi_name "newhtc"  //WIFI名称，区分大小写，不要写错\r\n#define wifi_password "qq123456"\r\n//WIFI密码 //固件链接，在巴法云控制台复制、粘贴到这里即可\r\nString upUrl = "http://bin.bemfa.com/b/3BcN2Q1NGY4NWFmNDI5NzZlZTNjMjY5M2U2OTJhNmJiNTk=light002.bin";\r\n/**********************************/ /** * 主函数 */\r\nvoid setup() {\r\n  Serial.begin(115200);  //波特率115200\r\n  WiFi.begin(wifi_name, wifi_password);\r\n  //连接wifi while (WiFi.status() != WL_CONNECTED) { //等待连接wifi\r\n  delay(500);\r\n  Serial.print(".");\r\n}\r\nupdateBin();    //开始升级 } \r\n/** * 循环函数 */\r\nvoid loop() {\r\n\r\n}  \r\n//当升级开始时，打印日志\r\nvoid update_started() {\r\n  Serial.println("CALLBACK: HTTP update process started");\r\n}\r\n//当升级结束时，打印日志\r\nvoid update_finished() {\r\n  Serial.println("CALLBACK: HTTP update process finished");\r\n}\r\n//当升级中，打印日志\r\nvoid update_progress(int cur, int total) {\r\n  Serial.printf("CALLBACK: HTTP update process at %d of %d bytes...\\n", cur, total);\r\n}\r\n//当升级失败时，打印日志\r\nvoid update_error(int err) {\r\n  Serial.printf("CALLBACK: HTTP update fatal error code %d\\n", err);\r\n}\r\n/** * 固件升级函数 * 在需要升级的地方，加上这个函数即可，例如setup中加的updateBin(); * 原理：通过http请求获取远程固件，实现升级 */\r\nvoid updateBin() {\r\n  Serial.println("start update");\r\n  WiFiClient UpdateClient;\r\n  ESPhttpUpdate.onStart(update_started);\r\n  //当升级开始时\r\n  ESPhttpUpdate.onEnd(update_finished);\r\n  //当升级结束时\r\n  ESPhttpUpdate.onProgress(update_progress);  //当升级中\r\n  ESPhttpUpdate.onError(update_error);        //当升级失败时\r\n  t_httpUpdate_return ret = ESPhttpUpdate.update(UpdateClient, upUrl);\r\n  switch (ret) {\r\n    case HTTP_UPDATE_FAILED:\r\n      //当升级失败\r\n      Serial.println("[update] Update failed.");\r\n      break;\r\n    case HTTP_UPDATE_NO_UPDATES:  //当无升级\r\n      Serial.println("[update] Update no Update.");\r\n      break;\r\n    case HTTP_UPDATE_OK:  //当升级成功\r\n      Serial.println("[update] Update ok.");\r\n      break;\r\n  }\r\n}', '', 'webserver'),
(7986, 20, 'esp32 巴法云OTA方法', '#include <WiFi.h>\r\n#include <HTTPUpdate.h>\r\n/******需要修改的地方****************/\r\n#define wifi_name "newhtc"        //WIFI名称，区分大小写，不要写错\r\n#define wifi_password "qq123456"  //WIFI密码 //固件链接，在巴法云控制台复制、粘贴到这里即可\r\nString upUrl = "http://bin.bemfa.com/b/3BcN2Q1NGY4NWFmNDI5NzZlZTNjMjY5M2U2OTJhNmJiNTk=esp32bin.bin";\r\n/**********************************/ /** * 主函数 */\r\nvoid setup() {\r\n  Serial.begin(115200);                    //波特率115200\r\n  WiFi.begin(wifi_name, wifi_password);    //连接wifi\r\n  while (WiFi.status() != WL_CONNECTED) {  //等待连接wifi\r\n    delay(500);\r\n    Serial.print(".");\r\n  }\r\n  updateBin();  //开始升级\r\n}\r\n/** * 循环函数 */\r\nvoid loop() {\r\n}\r\n//当升级开始时，打印日志\r\nvoid update_started() {\r\n  Serial.println("CALLBACK: HTTP update process started");\r\n}\r\n//当升级结束时，打印日志\r\nvoid update_finished() {\r\n  Serial.println("CALLBACK: HTTP update process finished");\r\n}\r\n//当升级中，打印日志\r\nvoid update_progress(int cur, int total) {\r\n  Serial.printf("CALLBACK: HTTP update process at %d of %d bytes...\\n", cur, total);\r\n}\r\n//当升级失败时，打印日志\r\nvoid update_error(int err) {\r\n  Serial.printf("CALLBACK: HTTP update fatal error code %d\\n", err);\r\n} /** * 固件升级函数 * 在需要升级的地方，加上这个函数即可，例如setup中加的updateBin(); * 原理：通过http请求获取远程固件，实现升级 */\r\nvoid updateBin() {\r\n  Serial.println("start update");\r\n  WiFiClient UpdateClient;\r\n  httpUpdate.onStart(update_started);      //当升级开始时\r\n  httpUpdate.onEnd(update_finished);       //当升级结束时\r\n  httpUpdate.onProgress(update_progress);  //当升级中\r\n  httpUpdate.onError(update_error);        //当升级失败时\r\n  t_httpUpdate_return ret = httpUpdate.update(UpdateClient, upUrl);\r\n  switch (ret) {\r\n    case HTTP_UPDATE_FAILED:  //当升级失败\r\n      Serial.println("[update] Update failed.");\r\n      break;\r\n    case HTTP_UPDATE_NO_UPDATES:  //当无升级\r\n      Serial.println("[update] Update no Update.");\r\n      break;\r\n    case HTTP_UPDATE_OK:  //当升级成功\r\n      Serial.println("[update] Update ok.");\r\n      break;\r\n  }\r\n}', '', 'webserver'),
(7988, 20, 'esp32点灯科技自动手动温控加热加水断电记忆', '#define BLINKER_WIFI\r\n#include <OneWire.h>\r\n#include <DallasTemperature.h>\r\n#include <ESP32httpUpdate.h>\r\n#include <FS.h>\r\n#include <SPIFFS.h>\r\n#include <ESPmDNS.h>\r\n#include <Ticker.h>\r\n#include <WebServer.h>\r\n#include <WiFi.h>\r\n#include <Blinker.h>\r\n#include <HTTPClient.h>\r\n#include <SPI.h>\r\n#include <TFT_eSPI.h>\r\n#include "ESPmDNS.h"\r\n#include <Ticker.h>\r\n#include <Thread.h>\r\n#include <WebServer.h>\r\n#include <Arduino.h>\r\n\r\nWiFiClient wificlient;\r\nThread myThread = Thread();\r\nTFT_eSPI tft = TFT_eSPI();\r\nString flash_file = "/false.txt";  //被读取的文件位置和名称\r\nString flash_bl = "/bl.txt";\r\nbool flash_bool = false;\r\nchar auth[] = "b07664fc1910";\r\nString ssid;\r\nString passwd;\r\nString html;\r\nbool heating = false;  //加热状态  true 正在加热  false 加热关闭\r\nbool water = false;    //加水状态  true 正在加水  false 加水关闭\r\nfloat waterT = 0.01;   //预设定水温\r\n//SDA 15\r\n//SCL 14\r\n//CS  5\r\n//DC  27\r\n//RST 33\r\n//BL  22\r\n// 定义数据线引脚 p17\r\n#define ONE_WIRE_BUS 17\r\n#define P22 16  //加热开关\r\n\r\n#define P21 21  //上水开关\r\n\r\n#define touch4 4  //设置WIFI\r\n#define m4 36\r\n#define m3 39\r\n#define m2 34\r\n#define m1 35\r\n\r\n// 初始化 OneWire 总线对象\r\nOneWire oneWire(ONE_WIRE_BUS);\r\n\r\n// 初始化 DallasTemperature 对象\r\nDallasTemperature sensors(&oneWire);\r\n\r\nBlinkerNumber Number3("num-yev");  //水位\r\n\r\nBlinkerNumber Number1("num-8sr");  //水温\r\nBlinkerButton Button1("btn-x2p");  //刷新水温\r\n\r\nBlinkerNumber Number2("num-yc4");  //预热水温\r\nBlinkerButton Button2("btn-s73");  //刷新预热水温\r\n\r\nBlinkerButton Button3("btn-8ft");  //手动加热开关\r\nBlinkerButton Button4("btn-bx8");  //上水开关\r\n\r\nBlinkerButton Button5("btn-4dx");  //刷新手动开关状态\r\nBlinkerButton Button6("btn-ems");  //刷新上水开关状态\r\n\r\nBlinkerText Text1("tex-qyx");  //显示加热开关或上水 状态\r\n\r\nTicker myTicker;\r\nString flashWifi = "/wifi.txt";  //wifi密码存放文件\r\nWebServer webServer;\r\nint touchJu = 0;\r\nint touchJr = 2;\r\n#define baudRate 115200\r\nvoid niceCallback() {\r\n  String HI = esp32getHI();\r\n  Serial.println(HI);\r\n  tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n  tft.setCursor(10, 10, 2);  //设置起始坐标(10, 10)，1 号字体\r\n  tft.println(HI);           //显示文字\r\n  millis();\r\n}\r\nvoid setup(void) {\r\n  pinMode(P22, OUTPUT);\r\n  pinMode(P21, OUTPUT);\r\n  //水位探测\r\n  pinMode(m1, INPUT_PULLUP);\r\n  pinMode(m2, INPUT_PULLUP);\r\n  pinMode(m3, INPUT_PULLUP);\r\n  pinMode(m4, INPUT_PULLUP);\r\n  pinMode(touchJr, INPUT_PULLUP);\r\n  pinMode(touchJu, INPUT_PULLUP);\r\n  digitalWrite(P22, LOW);\r\n  digitalWrite(P21, LOW);\r\n  myThread.onRun(niceCallback);\r\n  myThread.setInterval(10000);\r\n  Serial.begin(baudRate);\r\n  delay(200);\r\n  SPIFFS.begin();\r\n  delay(200);\r\n  if (FlashConnetWifi() == false) {\r\n    HtmlSetWifi();\r\n  }\r\n  WiFi.disconnect();\r\n  delay(300);\r\n  Blinker.begin(auth, ssid.c_str(), passwd.c_str());\r\n  Button1.attach(button1_callback);  //刷新水温\r\n  Button2.attach(button2_callback);  //刷新预热水温\r\n  Button3.attach(button3_callback);  //手动加热开关\r\n  Button4.attach(button4_callback);  //上水开关\r\n  Button5.attach(button5_callback);  //刷新手动开关状态\r\n  Button6.attach(button6_callback);  //刷新上水开关状态\r\n  Blinker.attachData(dataRead);\r\n\r\n  SPIFFS.begin();\r\n  if (SPIFFS.exists(flash_file) == false) {\r\n    File dataFile = SPIFFS.open(flash_file, "w");\r\n    dataFile.println("27.00");\r\n    waterT = 27.00;\r\n    dataFile.close();\r\n  } else {\r\n    SPIFFS.begin();\r\n    File dataFile = SPIFFS.open(flash_file, "r");\r\n    String result = dataFile.readString();\r\n    result.trim();\r\n    waterT = result.toFloat();\r\n  }\r\n\r\n  if (SPIFFS.exists(flash_bl) == false) {\r\n    File dataFile = SPIFFS.open(flash_bl, "w");\r\n    dataFile.println("false");\r\n    dataFile.close();\r\n  } else {\r\n    SPIFFS.begin();\r\n    File dataFile = SPIFFS.open(flash_bl, "r");\r\n    String result = dataFile.readString();\r\n    result.trim();\r\n    if (result == "true") {\r\n      digitalWrite(P22, HIGH);\r\n      heating = true;\r\n      flash_bool = true;\r\n    }\r\n  }\r\n  tft.init();\r\n  tft.fillScreen(TFT_BLACK);  //屏幕颜色\r\n  tft.setCursor(50, 60, 2);\r\n  tft.println("%");\r\n  String re = sendPostRequest();\r\n  if (re.length() > 10) {\r\n    re.trim();\r\n    t_httpUpdate_return ret = ESPhttpUpdate.update(re);\r\n  }\r\n  // 初始化DS18B20传感器\r\n  sensors.begin();\r\n}\r\n\r\nvoid loop(void) {\r\n  Blinker.run();\r\n  // 获取温度数据\r\n  sensors.requestTemperatures();\r\n  // 读取温度\r\n  float temperature = sensors.getTempCByIndex(0);\r\n  tft.setCursor(10, 40, 2);\r\n\r\n  tft.println(String(temperature) + " ° C");\r\n  if (temperature >= waterT) {\r\n    digitalWrite(P22, LOW);\r\n    heating = false;\r\n    if (flash_bool == false) {\r\n      SPIFFS.begin();\r\n      File dataFile = SPIFFS.open(flash_bl, "w");\r\n      dataFile.println("false");\r\n      dataFile.close();\r\n      flash_bool = true;\r\n    }\r\n\r\n    Serial.println("达到设定温度 关闭加热");\r\n  }\r\n  //delay(1000);\r\n  if (digitalRead(m4) == LOW) {\r\n    Serial.println("100");\r\n    Number3.print(100);\r\n    tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n    tft.setCursor(10, 60, 2);\r\n    tft.println("100");\r\n    if (water == true) {\r\n      water = false;\r\n      digitalWrite(P21, LOW);\r\n      tft.setCursor(10, 80, 2);\r\n      tft.println("water off");\r\n      Text1.print("加水已经关闭");\r\n      Button4.color("#000000");\r\n      Button4.text("加水已关");\r\n      Button4.print();\r\n    }\r\n  } else {\r\n    if (digitalRead(m3) == LOW) {\r\n      //75%\r\n      Serial.println("75");\r\n      Number3.print(75);\r\n      tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n      tft.setCursor(10, 60, 2);\r\n      tft.println(" 75");\r\n    } else {\r\n      if (digitalRead(m2) == LOW) {\r\n        //50%\r\n        Serial.println("50");\r\n        Number3.print(50);\r\n        tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n        tft.setCursor(10, 60, 2);  //设置起始坐标(10, 10)，1 号字体\r\n        tft.println(" 50");\r\n      } else {\r\n        if (digitalRead(m1) == LOW) {\r\n          //25%\r\n          Serial.println("25");\r\n          Number3.print(25);\r\n          tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n          tft.setCursor(10, 60, 2);\r\n          tft.println(" 25");\r\n        } else {\r\n          Serial.println("0");\r\n          Number3.print(0);\r\n          tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n          tft.setCursor(10, 60, 2);\r\n          tft.println("  0 ");\r\n          if (water == false) {\r\n            water = true;\r\n            digitalWrite(P21, HIGH);\r\n            tft.setCursor(10, 80, 2);\r\n            tft.println("water on ");\r\n            Text1.print("正在加水...");\r\n            Button4.color("#00FF00");\r\n            Button4.text("加水 开");\r\n            Button4.print();\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n  if (myThread.shouldRun()) {\r\n    myThread.run();\r\n  }\r\n\r\n  if (digitalRead(touchJu) == LOW) {\r\n    if (water == false) {\r\n      water = true;\r\n      digitalWrite(P21, HIGH);\r\n      Text1.print("正在加水...");\r\n      Button4.color("#00FF00");\r\n      Button4.text("正在加水");\r\n      tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n      tft.setCursor(10, 80, 2);\r\n      tft.println("water on ");\r\n    } else {\r\n      water = false;\r\n      digitalWrite(P21, LOW);\r\n      Text1.print("加水已经关闭");\r\n      Button4.color("#000000");\r\n      Button4.text("加水 关");\r\n      tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n      tft.setCursor(10, 80, 2);\r\n      tft.println("water off");\r\n    }\r\n    Button4.print();\r\n  }\r\n  if (digitalRead(touchJr) == LOW) {\r\n    SPIFFS.begin();\r\n    if (heating == false) {\r\n      heating = true;\r\n      digitalWrite(P22, HIGH);\r\n      if (flash_bool == false) {\r\n        File dataFile = SPIFFS.open(flash_bl, "w");\r\n        dataFile.println("true");\r\n        dataFile.close();\r\n        flash_bool = true;\r\n      }\r\n      Text1.print("正在加热...");\r\n      Button3.color("#00FF00");\r\n      Button3.text("加热开");\r\n      tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n      tft.setCursor(10, 100, 2);\r\n      tft.println("hot on ");\r\n    } else {\r\n      heating = false;\r\n      digitalWrite(P22, LOW);\r\n\r\n      if (flash_bool == true) {\r\n        File dataFile = SPIFFS.open(flash_bl, "w");\r\n        dataFile.println("false");\r\n        dataFile.close();\r\n        flash_bool = false;\r\n      }\r\n      Text1.print("加热已经关闭");\r\n      Button3.color("#000000");\r\n      Button3.text("加热已关");\r\n      tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n      tft.setCursor(10, 100, 2);\r\n      tft.println("hot off");\r\n    }\r\n    Button3.print();\r\n  }\r\n}\r\n//刷新水温\r\nvoid button1_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  sensors.requestTemperatures();\r\n  float temperature = sensors.getTempCByIndex(0);\r\n  Number1.print(temperature);\r\n  Text1.print(temperature);\r\n}\r\n//刷新预热水温\r\nvoid button2_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  SPIFFS.begin();\r\n  File dataFile = SPIFFS.open(flash_file, "r");\r\n  String result = dataFile.readString();\r\n  result.trim();  //清理字符两边的空格\r\n  Number2.print(result.toFloat());\r\n  Serial.print(result);\r\n}\r\n//手动加热开关\r\nvoid button3_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  SPIFFS.begin();\r\n  if (heating == false) {\r\n    heating = true;\r\n    digitalWrite(P22, HIGH);\r\n    if (flash_bool == false) {\r\n      File dataFile = SPIFFS.open(flash_bl, "w");\r\n      dataFile.println("true");\r\n      dataFile.close();\r\n      flash_bool = true;\r\n    }\r\n    tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n    tft.setCursor(10, 100, 2);\r\n    tft.println("hot on ");\r\n    Text1.print("正在加热...");\r\n    Button3.color("#00FF00");\r\n    Button3.text("加热开");\r\n  } else {\r\n    heating = false;\r\n    digitalWrite(P22, LOW);\r\n\r\n    if (flash_bool == true) {\r\n      File dataFile = SPIFFS.open(flash_bl, "w");\r\n      dataFile.println("false");\r\n      dataFile.close();\r\n      flash_bool = false;\r\n    }\r\n    tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n    tft.setCursor(10, 100, 2);\r\n    tft.println("hot off");\r\n    Text1.print("加热已经关闭");\r\n    Button3.color("#000000");\r\n    Button3.text("加热已关");\r\n  }\r\n  Button3.print();\r\n}\r\n//上水开关\r\nvoid button4_callback(const String& state) {\r\n  // BLINKER_LOG("get button state: ", state);\r\n  if (water == false) {\r\n    water = true;\r\n    digitalWrite(P21, HIGH);\r\n    Text1.print("正在加水...");\r\n    tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n    tft.setCursor(10, 80, 2);\r\n    tft.println("water on ");\r\n    Button4.color("#00FF00");\r\n    Button4.text("正在加水");\r\n  } else {\r\n    water = false;\r\n    digitalWrite(P21, LOW);\r\n    Text1.print("加水已经关闭");\r\n    tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n    tft.setCursor(10, 80, 2);\r\n    tft.println("water off");\r\n    Button4.color("#000000");\r\n    Button4.text("加水 关");\r\n  }\r\n  Button4.print();\r\n}\r\n//刷新手动加热开关状态\r\nvoid button5_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  if (heating == true) {\r\n    Text1.print("正在加热...");\r\n    Button3.color("#00FF00");\r\n    Button3.text("加热 开");\r\n  } else {\r\n    Button3.color("#000000");\r\n    Button3.text("加热 关");\r\n    Text1.print("加热已经关闭");\r\n  }\r\n  Button3.print();\r\n}\r\n//刷新上水开关状态\r\nvoid button6_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  if (water == true) {\r\n    Button4.color("#00FF00");\r\n    Button4.text("开");\r\n    Text1.print("正在加水...");\r\n  } else {\r\n    Button4.color("#000000");\r\n    Button4.text("加水 关");\r\n    Text1.print("加水已经关闭");\r\n  }\r\n  Button4.print();\r\n}\r\n\r\n// 如果未绑定的组件被触发，则会执行其中内容\r\nvoid dataRead(const String& data) {\r\n  BLINKER_LOG("Blinker readString: ", data);\r\n  float tmp = data.toFloat();\r\n\r\n  if (tmp == 0) {\r\n    Text1.print("失败,只能数字");\r\n  } else {\r\n    File dataFile = SPIFFS.open(flash_file, "w");\r\n    dataFile.println(data);\r\n    waterT = tmp;\r\n    dataFile.close();\r\n    Text1.print("预制温度 " + data);\r\n  }\r\n}\r\n\r\nvoid espReboot() {\r\n  ESP.restart();\r\n}\r\n\r\n\r\n\r\nString sendPostRequest() {\r\n  HTTPClient http;\r\n  String url = "http://jyan.nobiggie.cn/query/vs";\r\n  http.begin(wificlient, url);\r\n  http.setTimeout(3000);\r\n  String postStr = "vs=a13544957057";\r\n  char dataBuff[postStr.length()];\r\n  strcpy(dataBuff, postStr.c_str());\r\n  http.addHeader("Content-Type", "application/x-www-form-urlencoded");\r\n  int httpResponseCode = http.POST(dataBuff);\r\n  if (httpResponseCode > 0) {\r\n    String response = http.getString();\r\n    return response;\r\n  }\r\n  return "";\r\n}\r\n\r\nString esp32getHI() {\r\n  HTTPClient http;\r\n  String response;\r\n  String urlstr = "http://jyan.nobiggie.cn/query/HI";\r\n  http.begin(wificlient, urlstr);\r\n  http.setTimeout(3000);\r\n  int httpCode = http.GET();\r\n  // httpCode will be negative on error\r\n  if (httpCode == 200) {\r\n    response = http.getString();\r\n    return response;\r\n  } else {\r\n    return "";\r\n  }\r\n  http.end();\r\n}\r\n\r\n\r\nvoid HtmlSetWifi() {\r\n  WifiScan();\r\n  apStart();\r\n  delay(1000);\r\n  Serial.println("start webserver");\r\n  //5分后重启 防止停电后复电，路由器连接WIFI速度慢于ESP导致ESP连接不到路由器进入无限AP模式，所以这里只让AP激活5分钟后就重启\r\n  myTicker.once(300, espReboot);\r\n  delay(200);\r\n  webserverStart();\r\n  while (1) {\r\n    webServer.handleClient();  //检查网络服务请求并处理\r\n  }\r\n}\r\nvoid WifiScan() {\r\n  WiFi.disconnect();\r\n  Serial.begin(baudRate);\r\n  WiFi.mode(WIFI_STA);\r\n  delay(100);\r\n  int n = WiFi.scanNetworks();\r\n  if (n > 0) {\r\n    String a = "附近WiFi <select id=\\"ssid\\">";\r\n    for (int i = 0; i < n; i++) {\r\n      Serial.println(WiFi.SSID(i));\r\n      a = a + "<option value=\\"" + WiFi.SSID(i) + "\\">" + WiFi.SSID(i) + "</option>";\r\n      delay(50);\r\n    }\r\n    String HtmlStart = String("") + "<!DOCTYPE html>" + "<html>" + "<head>" + "<meta charset=\\"utf-8\\">" + "<meta name=\\"viewport\\" content=\\"width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\\" />" + "<title>设置WiFi</title>" + "<link rel=\\"stylesheet\\" href=\\"\\">" + "</head>" + "<script>" + "onload  = function() {" + "document.getElementById(\\"up\\").onclick = function(){" + "var ssida=document.getElementById(\\"ssid\\").value;" + "var ssid=ssida.replace(/\\\\s+/g, \\" \\");" + "var passwda=document.getElementsByTagName(''input'')[0].value;" + "var passwd=passwda.replace(/\\\\s+/g, \\" \\");" + "xhr = new XMLHttpRequest();" + "xhr.open(\\"POST\\",\\"./setWifi\\",true);" + "var posts = (\\"ssid=\\"+ssid+\\"&passwd=\\"+ passwd);" + "xhr.setRequestHeader(\\"Content-Type\\",\\"application/x-www-form-urlencoded\\");" + "xhr.send(posts);" + "xhr.onreadystatechange = function(){" + "if(this.readyState == 4 && this.status == 200){" + "alert(this.responseText);" + "}" + "}" + "}" + "}" + "</script>" + "<body>";\r\n    String HtmlEnd = String("") + "<p>WiFi密码<input type=\\"text\\" id=\\"passwd\\"></p>" + "<input type=\\"submit\\" id=\\"up\\" value=\\"设 置\\">" + "<hr/>" + "<div>如果附近WiFi没有显示到自己的WIFI<div>" + "<div>请重启或离信号近点</div>" + "<div>连接成功AP热点退出转WIFI_STA</div>" + "</body>" + "</html>";\r\n    a = a + "</select>";\r\n    html = HtmlStart + a + HtmlEnd;\r\n  } else {\r\n    html = "扫描不到网络";\r\n  }\r\n}\r\nvoid setWifi() {\r\n  ssid = webServer.arg(0);\r\n  passwd = webServer.arg(1);\r\n  const char* Ssid = ssid.c_str();\r\n  const char* Passwd = passwd.c_str();\r\n  String sp = ssid + "&" + passwd;\r\n  Serial.println(sp);\r\n  Serial.begin(baudRate);\r\n  delay(500);\r\n  WiFi.begin(Ssid, Passwd);\r\n  WiFi.mode(WIFI_STA);\r\n  delay(200);\r\n  Serial.println("wifi_connet");\r\n  int ii = 0;\r\n  for (ii; ii < 20; ii++) {\r\n    delay(500);\r\n    Serial.print(".");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      webServer.send(200, "text/plane", "Wifi密码正确,ESP准备重启");\r\n      webServer.close();\r\n      delay(500);\r\n      WiFi.disconnect();\r\n      delay(500);\r\n      //写入数据\r\n      SPIFFS.format();\r\n      delay(500);\r\n      SPIFFS.begin();\r\n      File dataFile = SPIFFS.open(flashWifi, "w");\r\n      dataFile.println(sp);\r\n      dataFile.close();\r\n      Serial.println("HTML设置网络连接成功");\r\n      delay(500);\r\n      ESP.restart();\r\n    }\r\n  }\r\n  webServer.send(200, "text/plane", "Wifi密码错误,请重新输入");\r\n}\r\n//------- 展示页面-------\r\nvoid handleRoot() {\r\n  webServer.send(500, "text/html", html);\r\n}\r\nvoid handleNotFound(void) {\r\n  webServer.send(404, "text/plain", "404-The page is not Found!");\r\n}\r\nvoid apStart() {\r\n  Serial.begin(baudRate);\r\n  WiFi.mode(WIFI_AP);\r\n  IPAddress local_IP(192, 168, 168, 2);\r\n  IPAddress gateway(192, 168, 168, 1);\r\n  IPAddress subnet(255, 255, 255, 0);\r\n  WiFi.softAPConfig(local_IP, gateway, subnet);\r\n  //启动AP模式，并设置账号和密码\r\n  boolean result = WiFi.softAP("192.168.168.2", "nobiggie.cn");\r\n  if (result) {\r\n    Serial.println(String("Soft-AP IP address = ") + WiFi.softAPIP());\r\n  }\r\n}\r\nvoid webserverStart() {\r\n  webServer.begin(80);            // 启用网络服务\r\n  webServer.on("/", handleRoot);  // / 在HTTP中，表示请求首页服务，\r\n  webServer.on("/setWifi", setWifi);\r\n  webServer.onNotFound(handleNotFound);  // 当服务器没找到所需的服务，调用404函数\r\n  Serial.println("webserver started");\r\n}\r\nbool FlashConnetWifi() {\r\n  Serial.begin(baudRate);\r\n  delay(200);\r\n  SPIFFS.begin();\r\n  if (SPIFFS.exists(flashWifi) == false) {\r\n    Serial.println("NOT FOUND");\r\n    return false;\r\n  }\r\n\r\n  File dateFile = SPIFFS.open(flashWifi, "r");\r\n  String result;\r\n  for (int i = 0; i < dateFile.size(); i++) {\r\n    //Serial.print((char)dateFile.read());\r\n    result += (char)dateFile.read();\r\n  }\r\n  result.trim();\r\n  Serial.println(result);\r\n  int i = result.indexOf("&");\r\n  String wifiname = result.substring(0, i);\r\n  String wifipw = result.substring(i + 1);\r\n  const char* WifiName = wifiname.c_str();\r\n  const char* WifiPw = wifipw.c_str();\r\n  Serial.println(WifiName);\r\n  Serial.println(WifiPw);\r\n  WiFi.begin(WifiName, WifiPw);\r\n  delay(500);\r\n  WiFi.mode(WIFI_STA);\r\n  Serial.println("FlashConnet...");\r\n  int ii = 0;\r\n  for (ii; ii < 30; ii++) {\r\n    delay(500);\r\n    Serial.print(" . ");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      Serial.println("flash connet success");\r\n      ssid = String(WifiName);\r\n      passwd = String(WifiPw);\r\n      return true;\r\n    }\r\n  }\r\n  Serial.println("flash read error");\r\n  return false;\r\n}', '', 'webserver'),
(7991, 20, '巴法云 温湿度 GPS定位1 ', '#include <WiFi.h>\r\n#include <PubSubClient.h>\r\n#include <DHT.h>\r\n\r\nString ssid = "webserver";            //这里改成你的WIFI名\r\nString wifipasswd = "www.360xyz.cn";  //这里你的WIFI密码\r\n#define DHT11_DATA_PIN 26\r\n#define DHTTYPE DHT11\r\nDHT dht(DHT11_DATA_PIN, DHTTYPE);\r\n\r\nWiFiClient espClient;\r\nPubSubClient client(espClient);\r\nconst char* mqttServer = "bemfa.com";\r\nconst int mqttPort = 9501;\r\nconst char* mqttUser = "test";\r\nconst char* mqttPassword = "abcdefg";\r\nconst char* mqttClientId = "07b120062a7972cf9831d7d9bc8012bc";\r\nconst char* mqttTopic = "test";\r\n\r\n\r\n#define Serial Serial\r\n#define L 25  //LED指示灯引脚\r\nstruct\r\n{\r\n  char GPS_Buffer[80];\r\n  bool isGetData;      //是否获取到GPS数据\r\n  bool isParseData;    //是否解析完成\r\n  char UTCTime[11];    //UTC时间\r\n  char latitude[11];   //纬度\r\n  char N_S[2];         //N/S\r\n  char longitude[12];  //经度\r\n  char E_W[2];         //E/W\r\n  bool isUsefull;      //定位信息是否有效\r\n} Save_Data;\r\nconst unsigned int gpsRxBufferLength = 600;\r\nchar gpsRxBuffer[gpsRxBufferLength];\r\nunsigned int ii = 0;\r\n\r\n\r\nvoid setup() {\r\n  // put your setup code here, to run once:\r\n  Serial.begin(9600);\r\n  pinMode(L, OUTPUT);\r\n  digitalWrite(L, LOW);\r\n  WiFi.begin(ssid.c_str(), wifipasswd.c_str());\r\n  delay(500);\r\n  WiFi.mode(WIFI_STA);\r\n\r\n  while (true) {\r\n    delay(500);\r\n    Serial.print(" . ");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      Serial.println("flash connet success");\r\n      break;\r\n    }\r\n  }\r\n  client.setServer(mqttServer, mqttPort);\r\n  client.setCallback(callback);\r\n  while (!client.connected()) {\r\n    Serial.println("正在连接MQTT");\r\n    if (client.connect(mqttClientId, mqttUser, mqttPassword)) {\r\n      Serial.println("正在连接MQTT成功");\r\n      client.subscribe(mqttTopic);\r\n    } else {\r\n      Serial.println("正在连接MQTT失败");\r\n      delay(5000);\r\n    }\r\n  }\r\n  Save_Data.isGetData = false;\r\n  Save_Data.isParseData = false;\r\n  Save_Data.isUsefull = false;\r\n  dht.begin();\r\n}\r\n\r\nvoid loop() {\r\n  // put your main code here, to run repeatedly:\r\n  if (!client.connected()) {\r\n    reconnect();\r\n  }\r\n  client.loop();\r\n}\r\nvoid callback(char* topic, byte* payload, unsigned int length) {\r\n  //Serial.println(topic);\r\n  String msg = "";\r\n  for (int i = 0; i < length; i++) {\r\n    msg += (char)payload[i];\r\n  }\r\n  Serial.print("Msg:");\r\n  Serial.println(msg);\r\n  if (msg == "温湿度") {\r\n    float h = dht.readHumidity();\r\n    float t = dht.readTemperature();\r\n    if (isnan(h) || isnan(t)) {\r\n      Serial.println(F("Failed to read from DHT sensor!"));\r\n      msg = "";\r\n      return;\r\n    }\r\n\r\n    Serial.print(F("Humidity: "));\r\n    Serial.print(h);\r\n    Serial.print(F("%  Temperature: "));\r\n    Serial.print(t);\r\n    Serial.print(F("°C "));\r\n    String tmp = String(t) + " °C " + String(h) + "%";\r\n    client.publish(mqttTopic, tmp.c_str());\r\n  }\r\n  if (msg == "定位") {\r\n    gpsRead();         //获取GPS数据\r\n    parseGpsBuffer();  //解析GPS数据\r\n    printGpsBuffer();  //输出解析后的数据\r\n    msg = "";\r\n    return;\r\n  }\r\n  msg = "";\r\n}\r\nvoid reconnect() {\r\n  // Loop until we''re reconnected\r\n  while (!client.connected()) {\r\n    Serial.print("Attempting MQTT connection...");\r\n    // Attempt to connect\r\n    if (client.connect(mqttClientId)) {\r\n      Serial.println("connected");\r\n      Serial.print("subscribe:");\r\n      Serial.println(mqttTopic);\r\n      //订阅主题，如果需要订阅多个主题，可发送多条订阅指令client.subscribe(topic2);client.subscribe(topic3);\r\n      client.subscribe(mqttTopic);\r\n    } else {\r\n      Serial.print("failed, rc=");\r\n      Serial.print(client.state());\r\n      Serial.println(" try again in 5 seconds");\r\n      // Wait 5 seconds before retrying\r\n      delay(5000);\r\n    }\r\n  }\r\n}\r\n\r\n\r\n////////////\r\nvoid errorLog(int num) {\r\n  Serial.print("ERROR");\r\n  Serial.println(num);\r\n  while (1) {\r\n    digitalWrite(L, HIGH);\r\n    delay(300);\r\n    digitalWrite(L, LOW);\r\n    delay(300);\r\n  }\r\n}\r\n\r\nvoid printGpsBuffer() {\r\n  if (Save_Data.isParseData) {\r\n    Save_Data.isParseData = false;\r\n\r\n    Serial.print("Save_Data.UTCTime = ");\r\n    Serial.println(Save_Data.UTCTime);\r\n\r\n    if (Save_Data.isUsefull) {\r\n      Save_Data.isUsefull = false;\r\n      Serial.print("Save_Data.latitude = ");\r\n      Serial.println(Save_Data.latitude);\r\n      Serial.print("Save_Data.N_S = ");\r\n      Serial.println(Save_Data.N_S);\r\n      Serial.print("Save_Data.longitude = ");\r\n      Serial.println(Save_Data.longitude);\r\n      Serial.print("Save_Data.E_W = ");\r\n      Serial.println(Save_Data.E_W);\r\n      String temp = "Save_Data.latitude = " + String(Save_Data.latitude) + "Save_Data.N_S = " + String(Save_Data.N_S) + "Save_Data.longitude = " + String(Save_Data.longitude) + "Save_Data.E_W = " + String(Save_Data.E_W);\r\n      Serial.println(temp);\r\n      client.publish(mqttTopic, temp.c_str());\r\n    } else {\r\n      Serial.println("GPS DATA is not usefull!");\r\n    }\r\n  }\r\n}\r\n\r\nvoid parseGpsBuffer() {\r\n  char* subString;\r\n  char* subStringNext;\r\n  if (Save_Data.isGetData) {\r\n    Save_Data.isGetData = false;\r\n    Serial.println("**************");\r\n    Serial.println(Save_Data.GPS_Buffer);\r\n\r\n\r\n    for (int i = 0; i <= 6; i++) {\r\n      if (i == 0) {\r\n        if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)\r\n          errorLog(1);  //解析错误\r\n      } else {\r\n        subString++;\r\n        if ((subStringNext = strstr(subString, ",")) != NULL) {\r\n          char usefullBuffer[2];\r\n          switch (i) {\r\n            case 1: memcpy(Save_Data.UTCTime, subString, subStringNext - subString); break;    //获取UTC时间\r\n            case 2: memcpy(usefullBuffer, subString, subStringNext - subString); break;        //获取UTC时间\r\n            case 3: memcpy(Save_Data.latitude, subString, subStringNext - subString); break;   //获取纬度信息\r\n            case 4: memcpy(Save_Data.N_S, subString, subStringNext - subString); break;        //获取N/S\r\n            case 5: memcpy(Save_Data.longitude, subString, subStringNext - subString); break;  //获取纬度信息\r\n            case 6: memcpy(Save_Data.E_W, subString, subStringNext - subString); break;        //获取E/W\r\n\r\n            default: break;\r\n          }\r\n\r\n          subString = subStringNext;\r\n          Save_Data.isParseData = true;\r\n          if (usefullBuffer[0] == ''A'')\r\n            Save_Data.isUsefull = true;\r\n          else if (usefullBuffer[0] == ''V'')\r\n            Save_Data.isUsefull = false;\r\n\r\n        } else {\r\n          errorLog(2);  //解析错误\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n\r\nvoid gpsRead() {\r\n  while (Serial.available()) {\r\n    gpsRxBuffer[ii++] = Serial.read();\r\n    if (ii == gpsRxBufferLength) clrGpsRxBuffer();\r\n  }\r\n\r\n  char* GPS_BufferHead;\r\n  char* GPS_BufferTail;\r\n  if ((GPS_BufferHead = strstr(gpsRxBuffer, "$GPRMC,")) != NULL || (GPS_BufferHead = strstr(gpsRxBuffer, "$GNRMC,")) != NULL) {\r\n    if (((GPS_BufferTail = strstr(GPS_BufferHead, "\\r\\n")) != NULL) && (GPS_BufferTail > GPS_BufferHead)) {\r\n      memcpy(Save_Data.GPS_Buffer, GPS_BufferHead, GPS_BufferTail - GPS_BufferHead);\r\n      Save_Data.isGetData = true;\r\n\r\n      clrGpsRxBuffer();\r\n    }\r\n  }\r\n}\r\n\r\nvoid clrGpsRxBuffer(void) {\r\n  memset(gpsRxBuffer, 0, gpsRxBufferLength);  //清空\r\n  ii = 0;\r\n}\r\n', '', 'webserver');
INSERT INTO `WisdomPreview` (`id`, `tid`, `title`, `content`, `imgtext`, `user`) VALUES
(7992, 20, 'esp8266 HTTPUpdate OTA', '#include <ESP8266WiFi.h>\r\n#include <ESP8266HTTPClient.h>\r\n#include <ESP8266httpUpdate.h>\r\nWiFiClient wificlient;\r\nString ssid="TP-LINK_C97D";\r\nString wifipwd="19805282968";\r\nvoid setup() {\r\n  Serial.begin(115200);\r\n  delay(500);\r\n  WiFi.begin(ssid.c_str(), wifipwd.c_str());\r\n  delay(500);\r\n  WiFi.mode(WIFI_STA);\r\n  Serial.println("Wifi->connet");\r\n  int ii = 0;\r\n  for (ii; ii < 20; ii++) {\r\n    delay(500);\r\n    Serial.print(" . ");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      Serial.println("Wifi 连接成功");\r\n      break;\r\n    }\r\n  }\r\n  String upUrl = esp8266post();\r\n  if (upUrl.length() > 10) {\r\n    upUrl.trim();  //http://jyan.nobiggie.cn/tool/bin/xxx/file.bin\r\n    while (1) {\r\n      ESPhttpUpdate.onStart(update_started);\r\n      ESPhttpUpdate.onEnd(update_finished);\r\n      ESPhttpUpdate.onProgress(update_progress);\r\n      ESPhttpUpdate.onError(update_error);\r\n      t_httpUpdate_return ret = ESPhttpUpdate.update(wificlient, upUrl);\r\n      switch (ret) {\r\n        case HTTP_UPDATE_FAILED: Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); break;\r\n\r\n        case HTTP_UPDATE_NO_UPDATES: Serial.println("HTTP_UPDATE_NO_UPDATES"); break;\r\n\r\n        case HTTP_UPDATE_OK: Serial.println("HTTP_UPDATE_OK"); break;\r\n      }\r\n    }\r\n    ESP.restart();\r\n  }\r\n}\r\n\r\nvoid loop() {\r\n  // put your main code here, to run repeatedly:\r\n}\r\nvoid update_started() {\r\n  Serial.println("CALLBACK:  HTTP update process started");\r\n}\r\n\r\nvoid update_finished() {\r\n  Serial.println("CALLBACK:  HTTP update process finished");\r\n}\r\nString esp8266post() {\r\n  HTTPClient http;\r\n  String url = "http://jyan.nobiggie.cn/arduino/vs";\r\n  http.begin(wificlient, url);\r\n  http.setTimeout(3000);\r\n  http.addHeader("Content-Type", "application/x-www-form-urlencoded");\r\n  String postData = "vs=abc1124267212";\r\n  int httpResponseCode = http.POST(postData);\r\n  if (httpResponseCode > 0) {\r\n    String response = http.getString();\r\n    if (response != "false") {\r\n      return response;\r\n    }\r\n  }\r\n  return "";\r\n}\r\nvoid update_progress(int cur, int total) {\r\n  Serial.printf("CALLBACK:  HTTP update process at %d of %d bytes...\\n", cur, total);\r\n}\r\n\r\nvoid update_error(int err) {\r\n  Serial.printf("CALLBACK:  HTTP update fatal error code %d\\n", err);\r\n}', '', 'webserver'),
(7993, 20, 'ESP8266 AP配网', '#include <ESP8266WiFi.h>\r\n#include <ESP8266WebServer.h>\r\n#include <ESP8266HTTPClient.h>\r\n#include <Ticker.h>\r\n\r\n\r\nTicker myTicker;\r\nWiFiClient wificlient;\r\n\r\n//被读取的文件位置和名称\r\nString flash_wifi = "/wifi.txt";\r\nESP8266WebServer ESP8266webServer;  // 创建网络服务器对象,HTTP服务的标准端口为：80\r\nString ssid = "";\r\nString passwd = "";\r\nString html;\r\n\r\nvoid setup(void) {\r\n  Serial.begin(115200);\r\n  delay(1000);\r\n  if (FlashConnetWifi() == false) {\r\n    HtmlSetWifi();\r\n  }\r\n}\r\nvoid loop(void) {\r\n}\r\n\r\nvoid SetWifi() {\r\n  ssid = ESP8266webServer.arg(0);\r\n  passwd = ESP8266webServer.arg(1);\r\n  String sp = ssid + "&" + passwd;\r\n  Serial.println(sp);\r\n  Serial.println("密码在前面");\r\n  Serial.begin(115200);\r\n  delay(500);\r\n  const char* Ssid = ssid.c_str();\r\n  const char* WifiPw = passwd.c_str();\r\n  WiFi.begin(Ssid, WifiPw);\r\n  WiFi.mode(WIFI_STA);\r\n  delay(200);\r\n  int ii = 0;\r\n  for (ii; ii < 20; ii++) {\r\n    delay(500);\r\n    Serial.print(".");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      ESP8266webServer.send(200, "text/plane", "Wifi密码正确,ESP准备重启");\r\n      ESP8266webServer.close();\r\n      delay(500);\r\n      WiFi.disconnect();\r\n      delay(500);\r\n\r\n      //写入数据\r\n      SPIFFS.format();\r\n      delay(500);\r\n      SPIFFS.begin();\r\n      File dataFile = SPIFFS.open(flash_wifi, "w");\r\n      dataFile.println(sp);\r\n      dataFile.close();\r\n      Serial.println("HTML连接成功");\r\n      delay(500);\r\n      ESP.restart();\r\n    }\r\n  }\r\n  ESP8266webServer.send(200, "text/plane", "Wifi密码错误,请重新输入");\r\n}\r\n//------- 展示页面-------\r\nvoid handlejsonStr() {\r\n  ESP8266webServer.send(500, "text/html", html);\r\n}\r\nvoid handleNotFound(void) {\r\n  ESP8266webServer.send(404, "text/plain", "404-The page is not Found!");\r\n}\r\n\r\nvoid ApStart() {\r\n  WiFi.disconnect();\r\n  delay(500);\r\n  Serial.begin(115200);\r\n  WiFi.mode(WIFI_AP);\r\n  IPAddress local_IP(192, 168, 168, 2);\r\n  IPAddress gateway(192, 168, 168, 1);\r\n  IPAddress subnet(255, 255, 255, 0);\r\n  WiFi.softAPConfig(local_IP, gateway, subnet);\r\n  //启动AP模式,并设置账号和密码\r\n  WiFi.softAP("192.168.168.2", "nobiggie.cn");\r\n}\r\nvoid WebserverStart() {\r\n  ESP8266webServer.begin(80);               // 启用网络服务\r\n  ESP8266webServer.on("/", handlejsonStr);  // / 在HTTP中,表示请求首页服务,\r\n  ESP8266webServer.on("/SetWifi", SetWifi);\r\n  ESP8266webServer.onNotFound(handleNotFound);  // 当服务器没找到所需的服务,调用404函数\r\n  Serial.println("webserver started");\r\n}\r\n\r\nvoid ForPing() {\r\n  //定时时间到了,先取消定时状态\r\n  myTicker.detach();\r\n  delay(500);\r\n  ESP.restart();\r\n}\r\n\r\n//扫描附件WIFI\r\nvoid WifiScan() {\r\n  Serial.begin(115200);\r\n  WiFi.disconnect();\r\n  WiFi.mode(WIFI_STA);\r\n  delay(100);\r\n  int n = WiFi.scanNetworks();\r\n  if (n > 0) {\r\n    Serial.println(n);\r\n    String a = "附近WiFi <select id=\\"ssid\\">";\r\n    for (int i = 0; i < n; i++) {\r\n      Serial.println(WiFi.SSID(i));\r\n      a = a + "<option value=\\"" + WiFi.SSID(i) + "\\">" + WiFi.SSID(i) + "</option>";\r\n      delay(50);\r\n    }\r\n    String HtmlStart = String("") + "<!DOCTYPE html>" + "<html>" + "<head>" + "<meta charset=\\"utf-8\\">" + "<meta name=\\"viewport\\" content=\\"width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\\" />" + "<title>设置WiFi</title>" + "<link rel=\\"stylesheet\\" href=\\"\\">" + "</head>" + "<script>" + "onload  = function() {" + "document.getElementById(\\"up\\").onclick = function(){" + "var ssida=document.getElementById(\\"ssid\\").value;" + "var ssid=ssida.replace(/\\\\s+/g, \\" \\");" + "var passwda=document.getElementsByTagName(''input'')[0].value;" + "var passwd=passwda.replace(/\\\\s+/g, \\" \\");" + "xhr = new XMLHttpRequest();" + "xhr.open(\\"POST\\",\\"./SetWifi\\",true);" + "var posts = (\\"ssid=\\"+ssid+\\"&passwd=\\"+ passwd);" + "xhr.setRequestHeader(\\"Content-Type\\",\\"application/x-www-form-urlencoded\\");" + "xhr.send(posts);" + "xhr.onreadystatechange = function(){" + "if(this.readyState == 4 && this.status == 200){" + "alert(this.responseText);" + "}" + "}" + "}" + "}" + "</script>" + "<body>";\r\n    String HtmlEnd = String("") + "<p>WiFi密码<input type=\\"text\\" id=\\"passwd\\"></p>" + "<input type=\\"submit\\" id=\\"up\\" value=\\"设 置\\">" + "<hr/>" + "<font color=\\"red\\">附近WiFi没有显示到自己的WIFI请重启或离信号源近点</font>" + "</body>" + "</html>";\r\n    a = a + "</select>";\r\n    html = HtmlStart + a + HtmlEnd;\r\n  } else {\r\n    html = "扫描不到网络";\r\n    Serial.println("扫描不到网络");\r\n  }\r\n}\r\nbool FlashConnetWifi() {\r\n  Serial.begin(115200);\r\n  delay(500);\r\n  //是否存在数据\r\n  SPIFFS.begin();\r\n  if (SPIFFS.exists(flash_wifi) == false) {\r\n    Serial.print(flash_wifi);\r\n    Serial.println(" NOT FOUND");\r\n    return false;\r\n  }\r\n\r\n  File dateFile = SPIFFS.open(flash_wifi, "r");\r\n  String result = dateFile.readString();\r\n  result.trim();\r\n  Serial.println(result);\r\n  int i = result.indexOf("&");\r\n  String wifiname = result.substring(0, i);\r\n  String wifipw = result.substring(i + 1);\r\n  const char* Ssid = wifiname.c_str();\r\n  const char* WifiPw = wifipw.c_str();\r\n  WiFi.begin(Ssid, WifiPw);\r\n  delay(500);\r\n  WiFi.mode(WIFI_STA);\r\n  Serial.println("FlashConnetWifi->connet");\r\n  int ii = 0;\r\n  for (ii; ii < 20; ii++) {\r\n    delay(500);\r\n    Serial.print(" . ");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      Serial.println("FlashConnetWifi 闪存配置连接成功");\r\n      return true;\r\n    }\r\n  }\r\n  Serial.println("FlashConnetWifi->false");\r\n  return false;\r\n}\r\n\r\nvoid HtmlSetWifi() {\r\n  WifiScan();\r\n  ApStart();\r\n  delay(1000);\r\n  Serial.println("启动网页");\r\n  myTicker.detach();\r\n  delay(200);\r\n  //5分后重启 防止停电后复电,路由器连接WIFI速度慢于ESP导致ESP连接不到路由器进入无限AP模式,所以这里只让AP 激活5分钟后就重启\r\n  myTicker.once(300, espReboot);\r\n  delay(200);\r\n  WebserverStart();\r\n  while (1) {\r\n    ESP8266webServer.handleClient();  // 检查网络服务请求并处理\r\n  }\r\n}\r\nvoid espReboot() {\r\n  ESP.restart();\r\n}\r\n', '', 'webserver'),
(7994, 20, 'esp32 HTTPUpdate OTA', '#include <Arduino.h>\r\n#include <WiFi.h>\r\n#include <HTTPClient.h>\r\n#include <HTTPUpdate.h>\r\nWiFiClient wificlient;\r\nString ssid="webserver";\r\nString wifipwd="www.360xyz.cn";\r\nvoid setup() {\r\n  Serial.begin(115200);\r\n  WiFi.begin(ssid.c_str(), wifipwd.c_str());\r\n  delay(500);\r\n  WiFi.mode(WIFI_STA);\r\n  Serial.println("wifiConnet...");\r\n  while (1) {\r\n    delay(500);\r\n    Serial.print(" . ");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      Serial.println("wifi connet success");\r\n      break;\r\n    }\r\n  }\r\n  delay(500);\r\n  String re = esp32post();\r\n  Serial.println(re);\r\n  re.trim();\r\n  if (re.length()>10) {\r\n    while (1) {\r\n      httpUpdate.onStart(update_started);\r\n      httpUpdate.onEnd(update_finished);\r\n      httpUpdate.onProgress(update_progress);\r\n      httpUpdate.onError(update_error);\r\n      t_httpUpdate_return ret = httpUpdate.update(wificlient, re);\r\n      //t_httpUpdate_return ret = httpUpdate.update(wificlient, "server", 80, "/file.bin");\r\n      switch (ret) {\r\n        case HTTP_UPDATE_FAILED:\r\n          Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());\r\n          break;\r\n        case HTTP_UPDATE_NO_UPDATES:\r\n          Serial.println("HTTP_UPDATE_NO_UPDATES");\r\n          break;\r\n        case HTTP_UPDATE_OK:\r\n          Serial.println("HTTP_UPDATE_OK");\r\n          break;\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\nvoid loop() {\r\n  // put your main code here, to run repeatedly:\r\n  delay(5000);\r\n  Serial.println("123");\r\n}\r\nvoid update_started() {\r\n  Serial.println("CALLBACK:  HTTP update process started");\r\n}\r\n\r\nvoid update_finished() {\r\n  Serial.println("CALLBACK:  HTTP update process finished");\r\n}\r\n\r\nvoid update_progress(int cur, int total) {\r\n  Serial.printf("CALLBACK:  HTTP update process at %d of %d bytes...\\n", cur, total);\r\n}\r\n\r\nvoid update_error(int err) {\r\n  Serial.printf("CALLBACK:  HTTP update fatal error code %d\\n", err);\r\n}\r\n\r\nString esp32post() {\r\n  HTTPClient http;\r\n  String url = "http://jyan.nobiggie.cn/query/vs";\r\n  http.begin(wificlient, url);\r\n  http.setTimeout(3000);\r\n  String postStr = "version=nodemcuesp32s01";\r\n  char dataBuff[postStr.length()];\r\n  strcpy(dataBuff, postStr.c_str());\r\n  http.addHeader("Content-Type", "application/x-www-form-urlencoded");\r\n  int httpResponseCode = http.POST(dataBuff);\r\n  if (httpResponseCode > 0) {\r\n    String response = http.getString();\r\n    return response;\r\n  }\r\n  return "";\r\n}', '', 'webserver'),
(7995, 20, 'esp32 http发送POST与GET请求 ', 'String esp32get() {\r\n  HTTPClient http;\r\n  String response;\r\n  String urlstr="http://jyan.nobiggie.cn/query/version?version=123456";\r\n  http.begin(wificlient, urlstr);\r\n  http.setTimeout(3000);\r\n  int httpCode = http.GET();\r\n  // httpCode will be negative on error\r\n  if (httpCode == 200) {\r\n    response = http.getString();\r\n    return response;\r\n  } else {\r\n    return "";\r\n  }\r\n  http.end();\r\n}\r\nString esp32post() {\r\n  HTTPClient http;\r\n  String url = "http://jyan.nobiggie.cn/query/version";  // 替换为你的POST接口地址\r\n  http.begin(wificlient, url);\r\n  http.setTimeout(3000);\r\n  String postStr = "version=esp32test10";\r\n  char dataBuff[postStr.length()];\r\n  strcpy(dataBuff, postStr.c_str());\r\n  http.addHeader("Content-Type", "application/x-www-form-urlencoded");\r\n  int httpResponseCode = http.POST(dataBuff);\r\n  if (httpResponseCode > 0) {\r\n    String response = http.getString();\r\n    return response;\r\n  }\r\n  return "";\r\n}', '', 'webserver'),
(7996, 20, 'ESP8266物联遥控大门与巴法云', '/*测试项目\r\n  正常网络状态下\r\n  1.上升时达到限位自动断开 如果已经是上升限位了 再点击上升按钮是不会再进行上升操作防止多次按,多次少量上升位移弄坏限位开关\r\n  2.下降时达到限位自动断开 如果已经是下降限位了 再点击上升按钮是不会再进行下降操作防止多次按,多次少量下降位移弄坏限位开关\r\n  3.上升限位时可以按下降,下降限位可以按上升  不存在两个都限位(除非故障)\r\n  4.不管上升或者下降,按 停止键立即停止 如果上升或者下降 有一个达到限位了,按停止键 就会提示已经达到 上升或者下降限位\r\n  5.没有网络的时候 自动休眠 2小时\r\n  6.esp主动发送ping 服务器返回 pong, 虽然服务器有ping 有时运行中,突然无网,返回Disconnected 很慢,或有时直接卡住需要手动重启ESP  webSocket.enableHeartbeat(15000, 1500, 2);也要加上\r\n  7.服务器也主动发送ping esp也返回pong (服务器为了看看哪个ESP掉线了,好在服务器里删除对应用户登陆)\r\n  特殊情况\r\n  8.在按上升 或者 下降时 运行途中突然无网络 所以用到上面第 5项可以解决\r\n  9.设备休眠 时间 > 6  小于 18  Timing存入2(代表 断开WIFI 打开广告灯)  否则存入1 (代表 断开WIFI)  存入0 (代表 不进行设备休眠)\r\n  10.在上升下降是,突然有语言播报,会导致失控,所以只能在开门上限或关门上限时播报\r\n*/\r\n\r\n#include <ESP8266WiFi.h>\r\n#include <ESP8266WebServer.h>\r\n#include <ESP8266HTTPClient.h>\r\n#include <WebSocketsClient.h>\r\n#include <ArduinoJson.h>\r\n#include <OneWire.h>\r\n#include <DallasTemperature.h>\r\n#include <Adafruit_Sensor.h>\r\n#include <DHT.h>\r\n#include <DHT_U.h>\r\n#include <Ticker.h>\r\n#include <SoftwareSerial.h>\r\n#include <ESP8266httpUpdate.h>\r\n\r\n//WIFI密码 //固件链接，在巴法云控制台复制、粘贴到这里即可\r\nString upUrl = "http://jyan.nobiggie.cn/tool/bin/nobiggiedoor1/file.bin";\r\nString version = "3.2";\r\nTicker myTicker;\r\nWiFiClient wificlient;\r\n\r\n#define DHTPIN 13  // 数字引脚连接DHT传感器\r\n// Feather HUZZAH ESP8266 note: use pins 3, 4, 5, 12, 13 or 14 --\r\n#define DHTTYPE DHT11  // DHT 11\r\nDHT_Unified dht(DHTPIN, DHTTYPE);\r\nWebSocketsClient webSocket;\r\n// 温度输入脚接开发板数字引脚13\r\n#define d7 13\r\nOneWire oneWire(d7);\r\nDallasTemperature sensors(&oneWire);\r\nint open = 5;\r\nint close = 4;\r\n\r\nint d0 = 16;\r\nint d5 = 14;\r\nint d6 = 12;\r\n//广告牌定时开关输出电平脚 D4脚 2 不能使用 使为低电平时WIFI芯片灯会一直亮\r\nint d8 = 15;\r\n//ggb为false代表没有开灯箱 true为已开启灯箱\r\nbool ggb = false;\r\n//开关状态 10为上升上限  0为下降上限 5为可以上升可降\r\nint state = 5;\r\n//此时执行中的状态  0关门  1开门  2停止 9什么也不代表\r\nint exec_status = 9;\r\nint humidity = 0;\r\nfloat temperature = 0;\r\nString hus;\r\nString tes;\r\n//最近操作物联用户相关信息\r\nString UserExec = "";\r\n\r\n\r\n//几个全局变量\r\nDynamicJsonDocument jsonBuffer(100);\r\nJsonObject jsonStr;\r\n//被读取的文件位置和名称\r\nString flash_wifi = "/wifi.txt";\r\n\r\nESP8266WebServer ESP8266webServer;  // 创建网络服务器对象,HTTP服务的标准端口为：80\r\nString ssid = "";\r\nString passwd = "";\r\n\r\nString html;\r\n//当前连接是哪个服务器 true为远程 false为本地\r\nbool networkRemoteLocal = true;\r\n//连接外网失败计数器\r\nint websocketTimeOut = 0;\r\n\r\nString Timing = "/timing.txt";\r\nString remoteDateUrl = "http://jyan.nobiggie.cn/arduino/h";\r\nString localServerIP = "server.nobiggie.cn";\r\nString localDateUrl = "http://server.nobiggie.cn/arduino/date";\r\n\r\nvoid setup(void) {\r\n  pinMode(open, OUTPUT);\r\n  pinMode(close, OUTPUT);\r\n  pinMode(d0, OUTPUT);\r\n  pinMode(d8, OUTPUT);\r\n\r\n  pinMode(d5, INPUT_PULLUP);\r\n  pinMode(d6, INPUT_PULLUP);\r\n\r\n  digitalWrite(open, LOW);\r\n  digitalWrite(close, LOW);\r\n  digitalWrite(d0, LOW);\r\n  digitalWrite(d8, LOW);\r\n\r\n  Serial.begin(115200);\r\n\r\n  SPIFFS.begin();\r\n  if (SPIFFS.exists(Timing) == false) {\r\n    SPIFFS.begin();\r\n    File dataFile = SPIFFS.open(Timing, "w");\r\n    dataFile.println("0");\r\n    dataFile.close();\r\n  }\r\n  File dataFile = SPIFFS.open(Timing, "r");\r\n  String resultTiming = dataFile.readString();\r\n  resultTiming.trim();\r\n  //Serial.print(resultTiming);\r\n  if (resultTiming == "1") {\r\n    //休眠状态 断开wifi\r\n    delay(200);\r\n    SPIFFS.begin();\r\n    File dataFile = SPIFFS.open(Timing, "w");\r\n    dataFile.println("0");\r\n    dataFile.close();\r\n    delay(200);\r\n    Serial.print("定时两个半小时");\r\n    myTicker.once(8460, espReboot);\r\n  } else if (resultTiming == "2") {\r\n    //休眠状态 断开wifi,打开广告牌\r\n    digitalWrite(d8, HIGH);\r\n    delay(200);\r\n    SPIFFS.begin();\r\n    File dataFile = SPIFFS.open(Timing, "w");\r\n    dataFile.println("0");\r\n    dataFile.close();\r\n    delay(200);\r\n    Serial.print("定时两个半小时");\r\n    myTicker.once(8460, espReboot);\r\n  } else {\r\n    //pinMode(flash_rst, INPUT_PULLUP);\r\n    delay(200);\r\n    dht.begin();\r\n    sensor_t sensor;\r\n    dht.temperature().getSensor(&sensor);\r\n    dht.humidity().getSensor(&sensor);\r\n\r\n    delay(1000);\r\n    if (FlashConnetWifi() == false) {\r\n      HtmlSetWifi();\r\n    }\r\n    delay(300);\r\n\r\n\r\n    String dateTmp1 = esp8266get(localDateUrl);\r\n    //如果本地服务器正常\r\n    if (dateTmp1.length() > 15) {\r\n      //通知服务器 我正在重启,验证一下广告牌开关状态 10秒后我启动完成发送广告牌开关状态给我\r\n      billboardPost();\r\n      webSocket.begin(localServerIP, 80, "/service/wss");\r\n    } else {\r\n      //如果本地服务器异常 ->重启后 休眠2小时\r\n      SPIFFS.begin();\r\n      File dataFile = SPIFFS.open(Timing, "w");\r\n      dataFile.println("1");\r\n      dataFile.close();\r\n      delay(200);\r\n      ESP.restart();\r\n    }\r\n\r\n    webSocket.onEvent(webSocketEvent);\r\n    webSocket.setAuthorization("user=mydoor1&passwd=efghijk&room=admin");\r\n    // try ever 5000 again if connection has failed\r\n    webSocket.setReconnectInterval(500);\r\n    /*虽然服务器有ping 但是有时运行中,突然无网络,返回连接失败Disconnected 很慢,或有时直接卡住需要手动重启ESP\r\n    所以 webSocket.enableHeartbeat(15000, 1500, 2);也要加上  */\r\n    webSocket.enableHeartbeat(15000, 2000, 2);\r\n    //防止 电源重启,门达到上限了,没有把状态改正,在这进行验证一下\r\n    if (digitalRead(d5) == HIGH) {\r\n      state = 10;\r\n    }\r\n    if (digitalRead(d6) == HIGH) {\r\n      state = 0;\r\n    }\r\n  }\r\n}\r\nvoid loop(void) {\r\n  webSocket.loop();\r\n  //操作运行时 上升达到限位了,并且上次状态不是上升上限, 并且执行状态是上升 限位开关断开\r\n  if (digitalRead(d5) == HIGH && state != 10 && exec_status == 1) {\r\n    //关闭所有开关\r\n    digitalWrite(open, LOW);\r\n    digitalWrite(close, LOW);\r\n    delay(200);\r\n    //断开电源接通\r\n    digitalWrite(d0, LOW);\r\n    Serial.println("开门达到上限");\r\n    state = 10;\r\n    webSocket.sendTXT("loop上升达到限制");\r\n    //执行状态为空\r\n    exec_status = 9;\r\n\r\n    String tmpH = esp8266get(remoteDateUrl);\r\n    if (tmpH.length() > 0) {\r\n      int dateL = tmpH.toInt();\r\n      if (dateL > 6 && dateL < 18) {\r\n        digitalWrite(d8, HIGH);\r\n        //这里长度记得除下2    使用前校验一下String的长度是否正确\r\n      }\r\n    }\r\n  }\r\n  //操作运行时 下降达到限位了,并且上次状态不是下降上限 并且执行状态是下降  限位开关开路\r\n  if (digitalRead(d6) == HIGH && state != 0 && exec_status == 0) {\r\n    digitalWrite(open, LOW);\r\n    digitalWrite(close, LOW);\r\n    delay(200);\r\n    //断开电源接通\r\n    digitalWrite(d0, LOW);\r\n    Serial.println("关门达到上限");\r\n\r\n    state = 0;\r\n    webSocket.sendTXT("loop关门达到限制");\r\n\r\n    //执行状态为空\r\n    exec_status = 9;\r\n\r\n    //关门就把广告灯箱关了\r\n    digitalWrite(d8, LOW);\r\n    //告诉服务器让其知道灯箱现在是关闭状态\r\n    webSocket.sendTXT("mydoor1灯箱关");\r\n    delay(500);\r\n  }\r\n  //即没有上限也没有下限状态\r\n  if (digitalRead(d5) == LOW && digitalRead(d6) == LOW && state != 5) {\r\n    state = 5;\r\n  }\r\n}\r\n\r\nvoid webSocketEvent(WStype_t type, uint8_t* payload, size_t length) {\r\n  switch (type) {\r\n    case WStype_DISCONNECTED:\r\n      digitalWrite(open, LOW);\r\n      digitalWrite(close, LOW);\r\n      Serial.println("Disconnected 开关状态全部关闭一下");\r\n\r\n      //防止开启突然没有网络,lop循环检测不到状态 这里再进行检测\r\n      if (digitalRead(d5) == HIGH && state != 10) {\r\n        state = 10;\r\n        CloseAll();\r\n        Serial.println("Disconnected  上限关闭");\r\n      }\r\n      //查询是否下降 限制,及时把状态改好\r\n      if (digitalRead(d6) == HIGH && state != 0) {\r\n        state = 0;\r\n        CloseAll();\r\n        Serial.println("Disconnected  下限关闭");\r\n      }\r\n      websocketTimeOut++;\r\n      //无法连接远程WSS服务器15次就自动 启动网页控制\r\n      if (websocketTimeOut > 25) {\r\n        CloseAll();\r\n        delay(500);\r\n        webSocket.disconnect();\r\n        delay(500);\r\n        //计数器归0\r\n        websocketTimeOut = 0;\r\n        HtmlSetWifi();\r\n      }\r\n      break;\r\n    case WStype_CONNECTED:\r\n      {\r\n        Serial.printf("[WSc] Connected to url: %s\\n", payload);\r\n        //计数器归0\r\n        websocketTimeOut = 0;\r\n        delay(200);\r\n      }\r\n      break;\r\n    case WStype_TEXT:\r\n      Serial.printf("[WSc] get text: %s\\n", payload);\r\n\r\n      deserializeJson(jsonBuffer, payload);\r\n      jsonStr = jsonBuffer.as<JsonObject>();\r\n      if (jsonStr["message"] != "") {\r\n        String user = jsonStr["user"];\r\n        String date = jsonStr["date"];\r\n        String message = jsonStr["message"];\r\n        if (message == "mydoor1.bt01up") {\r\n          //限位开关导通为低电平 表明还没有达到限位,并且没有达到上升最大限制 能正常上升,断开为高电平表明达到限位了\r\n          if (digitalRead(d5) == LOW && state != 10) {\r\n            //主电源接通\r\n            digitalWrite(d0, HIGH);\r\n            delay(200);\r\n            //开 上升\r\n            webSocket.sendTXT("正在开门 ...");\r\n            digitalWrite(close, LOW);\r\n\r\n            delay(200);\r\n            digitalWrite(open, HIGH);\r\n            UserExec = user + " mydoor1.↑ " + date;\r\n            exec_status = 1;\r\n\r\n          } else {\r\n            webSocket.sendTXT("达到限制,上升指令失效");\r\n          }\r\n          return;\r\n        }\r\n\r\n        if (message == "mydoor1.bt02stop") {\r\n          //如果已经在上限或下限时只更新响应时间\r\n          Serial.println("停止");\r\n          CloseAll();\r\n          if (digitalRead(d5) == LOW && digitalRead(d6) == LOW) {\r\n            webSocket.sendTXT("停止");\r\n            state = 5;\r\n            delay(200);\r\n            return;\r\n          }\r\n          //状态不为空说明 不是上升上限就是下降上限\r\n          if (digitalRead(d5) == HIGH || digitalRead(d6) == HIGH) {\r\n            //查询是否下降 限制,及时把状态改好\r\n            if (digitalRead(d5) == HIGH) {\r\n              state = 10;\r\n              String tempstr = ggb == true ? "灯箱亮" : "灯箱关";\r\n              String rez = "开门达到限制 " + tempstr;\r\n              webSocket.sendTXT(rez);\r\n            } else {\r\n              state = 0;\r\n              String tempstr = ggb == true ? "灯箱亮" : "灯箱关";\r\n              String rez = "关门达到限制 " + tempstr;\r\n              webSocket.sendTXT(rez);\r\n            }\r\n          }\r\n          return;\r\n        }\r\n        if (message == "mydoor1.bt03down") {\r\n          //限位开关导通时为低电平表明还没有达到限位,并且没到达到下降最大限制  能正常下降,断开为高电平表明达到限位了\r\n          if (digitalRead(d6) == LOW && state != 0) {\r\n            //主电源接通\r\n            digitalWrite(d0, HIGH);\r\n            delay(200);\r\n            //关 下降\r\n            webSocket.sendTXT("正在关门 ...");\r\n            digitalWrite(open, LOW);\r\n            delay(200);\r\n            digitalWrite(close, HIGH);\r\n            UserExec = user + " mydoor1.↓ " + date;\r\n            exec_status = 0;\r\n          } else {\r\n            webSocket.sendTXT("关门达到限制,关门指令失效");\r\n          }\r\n          return;\r\n        }\r\n        if (message == "mydoor1.bt04tap") {\r\n          sensors_event_t event;\r\n          dht.temperature().getEvent(&event);\r\n          if (isnan(event.temperature)) {\r\n            Serial.println(F("Error reading temperature!"));\r\n          } else {\r\n            temperature = event.temperature;\r\n            if (temperature < -10) {\r\n              tes = "防冻";\r\n            }\r\n            if (temperature >= -10 && temperature < 18) {\r\n              tes = "寒冷";\r\n            }\r\n            if (temperature >= 18 && temperature <= 25) {\r\n              tes = "舒适";\r\n            }\r\n            if (temperature > 25 && temperature <= 36) {\r\n              tes = "炎热";\r\n            }\r\n            if (temperature > 36) {\r\n              tes = "防暑";\r\n            }\r\n          }\r\n          delay(500);\r\n          // Get humidity event and print its value.\r\n          dht.humidity().getEvent(&event);\r\n          if (isnan(event.relative_humidity)) {\r\n            Serial.println(F("Error reading humidity!"));\r\n          } else {\r\n            humidity = event.relative_humidity;\r\n            if (humidity < 40) {\r\n              hus = "干燥";\r\n            }\r\n            if (humidity >= 40 && humidity <= 70) {\r\n              hus = "舒适";\r\n            }\r\n            if (humidity > 70) {\r\n              hus = "潮湿";\r\n            }\r\n          }\r\n          String th = String(temperature) + "°C" + tes + "   " + String(humidity) + "%湿度" + hus;\r\n          webSocket.sendTXT(th);\r\n          return;\r\n        }\r\n        if (message == "mydoor1.bt05tap") {\r\n          if (ggb == false) {\r\n            digitalWrite(d8, HIGH);\r\n            ggb = true;\r\n            if (user == "系统任务") {\r\n              String strtem = "系统任务 广告牌灯箱已开";\r\n              webSocket.sendTXT(strtem);\r\n            } else {\r\n              String strtem = user + " 广告牌灯箱已开";\r\n              webSocket.sendTXT(strtem);\r\n            }\r\n          } else {\r\n            digitalWrite(d8, LOW);\r\n            ggb = false;\r\n            if (user == "系统任务") {\r\n              String strtem = "系统任务 广告牌灯箱已关";\r\n              webSocket.sendTXT(strtem);\r\n            } else {\r\n              String strtem = user + " 广告牌灯箱已关";\r\n              webSocket.sendTXT(strtem);\r\n            }\r\n          }\r\n          return;\r\n        }\r\n        if (message == "mydoor1.bt06on") {\r\n          espSleep();\r\n        }\r\n        if (message.indexOf("mydoor1.温馨提示") != -1) {\r\n          //防止大门开启的时候,同时播报导致大门控制失灵 只有在上,下限的时候才播报\r\n          if (state == 0 || state == 10) {\r\n            digitalWrite(d0, HIGH);\r\n            delay(2000);\r\n            String data = message.substring(message.indexOf("mydoor1.温馨提示"), message.length());\r\n            data = data.substring(20);\r\n            data.replace(" ", "");\r\n            //String data = "020104C0";\r\n            //这里长度记得除下2    使用前校验一下String的长度是否正确\r\n            byte byteArray[data.length() / 2] = { 0 };\r\n            hexCharacterStringToBytes(byteArray, data.c_str());\r\n            //两个参数，第一个接收byte的数组,第二个要String.c_str()\r\n            Serial.write(byteArray, data.length() / 2);\r\n            delay(25000);\r\n            digitalWrite(d0, LOW);\r\n            return;\r\n          }\r\n        }\r\n        if (message.indexOf("mydoor1.铃声") != -1) {\r\n          digitalWrite(d0, HIGH);\r\n          delay(2000);\r\n          String s = message.substring(message.length() - 1);\r\n          String data = "FD 00 08 01 01 72 69 6E 67 5F 3" + s;\r\n          data.replace(" ", "");\r\n          //String data = "020104C0";\r\n          //这里长度记得除下2    使用前校验一下String的长度是否正确\r\n          byte byteArray[data.length() / 2] = { 0 };\r\n          hexCharacterStringToBytes(byteArray, data.c_str());\r\n          //两个参数，第一个接收byte的数组,第二个要String.c_str()\r\n          Serial.write(byteArray, data.length() / 2);\r\n          delay(7000);\r\n          digitalWrite(d0, LOW);\r\n          return;\r\n        }\r\n        if (message.indexOf("mydoor1.信息提示音") != -1) {\r\n          digitalWrite(d0, HIGH);\r\n          delay(2000);\r\n          String s = message.substring(message.length() - 1);\r\n          String data = "FD 00 0B 01 01 6D 65 73 73 61 67 65 5F 3" + s;\r\n          data.replace(" ", "");\r\n          //String data = "020104C0";\r\n          //这里长度记得除下2    使用前校验一下String的长度是否正确\r\n          byte byteArray[data.length() / 2] = { 0 };\r\n          hexCharacterStringToBytes(byteArray, data.c_str());\r\n          //两个参数，第一个接收byte的数组,第二个要String.c_str()\r\n          Serial.write(byteArray, data.length() / 2);\r\n          delay(7000);\r\n          digitalWrite(d0, LOW);\r\n          return;\r\n        }\r\n        if (message.indexOf("mydoor1.警示音") != -1) {\r\n          digitalWrite(d0, HIGH);\r\n          delay(2000);\r\n          String s = message.substring(message.length() - 1);\r\n          String data = "FD 00 09 01 01 61 6C 65 72 74 5F 3" + s;\r\n          data.replace(" ", "");\r\n          //String data = "020104C0";\r\n          //这里长度记得除下2    使用前校验一下String的长度是否正确\r\n          byte byteArray[data.length() / 2] = { 0 };\r\n          hexCharacterStringToBytes(byteArray, data.c_str());\r\n          //两个参数，第一个接收byte的数组,第二个要String.c_str()\r\n          Serial.write(byteArray, data.length() / 2);\r\n          delay(7000);\r\n          digitalWrite(d0, LOW);\r\n          return;\r\n        }\r\n        if (message == "mydoor1.重启") {\r\n          ESP.restart();\r\n        }\r\n        if (message == "mydoor1.version") {\r\n          webSocket.sendTXT(version);\r\n        }\r\n        if (message == "mydoor1.updateBin") {\r\n          while (1) {\r\n            // Add optional callback notifiers\r\n            ESPhttpUpdate.onStart(update_started);\r\n            ESPhttpUpdate.onEnd(update_finished);\r\n            ESPhttpUpdate.onProgress(update_progress);\r\n            ESPhttpUpdate.onError(update_error);\r\n            t_httpUpdate_return ret = ESPhttpUpdate.update(wificlient, upUrl);\r\n            switch (ret) {\r\n              case HTTP_UPDATE_FAILED: Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); break;\r\n\r\n              case HTTP_UPDATE_NO_UPDATES: Serial.println("HTTP_UPDATE_NO_UPDATES"); break;\r\n\r\n              case HTTP_UPDATE_OK: Serial.println("HTTP_UPDATE_OK"); break;\r\n            }\r\n          }\r\n          espReboot();\r\n        }\r\n      }\r\n      break;\r\n    case WStype_BIN:\r\n      Serial.printf("[WSc] get binary length: % u\\n", length);\r\n      //hexdump(payload, length);\r\n      // webSocket.sendBIN(payload, length);\r\n      break;\r\n    case WStype_PING:\r\n      // pong will be send automatically\r\n      //Serial.printf("[WSc] get ping\\n");\r\n      break;\r\n    case WStype_PONG:\r\n      // answer to a ping we send\r\n      Serial.printf("[WSc] get pong\\n");\r\n      //防止开启突然没有网络,lop循环检测不到状态 这里再进行检测\r\n      if (digitalRead(d5) == HIGH && state != 10) {\r\n        state = 10;\r\n        CloseAll();\r\n      }\r\n      //查询是否下降 限制,及时把状态改好\r\n      if (digitalRead(d6) == HIGH && state != 0) {\r\n        state = 0;\r\n        CloseAll();\r\n      }\r\n      //如果websocket连接网络失败重启时又能连网就重置0\r\n      if (websocketTimeOut != 0) {\r\n        websocketTimeOut = 0;\r\n      }\r\n      break;\r\n  }\r\n}\r\nvoid SetWifi() {\r\n  ssid = ESP8266webServer.arg(0);\r\n  passwd = ESP8266webServer.arg(1);\r\n  String sp = ssid + "&" + passwd;\r\n  Serial.println(sp);\r\n  Serial.println("密码在前面");\r\n  Serial.begin(115200);\r\n  delay(500);\r\n  const char* Ssid = ssid.c_str();\r\n  const char* WifiPw = passwd.c_str();\r\n  WiFi.begin(Ssid, WifiPw);\r\n  WiFi.mode(WIFI_STA);\r\n  delay(200);\r\n  Serial.println("wifi_connet");\r\n  int ii = 0;\r\n  for (ii; ii < 20; ii++) {\r\n    delay(500);\r\n    Serial.print(".");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      ESP8266webServer.send(200, "text/plane", "Wifi密码正确,ESP准备重启");\r\n      ESP8266webServer.close();\r\n      delay(500);\r\n      WiFi.disconnect();\r\n      delay(500);\r\n\r\n      //写入数据\r\n      SPIFFS.format();\r\n      delay(500);\r\n      SPIFFS.begin();\r\n      File dataFile = SPIFFS.open(flash_wifi, "w");\r\n      dataFile.println(sp);\r\n      dataFile.close();\r\n\r\n      Serial.println("HTML连接成功");\r\n      delay(500);\r\n      ESP.restart();\r\n    }\r\n  }\r\n  ESP8266webServer.send(200, "text/plane", "Wifi密码错误,请重新输入");\r\n  //HtmlSetWifi();\r\n}\r\n//------- 展示页面-------\r\nvoid handlejsonStr() {\r\n  ESP8266webServer.send(500, "text/html", html);\r\n}\r\nvoid handleNotFound(void) {\r\n  ESP8266webServer.send(404, "text/plain", "404-The page is not Found!");\r\n}\r\n\r\nvoid ApStart() {\r\n  WiFi.disconnect();\r\n  delay(500);\r\n  Serial.begin(115200);\r\n  WiFi.mode(WIFI_AP);\r\n  IPAddress local_IP(192, 168, 168, 2);\r\n  IPAddress gateway(192, 168, 168, 1);\r\n  IPAddress subnet(255, 255, 255, 0);\r\n  WiFi.softAPConfig(local_IP, gateway, subnet);\r\n\r\n  //启动AP模式,并设置账号和密码\r\n  WiFi.softAP("192.168.168.2", "www.nobiggie.cn");\r\n}\r\nvoid WebserverStart() {\r\n  //-----------------启动webserver网络服务--------------------\r\n  ESP8266webServer.begin(80);               // 启用网络服务\r\n  ESP8266webServer.on("/", handlejsonStr);  // / 在HTTP中,表示请求首页服务,\r\n  ESP8266webServer.on("/SetWifi", SetWifi);\r\n  ESP8266webServer.onNotFound(handleNotFound);  // 当服务器没找到所需的服务,调用404函数\r\n  Serial.println("webserver started");\r\n}\r\n\r\nvoid ForPing() {\r\n  //定时时间到了,先取消定时状态\r\n  myTicker.detach();\r\n  CloseAll();\r\n  delay(500);\r\n\r\n  ESP.restart();\r\n}\r\n\r\n\r\n//关闭上升,下降,变压器主电源\r\nvoid CloseAll() {\r\n  digitalWrite(open, LOW);\r\n  digitalWrite(close, LOW);\r\n  delay(200);\r\n  //断开电源接通\r\n  digitalWrite(d0, LOW);\r\n  //取消定时状态\r\n  myTicker.detach();\r\n  webSocket.sendTXT("变压器电源已断开");\r\n}\r\n\r\n\r\n//扫描附件WIFI\r\nvoid WifiScan() {\r\n  Serial.begin(115200);\r\n  WiFi.disconnect();\r\n  WiFi.mode(WIFI_STA);\r\n  delay(100);\r\n  int n = WiFi.scanNetworks();\r\n  if (n > 0) {\r\n    Serial.println(n);\r\n    String a = "附近WiFi <select id=\\"ssid\\">";\r\n    for (int i = 0; i < n; i++) {\r\n      Serial.println(WiFi.SSID(i));\r\n      a = a + "<option value=\\"" + WiFi.SSID(i) + "\\">" + WiFi.SSID(i) + "</option>";\r\n      delay(50);\r\n    }\r\n    String HtmlStart = String("") + "<!DOCTYPE html>" + "<html>" + "<head>" + "<meta charset=\\"utf-8\\">" + "<meta name=\\"viewport\\" content=\\"width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\\" />" + "<title>设置WiFi</title>" + "<link rel=\\"stylesheet\\" href=\\"\\">" + "</head>" + "<script>" + "onload  = function() {" + "document.getElementById(\\"up\\").onclick = function(){" + "var ssida=document.getElementById(\\"ssid\\").value;" + "var ssid=ssida.replace(/\\\\s+/g, \\" \\");" + "var passwda=document.getElementsByTagName(''input'')[0].value;" + "var passwd=passwda.replace(/\\\\s+/g, \\" \\");" + "xhr = new XMLHttpRequest();" + "xhr.open(\\"POST\\",\\"./SetWifi\\",true);" + "var posts = (\\"ssid=\\"+ssid+\\"&passwd=\\"+ passwd);" + "xhr.setRequestHeader(\\"Content-Type\\",\\"application/x-www-form-urlencoded\\");" + "xhr.send(posts);" + "xhr.onreadystatechange = function(){" + "if(this.readyState == 4 && this.status == 200){" + "alert(this.responseText);" + "}" + "}" + "}" + "}" + "</script>" + "<body>";\r\n    String HtmlEnd = String("") + "<p>WiFi密码<input type=\\"text\\" id=\\"passwd\\"></p>" + "<input type=\\"submit\\" id=\\"up\\" value=\\"设 置\\">" + "<hr/>" + "<font color=\\"red\\">附近WiFi没有显示到自己的WIFI请重启或离信号源近点</font>" + "</body>" + "</html>";\r\n    a = a + "</select>";\r\n    html = HtmlStart + a + HtmlEnd;\r\n  } else {\r\n    html = "扫描不到网络";\r\n    Serial.println("扫描不到网络");\r\n  }\r\n}\r\nbool FlashConnetWifi() {\r\n  Serial.begin(115200);\r\n  delay(500);\r\n  //是否存在数据\r\n  SPIFFS.begin();\r\n  if (SPIFFS.exists(flash_wifi) == false) {\r\n    Serial.print(flash_wifi);\r\n    Serial.println(" NOT FOUND");\r\n    return false;\r\n  }\r\n\r\n  File dateFile = SPIFFS.open(flash_wifi, "r");\r\n  String result = dateFile.readString();\r\n  result.trim();\r\n  Serial.println(result);\r\n  int i = result.indexOf("&");\r\n  String wifiname = result.substring(0, i);\r\n  String wifipw = result.substring(i + 1);\r\n  const char* Ssid = wifiname.c_str();\r\n  const char* WifiPw = wifipw.c_str();\r\n  Serial.println(Ssid);\r\n  Serial.println(WifiPw);\r\n  WiFi.begin(Ssid, WifiPw);\r\n  delay(500);\r\n  WiFi.mode(WIFI_STA);\r\n  Serial.println("FlashConnetWifi->connet");\r\n  int wifiTimeout = 0;\r\n  for (wifiTimeout; wifiTimeout < 30; wifiTimeout++) {\r\n    delay(500);\r\n    Serial.print(" . ");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      Serial.println("FlashConnetWifi 闪存配置连接成功");\r\n      return true;\r\n    }\r\n  }\r\n  Serial.println("FlashConnetWifi-> timeout");\r\n  return false;\r\n}\r\n\r\nvoid HtmlSetWifi() {\r\n  WifiScan();\r\n  ApStart();\r\n  delay(1000);\r\n  Serial.println("启动网页");\r\n  myTicker.detach();\r\n  delay(200);\r\n  //5分后重启 防止停电后复电,路由器连接WIFI速度慢于ESP导致ESP连接不到路由器进入无限AP模式,所以这里只让AP 激活5分钟后就重启\r\n  myTicker.once(300, espReboot);\r\n  delay(200);\r\n  WebserverStart();\r\n  while (1) {\r\n    ESP8266webServer.handleClient();  // 检查网络服务请求并处理\r\n  }\r\n}\r\nvoid espReboot() {\r\n  ESP.restart();\r\n}\r\n\r\n//无网特殊状态下安全限位\r\nvoid html_whlie() {\r\n  //操作运行时 上升达到限位了,并且上次状态不是上升上限, 并且执行状态是上升 限位开关断开\r\n  if (digitalRead(d5) == HIGH || digitalRead(d6) == HIGH) {\r\n    //关闭所有开关\r\n    CloseAll();\r\n    Serial.println("达到上限");\r\n    myTicker.detach();\r\n    delay(200);\r\n    ESP.restart();\r\n  }\r\n}\r\n\r\n\r\nString esp8266get(String string) {\r\n  HTTPClient http;\r\n  String response;\r\n  http.begin(wificlient, string);\r\n  http.setTimeout(3000);\r\n  int httpCode = http.GET();\r\n  if (httpCode == 200) {\r\n    response = http.getString();\r\n    return response;\r\n  } else {\r\n    return "";\r\n  }\r\n  http.end();\r\n}\r\nvoid billboardPost() {\r\n  HTTPClient http;\r\n  String response;\r\n  String postStr = "a=a";\r\n  http.begin(wificlient, "http://server.nobiggie.cn/arduino/bill-board");\r\n  http.setTimeout(500);\r\n  //需要传输的数据\r\n  char dataBuff[postStr.length()];\r\n  strcpy(dataBuff, postStr.c_str());\r\n  http.addHeader("Content-Type", "application/x-www-form-urlencoded");\r\n  http.POST(dataBuff);\r\n  http.end();\r\n}\r\nString esp8266post(String url, String postStr) {\r\n  HTTPClient http;\r\n  String response;\r\n  http.begin(wificlient, url);\r\n  http.setTimeout(3000);\r\n  //需要传输的数据\r\n  char dataBuff[postStr.length()];\r\n  strcpy(dataBuff, postStr.c_str());\r\n  //头信息,需要的反注释就可以\r\n  http.addHeader("Content-Type", "application/x-www-form-urlencoded");\r\n  int httpCode = http.POST(dataBuff);\r\n  if (httpCode == 200) {\r\n    response = http.getString();\r\n    return response;\r\n  } else {\r\n    return "";\r\n  }\r\n  http.end();\r\n}\r\nvoid hexCharacterStringToBytes(byte* byteArray, const char* hexString) {\r\n  bool oddLength = strlen(hexString) & 1;\r\n  byte currentByte = 0;\r\n  byte byteIndex = 0;\r\n  for (byte charIndex = 0; charIndex < strlen(hexString); charIndex++) {\r\n    bool oddCharIndex = charIndex & 1;\r\n    if (oddLength) {\r\n      // If the length is odd\r\n      if (oddCharIndex) {\r\n        // odd characters go in high nibble\r\n        currentByte = nibble(hexString[charIndex]) << 4;\r\n      } else {\r\n        // Even characters go into low nibble\r\n        currentByte |= nibble(hexString[charIndex]);\r\n        byteArray[byteIndex++] = currentByte;\r\n        currentByte = 0;\r\n      }\r\n    } else {\r\n      // If the length is even\r\n      if (!oddCharIndex) {\r\n        // Odd characters go into the high nibble\r\n        currentByte = nibble(hexString[charIndex]) << 4;\r\n      } else {\r\n        // Odd characters go into low nibble\r\n        currentByte |= nibble(hexString[charIndex]);\r\n        byteArray[byteIndex++] = currentByte;\r\n        currentByte = 0;\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\nbyte nibble(char c) {\r\n  if (c >= ''0'' && c <= ''9'')\r\n    return c - ''0'';\r\n\r\n  if (c >= ''a'' && c <= ''f'')\r\n    return c - ''a'' + 10;\r\n\r\n  if (c >= ''A'' && c <= ''F'')\r\n    return c - ''A'' + 10;\r\n\r\n  return 0;  // Not a valid hexadecimal character\r\n}\r\nvoid update_started() {\r\n  Serial.println("CALLBACK:  HTTP update process started");\r\n}\r\n\r\nvoid update_finished() {\r\n  Serial.println("CALLBACK:  HTTP update process finished");\r\n}\r\n\r\nvoid update_progress(int cur, int total) {\r\n  Serial.printf("CALLBACK:  HTTP update process at %d of %d bytes...\\n", cur, total);\r\n  webSocket.sendTXT(Serial.printf("CALLBACK:  HTTP update process at %d of %d bytes...\\n", cur, total));\r\n}\r\n\r\nvoid update_error(int err) {\r\n  Serial.printf("CALLBACK:  HTTP update fatal error code %d\\n", err);\r\n}\r\n\r\nvoid espSleep() {\r\n  CloseAll();\r\n  delay(500);\r\n  String timingStr = "1";\r\n  String tmepH = esp8266get(remoteDateUrl);\r\n  if (tmepH.length() > 0) {\r\n    int dateInt = tmepH.toInt();\r\n    if (dateInt > 6 && dateInt < 18) {\r\n      timingStr = "2";\r\n    }\r\n  }\r\n  webSocket.sendTXT("mydoor1休眠两个半小时...");\r\n  delay(200);\r\n  webSocket.disconnect();\r\n  delay(300);\r\n  WiFi.disconnect();\r\n  SPIFFS.begin();\r\n  File dataFile = SPIFFS.open(Timing, "w");\r\n  dataFile.println(timingStr);\r\n  dataFile.close();\r\n  espReboot();\r\n}', '', 'webserver');
INSERT INTO `WisdomPreview` (`id`, `tid`, `title`, `content`, `imgtext`, `user`) VALUES
(7997, 20, 'ESP8266物联遥控大门远程本地网页控制', '/*测试项目\r\n  正常网络状态下\r\n  1.上升时达到限位自动断开 如果已经是上升限位了 再点击上升按钮是不会再进行上升操作防止多次按,多次少量上升位移弄坏限位开关\r\n  2.下降时达到限位自动断开 如果已经是下降限位了 再点击上升按钮是不会再进行下降操作防止多次按,多次少量下降位移弄坏限位开关\r\n  3.上升限位时可以按下降,下降限位可以按上升  不存在两个都限位(除非故障)\r\n  4.不管上升或者下降,按 停止键立即停止 如果上升或者下降 有一个达到限位了,按停止键 就会提示已经达到 上升或者下降限位\r\n  5.没有网络的时候 自动连接192.168.x.254\r\n  6.esp主动发送ping 服务器返回 pong, 虽然服务器有ping 有时运行中,突然无网,返回Disconnected 很慢,或有时直接卡住需要手动重启ESP  webSocket.enableHeartbeat(15000, 1500, 2);也要加上\r\n  7.服务器也主动发送ping esp也返回pong (服务器为了看看哪个ESP掉线了,好在服务器里删除对应用户登陆)\r\n  特殊情况\r\n  8.在按上升 或者 下降时 运行途中突然无网络 所以用到上面第 5项可以解决\r\n  9.设备休眠 时间 > 6  小于 18  Timing存入2(代表 断开WIFI 打开广告灯)  否则存入1 (代表 断开WIFI)  存入0 (代表 不进行设备休眠)\r\n  10.在上升下降是,突然有语言播报,会导致失控,所以只能在开门上限或关门上限时播报\r\n*/\r\n\r\n#include <ESP8266WiFi.h>\r\n#include <ESP8266WebServer.h>\r\n#include <ESP8266HTTPClient.h>\r\n#include <WebSocketsClient.h>\r\n#include <ArduinoJson.h>\r\n#include <OneWire.h>\r\n#include <DallasTemperature.h>\r\n#include <Adafruit_Sensor.h>\r\n#include <DHT.h>\r\n#include <DHT_U.h>\r\n#include <Ticker.h>\r\n#include <SoftwareSerial.h>\r\n#include <ESP8266httpUpdate.h>\r\n\r\n//OTA\r\nString upUrl = "http://jyan.nobiggie.cn/tool/bin/nobiggiedoor1/file.bin";\r\nString version = "1.0";\r\nTicker myTicker;\r\nWiFiClient wificlient;\r\n\r\n#define DHTPIN 13  // 数字引脚连接DHT传感器\r\n// Feather HUZZAH ESP8266 note: use pins 3, 4, 5, 12, 13 or 14 --\r\n#define DHTTYPE DHT11  // DHT 11\r\nDHT_Unified dht(DHTPIN, DHTTYPE);\r\nWebSocketsClient webSocket;\r\n// 温度输入脚接开发板数字引脚13\r\n#define d7 13\r\nOneWire oneWire(d7);\r\nDallasTemperature sensors(&oneWire);\r\nint open = 5;\r\nint close = 4;\r\n\r\nint d0 = 16;\r\nint d5 = 14;\r\nint d6 = 12;\r\n//广告牌定时开关输出电平脚 D4脚 2 不能使用 使为低电平时WIFI芯片灯会一直亮\r\nint d8 = 15;\r\n\r\n//开关状态 10为上升上限  0为下降上限 5为可以上升可降\r\nint state = 5;\r\n//此时执行中的状态  0关门  1开门  2停止 9什么也不代表\r\nint exec_status = 9;\r\nint humidity = 0;\r\nfloat temperature = 0;\r\nString hus;\r\nString tes;\r\n//最近操作物联用户相关信息\r\nString UserExec = "";\r\n\r\n//ggb为false代表没有开灯箱 true为已开启灯箱\r\nbool ggb = false;\r\n//几个全局变量\r\nDynamicJsonDocument jsonBuffer(100);\r\nJsonObject jsonStr;\r\n//被读取的文件位置和名称\r\nString flash_wifi = "/wifi.txt";\r\n\r\nESP8266WebServer ESP8266webServer;  // 创建网络服务器对象,HTTP服务的标准端口为：80\r\nString ssid = "";\r\nString passwd = "";\r\n\r\nString html;\r\n//当前连接是哪个服务器 true为远程 false为本地\r\nbool networkRemoteLocal = true;\r\n//连接外网失败计数器\r\nint internet_i = 0;\r\n\r\nString Timing = "/timing.txt";\r\nString remoteDateUrl = "http://quan.suning.com/getSysTime.do";\r\nString localDateUrl = "http://server.nobiggie.cn/query/date";\r\nString localServerIP = "server.nobiggie.cn";\r\n\r\n\r\nvoid setup(void) {\r\n  pinMode(open, OUTPUT);\r\n  pinMode(close, OUTPUT);\r\n  pinMode(d0, OUTPUT);\r\n  pinMode(d8, OUTPUT);\r\n  pinMode(d5, INPUT_PULLUP);\r\n  pinMode(d6, INPUT_PULLUP);\r\n\r\n  digitalWrite(open, LOW);\r\n  digitalWrite(close, LOW);\r\n  digitalWrite(d0, LOW);\r\n  digitalWrite(d8, LOW);\r\n\r\n  Serial.begin(115200);\r\n  SPIFFS.begin();\r\n  if (SPIFFS.exists(Timing) == false) {\r\n    SPIFFS.begin();\r\n    File dataFile = SPIFFS.open(Timing, "w");\r\n    dataFile.println("0");\r\n    dataFile.close();\r\n  }\r\n  File dataFile = SPIFFS.open(Timing, "r");\r\n  String resultTiming = dataFile.readString();\r\n  resultTiming.trim();\r\n  //Serial.print(resultTiming);\r\n  if (resultTiming == "1") {\r\n    //休眠断开wifi\r\n    delay(200);\r\n    SPIFFS.begin();\r\n    File dataFile = SPIFFS.open(Timing, "w");\r\n    dataFile.println("0");\r\n    dataFile.close();\r\n    delay(200);\r\n    Serial.print("定时两个半小时");\r\n    myTicker.once(8460, espReboot);\r\n  } else if (resultTiming == "2") {\r\n    //休眠断开wifi,打开广告牌\r\n    digitalWrite(d8, HIGH);\r\n    delay(200);\r\n    SPIFFS.begin();\r\n    File dataFile = SPIFFS.open(Timing, "w");\r\n    dataFile.println("0");\r\n    dataFile.close();\r\n    delay(200);\r\n    Serial.print("定时两个半小时");\r\n    myTicker.once(8460, espReboot);\r\n  } else {\r\n\r\n    //pinMode(flash_rst, INPUT_PULLUP);\r\n    delay(200);\r\n    dht.begin();\r\n    sensor_t sensor;\r\n    dht.temperature().getSensor(&sensor);\r\n    dht.humidity().getSensor(&sensor);\r\n\r\n    delay(1000);\r\n    if (FlashConnetWifi() == false) {\r\n      HtmlSetWifi();\r\n    }\r\n    delay(300);\r\n    String dateTmp = myHttpGet(remoteDateUrl);\r\n    deserializeJson(jsonBuffer, dateTmp);\r\n    jsonStr = jsonBuffer.as<JsonObject>();\r\n    String temp = jsonStr["sysTime2"];\r\n    if (temp.length() > 15) {\r\n      dateTmp = temp.substring(11, 13);\r\n      int dateI = temp.toInt();\r\n      if (dateI > 6 && dateI < 18) {\r\n        digitalWrite(d8, HIGH);\r\n      }\r\n\r\n      webSocket.beginSSL("www.nobiggie.cn", 443, "/service/wss");\r\n    } else {\r\n      String dateTmp1 = myHttpGet(localDateUrl);\r\n      //如果本地服务器正常\r\n      if (dateTmp1.length() > 15) {\r\n        dateTmp1 = dateTmp1.substring(11, 13);\r\n        int dateI = dateTmp1.toInt();\r\n        if (dateI > 6 && dateI < 18) {\r\n          digitalWrite(d8, HIGH);\r\n        }\r\n        webSocket.begin(localServerIP, 80, "/service/wss");\r\n      } else {\r\n        //如果本地服务器异常 ->重启后 休眠2小时\r\n        SPIFFS.begin();\r\n        File dataFile = SPIFFS.open(Timing, "w");\r\n        dataFile.println("1");\r\n        dataFile.close();\r\n        delay(200);\r\n        ESP.restart();\r\n      }\r\n    }\r\n\r\n    webSocket.onEvent(webSocketEvent);\r\n    webSocket.setAuthorization("user=mydoor1&passwd=efghijk&room=admin");\r\n    // try ever 5000 again if connection has failed\r\n    webSocket.setReconnectInterval(500);\r\n\r\n    /*虽然服务器有ping 但是有时运行中,突然无网络,返回连接失败Disconnected 很慢,或有时直接卡住需要手动重启ESP\r\n    所以 webSocket.enableHeartbeat(15000, 1500, 2);也要加上  */\r\n    webSocket.enableHeartbeat(15000, 2000, 2);\r\n    //防止 电源重启,门达到上限了,没有把状态改正,在这进行验证一下\r\n    if (digitalRead(d5) == HIGH) {\r\n      state = 10;\r\n    }\r\n    if (digitalRead(d6) == HIGH) {\r\n      state = 0;\r\n    }\r\n  }\r\n}\r\nvoid loop(void) {\r\n  webSocket.loop();\r\n  //操作运行时 上升达到限位了,并且上次状态不是上升上限, 并且执行状态是上升 限位开关断开\r\n  if (digitalRead(d5) == HIGH && state != 10 && exec_status == 1) {\r\n    //关闭所有开关\r\n    digitalWrite(open, LOW);\r\n    digitalWrite(close, LOW);\r\n    delay(200);\r\n    //断开电源接通\r\n    digitalWrite(d0, LOW);\r\n    Serial.println("开门达到上限");\r\n    state = 10;\r\n    webSocket.sendTXT("loop上升达到限制");\r\n    //执行状态为空\r\n    exec_status = 9;\r\n\r\n    String tmpDate = myHttpGet(remoteDateUrl);\r\n    deserializeJson(jsonBuffer, tmpDate);\r\n    jsonStr = jsonBuffer.as<JsonObject>();\r\n    String temp = jsonStr["sysTime2"];\r\n    if (temp.length() > 15) {\r\n      tmpDate = temp.substring(11, 13);\r\n      int dateL = temp.toInt();\r\n      if (dateL > 6 && dateL < 18) {\r\n        digitalWrite(d8, HIGH);\r\n        //这里长度记得除下2    使用前校验一下String的长度是否正确\r\n      }\r\n    }\r\n  }\r\n  //操作运行时 下降达到限位了,并且上次状态不是下降上限 并且执行状态是下降  限位开关开路\r\n  if (digitalRead(d6) == HIGH && state != 0 && exec_status == 0) {\r\n    digitalWrite(open, LOW);\r\n    digitalWrite(close, LOW);\r\n    delay(200);\r\n    //断开电源接通\r\n    digitalWrite(d0, LOW);\r\n    Serial.println("关门达到上限");\r\n\r\n    state = 0;\r\n    webSocket.sendTXT("loop关门达到限制");\r\n    //执行状态为空\r\n    exec_status = 9;\r\n\r\n    //关门就把广告灯箱关了\r\n    digitalWrite(d8, LOW);\r\n    //告诉服务器让其知道灯箱现在是关闭状态\r\n    webSocket.sendTXT("mydoor1灯箱关");\r\n    delay(500);\r\n  }\r\n  //即没有上限也没有下限状态\r\n  if (digitalRead(d5) == LOW && digitalRead(d6) == LOW && state != 5) {\r\n    state = 5;\r\n  }\r\n\r\n}\r\n\r\n\r\nvoid webSocketEvent(WStype_t type, uint8_t* payload, size_t length) {\r\n  switch (type) {\r\n    case WStype_DISCONNECTED:\r\n      digitalWrite(open, LOW);\r\n      digitalWrite(close, LOW);\r\n      Serial.println("Disconnected 开关状态全部关闭一下");\r\n\r\n      //防止开启突然没有网络,lop循环检测不到状态 这里再进行检测\r\n      if (digitalRead(d5) == HIGH && state != 10) {\r\n        state = 10;\r\n        //关闭所有开关\r\n        CloseAll();\r\n        Serial.println("Disconnected  上限关闭");\r\n      }\r\n      //查询是否下降 限制,及时把状态改好\r\n      if (digitalRead(d6) == HIGH && state != 0) {\r\n        state = 0;\r\n        //关闭所有开关\r\n        CloseAll();\r\n        Serial.println("Disconnected  下限关闭");\r\n      }\r\n      internet_i++;\r\n      //无法连接远程WSS服务器15次就自动 启动网页控制\r\n      if (internet_i > 15) {\r\n        CloseAll();\r\n        delay(500);\r\n        webSocket.disconnect();\r\n        delay(500);\r\n        //计数器归0\r\n        internet_i = 0;\r\n        if (networkRemoteLocal == true) {\r\n          //连接192.168.X.254\r\n          wsRaspberry();\r\n        } else {\r\n          wssRaspberry();\r\n        }\r\n      }\r\n      break;\r\n    case WStype_CONNECTED:\r\n      {\r\n        Serial.printf("[WSc] Connected to url: %s\\n", payload);\r\n        // send message to server when Connected\r\n        //计数器归0\r\n        internet_i = 0;\r\n        delay(200);\r\n      }\r\n      break;\r\n    case WStype_TEXT:\r\n      Serial.printf("[WSc] get text: %s\\n", payload);\r\n\r\n      deserializeJson(jsonBuffer, payload);\r\n      jsonStr = jsonBuffer.as<JsonObject>();\r\n      if (jsonStr["message"] != "") {\r\n        String user = jsonStr["user"];\r\n        String date = jsonStr["date"];\r\n        String message = jsonStr["message"];\r\n        if (message == "mydoor1.↓") {\r\n          //限位开关导通时为低电平表明还没有达到限位,并且没到达到下降最大限制  能正常下降,断开为高电平表明达到限位了\r\n          if (digitalRead(d6) == LOW && state != 0) {\r\n            //主电源接通\r\n            digitalWrite(d0, HIGH);\r\n            delay(200);\r\n            //关 下降\r\n            webSocket.sendTXT("正在关门 ...");\r\n            digitalWrite(open, LOW);\r\n            delay(200);\r\n            digitalWrite(close, HIGH);\r\n            UserExec = user + " mydoor1.↓ " + date;\r\n            exec_status = 0;\r\n\r\n          } else {\r\n            webSocket.sendTXT("关门达到限制,关门指令失效");\r\n          }\r\n          return;\r\n        }\r\n        if (message == "mydoor1.↑") {\r\n          //限位开关导通为低电平 表明还没有达到限位,并且没有达到上升最大限制 能正常上升,断开为高电平表明达到限位了\r\n          if (digitalRead(d5) == LOW && state != 10) {\r\n            //主电源接通\r\n            digitalWrite(d0, HIGH);\r\n\r\n            delay(200);\r\n            //开 上升\r\n            webSocket.sendTXT("正在开门 ...");\r\n            digitalWrite(close, LOW);\r\n\r\n            delay(200);\r\n            digitalWrite(open, HIGH);\r\n            UserExec = user + " mydoor1.↑ " + date;\r\n            exec_status = 1;\r\n\r\n          } else {\r\n            webSocket.sendTXT("达到限制,上升指令失效");\r\n\r\n          }\r\n          return;\r\n        }\r\n\r\n        if (message == "mydoor1.■") {\r\n          //如果已经在上限或下限时只更新响应时间\r\n          Serial.println("停止");\r\n          CloseAll();\r\n          if (digitalRead(d5) == LOW && digitalRead(d6) == LOW) {\r\n            webSocket.sendTXT("停止");\r\n            state = 5;\r\n            delay(200);\r\n            return;\r\n          }\r\n          //状态不为空说明 不是上升上限就是下降上限\r\n          if (digitalRead(d5) == HIGH || digitalRead(d6) == HIGH) {\r\n            //查询是否下降 限制,及时把状态改好\r\n            if (digitalRead(d5) == HIGH) {\r\n              state = 10;\r\n              String tempstr = ggb == true ? "灯箱亮" : "灯箱关";\r\n              UserExec = UserExec + tempstr;\r\n              String rez = "开门达到限制 " + UserExec;\r\n              webSocket.sendTXT(rez);\r\n            } else {\r\n              state = 0;\r\n              String tempstr = ggb == true ? "灯箱亮" : "灯箱关";\r\n              UserExec = UserExec + tempstr;\r\n              String rez = "关门达到限制 " + UserExec;\r\n              webSocket.sendTXT(rez);\r\n            }\r\n          }\r\n          return;\r\n        }\r\n        if (message == "mydoor1.设备休眠") {\r\n          CloseAll();\r\n          delay(500);\r\n          String timingStr = "1";\r\n          String date = myHttpGet(remoteDateUrl);\r\n          deserializeJson(jsonBuffer, date);\r\n          jsonStr = jsonBuffer.as<JsonObject>();\r\n          String temp = jsonStr["sysTime2"];\r\n          if (temp.length() > 15) {\r\n            date = temp.substring(11, 13);\r\n            int dateInt = temp.toInt();\r\n            Serial.println(dateInt);\r\n            if (dateInt > 6 && dateInt < 18) {\r\n              timingStr = "2";\r\n            }\r\n          }\r\n          webSocket.sendTXT("mydoor1休眠两个半小时...");\r\n          delay(200);\r\n          webSocket.disconnect();\r\n          delay(500);\r\n          WiFi.disconnect();\r\n          SPIFFS.begin();\r\n          File dataFile = SPIFFS.open(Timing, "w");\r\n          dataFile.println(timingStr);\r\n          dataFile.close();\r\n          espReboot();\r\n        }\r\n        if (message.indexOf("mydoor1.温馨提示") != -1) {\r\n          //防止大门开启的时候,同时播报导致大门控制失灵 只有在上,下限的时候才播报\r\n          if (state == 0 || state == 10) {\r\n            digitalWrite(d0, HIGH);\r\n            delay(2000);\r\n            String data = message.substring(message.indexOf("mydoor1.温馨提示"), message.length());\r\n            data = data.substring(20);\r\n            data.replace(" ", "");\r\n            //String data = "020104C0";\r\n            //这里长度记得除下2    使用前校验一下String的长度是否正确\r\n            byte byteArray[data.length() / 2] = { 0 };\r\n            hexCharacterStringToBytes(byteArray, data.c_str());\r\n            //两个参数，第一个接收byte的数组,第二个要String.c_str()\r\n            Serial.write(byteArray, data.length() / 2);\r\n            delay(25000);\r\n            digitalWrite(d0, LOW);\r\n            return;\r\n          }\r\n        }\r\n        if (message.indexOf("mydoor1.铃声") != -1) {\r\n          digitalWrite(d0, HIGH);\r\n          delay(2000);\r\n          String s = message.substring(message.length() - 1);\r\n          String data = "FD 00 08 01 01 72 69 6E 67 5F 3" + s;\r\n          data.replace(" ", "");\r\n          //String data = "020104C0";\r\n          //这里长度记得除下2    使用前校验一下String的长度是否正确\r\n          byte byteArray[data.length() / 2] = { 0 };\r\n          hexCharacterStringToBytes(byteArray, data.c_str());\r\n          //两个参数，第一个接收byte的数组,第二个要String.c_str()\r\n          Serial.write(byteArray, data.length() / 2);\r\n          delay(7000);\r\n          digitalWrite(d0, LOW);\r\n          return;\r\n        }\r\n        if (message.indexOf("mydoor1.信息提示音") != -1) {\r\n          digitalWrite(d0, HIGH);\r\n          delay(2000);\r\n          String s = message.substring(message.length() - 1);\r\n          String data = "FD 00 0B 01 01 6D 65 73 73 61 67 65 5F 3" + s;\r\n          data.replace(" ", "");\r\n          //String data = "020104C0";\r\n          //这里长度记得除下2    使用前校验一下String的长度是否正确\r\n          byte byteArray[data.length() / 2] = { 0 };\r\n          hexCharacterStringToBytes(byteArray, data.c_str());\r\n          //两个参数，第一个接收byte的数组,第二个要String.c_str()\r\n          Serial.write(byteArray, data.length() / 2);\r\n          delay(7000);\r\n          digitalWrite(d0, LOW);\r\n          return;\r\n        }\r\n        if (message.indexOf("mydoor1.警示音") != -1) {\r\n          digitalWrite(d0, HIGH);\r\n          delay(2000);\r\n          String s = message.substring(message.length() - 1);\r\n          String data = "FD 00 09 01 01 61 6C 65 72 74 5F 3" + s;\r\n          data.replace(" ", "");\r\n          //String data = "020104C0";\r\n          //这里长度记得除下2    使用前校验一下String的长度是否正确\r\n          byte byteArray[data.length() / 2] = { 0 };\r\n          hexCharacterStringToBytes(byteArray, data.c_str());\r\n          //两个参数，第一个接收byte的数组,第二个要String.c_str()\r\n          Serial.write(byteArray, data.length() / 2);\r\n          delay(7000);\r\n          digitalWrite(d0, LOW);\r\n          return;\r\n        }\r\n        if (message == "mydoor1.温湿度") {\r\n          // 获取温度事件并打印其值.\r\n          sensors_event_t event;\r\n          dht.temperature().getEvent(&event);\r\n          if (isnan(event.temperature)) {\r\n            Serial.println(F("Error reading temperature!"));\r\n          } else {\r\n            temperature = event.temperature;\r\n            if (temperature < -10) {\r\n              tes = "防冻";\r\n            }\r\n            if (temperature >= -10 && temperature < 18) {\r\n              tes = "寒冷";\r\n            }\r\n            if (temperature >= 18 && temperature <= 25) {\r\n              tes = "舒适";\r\n            }\r\n            if (temperature > 25 && temperature <= 36) {\r\n              tes = "炎热";\r\n            }\r\n            if (temperature > 36) {\r\n              tes = "防暑";\r\n            }\r\n          }\r\n          delay(500);\r\n          // Get humidity event and print its value.\r\n          dht.humidity().getEvent(&event);\r\n          if (isnan(event.relative_humidity)) {\r\n            Serial.println(F("Error reading humidity!"));\r\n          } else {\r\n            humidity = event.relative_humidity;\r\n            if (humidity < 40) {\r\n              hus = "干燥";\r\n            }\r\n            if (humidity >= 40 && humidity <= 70) {\r\n              hus = "舒适";\r\n            }\r\n            if (humidity > 70) {\r\n              hus = "潮湿";\r\n            }\r\n          }\r\n          String th = String(temperature) + "°C" + tes + "   " + String(humidity) + "%湿度" + hus;\r\n          webSocket.sendTXT(th);\r\n          return;\r\n        }\r\n\r\n        if (message == "mydoor1.灯箱开") {\r\n          digitalWrite(d8, HIGH);\r\n          ggb = true;\r\n          if (user == "系统任务") {\r\n            String strtem = "系统任务 广告牌灯箱已开";\r\n            webSocket.sendTXT(strtem);\r\n          } else {\r\n            String strtem = user + " 广告牌灯箱已开";\r\n            webSocket.sendTXT(strtem);\r\n          }\r\n          return;\r\n        }\r\n        if (message == "mydoor1.灯箱关") {\r\n          digitalWrite(d8, LOW);\r\n          ggb = false;\r\n          if (user == "系统任务") {\r\n            String strtem = "系统任务 广告牌灯箱已关";\r\n            webSocket.sendTXT(strtem);\r\n          } else {\r\n            String strtem = user + " 广告牌灯箱已关";\r\n            webSocket.sendTXT(strtem);\r\n          }\r\n          return;\r\n        }\r\n        if (message == "mydoor1.重启") {\r\n          ESP.restart();\r\n        }\r\n        if (message == "mydoor1.version") {\r\n          webSocket.sendTXT(version);\r\n        }\r\n        if (message == "mydoor1.updateBin") {\r\n          while (1) {\r\n            // Add optional callback notifiers\r\n            ESPhttpUpdate.onStart(update_started);\r\n            ESPhttpUpdate.onEnd(update_finished);\r\n            ESPhttpUpdate.onProgress(update_progress);\r\n            ESPhttpUpdate.onError(update_error);\r\n            t_httpUpdate_return ret = ESPhttpUpdate.update(wificlient, upUrl);\r\n            switch (ret) {\r\n              case HTTP_UPDATE_FAILED: Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); break;\r\n\r\n              case HTTP_UPDATE_NO_UPDATES: Serial.println("HTTP_UPDATE_NO_UPDATES"); break;\r\n\r\n              case HTTP_UPDATE_OK: Serial.println("HTTP_UPDATE_OK"); break;\r\n            }\r\n          }\r\n          espReboot();\r\n        }\r\n      }\r\n      // send message to server\r\n      //       webSocket.sendTXT("message here");\r\n      break;\r\n    case WStype_BIN:\r\n      Serial.printf("[WSc] get binary length: % u\\n", length);\r\n      //hexdump(payload, length);\r\n      // webSocket.sendBIN(payload, length);\r\n      break;\r\n    case WStype_PING:\r\n      // pong will be send automatically\r\n      //Serial.printf("[WSc] get ping\\n");\r\n\r\n      break;\r\n    case WStype_PONG:\r\n      // answer to a ping we send\r\n      Serial.printf("[WSc] get pong\\n");\r\n      //防止开启突然没有网络,lop循环检测不到状态 这里再进行检测\r\n      if (digitalRead(d5) == HIGH && state != 10) {\r\n        state = 10;\r\n        //关闭所有开关\r\n        CloseAll();\r\n        //Serial.println("Disconnected  state = 10");\r\n      }\r\n      //查询是否下降 限制,及时把状态改好\r\n      if (digitalRead(d6) == HIGH && state != 0) {\r\n        state = 0;\r\n        //关闭所有开关\r\n        CloseAll();\r\n      }\r\n      //如果websocket连接网络失败重启时又能连网就重置0\r\n      if (internet_i != 0) {\r\n        internet_i = 0;\r\n      }\r\n      break;\r\n  }\r\n}\r\nvoid SetWifi() {\r\n  ssid = ESP8266webServer.arg(0);\r\n  passwd = ESP8266webServer.arg(1);\r\n  String sp = ssid + "&" + passwd;\r\n  Serial.println(sp);\r\n  Serial.println("密码在前面");\r\n  Serial.begin(115200);\r\n  delay(500);\r\n  const char* Ssid = ssid.c_str();\r\n  const char* WifiPw = passwd.c_str();\r\n  WiFi.begin(Ssid, WifiPw);\r\n  WiFi.mode(WIFI_STA);\r\n  delay(200);\r\n  Serial.println("wifi_connet");\r\n  int ii = 0;\r\n  for (ii; ii < 20; ii++) {\r\n    delay(500);\r\n    Serial.print(".");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      ESP8266webServer.send(200, "text/plane", "Wifi密码正确,ESP准备重启");\r\n      ESP8266webServer.close();\r\n      delay(500);\r\n      WiFi.disconnect();\r\n      delay(500);\r\n\r\n      //写入数据\r\n      SPIFFS.format();\r\n      delay(500);\r\n      SPIFFS.begin();\r\n      File dataFile = SPIFFS.open(flash_wifi, "w");\r\n      dataFile.println(sp);\r\n      dataFile.close();\r\n\r\n      Serial.println("HTML连接成功");\r\n      delay(500);\r\n      ESP.restart();\r\n    }\r\n  }\r\n  ESP8266webServer.send(200, "text/plane", "Wifi密码错误,请重新输入");\r\n  //HtmlSetWifi();\r\n}\r\n//------- 展示页面-------\r\nvoid handlejsonStr() {\r\n  ESP8266webServer.send(500, "text/html", html);\r\n}\r\nvoid handleNotFound(void) {\r\n  ESP8266webServer.send(404, "text/plain", "404-The page is not Found!");\r\n}\r\n\r\n\r\nvoid ApStart() {\r\n  WiFi.disconnect();\r\n  delay(500);\r\n  Serial.begin(115200);\r\n  WiFi.mode(WIFI_AP);\r\n  IPAddress local_IP(192, 168, 168, 2);\r\n  IPAddress gateway(192, 168, 168, 1);\r\n  IPAddress subnet(255, 255, 255, 0);\r\n  WiFi.softAPConfig(local_IP, gateway, subnet);\r\n\r\n  //启动AP模式,并设置账号和密码\r\n  WiFi.softAP("192.168.168.2", "192.168.168.2");\r\n}\r\nvoid WebserverStart() {\r\n  //-----------------启动webserver网络服务--------------------\r\n  ESP8266webServer.begin(80);               // 启用网络服务\r\n  ESP8266webServer.on("/", handlejsonStr);  // / 在HTTP中,表示请求首页服务,\r\n  ESP8266webServer.on("/SetWifi", SetWifi);\r\n  ESP8266webServer.onNotFound(handleNotFound);  // 当服务器没找到所需的服务,调用404函数\r\n  Serial.println("webserver started");\r\n}\r\n\r\n\r\n\r\nvoid ForPing() {\r\n  //定时时间到了,先取消定时状态\r\n  myTicker.detach();\r\n  CloseAll();\r\n  delay(500);\r\n\r\n  ESP.restart();\r\n}\r\n\r\n\r\n//关闭上升,下降,变压器主电源\r\nvoid CloseAll() {\r\n  digitalWrite(open, LOW);\r\n  digitalWrite(close, LOW);\r\n  delay(200);\r\n  //断开电源接通\r\n  digitalWrite(d0, LOW);\r\n  //取消定时状态\r\n  myTicker.detach();\r\n  webSocket.sendTXT("变压器电源已断开");\r\n}\r\n\r\n\r\n//扫描附件WIFI\r\nvoid WifiScan() {\r\n  Serial.begin(115200);\r\n  WiFi.disconnect();\r\n  WiFi.mode(WIFI_STA);\r\n  delay(100);\r\n  int n = WiFi.scanNetworks();\r\n  if (n > 0) {\r\n    Serial.println(n);\r\n    String a = "附近WiFi <select id=\\"ssid\\">";\r\n    for (int i = 0; i < n; i++) {\r\n      Serial.println(WiFi.SSID(i));\r\n      a = a + "<option value=\\"" + WiFi.SSID(i) + "\\">" + WiFi.SSID(i) + "</option>";\r\n      delay(50);\r\n    }\r\n    String HtmlStart = String("") + "<!DOCTYPE html>" + "<html>" + "<head>" + "<meta charset=\\"utf-8\\">" + "<meta name=\\"viewport\\" content=\\"width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\\" />" + "<title>设置WiFi</title>" + "<link rel=\\"stylesheet\\" href=\\"\\">" + "</head>" + "<script>" + "onload  = function() {" + "document.getElementById(\\"up\\").onclick = function(){" + "var ssida=document.getElementById(\\"ssid\\").value;" + "var ssid=ssida.replace(/\\\\s+/g, \\" \\");" + "var passwda=document.getElementsByTagName(''input'')[0].value;" + "var passwd=passwda.replace(/\\\\s+/g, \\" \\");" + "xhr = new XMLHttpRequest();" + "xhr.open(\\"POST\\",\\"./SetWifi\\",true);" + "var posts = (\\"ssid=\\"+ssid+\\"&passwd=\\"+ passwd);" + "xhr.setRequestHeader(\\"Content-Type\\",\\"application/x-www-form-urlencoded\\");" + "xhr.send(posts);" + "xhr.onreadystatechange = function(){" + "if(this.readyState == 4 && this.status == 200){" + "alert(this.responseText);" + "}" + "}" + "}" + "}" + "</script>" + "<body>";\r\n    String HtmlEnd = String("") + "<p>WiFi密码<input type=\\"text\\" id=\\"passwd\\"></p>" + "<input type=\\"submit\\" id=\\"up\\" value=\\"设 置\\">" + "<hr/>" + "<font color=\\"red\\">附近WiFi没有显示到自己的WIFI请重启或离信号源近点</font>" + "</body>" + "</html>";\r\n    a = a + "</select>";\r\n    html = HtmlStart + a + HtmlEnd;\r\n  } else {\r\n    html = "扫描不到网络";\r\n    Serial.println("扫描不到网络");\r\n  }\r\n}\r\nbool FlashConnetWifi() {\r\n  Serial.begin(115200);\r\n  delay(500);\r\n  //是否存在数据\r\n  SPIFFS.begin();\r\n  if (SPIFFS.exists(flash_wifi) == false) {\r\n    Serial.print(flash_wifi);\r\n    Serial.println(" NOT FOUND");\r\n    return false;\r\n  }\r\n\r\n  File dateFile = SPIFFS.open(flash_wifi, "r");\r\n  String result = dateFile.readString();\r\n  result.trim();\r\n  Serial.println(result);\r\n  int i = result.indexOf("&");\r\n  String wifiname = result.substring(0, i);\r\n  String wifipw = result.substring(i + 1);\r\n  const char* Ssid = wifiname.c_str();\r\n  const char* WifiPw = wifipw.c_str();\r\n  Serial.println(Ssid);\r\n  Serial.println(WifiPw);\r\n  WiFi.begin(Ssid, WifiPw);\r\n  delay(500);\r\n  WiFi.mode(WIFI_STA);\r\n  Serial.println("FlashConnetWifi->connet");\r\n  int ii = 0;\r\n  for (ii; ii < 25; ii++) {\r\n    delay(500);\r\n    Serial.print(" . ");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      Serial.println("FlashConnetWifi 闪存配置连接成功");\r\n      return true;\r\n    }\r\n  }\r\n  Serial.println("FlashConnetWifi->false");\r\n  return false;\r\n}\r\n\r\nvoid HtmlSetWifi() {\r\n  WifiScan();\r\n  ApStart();\r\n  delay(1000);\r\n  Serial.println("启动网页");\r\n  myTicker.detach();\r\n  delay(200);\r\n  //5分后重启 防止停电后复电,路由器连接WIFI速度慢于ESP导致ESP连接不到路由器进入无限AP模式,所以这里只让AP 激活5分钟后就重启\r\n  myTicker.once(300, espReboot);\r\n  delay(200);\r\n  WebserverStart();\r\n  while (1) {\r\n    ESP8266webServer.handleClient();  // 检查网络服务请求并处理\r\n  }\r\n}\r\nvoid espReboot() {\r\n  ESP.restart();\r\n}\r\nvoid wssRaspberry() {\r\n  //WiFi.disconnect();\r\n  webSocket.disconnect();\r\n  Serial.begin(115200);\r\n  delay(500);\r\n  networkRemoteLocal = true;\r\n\r\n  webSocket.beginSSL("www.nobiggie.cn", 443, "/service/wss");\r\n  webSocket.onEvent(webSocketEvent);\r\n  webSocket.setAuthorization("user=mydoor1&passwd=efghijk&room=admin");\r\n  // try ever 5000 again if connection has failed\r\n  webSocket.setReconnectInterval(500);\r\n  /*虽然服务器有ping 但是有时运行中,突然无网络,返回连接失败Disconnected 很慢,或有时直接卡住需要手动重启ESP\r\n    所以 webSocket.enableHeartbeat(15000, 1500, 2);也要加上  */\r\n  webSocket.enableHeartbeat(15000, 2000, 2);\r\n  //防止 电源重启,门达到上限了,没有把状态改正,在这进行验证一下\r\n  if (digitalRead(d5) == HIGH) {\r\n    state = 10;\r\n  }\r\n  if (digitalRead(d6) == HIGH) {\r\n    state = 0;\r\n  }\r\n}\r\nvoid wsRaspberry() {\r\n  //WiFi.disconnect();\r\n  webSocket.disconnect();\r\n  Serial.begin(115200);\r\n  delay(500);\r\n  networkRemoteLocal = false;\r\n\r\n  Serial.println("webSocket->" + localServerIP);\r\n  webSocket.begin(localServerIP, 80, "/service/wss");\r\n  webSocket.onEvent(webSocketEvent);\r\n  webSocket.setAuthorization("user=mydoor1&passwd=efghijk&room=admin");\r\n  // try ever 5000 again if connection has failed\r\n  webSocket.setReconnectInterval(500);\r\n  webSocket.enableHeartbeat(15000, 2000, 2);\r\n  //防止 电源重启,门达到上限了,没有把状态改正,在这进行验证一下\r\n  if (digitalRead(d5) == HIGH) {\r\n    state = 10;\r\n  }\r\n  if (digitalRead(d6) == HIGH) {\r\n    state = 0;\r\n  }\r\n}\r\n//无网特殊状态下安全限位\r\nvoid html_whlie() {\r\n  //操作运行时 上升达到限位了,并且上次状态不是上升上限, 并且执行状态是上升 限位开关断开\r\n  if (digitalRead(d5) == HIGH || digitalRead(d6) == HIGH) {\r\n    //关闭所有开关\r\n    CloseAll();\r\n    Serial.println("达到上限");\r\n    myTicker.detach();\r\n    delay(200);\r\n    ESP.restart();\r\n  }\r\n}\r\n\r\n\r\nString myHttpGet(String string) {\r\n  HTTPClient http;\r\n  String response;\r\n  http.begin(wificlient, string);\r\n  http.setTimeout(3000);\r\n  int httpCode = http.GET();\r\n  if (httpCode == 200) {\r\n    response = http.getString();\r\n    return response;\r\n  } else {\r\n    return "";\r\n  }\r\n  http.end();\r\n}\r\nString myHttpPost(String url, String postStr) {\r\n  HTTPClient http;\r\n  String response;\r\n  http.begin(wificlient, url);\r\n  http.setTimeout(3000);\r\n  //需要传输的数据\r\n  char dataBuff[postStr.length()];\r\n  strcpy(dataBuff, postStr.c_str());\r\n  //头信息,需要的反注释就可以\r\n  //http.addHeader("Content-Type", "application/json;charset=utf-8");\r\n  http.addHeader("Content-Type", "application/x-www-form-urlencoded");\r\n  int httpCode = http.POST(dataBuff);\r\n  if (httpCode == 200) {\r\n    response = http.getString();\r\n    return response;\r\n  } else {\r\n    return "";\r\n  }\r\n  http.end();\r\n}\r\nvoid hexCharacterStringToBytes(byte* byteArray, const char* hexString) {\r\n  bool oddLength = strlen(hexString) & 1;\r\n\r\n  byte currentByte = 0;\r\n  byte byteIndex = 0;\r\n\r\n  for (byte charIndex = 0; charIndex < strlen(hexString); charIndex++) {\r\n    bool oddCharIndex = charIndex & 1;\r\n\r\n    if (oddLength) {\r\n      // If the length is odd\r\n      if (oddCharIndex) {\r\n        // odd characters go in high nibble\r\n        currentByte = nibble(hexString[charIndex]) << 4;\r\n      } else {\r\n        // Even characters go into low nibble\r\n        currentByte |= nibble(hexString[charIndex]);\r\n        byteArray[byteIndex++] = currentByte;\r\n        currentByte = 0;\r\n      }\r\n    } else {\r\n      // If the length is even\r\n      if (!oddCharIndex) {\r\n        // Odd characters go into the high nibble\r\n        currentByte = nibble(hexString[charIndex]) << 4;\r\n      } else {\r\n        // Odd characters go into low nibble\r\n        currentByte |= nibble(hexString[charIndex]);\r\n        byteArray[byteIndex++] = currentByte;\r\n        currentByte = 0;\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\nbyte nibble(char c) {\r\n  if (c >= ''0'' && c <= ''9'')\r\n    return c - ''0'';\r\n\r\n  if (c >= ''a'' && c <= ''f'')\r\n    return c - ''a'' + 10;\r\n\r\n  if (c >= ''A'' && c <= ''F'')\r\n    return c - ''A'' + 10;\r\n\r\n  return 0;  // Not a valid hexadecimal character\r\n}\r\nvoid update_started() {\r\n  Serial.println("CALLBACK:  HTTP update process started");\r\n}\r\n\r\nvoid update_finished() {\r\n  Serial.println("CALLBACK:  HTTP update process finished");\r\n}\r\n\r\nvoid update_progress(int cur, int total) {\r\n  Serial.printf("CALLBACK:  HTTP update process at %d of %d bytes...\\n", cur, total);\r\n  webSocket.sendTXT(Serial.printf("CALLBACK:  HTTP update process at %d of %d bytes...\\n", cur, total));\r\n}\r\n\r\nvoid update_error(int err) {\r\n  Serial.printf("CALLBACK:  HTTP update fatal error code %d\\n", err);\r\n}', '', 'webserver'),
(7998, 20, 'ESP8266 http Post与Get请求', '#include <ESP8266WiFi.h>\r\n#include <ESP8266HTTPClient.h>\r\nWiFiClient wificlient;\r\nvoid setup() {\r\n  // put your setup code here, to run once:\r\n  Serial.begin(115200);\r\n  WiFi.begin("webserver", "www.360xyz.cn");\r\n  delay(500);\r\n  WiFi.mode(WIFI_STA);\r\n  Serial.println("FlashConnetWifi->connet");\r\n  while (1) {\r\n    delay(500);\r\n    Serial.print(" . ");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      Serial.println("FlashConnetWifi 闪存配置连接成功");\r\n      break;\r\n    }\r\n  }\r\n}\r\n\r\nvoid loop() {\r\n\r\n  String a = esp8266Get("http://server.nobiggie.cn/query/date");\r\n  Serial.println(a);\r\n  delay(5000);\r\n}\r\nString esp8266Get(String string) {\r\n  HTTPClient http;\r\n  String response;\r\n  http.begin(wificlient, string);\r\n  http.setTimeout(3000);\r\n  int httpCode = http.GET();\r\n  // httpCode will be negative on error\r\n  if (httpCode == 200) {\r\n    response = http.getString();\r\n    return response;\r\n  } else {\r\n    return "";\r\n  }\r\n  http.end();\r\n}\r\nString esp8266Post(String url, String postStr) {\r\n  HTTPClient http;\r\n  String response;\r\n  http.begin(wificlient, url);\r\n  http.setTimeout(3000);\r\n  //需要传输的数据\r\n  char dataBuff[postStr.length()];\r\n  strcpy(dataBuff, postStr.c_str());\r\n  //头信息，需要的反注释就可以\r\n  //http.addHeader("Content-Type", "application/json;charset=utf-8");\r\n  http.addHeader("Content-Type", "application/x-www-form-urlencoded");\r\n  int httpCode = http.POST(dataBuff);\r\n  if (httpCode == 200) {\r\n    response = http.getString();\r\n    return response;\r\n  } else {\r\n    return "";\r\n  }\r\n  http.end();\r\n}', '', 'webserver'),
(7999, 20, '智能照明', '#define BLINKER_WIFI\r\n#include <Arduino.h>\r\n#include <Blinker.h>\r\nchar auth[] = "1fac905d4e32";\r\nchar ssid[] = "webserver";      //你的wifi\r\nchar pswd[] = "www.360xyz.cn";  //你的WIFI密码\r\n\r\n#define D5 14                      //人体感应\r\n#define D6 12                      //光敏感应\r\n#define D8 15                       //灯\r\nBlinkerButton Button1("btn-64g");  //遥控灯开关\r\nbool lightStatu = false;           //默认灯是关的状态\r\nbool onOff = false;                //开关状态 默认关\r\nvoid setup() {\r\n  pinMode(D5, INPUT);\r\n  pinMode(D6, INPUT);\r\n  pinMode(D8, OUTPUT);\r\n  digitalWrite(D8, LOW);\r\n  // put your setup code here, to run once:\r\n  Serial.begin(115200);\r\n  Blinker.begin(auth, ssid, pswd);\r\n  Button1.attach(button1_callback);\r\n  delay(500);\r\n}\r\n\r\nvoid loop() {\r\n  // put your main code here, to run repeatedly:\r\n  Blinker.run();\r\n  //晚上光敏导通  全亮\r\n  if (digitalRead(D6) == HIGH) {\r\n    if (lightStatu == false) {\r\n      lightStatu = true;\r\n      digitalWrite(D8, HIGH);  //点亮灯\r\n      Button1.color("#00FF00");\r\n      Button1.text("开");\r\n      Button1.print();\r\n      Serial.println("晚上光敏导通  全亮");\r\n    }\r\n  } else {\r\n    //白天\r\n    //并且是开灯状态 并且 人体感应 没有人    关灯\r\n    if (lightStatu == true && digitalRead(D5) == LOW && onOff == false) {\r\n      lightStatu = false;\r\n      digitalWrite(D8, LOW);  //关灯\r\n      Button1.color("#000000");\r\n      Button1.text("关");\r\n      Button1.print();\r\n      Serial.println("并且是开灯状态 并且 人体感应 没有人    ->关灯");\r\n    } else {\r\n      //人体感应 有人 并且灯没有点亮\r\n      if (digitalRead(D5) == HIGH && lightStatu == false) {\r\n        lightStatu = true;       //点亮\r\n        digitalWrite(D8, HIGH);  //点亮灯\r\n        Button1.color("#00FF00");\r\n        Button1.text("开");\r\n        Button1.print();\r\n        Serial.println("人体感应 有人 并且灯没有点亮");\r\n      }\r\n      //如果人体感应 没有人 并且 灯的状态是开的 并且没有手动开灯\r\n      if (digitalRead(D5) == LOW && lightStatu == true && onOff == false) {\r\n        lightStatu = false;\r\n        digitalWrite(D8, LOW);  //关灯\r\n        Button1.color("#000000");\r\n        Button1.text("关");\r\n        Button1.print();\r\n        Serial.println("如果人体感应 没有人 并且 灯的状态是开的 并且没有手动开灯");\r\n      }\r\n    }\r\n  }\r\n}\r\nvoid button1_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  if (lightStatu == false) {\r\n    Button1.color("#00FF00");\r\n    Button1.text("开");\r\n    Button1.print();\r\n    lightStatu = true;\r\n    digitalWrite(D8, HIGH);\r\n    onOff = true;\r\n  } else {\r\n    Button1.color("#000000");\r\n    Button1.text("关");\r\n    Button1.print();\r\n    lightStatu = false;\r\n    digitalWrite(D8, LOW);\r\n    onOff = false;\r\n  }\r\n}\r\n', '', 'webserver'),
(8000, 20, '点灯科技6个震动器', '#define BLINKER_WIFI\r\n#include <Blinker.h>\r\n#include <ESP8266WiFi.h>\r\nchar ssid[] = "webserver";      //你的WIFI名\r\nchar pswd[] = "www.360xyz.cn";  //你的WIFI密码\r\nchar auth[] = "0371ea173c72";\r\n#define D1 5\r\n#define D2 4\r\n#define D5 14\r\n#define D6 12\r\n#define D7 13\r\n#define D8 15\r\nint vibrationTime = 3;  //震动时间\r\n\r\nBlinkerButton Button1("btn-hog");\r\nBlinkerButton Button2("btn-1vs");\r\nBlinkerButton Button3("btn-ed9");\r\nBlinkerButton Button4("btn-cjh");\r\nBlinkerButton Button5("btn-94j");\r\nBlinkerButton Button6("btn-u0a");\r\nvoid setup() {\r\n  pinMode(D1, OUTPUT);\r\n  pinMode(D2, OUTPUT);\r\n  pinMode(D5, OUTPUT);\r\n  pinMode(D6, OUTPUT);\r\n  pinMode(D7, OUTPUT);\r\n  pinMode(D8, OUTPUT);\r\n  digitalWrite(D1, LOW);\r\n  digitalWrite(D2, LOW);\r\n  digitalWrite(D5, LOW);\r\n  digitalWrite(D6, LOW);\r\n  digitalWrite(D7, LOW);\r\n  digitalWrite(D8, LOW);\r\n  Serial.begin(115200);\r\n  Blinker.begin(auth, ssid, pswd);\r\n  Button1.attach(button1_callback);\r\n  Button2.attach(button2_callback);\r\n  Button3.attach(button3_callback);\r\n  Button4.attach(button4_callback);\r\n  Button5.attach(button5_callback);\r\n  Button6.attach(button6_callback);\r\n  Blinker.attachData(dataRead);\r\n}\r\n\r\nvoid loop() {\r\n  Blinker.run();\r\n}\r\nvoid button1_callback(const String& state) {\r\n  BLINKER_LOG("get button state: ", state);\r\n  digitalWrite(D1, HIGH);\r\n  Button1.color("#00FF00");\r\n  Button1.text("1#正在震动");\r\n  Button1.print();\r\n  delay(vibrationTime * 1000);\r\n  digitalWrite(D1, LOW);\r\n  Button1.color("#000000");\r\n  Button1.text("1#已停止");\r\n  Button1.print();\r\n}\r\n\r\n//停止\r\nvoid button2_callback(const String& state) {\r\n  BLINKER_LOG("get button state: ", state);\r\n  digitalWrite(D2, HIGH);\r\n  Button2.color("#00FF00");\r\n  Button2.text("2#正在震动");\r\n  Button2.print();\r\n  delay(vibrationTime * 1000);\r\n  digitalWrite(D2, LOW);\r\n  Button2.color("#000000");\r\n  Button2.text("2#已停止");\r\n  Button2.print();\r\n}\r\n//下降\r\nvoid button3_callback(const String& state) {\r\n  BLINKER_LOG("get button state: ", state);\r\n  digitalWrite(D5, HIGH);\r\n  Button3.color("#00FF00");\r\n  Button3.text("3#正在震动");\r\n  Button3.print();\r\n  delay(vibrationTime * 1000);\r\n  digitalWrite(D5, LOW);\r\n  Button3.color("#000000");\r\n  Button3.text("3#已停止");\r\n  Button3.print();\r\n}\r\nvoid button4_callback(const String& state) {\r\n  BLINKER_LOG("get button state: ", state);\r\n  digitalWrite(D6, HIGH);\r\n  Button4.color("#00FF00");\r\n  Button4.text("4#正在震动");\r\n  Button4.print();\r\n  delay(vibrationTime * 1000);\r\n  digitalWrite(D6, LOW);\r\n  Button4.color("#000000");\r\n  Button4.text("4#已停止");\r\n  Button4.print();\r\n}\r\n\r\nvoid button5_callback(const String& state) {\r\n  BLINKER_LOG("get button state: ", state);\r\n  digitalWrite(D7, HIGH);\r\n  Button5.color("#00FF00");\r\n  Button5.text("5#正在震动");\r\n  Button5.print();\r\n  delay(vibrationTime * 1000);\r\n  digitalWrite(D7, LOW);\r\n  Button5.color("#000000");\r\n  Button5.text("5#已停止");\r\n  Button5.print();\r\n}\r\nvoid button6_callback(const String& state) {\r\n  BLINKER_LOG("get button state: ", state);\r\n  digitalWrite(D8, HIGH);\r\n  Button6.color("#00FF00");\r\n  Button6.text("6#正在震动");\r\n  Button6.print();\r\n  delay(vibrationTime * 1000);\r\n  digitalWrite(D8, LOW);\r\n  Button6.color("#000000");\r\n  Button6.text("6#已停止");\r\n  Button6.print();\r\n}\r\nvoid dataRead(const String& data) {\r\n  BLINKER_LOG("Blinker readString: ", data);\r\n  int tmp = data.toInt();\r\n  vibrationTime=tmp;\r\n}', '', 'webserver'),
(8002, 20, '摄像头4组开关温湿度1', '/* *****************************************************************\r\n *\r\n * Download latest Blinker library here:\r\n * https://github.com/blinker-iot/blinker-library/archive/master.zip\r\n * \r\n * \r\n * Blinker is a cross-hardware, cross-platform solution for the IoT. \r\n * It provides APP, device and server support, \r\n * and uses public cloud services for data transmission and storage.\r\n * It can be used in smart home, data monitoring and other fields \r\n * to help users build Internet of Things projects better and faster.\r\n * \r\n * Make sure installed 2.7.4 or later ESP8266/Arduino package,\r\n * if use ESP8266 with Blinker.\r\n * https://github.com/esp8266/Arduino/releases\r\n * \r\n * Make sure installed 1.0.5 or later ESP32/Arduino package,\r\n * if use ESP32 with Blinker.\r\n * https://github.com/espressif/arduino-esp32/releases\r\n * \r\n * Docs: https://diandeng.tech/doc\r\n *       \r\n * \r\n * *****************************************************************\r\n * \r\n * Blinker 库下载地址:\r\n * https://github.com/blinker-iot/blinker-library/archive/master.zip\r\n * \r\n * Blinker 是一套跨硬件、跨平台的物联网解决方案，提供APP端、设备端、\r\n * 服务器端支持，使用公有云服务进行数据传输存储。可用于智能家居、\r\n * 数据监测等领域，可以帮助用户更好更快地搭建物联网项目。\r\n * \r\n * 如果使用 ESP8266 接入 Blinker,\r\n * 请确保安装了 2.7.4 或更新的 ESP8266/Arduino 支持包。\r\n * https://github.com/esp8266/Arduino/releases\r\n * \r\n * 如果使用 ESP32 接入 Blinker,\r\n * 请确保安装了 1.0.5 或更新的 ESP32/Arduino 支持包。\r\n * https://github.com/espressif/arduino-esp32/releases\r\n * \r\n * 文档: https://diandeng.tech/doc\r\n *       \r\n * \r\n * *****************************************************************/\r\n\r\n#define BLINKER_WIFI\r\n\r\n#include <Blinker.h>\r\n#include "ESP32_CAM_SERVER.h"\r\n\r\nchar ssid[] = "webserver";\r\nchar wifipwd[] = "www.360xyz.cn";\r\nchar auth[] = "7eb873d19e73";\r\nint D12 = 12;\r\nint D13 = 13;\r\nint D15 = 15;\r\nint D14 = 14;\r\nBlinkerButton Button1("btn-xyb");  //\r\nBlinkerButton Button2("btn-902");  //\r\nBlinkerButton Button3("btn-fmc");  //\r\nBlinkerButton Button4("btn-126");  //\r\n\r\nbool d1 = false;\r\nbool d2 = false;\r\nbool d5 = false;\r\nbool d6 = false;\r\nbool setup_camera = false;\r\n\r\nvoid dataRead(const String& data) {\r\n  BLINKER_LOG("Blinker readString: ", data);\r\n\r\n  Blinker.vibrate();\r\n\r\n  uint32_t BlinkerTime = millis();\r\n\r\n  Blinker.print("millis", BlinkerTime);\r\n}\r\n\r\nvoid setup() {\r\n  pinMode(D12, OUTPUT);\r\n  pinMode(D13, OUTPUT);\r\n  pinMode(D15, OUTPUT);\r\n  pinMode(D14, OUTPUT);\r\n  digitalWrite(D12, LOW);\r\n  digitalWrite(D13, LOW);\r\n  digitalWrite(D15, LOW);\r\n  digitalWrite(D14, LOW);\r\n  Serial.begin(115200);\r\n  BLINKER_DEBUG.stream(Serial);\r\n\r\n  pinMode(LED_BUILTIN, OUTPUT);\r\n  digitalWrite(LED_BUILTIN, LOW);\r\n\r\n  Blinker.begin(auth, ssid, wifipwd);\r\n  Blinker.attachData(dataRead);\r\n  Button1.attach(button1_callback);\r\n  Button2.attach(button2_callback);\r\n  Button3.attach(button3_callback);\r\n  Button4.attach(button4_callback);\r\n}\r\n\r\nvoid loop() {\r\n  Blinker.run();\r\n\r\n  if (Blinker.connected() && !setup_camera) {\r\n    setupCamera();\r\n    setup_camera = true;\r\n\r\n    Blinker.printObject("video", "{\\"str\\":\\"mjpg\\",\\"url\\":\\"http://" + WiFi.localIP().toString() + "\\"}");\r\n  }\r\n}\r\nvoid button1_callback(const String& state) {\r\n  if (d1 == true) {\r\n    d1 = false;\r\n    digitalWrite(D12, LOW);\r\n    Button1.color("#000000");\r\n    Button1.text("关");\r\n  } else {\r\n    d1 = true;\r\n    digitalWrite(D12, HIGH);\r\n    Button1.color("#00FF00");\r\n    Button1.text("开");\r\n  }\r\n  Button1.print();\r\n}\r\nvoid button2_callback(const String& state) {\r\n  if (d2 == true) {\r\n    d2 = false;\r\n    digitalWrite(D13, LOW);\r\n    Button2.color("#000000");\r\n    Button2.text("关");\r\n  } else {\r\n    d2 = true;\r\n    digitalWrite(D13, HIGH);\r\n    Button2.color("#00FF00");\r\n    Button2.text("开");\r\n  }\r\n  Button2.print();\r\n}\r\nvoid button3_callback(const String& state) {\r\n  if (d5 == true) {\r\n    d5 = false;\r\n    digitalWrite(D15, LOW);\r\n    Button3.color("#000000");\r\n    Button3.text("关");\r\n  } else {\r\n    d5 = true;\r\n    digitalWrite(D15, HIGH);\r\n    Button3.color("#00FF00");\r\n    Button3.text("开");\r\n  }\r\n  Button3.print();\r\n}\r\nvoid button4_callback(const String& state) {\r\n  if (d6 == true) {\r\n    d6 = false;\r\n    digitalWrite(D14, LOW);\r\n    Button4.color("#000000");\r\n    Button4.text("关");\r\n  } else {\r\n    d6 = true;\r\n    digitalWrite(D14, HIGH);\r\n    Button4.color("#00FF00");\r\n    Button4.text("开");\r\n  }\r\n  Button4.print();\r\n}\r\n', '', 'webserver');
INSERT INTO `WisdomPreview` (`id`, `tid`, `title`, `content`, `imgtext`, `user`) VALUES
(8003, 20, 'TFT_eSPI.h esp32s 配置使用', 'libraries/TFT_eSPI\r\n\r\n85行 #define TFT_WIDTH\r\n88 行找出 尺寸高度  #define TFT_HEIGHT\r\n\r\n\r\n\r\n223行\r\n#define TFT_MOSI 15 // SDA In some display driver board, it might be written as "SDA" and so on.\r\n#define TFT_SCLK 14  //SCL\r\n#define TFT_CS   5  // Chip select control pin\r\n#define TFT_DC   27  // Data Command control pin\r\n#define TFT_RST  33  // Reset pin (could connect to Arduino RESET pin)\r\n#define TFT_BL   22  // LED back-light\r\n\r\n\r\n代码段\r\n#include <SPI.h> //导入库\r\n#include <TFT_eSPI.h> \r\n  \r\nTFT_eSPI tft = TFT_eSPI(); \r\nvoid setup() {\r\n  // put your setup code here, to run once:\r\n  Serial.begin(115200);\r\n  tft.init();                               //初始化\r\n  tft.fillScreen(TFT_BLACK);                //屏幕颜色\r\n  tft.setCursor(10, 10, 1);                 //设置起始坐标(10, 10)，1 号字体\r\n  tft.setTextColor(TFT_YELLOW);             //设置文本颜色为黄色\r\n  tft.setTextSize(2);                       //设置文字的大小 (1~7)\r\n  tft.println("TFT_Text");                  //显示文字\r\n  \r\n  tft.fillCircle(30,30,10,TFT_BLUE);        //画圆\r\n  tft.drawLine(10,50, 118, 50, TFT_WHITE);  //画线\r\n  tft.drawPixel(70,70,TFT_RED);             //画点\r\n  \r\n  tft.setTextColor(TFT_WHITE,TFT_BLUE);     //设置文字颜色和背景颜色\r\n  tft.setCursor(10, 80, 1);                 //设置起始坐标(10, 10)，1 号字体\r\n  tft.println("GEJC");                  //显示文字\r\n}', '', 'webserver'),
(8004, 321, 'linux mysql备份指定几个表', 'mysqldump -uroot -pqq282246101 xyz  WarehouseGoods WarehousePreorder WisdomCategory WisdomPreview WisdomToolsType WisdomToolsName WisdomBartitle WisdomBarrtitle > /home/php.sql', '', 'webserver'),
(8005, 20, '点灯科技esp8266 4路遥控+温湿度', '#define BLINKER_WIFI\r\n#include <OneWire.h>\r\n#include <DallasTemperature.h>\r\n#include <Blinker.h>\r\n#include <ESP8266HTTPClient.h>\r\n#include <ESP8266httpUpdate.h>\r\n#include <DHT.h>\r\n#include <DHT_U.h>\r\nchar ssid[] = "TP-LINK_C97D";\r\nchar wifipwd[] = "19805282968";\r\nchar auth[] = "7eb873d19e73";\r\n\r\nint DD1 = 5;\r\nint DD2 = 4;\r\nint DD5 = 14;\r\nint DD6 = 12;\r\nbool bl1 = false;\r\nbool bl2 = false;\r\nbool bl3 = false;\r\nbool bl4 = false;\r\nWiFiClient wificlient;\r\nBlinkerButton Button1("btn-xyb");  //\r\nBlinkerButton Button2("btn-902");  //\r\nBlinkerButton Button3("btn-fmc");  //\r\nBlinkerButton Button4("btn-126");  //\r\nBlinkerButton Button5("btn-7se");  //\r\nfloat temperature = 0;\r\nint humidity = 0;\r\nBlinkerNumber Number1("num-1e7");  //温\r\nBlinkerNumber Number2("num-wlj");  //湿度\r\n\r\n#define DHTPIN 13\r\n#define DHTTYPE DHT11  // DHT 11\r\nDHT_Unified dht(DHTPIN, DHTTYPE);\r\n#define d7 13\r\nOneWire oneWire(d7);\r\nvoid setup() {\r\n  pinMode(DD1, OUTPUT);\r\n  pinMode(DD2, OUTPUT);\r\n  pinMode(DD5, OUTPUT);\r\n  pinMode(DD6, OUTPUT);\r\n  digitalWrite(DD1, LOW);\r\n  digitalWrite(DD2, LOW);\r\n  digitalWrite(DD5, LOW);\r\n  digitalWrite(DD6, LOW);\r\n  Serial.begin(115200);\r\n  BLINKER_DEBUG.stream(Serial);\r\n\r\n  pinMode(LED_BUILTIN, OUTPUT);\r\n  digitalWrite(LED_BUILTIN, LOW);\r\n\r\n  Blinker.begin(auth, ssid, wifipwd);\r\n  String upUrl = esp8266post();\r\n  if (upUrl.length() > 10) {\r\n    upUrl.trim();\r\n    while (1) {\r\n      ESPhttpUpdate.onStart(update_started);\r\n      ESPhttpUpdate.onEnd(update_finished);\r\n      ESPhttpUpdate.onProgress(update_progress);\r\n      ESPhttpUpdate.onError(update_error);\r\n      ESPhttpUpdate.update(wificlient, upUrl);\r\n    }\r\n    ESP.restart();\r\n  }\r\n  Blinker.attachData(dataRead);\r\n  Button1.attach(button1_callback);\r\n  Button2.attach(button2_callback);\r\n  Button3.attach(button3_callback);\r\n  Button4.attach(button4_callback);\r\n  Button5.attach(button5_callback);\r\n}\r\n\r\nvoid loop() {\r\n  Blinker.run();\r\n}\r\nvoid button1_callback(const String& state) {\r\n  if (bl1 == true) {\r\n    bl1 = false;\r\n    digitalWrite(DD1, LOW);\r\n    Button1.color("#000000");\r\n    Button1.text("关");\r\n  } else {\r\n    bl1 = true;\r\n    digitalWrite(DD1, HIGH);\r\n    Button1.color("#00FF00");\r\n    Button1.text("开");\r\n  }\r\n  Button1.print();\r\n}\r\nvoid button2_callback(const String& state) {\r\n  if (bl2 == true) {\r\n    bl2 = false;\r\n    digitalWrite(DD2, LOW);\r\n    Button2.color("#000000");\r\n    Button2.text("关");\r\n  } else {\r\n    bl2 = true;\r\n    digitalWrite(DD2, HIGH);\r\n    Button2.color("#00FF00");\r\n    Button2.text("开");\r\n  }\r\n  Button2.print();\r\n}\r\nvoid button3_callback(const String& state) {\r\n  if (bl3 == true) {\r\n    bl3 = false;\r\n    digitalWrite(DD5, LOW);\r\n    Button3.color("#000000");\r\n    Button3.text("关");\r\n  } else {\r\n    bl3 = true;\r\n    digitalWrite(DD5, HIGH);\r\n    Button3.color("#00FF00");\r\n    Button3.text("开");\r\n  }\r\n  Button3.print();\r\n}\r\nvoid button4_callback(const String& state) {\r\n  if (bl4 == true) {\r\n    bl4 = false;\r\n    digitalWrite(DD6, LOW);\r\n    Button4.color("#000000");\r\n    Button4.text("关");\r\n  } else {\r\n    bl4 = true;\r\n    digitalWrite(DD6, HIGH);\r\n    Button4.color("#00FF00");\r\n    Button4.text("开");\r\n  }\r\n  Button4.print();\r\n}\r\nvoid button5_callback(const String& state) {\r\n  sensors_event_t event;\r\n  dht.temperature().getEvent(&event);\r\n  if (isnan(event.temperature)) {\r\n    Serial.println(F("Error reading temperature!"));\r\n  } else {\r\n    temperature = event.temperature;\r\n  }\r\n  delay(500);\r\n  dht.humidity().getEvent(&event);\r\n  if (isnan(event.relative_humidity)) {\r\n    Serial.println(F("Error reading humidity!"));\r\n  } else {\r\n    humidity = event.relative_humidity;\r\n  }\r\n  Number1.print(temperature);\r\n  Number2.print(humidity);\r\n}\r\nString esp8266post() {\r\n  HTTPClient http;\r\n  String url = "http://jyan.nobiggie.cn/arduino/vs";\r\n  http.begin(wificlient, url);\r\n  http.setTimeout(3000);\r\n  http.addHeader("Content-Type", "application/x-www-form-urlencoded");\r\n  String postData = "vs=abc1124267212";\r\n  int httpResponseCode = http.POST(postData);\r\n  if (httpResponseCode > 0) {\r\n    String response = http.getString();\r\n    if (response != "false") {\r\n      return response;\r\n    }\r\n  }\r\n  return "";\r\n}\r\nvoid update_started() {\r\n}\r\nvoid update_finished() {\r\n}\r\nvoid update_progress(int cur, int total) {\r\n}\r\nvoid update_error(int err) {\r\n}\r\nvoid dataRead(const String& data) {\r\n}', '', 'webserver'),
(8006, 20, 'nodeMCUesp8266发货通用OTA', '#include <ESP8266WiFi.h>\r\n#include <ESP8266HTTPClient.h>\r\n#include <ESP8266httpUpdate.h>\r\nWiFiClient wificlient;\r\nString ssid="TP-LINK_C97D"; //你的wifif名\r\nString wifipwd="19805282968"; //你的wifi密码\r\nvoid setup() {\r\n  Serial.begin(115200);\r\n  delay(500);\r\n  WiFi.begin(ssid.c_str(), wifipwd.c_str());\r\n  delay(500);\r\n  WiFi.mode(WIFI_STA);\r\n  Serial.println("Wifi->connet");\r\n  int ii = 0;\r\n  for (ii; ii < 20; ii++) {\r\n    delay(500);\r\n    Serial.print(" . ");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      Serial.println("Wifi 连接成功");\r\n      break;\r\n    }\r\n  }\r\n  String upUrl = esp8266post();\r\n  if (upUrl.length() > 10) {\r\n    upUrl.trim(); \r\n    while (1) {\r\n      ESPhttpUpdate.onStart(update_started);\r\n      ESPhttpUpdate.onEnd(update_finished);\r\n      ESPhttpUpdate.onProgress(update_progress);\r\n      ESPhttpUpdate.onError(update_error);\r\n      ESPhttpUpdate.update(wificlient, upUrl);\r\n\r\n    }\r\n    ESP.restart();\r\n  }\r\n}\r\n\r\nvoid loop() {\r\n  // put your main code here, to run repeatedly:\r\n}\r\nvoid update_started() {\r\n  Serial.println("CALLBACK:  HTTP update process started");\r\n}\r\n\r\nvoid update_finished() {\r\n  Serial.println("CALLBACK:  HTTP update process finished");\r\n}\r\nString esp8266post() {\r\n  HTTPClient http;\r\n  String url = "http://jyan.nobiggie.cn/query/vs";\r\n  http.begin(wificlient, url);\r\n  http.setTimeout(3000);\r\n  http.addHeader("Content-Type", "application/x-www-form-urlencoded");\r\n  String postData = "vs=abc1124267212";\r\n  int httpResponseCode = http.POST(postData);\r\n  if (httpResponseCode > 0) {\r\n    String response = http.getString();\r\n    if (response != "false") {\r\n      return response;\r\n    }\r\n  }\r\n  return "";\r\n}\r\nvoid update_progress(int cur, int total) {\r\n  Serial.printf("CALLBACK:  HTTP update process at %d of %d bytes...\\n", cur, total);\r\n}\r\n\r\nvoid update_error(int err) {\r\n  Serial.printf("CALLBACK:  HTTP update fatal error code %d\\n", err);\r\n}', '', 'webserver'),
(8007, 20, 'esp32点灯科技自动手动温控加热加水断电记忆1', '#define BLINKER_WIFI\r\n#include <OneWire.h>\r\n#include <DallasTemperature.h>\r\n#include <ESP32httpUpdate.h>\r\n#include <FS.h>\r\n#include <SPIFFS.h>\r\n#include <ESPmDNS.h>\r\n#include <Ticker.h>\r\n#include <WebServer.h>\r\n#include <WiFi.h>\r\n#include <Blinker.h>\r\n#include <HTTPClient.h>\r\n#include <SPI.h>\r\n#include <TFT_eSPI.h>\r\n#include "ESPmDNS.h"\r\n#include <Ticker.h>\r\n#include <Thread.h>\r\n#include <WebServer.h>\r\n#include <Arduino.h>\r\n\r\nWiFiClient wificlient;\r\nThread myThread = Thread();\r\nTFT_eSPI tft = TFT_eSPI();\r\nString flash_file = "/false.txt";  //被读取的文件位置和名称\r\nString flash_bl = "/bl.txt";\r\nbool flash_bool = false;\r\nchar auth[] = "b07664fc1910";\r\nString ssid;\r\nString passwd;\r\nString html;\r\nbool heating = false;  //加热状态  true 正在加热  false 加热关闭\r\nbool water = false;    //加水状态  true 正在加水  false 加水关闭\r\nfloat waterT = 0.01;   //预设定水温\r\n//SDA 15\r\n//SCL 14\r\n//CS  5\r\n//DC  27\r\n//RST 33\r\n//BL  22\r\n// 定义数据线引脚 p17\r\n#define ONE_WIRE_BUS 17\r\n#define P22 16  //加热开关\r\n\r\n#define P21 21  //上水开关\r\n\r\n#define touch4 4  //设置WIFI\r\n#define m4 25\r\n\r\n// 初始化 OneWire 总线对象\r\nOneWire oneWire(ONE_WIRE_BUS);\r\n\r\n// 初始化 DallasTemperature 对象\r\nDallasTemperature sensors(&oneWire);\r\n\r\nBlinkerNumber Number3("num-yev");  //水位\r\n\r\nBlinkerNumber Number1("num-8sr");  //水温\r\nBlinkerButton Button1("btn-x2p");  //刷新水温\r\n\r\nBlinkerNumber Number2("num-yc4");  //预热水温\r\nBlinkerButton Button2("btn-s73");  //刷新预热水温\r\n\r\nBlinkerButton Button3("btn-8ft");  //手动加热开关\r\nBlinkerButton Button4("btn-bx8");  //上水开关\r\n\r\nBlinkerButton Button5("btn-4dx");  //刷新手动开关状态\r\nBlinkerButton Button6("btn-ems");  //刷新上水开关状态\r\n\r\nBlinkerText Text1("tex-qyx");  //显示加热开关或上水 状态\r\n\r\nTicker myTicker;\r\nString flashWifi = "/wifi.txt";  //wifi密码存放文件\r\nWebServer webServer;\r\nint touchJu = 0;\r\nint touchJr = 2;\r\n#define baudRate 115200\r\nvoid niceCallback() {\r\n  String HI = esp32getHI();\r\n  Serial.println(HI);\r\n  tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n  tft.setCursor(10, 10, 2);  //设置起始坐标(10, 10)，1 号字体\r\n  tft.println(HI);           //显示文字\r\n  millis();\r\n}\r\nvoid setup(void) {\r\n  pinMode(P22, OUTPUT);\r\n  pinMode(P21, OUTPUT);\r\n  //水位探测\r\n  pinMode(m4, INPUT_PULLUP);\r\n\r\n  pinMode(touchJr, INPUT_PULLUP);\r\n  pinMode(touchJu, INPUT_PULLUP);\r\n  digitalWrite(P22, LOW);\r\n  digitalWrite(P21, LOW);\r\n  myThread.onRun(niceCallback);\r\n  myThread.setInterval(10000);\r\n  Serial.begin(baudRate);\r\n  delay(200);\r\n  SPIFFS.begin();\r\n  delay(200);\r\n  if (FlashConnetWifi() == false) {\r\n    HtmlSetWifi();\r\n  }\r\n  WiFi.disconnect();\r\n  delay(300);\r\n  Blinker.begin(auth, ssid.c_str(), passwd.c_str());\r\n  Button1.attach(button1_callback);  //刷新水温\r\n  Button2.attach(button2_callback);  //刷新预热水温\r\n  Button3.attach(button3_callback);  //手动加热开关\r\n  Button4.attach(button4_callback);  //上水开关\r\n  Button5.attach(button5_callback);  //刷新手动开关状态\r\n  Button6.attach(button6_callback);  //刷新上水开关状态\r\n  Blinker.attachData(dataRead);\r\n\r\n  SPIFFS.begin();\r\n  if (SPIFFS.exists(flash_file) == false) {\r\n    File dataFile = SPIFFS.open(flash_file, "w");\r\n    dataFile.println("27.00");\r\n    waterT = 27.00;\r\n    dataFile.close();\r\n  } else {\r\n    SPIFFS.begin();\r\n    File dataFile = SPIFFS.open(flash_file, "r");\r\n    String result = dataFile.readString();\r\n    result.trim();\r\n    waterT = result.toFloat();\r\n  }\r\n\r\n  if (SPIFFS.exists(flash_bl) == false) {\r\n    File dataFile = SPIFFS.open(flash_bl, "w");\r\n    dataFile.println("false");\r\n    dataFile.close();\r\n  } else {\r\n    SPIFFS.begin();\r\n    File dataFile = SPIFFS.open(flash_bl, "r");\r\n    String result = dataFile.readString();\r\n    result.trim();\r\n    if (result == "true") {\r\n      digitalWrite(P22, HIGH);\r\n      heating = true;\r\n      flash_bool = true;\r\n    }\r\n  }\r\n  tft.init();\r\n  tft.fillScreen(TFT_BLACK);  //屏幕颜色\r\n  tft.setCursor(10, 60, 2);\r\n  tft.println("  x % ");\r\n  String re = sendPostRequest();\r\n  if (re.length() > 10) {\r\n    re.trim();\r\n    t_httpUpdate_return ret = ESPhttpUpdate.update(re);\r\n  }\r\n  // 初始化DS18B20传感器\r\n  sensors.begin();\r\n}\r\n\r\nvoid loop(void) {\r\n  Blinker.run();\r\n  // 获取温度数据\r\n  sensors.requestTemperatures();\r\n  // 读取温度\r\n  float temperature = sensors.getTempCByIndex(0);\r\n  tft.setCursor(10, 40, 2);\r\n\r\n  tft.println(String(temperature) + " ° C");\r\n  if (temperature >= waterT) {\r\n    digitalWrite(P22, LOW);\r\n    heating = false;\r\n    if (flash_bool == false) {\r\n      SPIFFS.begin();\r\n      File dataFile = SPIFFS.open(flash_bl, "w");\r\n      dataFile.println("false");\r\n      dataFile.close();\r\n      flash_bool = true;\r\n    }\r\n\r\n    Serial.println("达到设定温度 关闭加热");\r\n  }\r\n  //delay(1000);\r\n  if (digitalRead(m4) == LOW) {\r\n    Serial.println("100");\r\n    Number3.print(100);\r\n    tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n    tft.setCursor(10, 60, 2);\r\n    tft.println("100 % ");\r\n    if (water == true) {\r\n      water = false;\r\n      digitalWrite(P21, LOW);\r\n      tft.setCursor(10, 80, 2);\r\n      tft.println("water off");\r\n      Text1.print("加水已经关闭");\r\n      Button4.color("#000000");\r\n      Button4.text("加水已关");\r\n      Button4.print();\r\n    }\r\n  } else {\r\n    if (water == false) {\r\n      Number3.print(10);\r\n      tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n      tft.setCursor(10, 60, 2);\r\n      tft.println("  x % ");\r\n    }\r\n  }\r\n  if (myThread.shouldRun()) {\r\n    myThread.run();\r\n  }\r\n\r\n  if (digitalRead(touchJu) == LOW) {\r\n    if (water == false) {\r\n      water = true;\r\n      digitalWrite(P21, HIGH);\r\n      Text1.print("正在加水...");\r\n      Button4.color("#00FF00");\r\n      Button4.text("正在加水");\r\n      tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n      tft.setCursor(10, 80, 2);\r\n      tft.println("water on ");\r\n    } else {\r\n      water = false;\r\n      digitalWrite(P21, LOW);\r\n      Text1.print("加水已经关闭");\r\n      Button4.color("#000000");\r\n      Button4.text("加水 关");\r\n      tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n      tft.setCursor(10, 80, 2);\r\n      tft.println("water off");\r\n    }\r\n    Button4.print();\r\n  }\r\n  if (digitalRead(touchJr) == LOW) {\r\n    SPIFFS.begin();\r\n    if (heating == false) {\r\n      heating = true;\r\n      digitalWrite(P22, HIGH);\r\n      if (flash_bool == false) {\r\n        File dataFile = SPIFFS.open(flash_bl, "w");\r\n        dataFile.println("true");\r\n        dataFile.close();\r\n        flash_bool = true;\r\n      }\r\n      Text1.print("正在加热...");\r\n      Button3.color("#00FF00");\r\n      Button3.text("加热开");\r\n      tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n      tft.setCursor(10, 100, 2);\r\n      tft.println("hot on ");\r\n    } else {\r\n      heating = false;\r\n      digitalWrite(P22, LOW);\r\n\r\n      if (flash_bool == true) {\r\n        File dataFile = SPIFFS.open(flash_bl, "w");\r\n        dataFile.println("false");\r\n        dataFile.close();\r\n        flash_bool = false;\r\n      }\r\n      Text1.print("加热已经关闭");\r\n      Button3.color("#000000");\r\n      Button3.text("加热已关");\r\n      tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n      tft.setCursor(10, 100, 2);\r\n      tft.println("hot off");\r\n    }\r\n    Button3.print();\r\n  }\r\n}\r\n//刷新水温\r\nvoid button1_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  sensors.requestTemperatures();\r\n  float temperature = sensors.getTempCByIndex(0);\r\n  Number1.print(temperature);\r\n  Text1.print(temperature);\r\n}\r\n//刷新预热水温\r\nvoid button2_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  SPIFFS.begin();\r\n  File dataFile = SPIFFS.open(flash_file, "r");\r\n  String result = dataFile.readString();\r\n  result.trim();  //清理字符两边的空格\r\n  Number2.print(result.toFloat());\r\n  Serial.print(result);\r\n}\r\n//手动加热开关\r\nvoid button3_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  SPIFFS.begin();\r\n  if (heating == false) {\r\n    heating = true;\r\n    digitalWrite(P22, HIGH);\r\n    if (flash_bool == false) {\r\n      File dataFile = SPIFFS.open(flash_bl, "w");\r\n      dataFile.println("true");\r\n      dataFile.close();\r\n      flash_bool = true;\r\n    }\r\n    tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n    tft.setCursor(10, 100, 2);\r\n    tft.println("hot on ");\r\n    Text1.print("正在加热...");\r\n    Button3.color("#00FF00");\r\n    Button3.text("加热开");\r\n  } else {\r\n    heating = false;\r\n    digitalWrite(P22, LOW);\r\n\r\n    if (flash_bool == true) {\r\n      File dataFile = SPIFFS.open(flash_bl, "w");\r\n      dataFile.println("false");\r\n      dataFile.close();\r\n      flash_bool = false;\r\n    }\r\n    tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n    tft.setCursor(10, 100, 2);\r\n    tft.println("hot off");\r\n    Text1.print("加热已经关闭");\r\n    Button3.color("#000000");\r\n    Button3.text("加热已关");\r\n  }\r\n  Button3.print();\r\n}\r\n//上水开关\r\nvoid button4_callback(const String& state) {\r\n  // BLINKER_LOG("get button state: ", state);\r\n  if (water == false) {\r\n    water = true;\r\n    digitalWrite(P21, HIGH);\r\n    Text1.print("正在加水...");\r\n    tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n    tft.setCursor(10, 80, 2);\r\n    tft.println("water on ");\r\n    Button4.color("#00FF00");\r\n    Button4.text("正在加水");\r\n  } else {\r\n    water = false;\r\n    digitalWrite(P21, LOW);\r\n    Text1.print("加水已经关闭");\r\n    tft.setTextColor(TFT_WHITE, TFT_BLACK);\r\n    tft.setCursor(10, 80, 2);\r\n    tft.println("water off");\r\n    Button4.color("#000000");\r\n    Button4.text("加水 关");\r\n  }\r\n  Button4.print();\r\n}\r\n//刷新手动加热开关状态\r\nvoid button5_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  if (heating == true) {\r\n    Text1.print("正在加热...");\r\n    Button3.color("#00FF00");\r\n    Button3.text("加热 开");\r\n  } else {\r\n    Button3.color("#000000");\r\n    Button3.text("加热 关");\r\n    Text1.print("加热已经关闭");\r\n  }\r\n  Button3.print();\r\n}\r\n//刷新上水开关状态\r\nvoid button6_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  if (water == true) {\r\n    Button4.color("#00FF00");\r\n    Button4.text("开");\r\n    Text1.print("正在加水...");\r\n  } else {\r\n    Button4.color("#000000");\r\n    Button4.text("加水 关");\r\n    Text1.print("加水已经关闭");\r\n  }\r\n  Button4.print();\r\n}\r\n\r\n// 如果未绑定的组件被触发，则会执行其中内容\r\nvoid dataRead(const String& data) {\r\n  BLINKER_LOG("Blinker readString: ", data);\r\n  float tmp = data.toFloat();\r\n\r\n  if (tmp == 0) {\r\n    Text1.print("失败,只能数字");\r\n  } else {\r\n    File dataFile = SPIFFS.open(flash_file, "w");\r\n    dataFile.println(data);\r\n    waterT = tmp;\r\n    dataFile.close();\r\n    Text1.print("预制温度 " + data);\r\n  }\r\n}\r\n\r\nvoid espReboot() {\r\n  ESP.restart();\r\n}\r\n\r\n\r\n\r\nString sendPostRequest() {\r\n  HTTPClient http;\r\n  String url = "http://jyan.nobiggie.cn/arduino/vs";\r\n  http.begin(wificlient, url);\r\n  http.setTimeout(3000);\r\n  String postStr = "vs=a13544957057";\r\n  char dataBuff[postStr.length()];\r\n  strcpy(dataBuff, postStr.c_str());\r\n  http.addHeader("Content-Type", "application/x-www-form-urlencoded");\r\n  int httpResponseCode = http.POST(dataBuff);\r\n  if (httpResponseCode > 0) {\r\n    String response = http.getString();\r\n    return response;\r\n  }\r\n  return "";\r\n}\r\n\r\nString esp32getHI() {\r\n  HTTPClient http;\r\n  String response;\r\n  String urlstr = "http://jyan.nobiggie.cn/arduino/hi";\r\n  http.begin(wificlient, urlstr);\r\n  http.setTimeout(3000);\r\n  int httpCode = http.GET();\r\n  // httpCode will be negative on error\r\n  if (httpCode == 200) {\r\n    response = http.getString();\r\n    return response;\r\n  } else {\r\n    return "";\r\n  }\r\n  http.end();\r\n}\r\n\r\n\r\nvoid HtmlSetWifi() {\r\n  WifiScan();\r\n  apStart();\r\n  delay(1000);\r\n  Serial.println("start webserver");\r\n  //5分后重启 防止停电后复电，路由器连接WIFI速度慢于ESP导致ESP连接不到路由器进入无限AP模式，所以这里只让AP激活5分钟后就重启\r\n  myTicker.once(300, espReboot);\r\n  delay(200);\r\n  webserverStart();\r\n  while (1) {\r\n    webServer.handleClient();  //检查网络服务请求并处理\r\n  }\r\n}\r\nvoid WifiScan() {\r\n  WiFi.disconnect();\r\n  Serial.begin(baudRate);\r\n  WiFi.mode(WIFI_STA);\r\n  delay(100);\r\n  int n = WiFi.scanNetworks();\r\n  if (n > 0) {\r\n    String a = "附近WiFi <select id=\\"ssid\\">";\r\n    for (int i = 0; i < n; i++) {\r\n      Serial.println(WiFi.SSID(i));\r\n      a = a + "<option value=\\"" + WiFi.SSID(i) + "\\">" + WiFi.SSID(i) + "</option>";\r\n      delay(50);\r\n    }\r\n    String HtmlStart = String("") + "<!DOCTYPE html>" + "<html>" + "<head>" + "<meta charset=\\"utf-8\\">" + "<meta name=\\"viewport\\" content=\\"width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\\" />" + "<title>设置WiFi</title>" + "<link rel=\\"stylesheet\\" href=\\"\\">" + "</head>" + "<script>" + "onload  = function() {" + "document.getElementById(\\"up\\").onclick = function(){" + "var ssida=document.getElementById(\\"ssid\\").value;" + "var ssid=ssida.replace(/\\\\s+/g, \\" \\");" + "var passwda=document.getElementsByTagName(''input'')[0].value;" + "var passwd=passwda.replace(/\\\\s+/g, \\" \\");" + "xhr = new XMLHttpRequest();" + "xhr.open(\\"POST\\",\\"./setWifi\\",true);" + "var posts = (\\"ssid=\\"+ssid+\\"&passwd=\\"+ passwd);" + "xhr.setRequestHeader(\\"Content-Type\\",\\"application/x-www-form-urlencoded\\");" + "xhr.send(posts);" + "xhr.onreadystatechange = function(){" + "if(this.readyState == 4 && this.status == 200){" + "alert(this.responseText);" + "}" + "}" + "}" + "}" + "</script>" + "<body>";\r\n    String HtmlEnd = String("") + "<p>WiFi密码<input type=\\"text\\" id=\\"passwd\\"></p>" + "<input type=\\"submit\\" id=\\"up\\" value=\\"设 置\\">" + "<hr/>" + "<div>如果附近WiFi没有显示到自己的WIFI<div>" + "<div>请重启或离信号近点</div>" + "<div>连接成功AP热点退出转WIFI_STA</div>" + "</body>" + "</html>";\r\n    a = a + "</select>";\r\n    html = HtmlStart + a + HtmlEnd;\r\n  } else {\r\n    html = "扫描不到网络";\r\n  }\r\n}\r\nvoid setWifi() {\r\n  ssid = webServer.arg(0);\r\n  passwd = webServer.arg(1);\r\n  const char* Ssid = ssid.c_str();\r\n  const char* Passwd = passwd.c_str();\r\n  String sp = ssid + "&" + passwd;\r\n  Serial.println(sp);\r\n  Serial.begin(baudRate);\r\n  delay(500);\r\n  WiFi.begin(Ssid, Passwd);\r\n  WiFi.mode(WIFI_STA);\r\n  delay(200);\r\n  Serial.println("wifi_connet");\r\n  int ii = 0;\r\n  for (ii; ii < 20; ii++) {\r\n    delay(500);\r\n    Serial.print(".");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      webServer.send(200, "text/plane", "Wifi密码正确,ESP准备重启");\r\n      webServer.close();\r\n      delay(500);\r\n      WiFi.disconnect();\r\n      delay(500);\r\n      //写入数据\r\n      SPIFFS.format();\r\n      delay(500);\r\n      SPIFFS.begin();\r\n      File dataFile = SPIFFS.open(flashWifi, "w");\r\n      dataFile.println(sp);\r\n      dataFile.close();\r\n      Serial.println("HTML设置网络连接成功");\r\n      delay(500);\r\n      ESP.restart();\r\n    }\r\n  }\r\n  webServer.send(200, "text/plane", "Wifi密码错误,请重新输入");\r\n}\r\n//------- 展示页面-------\r\nvoid handleRoot() {\r\n  webServer.send(500, "text/html", html);\r\n}\r\nvoid handleNotFound(void) {\r\n  webServer.send(404, "text/plain", "404-The page is not Found!");\r\n}\r\nvoid apStart() {\r\n  Serial.begin(baudRate);\r\n  WiFi.mode(WIFI_AP);\r\n  IPAddress local_IP(192, 168, 168, 2);\r\n  IPAddress gateway(192, 168, 168, 1);\r\n  IPAddress subnet(255, 255, 255, 0);\r\n  WiFi.softAPConfig(local_IP, gateway, subnet);\r\n  //启动AP模式，并设置账号和密码\r\n  boolean result = WiFi.softAP("192.168.168.2", "nobiggie.cn");\r\n  if (result) {\r\n    Serial.println(String("Soft-AP IP address = ") + WiFi.softAPIP());\r\n  }\r\n}\r\nvoid webserverStart() {\r\n  webServer.begin(80);            // 启用网络服务\r\n  webServer.on("/", handleRoot);  // / 在HTTP中，表示请求首页服务，\r\n  webServer.on("/setWifi", setWifi);\r\n  webServer.onNotFound(handleNotFound);  // 当服务器没找到所需的服务，调用404函数\r\n  Serial.println("webserver started");\r\n}\r\nbool FlashConnetWifi() {\r\n  Serial.begin(baudRate);\r\n  delay(200);\r\n  SPIFFS.begin();\r\n  if (SPIFFS.exists(flashWifi) == false) {\r\n    Serial.println("NOT FOUND");\r\n    return false;\r\n  }\r\n\r\n  File dateFile = SPIFFS.open(flashWifi, "r");\r\n  String result;\r\n  for (int i = 0; i < dateFile.size(); i++) {\r\n    //Serial.print((char)dateFile.read());\r\n    result += (char)dateFile.read();\r\n  }\r\n  result.trim();\r\n  Serial.println(result);\r\n  int i = result.indexOf("&");\r\n  String wifiname = result.substring(0, i);\r\n  String wifipw = result.substring(i + 1);\r\n  const char* WifiName = wifiname.c_str();\r\n  const char* WifiPw = wifipw.c_str();\r\n  Serial.println(WifiName);\r\n  Serial.println(WifiPw);\r\n  WiFi.begin(WifiName, WifiPw);\r\n  delay(500);\r\n  WiFi.mode(WIFI_STA);\r\n  Serial.println("FlashConnet...");\r\n  int ii = 0;\r\n  for (ii; ii < 30; ii++) {\r\n    delay(500);\r\n    Serial.print(" . ");\r\n    if (WiFi.status() == WL_CONNECTED) {\r\n      Serial.println("flash connet success");\r\n      ssid = String(WifiName);\r\n      passwd = String(WifiPw);\r\n      return true;\r\n    }\r\n  }\r\n  Serial.println("flash read error");\r\n  return false;\r\n}', '', 'webserver'),
(8009, 20, '点灯科技esp32遥控车', '#define BLINKER_WIFI\r\n#include <Arduino.h>\r\n#include <Blinker.h>\r\n#include <Ticker.h>\r\n\r\nchar auth[] = "fef9287848c3";\r\nchar ssid[] = "webserver";\r\nchar pswd[] = "www.360xyz.cn";\r\n\r\n#define D1 32\r\n#define D2 33\r\n#define D3 25\r\n#define D4 26\r\n#define D5 27\r\n#define D6 14\r\n#define D7 12\r\n#define D8 13\r\n#define D9 15\r\n#define D10 2\r\nbool bl1 = false;\r\nbool bl2 = false;\r\nbool bl3 = false;\r\nbool bl4 = false;\r\nbool bl5 = false;\r\nbool bl6 = false;\r\nbool bl7 = false;\r\nbool bl8 = false;\r\nbool bl9 = false;\r\nbool bl10 = false;\r\n\r\nBlinkerButton Button1("btn-ho0");\r\nBlinkerButton Button2("btn-3xq");\r\nBlinkerButton Button3("btn-qsi");\r\nBlinkerButton Button4("btn-qg3");\r\nBlinkerButton Button5("btn-88b");\r\nBlinkerButton Button6("btn-gjj");\r\nBlinkerButton Button7("btn-fpd");\r\nBlinkerButton Button8("btn-hca");\r\nBlinkerButton Button9("btn-n33");\r\nBlinkerButton Button10("btn-5lk");\r\nvoid setup() {\r\n  pinMode(D1, OUTPUT);\r\n  pinMode(D2, OUTPUT);\r\n  pinMode(D3, OUTPUT);\r\n  pinMode(D4, OUTPUT);\r\n  pinMode(D5, OUTPUT);\r\n  pinMode(D6, OUTPUT);\r\n  pinMode(D7, OUTPUT);\r\n  pinMode(D8, OUTPUT);\r\n  pinMode(D9, OUTPUT);\r\n  pinMode(D10, OUTPUT);\r\n  digitalWrite(D1, LOW);\r\n  digitalWrite(D2, LOW);\r\n  digitalWrite(D3, LOW);\r\n  digitalWrite(D4, LOW);\r\n  digitalWrite(D5, LOW);\r\n  digitalWrite(D6, LOW);\r\n  digitalWrite(D7, LOW);\r\n  digitalWrite(D8, LOW);\r\n  digitalWrite(D9, LOW);\r\n  digitalWrite(D10, LOW);\r\n  Serial.begin(115200);\r\n  Blinker.begin(auth, ssid, pswd);\r\n  Button1.attach(button1_callback);\r\n  Button2.attach(button2_callback);\r\n  Button3.attach(button3_callback);\r\n  Button4.attach(button4_callback);\r\n  Button5.attach(button5_callback);\r\n  Button6.attach(button6_callback);\r\n  Button7.attach(button7_callback);\r\n  Button8.attach(button8_callback);\r\n  Button9.attach(button9_callback);\r\n  Button10.attach(button10_callback);\r\n  Blinker.attachData(dataRead);\r\n}\r\n\r\nvoid loop() {\r\n  Blinker.run();\r\n\r\n  if (bl1 == true && bl10 == true) {\r\n    digitalWrite(D1, HIGH);\r\n    digitalWrite(D10, HIGH);\r\n    delay(1000);\r\n    digitalWrite(D1, LOW);\r\n    digitalWrite(D10, LOW);\r\n  } else if (bl2 == true && bl10 == true) {\r\n    digitalWrite(D2, HIGH);\r\n    digitalWrite(D10, HIGH);\r\n    delay(1000);\r\n    digitalWrite(D2, LOW);\r\n    digitalWrite(D10, LOW);\r\n  } else {\r\n    if (bl1 == true) {\r\n      digitalWrite(D1, HIGH);\r\n      delay(1000);\r\n      digitalWrite(D1, LOW);\r\n    }\r\n    if (bl2 == true) {\r\n      digitalWrite(D2, HIGH);\r\n      delay(1000);\r\n      digitalWrite(D2, LOW);\r\n    }\r\n    if (bl10 == true) {\r\n      digitalWrite(D10, HIGH);\r\n      delay(1000);\r\n      digitalWrite(D10, LOW);\r\n    }\r\n  }\r\n}\r\nvoid button1_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n  if (bl1 == false) {\r\n    bl1 = true;\r\n    bl2=false;\r\n    digitalWrite(D2, LOW);\r\n    Button2.color("#000000");\r\n    Button2.text("已停");\r\n    Button2.print();\r\n    Button1.color("#00FF00");\r\n    Button1.text("左转");\r\n  } else {\r\n    bl1 = false;\r\n    Button1.color("#000000");\r\n    Button1.text("已停");\r\n  }\r\n  Button1.print();\r\n}\r\nvoid button2_callback(const String& state) {\r\n  if (bl2 == false) {\r\n    bl2 = true;\r\n    bl1=false;\r\n    Button1.color("#000000");\r\n    Button1.text("已停");\r\n    Button1.print();\r\n    digitalWrite(D1, LOW);\r\n    Button2.color("#00FF00");\r\n    Button2.text("右转");\r\n  } else {\r\n    bl2 = false;\r\n    Button2.color("#000000");\r\n    Button2.text("已停");\r\n  }\r\n  Button2.print();\r\n}\r\n\r\nvoid button3_callback(const String& state) {\r\n  if (bl3 == false) {\r\n    bl3 = true;\r\n    digitalWrite(D3, HIGH);\r\n    Button3.color("#00FF00");\r\n    Button3.text("已开");\r\n  } else {\r\n    bl3 = false;\r\n    digitalWrite(D3, LOW);\r\n    Button3.color("#000000");\r\n    Button3.text("已关");\r\n  }\r\n  Button3.print();\r\n}\r\nvoid button4_callback(const String& state) {\r\n  if (bl4 == false) {\r\n    bl4 = true;\r\n    digitalWrite(D4, HIGH);\r\n    Button4.color("#00FF00");\r\n    Button4.text("已开");\r\n  } else {\r\n    bl4 = false;\r\n    digitalWrite(D4, LOW);\r\n    Button4.color("#000000");\r\n    Button4.text("已关");\r\n  }\r\n  Button4.print();\r\n}\r\nvoid button5_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n}\r\nvoid button6_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n}\r\nvoid button7_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n}\r\nvoid button8_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n}\r\nvoid button9_callback(const String& state) {\r\n  //BLINKER_LOG("get button state: ", state);\r\n}\r\nvoid button10_callback(const String& state) {\r\n  if (bl10 == false) {\r\n    bl10 = true;\r\n    Button10.color("#00FF00");\r\n    Button10.text("闪烁中");\r\n  } else {\r\n    bl10 = false;\r\n    Button10.color("#000000");\r\n    Button10.text("已关");\r\n  }\r\n  Button10.print();\r\n}\r\nvoid dataRead(const String& data) {\r\n  BLINKER_LOG("Blinker readString: ", data);\r\n}\r\n', '', 'webserver'),
(8010, 20, 'esp300', '#include <Arduino.h>\r\n#include <WiFi.h>\r\n#include <WiFiMulti.h>\r\n#include <WiFiClientSecure.h>\r\n#include <ArduinoJson.h>\r\n#include <WebSocketsClient.h>\r\n\r\nDynamicJsonDocument jsonBuffer(100);\r\nJsonObject jsonStr;\r\nWiFiMulti WiFiMulti;\r\nWebSocketsClient webSocket;\r\nchar ssid[] = "webserver";\r\nchar pswd[] = "www.360xyz.cn";\r\n#define D1 32\r\n#define D2 33\r\n#define D3 25\r\n#define D4 26\r\n#define D5 27\r\n#define D6 14\r\n#define D7 12\r\n#define D8 13\r\n#define D9 15\r\n#define D10 2\r\nbool bl1 = false;\r\nbool bl2 = false;\r\nbool bl3 = false;\r\nbool bl4 = false;\r\nbool bl5 = false;\r\nbool bl6 = false;\r\nbool bl7 = false;\r\nbool bl8 = false;\r\nbool bl9 = false;\r\nbool bl10 = false;\r\nvoid hexdump(const void* mem, uint32_t len, uint8_t cols = 16) {\r\n  const uint8_t* src = (const uint8_t*)mem;\r\n  Serial.printf("\\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);\r\n  for (uint32_t i = 0; i < len; i++) {\r\n    if (i % cols == 0) {\r\n      Serial.printf("\\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);\r\n    }\r\n    Serial.printf("%02X ", *src);\r\n    src++;\r\n  }\r\n  Serial.printf("\\n");\r\n}\r\n\r\nvoid webSocketEvent(WStype_t type, uint8_t* payload, size_t length) {\r\n\r\n  switch (type) {\r\n    case WStype_DISCONNECTED:\r\n      Serial.printf("[WSc] Disconnected!\\n");\r\n      break;\r\n    case WStype_CONNECTED:\r\n      Serial.printf("[WSc] Connected to url: %s\\n", payload);\r\n\r\n      // send message to server when Connected\r\n      webSocket.sendTXT("Connected");\r\n      break;\r\n    case WStype_TEXT:\r\n      Serial.printf("[WSc] get text: %s\\n", payload);\r\n\r\n      deserializeJson(jsonBuffer, payload);\r\n      jsonStr = jsonBuffer.as<JsonObject>();\r\n      if (jsonStr["message"] != "") {\r\n        if (jsonStr["message"] == "nodeMCUesp32.↑") {\r\n        }\r\n        if (jsonStr["message"] == "nodeMCUesp32.←") {\r\n          if (bl1 == false) {\r\n            bl1 = true;\r\n            bl2 = false;\r\n            //digitalWrite(D2, LOW);\r\n            //webSocket.sendTXT("已停");\r\n            webSocket.sendTXT("左转");\r\n          } else {\r\n            bl1 = false;\r\n            //webSocket.sendTXT("已停");\r\n          }\r\n        }\r\n        if (jsonStr["message"] == "nodeMCUesp32.→") {\r\n          if (bl2 == false) {\r\n            bl2 = true;\r\n            bl1 = false;\r\n           // digitalWrite(D1, LOW);\r\n            webSocket.sendTXT("右转");\r\n          } else {\r\n            bl2 = false;\r\n            //webSocket.sendTXT("已停");\r\n          }\r\n        }\r\n        if (jsonStr["message"] == "nodeMCUesp32.■") {\r\n          if (bl3 == false) {\r\n            bl3 = true;\r\n            digitalWrite(D3, HIGH);\r\n            webSocket.sendTXT("3已开");\r\n          } else {\r\n            bl3 = false;\r\n            digitalWrite(D3, LOW);\r\n            webSocket.sendTXT("3已关");\r\n          }\r\n        }\r\n        if (jsonStr["message"] == "nodeMCUesp32.音频") {\r\n          if (bl4 == false) {\r\n            bl4 = true;\r\n            digitalWrite(D4, HIGH);\r\n            webSocket.sendTXT("4已开");\r\n          } else {\r\n            bl4 = false;\r\n            digitalWrite(D4, LOW);\r\n          }\r\n        }\r\n        if (jsonStr["message"] == "nodeMCUesp32.喇叭") {\r\n          if (bl10 == false) {\r\n            bl10 = true;\r\n            webSocket.sendTXT("10闪烁中");\r\n          } else {\r\n            bl10 = false;\r\n          }\r\n        }\r\n      }\r\n      // send message to server\r\n      // webSocket.sendTXT("message here");\r\n      break;\r\n    case WStype_BIN:\r\n      Serial.printf("[WSc] get binary length: %u\\n", length);\r\n      hexdump(payload, length);\r\n\r\n      // send data to server\r\n      // webSocket.sendBIN(payload, length);\r\n      break;\r\n    case WStype_ERROR:\r\n    case WStype_FRAGMENT_TEXT_START:\r\n    case WStype_FRAGMENT_BIN_START:\r\n    case WStype_FRAGMENT:\r\n    case WStype_FRAGMENT_FIN:\r\n      break;\r\n  }\r\n}\r\n\r\nvoid setup() {\r\n  pinMode(D1, OUTPUT);\r\n  pinMode(D2, OUTPUT);\r\n  pinMode(D3, OUTPUT);\r\n  pinMode(D4, OUTPUT);\r\n  pinMode(D5, OUTPUT);\r\n  pinMode(D6, OUTPUT);\r\n  pinMode(D7, OUTPUT);\r\n  pinMode(D8, OUTPUT);\r\n  pinMode(D9, OUTPUT);\r\n  pinMode(D10, OUTPUT);\r\n  digitalWrite(D1, LOW);\r\n  digitalWrite(D2, LOW);\r\n  digitalWrite(D3, LOW);\r\n  digitalWrite(D4, LOW);\r\n  digitalWrite(D5, LOW);\r\n  digitalWrite(D6, LOW);\r\n  digitalWrite(D7, LOW);\r\n  digitalWrite(D8, LOW);\r\n  digitalWrite(D9, LOW);\r\n  digitalWrite(D10, LOW);\r\n  Serial.begin(115200);\r\n\r\n  //Serial.setDebugOutput(true);\r\n  for (uint8_t t = 2; t > 0; t--) {\r\n    Serial.printf("[SETUP] BOOT WAIT %d...\\n", t);\r\n    Serial.flush();\r\n    delay(1000);\r\n  }\r\n\r\n  WiFiMulti.addAP(ssid, pswd);\r\n\r\n  //WiFi.disconnect();\r\n  while (WiFiMulti.run() != WL_CONNECTED) {\r\n    delay(100);\r\n  }\r\n  Serial.println("连网成功");\r\n  // server address, port and URL 114.132.96.86\r\n  webSocket.begin("192.168.0.250", 80, "/ws/ws-login");\r\n  webSocket.setAuthorization("user=nodeMCUesp32&passwd=abcdefg&room=esp");\r\n  // event handler\r\n  webSocket.onEvent(webSocketEvent);\r\n  // try ever 5000 again if connection has failed\r\n  webSocket.setReconnectInterval(5000);\r\n}\r\n\r\nvoid loop() {\r\n  webSocket.loop();\r\n\r\n  if (bl1 == true && bl10 == true) {\r\n    digitalWrite(D2, LOW);\r\n    digitalWrite(D1, HIGH);\r\n    digitalWrite(D10, HIGH);\r\n    delay(1000);\r\n    digitalWrite(D1, LOW);\r\n    digitalWrite(D10, LOW);\r\n  } else if (bl2 == true && bl10 == true) {\r\n    digitalWrite(D1, LOW);\r\n    digitalWrite(D2, HIGH);\r\n    digitalWrite(D10, HIGH);\r\n    delay(1000);\r\n    digitalWrite(D2, LOW);\r\n    digitalWrite(D10, LOW);\r\n  } else {\r\n    if (bl1 == true) {\r\n      digitalWrite(D2, LOW);\r\n      digitalWrite(D1, HIGH);\r\n      delay(1000);\r\n      digitalWrite(D1, LOW);\r\n    }\r\n    if (bl2 == true) {\r\n      digitalWrite(D1, LOW);\r\n      digitalWrite(D2, HIGH);\r\n      delay(1000);\r\n      digitalWrite(D2, LOW);\r\n    }\r\n    if (bl10 == true) {\r\n      digitalWrite(D10, HIGH);\r\n      delay(1000);\r\n      digitalWrite(D10, LOW);\r\n    }\r\n  }\r\n}\r\n', '', 'webserver'),
(8011, 20, 'esp3001', '#include <Arduino.h>\r\n#include <WiFi.h>\r\n#include <WiFiMulti.h>\r\n#include <WiFiClientSecure.h>\r\n#include <ArduinoJson.h>\r\n#include <WebSocketsClient.h>\r\n\r\nchar ssid[] = "你的WIFI名"; \r\nchar pswd[] = "wifi密码";\r\n\r\n\r\nDynamicJsonDocument jsonBuffer(100);\r\nJsonObject jsonStr;\r\nWiFiMulti WiFiMulti;\r\nWebSocketsClient webSocket;\r\n\r\n#define D1 32\r\n#define D2 33\r\n#define D3 25\r\n#define D4 26\r\n#define D5 27\r\n#define D6 14\r\n#define D7 12\r\n#define D8 13\r\n#define D9 15\r\n#define D10 2\r\nbool bl1 = false;\r\nbool bl2 = false;\r\nbool bl3 = false;\r\nbool bl4 = false;\r\nbool bl5 = false;\r\nbool bl6 = false;\r\nbool bl7 = false;\r\nbool bl8 = false;\r\nbool bl9 = false;\r\nbool bl10 = false;\r\nvoid hexdump(const void* mem, uint32_t len, uint8_t cols = 16) {\r\n  const uint8_t* src = (const uint8_t*)mem;\r\n  Serial.printf("\\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);\r\n  for (uint32_t i = 0; i < len; i++) {\r\n    if (i % cols == 0) {\r\n      Serial.printf("\\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);\r\n    }\r\n    Serial.printf("%02X ", *src);\r\n    src++;\r\n  }\r\n  Serial.printf("\\n");\r\n}\r\n\r\nvoid webSocketEvent(WStype_t type, uint8_t* payload, size_t length) {\r\n\r\n  switch (type) {\r\n    case WStype_DISCONNECTED:\r\n      Serial.printf("[WSc] Disconnected!\\n");\r\n      break;\r\n    case WStype_CONNECTED:\r\n      Serial.printf("[WSc] Connected to url: %s\\n", payload);\r\n\r\n      // send message to server when Connected\r\n      webSocket.sendTXT("Connected");\r\n      break;\r\n    case WStype_TEXT:\r\n      Serial.printf("[WSc] get text: %s\\n", payload);\r\n\r\n      deserializeJson(jsonBuffer, payload);\r\n      jsonStr = jsonBuffer.as<JsonObject>();\r\n      if (jsonStr["message"] != "") {\r\n\r\n        if (jsonStr["message"] == "bt01") {\r\n          if (bl1 == false) {\r\n            bl1 = true;\r\n            bl2 = false;\r\n            //digitalWrite(D2, LOW);\r\n            //webSocket.sendTXT("已停");\r\n            webSocket.sendTXT("bt01on");\r\n          } else {\r\n            bl1 = false;\r\n            webSocket.sendTXT("bt01off");\r\n          }\r\n        }\r\n        if (jsonStr["message"] == "bt02") {\r\n          if (bl2 == false) {\r\n            bl2 = true;\r\n            bl1 = false;\r\n            // digitalWrite(D1, LOW);\r\n            webSocket.sendTXT("bt02on");\r\n          } else {\r\n            bl2 = false;\r\n            webSocket.sendTXT("bt02off");\r\n          }\r\n        }\r\n        if (jsonStr["message"] == "bt03") {\r\n          if (bl3 == false) {\r\n            bl3 = true;\r\n            digitalWrite(D3, HIGH);\r\n            webSocket.sendTXT("bt03on");\r\n          } else {\r\n            bl3 = false;\r\n            digitalWrite(D3, LOW);\r\n            webSocket.sendTXT("bt03off");\r\n          }\r\n        }\r\n        if (jsonStr["message"] == "bt04") {\r\n          if (bl4 == false) {\r\n            bl4 = true;\r\n            digitalWrite(D4, HIGH);\r\n            webSocket.sendTXT("bt04on");\r\n          } else {\r\n            bl4 = false;\r\n            digitalWrite(D4, LOW);\r\n            webSocket.sendTXT("bt04off");\r\n          }\r\n        }\r\n        if (jsonStr["message"] == "bt05") {\r\n          if (bl5 == false) {\r\n            bl5 = true;\r\n            digitalWrite(D5, HIGH);\r\n            webSocket.sendTXT("bt05on");\r\n          } else {\r\n            bl4 = false;\r\n            digitalWrite(D4, LOW);\r\n            webSocket.sendTXT("bt05off");\r\n          }\r\n        }\r\n        if (jsonStr["message"] == "bt06") {\r\n          if (bl6 == false) {\r\n            bl6 = true;\r\n            digitalWrite(D6, HIGH);\r\n            webSocket.sendTXT("bt06on");\r\n          } else {\r\n            bl6 = false;\r\n            digitalWrite(D6, LOW);\r\n            webSocket.sendTXT("bt06off");\r\n          }\r\n        }\r\n        if (jsonStr["message"] == "bt07") {\r\n          if (bl7 == false) {\r\n            bl7 = true;\r\n            digitalWrite(D7, HIGH);\r\n            webSocket.sendTXT("bt07on");\r\n          } else {\r\n            bl7 = false;\r\n            digitalWrite(D7, LOW);\r\n            webSocket.sendTXT("bt07off");\r\n          }\r\n        }\r\n        if (jsonStr["message"] == "bt08") {\r\n          if (bl8 == false) {\r\n            bl8 = true;\r\n            digitalWrite(D8, HIGH);\r\n            webSocket.sendTXT("bt08on");\r\n          } else {\r\n            bl4 = false;\r\n            digitalWrite(D8, LOW);\r\n            webSocket.sendTXT("bt08off");\r\n          }\r\n        }\r\n        if (jsonStr["message"] == "bt09") {\r\n          if (bl9 == false) {\r\n            bl9 = true;\r\n            digitalWrite(D9, HIGH);\r\n            webSocket.sendTXT("bt09on");\r\n          } else {\r\n            bl4 = false;\r\n            digitalWrite(D9, LOW);\r\n             webSocket.sendTXT("bt09off");\r\n          }\r\n        }\r\n\r\n        if (jsonStr["message"] == "bt10") {\r\n          if (bl10 == false) {\r\n            bl10 = true;\r\n            webSocket.sendTXT("bt10on");\r\n          } else {\r\n            bl10 = false;\r\n            webSocket.sendTXT("bt10off");\r\n          }\r\n        }\r\n      }\r\n      // send message to server\r\n      // webSocket.sendTXT("message here");\r\n      break;\r\n    case WStype_BIN:\r\n      Serial.printf("[WSc] get binary length: %u\\n", length);\r\n      hexdump(payload, length);\r\n\r\n      // send data to server\r\n      // webSocket.sendBIN(payload, length);\r\n      break;\r\n    case WStype_ERROR:\r\n    case WStype_FRAGMENT_TEXT_START:\r\n    case WStype_FRAGMENT_BIN_START:\r\n    case WStype_FRAGMENT:\r\n    case WStype_FRAGMENT_FIN:\r\n      break;\r\n  }\r\n}\r\n\r\nvoid setup() {\r\n  pinMode(D1, OUTPUT);\r\n  pinMode(D2, OUTPUT);\r\n  pinMode(D3, OUTPUT);\r\n  pinMode(D4, OUTPUT);\r\n  pinMode(D5, OUTPUT);\r\n  pinMode(D6, OUTPUT);\r\n  pinMode(D7, OUTPUT);\r\n  pinMode(D8, OUTPUT);\r\n  pinMode(D9, OUTPUT);\r\n  pinMode(D10, OUTPUT);\r\n  digitalWrite(D1, LOW);\r\n  digitalWrite(D2, LOW);\r\n  digitalWrite(D3, LOW);\r\n  digitalWrite(D4, LOW);\r\n  digitalWrite(D5, LOW);\r\n  digitalWrite(D6, LOW);\r\n  digitalWrite(D7, LOW);\r\n  digitalWrite(D8, LOW);\r\n  digitalWrite(D9, LOW);\r\n  digitalWrite(D10, LOW);\r\n  Serial.begin(115200);\r\n\r\n  //Serial.setDebugOutput(true);\r\n  for (uint8_t t = 2; t > 0; t--) {\r\n    Serial.printf("[SETUP] BOOT WAIT %d...\\n", t);\r\n    Serial.flush();\r\n    delay(1000);\r\n  }\r\n\r\n  WiFiMulti.addAP(ssid, pswd);\r\n\r\n  //WiFi.disconnect();\r\n  while (WiFiMulti.run() != WL_CONNECTED) {\r\n    delay(100);\r\n  }\r\n  Serial.println("连网成功");\r\n  // server address, port and URL 114.132.96.86\r\n  webSocket.begin("114.132.96.86", 80, "/ws/ws-login");\r\n  webSocket.setAuthorization("user=nodeMCUesp32&passwd=abcdefg&room=esp");\r\n  // event handler\r\n  webSocket.onEvent(webSocketEvent);\r\n  // try ever 5000 again if connection has failed\r\n  webSocket.setReconnectInterval(5000);\r\n}\r\n\r\nvoid loop() {\r\n  webSocket.loop();\r\n\r\n  if (bl1 == true && bl10 == true) {\r\n    digitalWrite(D2, LOW);\r\n    digitalWrite(D1, HIGH);\r\n    digitalWrite(D10, HIGH);\r\n    delay(1000);\r\n    digitalWrite(D1, LOW);\r\n    digitalWrite(D10, LOW);\r\n  } else if (bl2 == true && bl10 == true) {\r\n    digitalWrite(D1, LOW);\r\n    digitalWrite(D2, HIGH);\r\n    digitalWrite(D10, HIGH);\r\n    delay(1000);\r\n    digitalWrite(D2, LOW);\r\n    digitalWrite(D10, LOW);\r\n  } else {\r\n    if (bl1 == true) {\r\n      digitalWrite(D2, LOW);\r\n      digitalWrite(D1, HIGH);\r\n      delay(1000);\r\n      digitalWrite(D1, LOW);\r\n    }\r\n    if (bl2 == true) {\r\n      digitalWrite(D1, LOW);\r\n      digitalWrite(D2, HIGH);\r\n      delay(1000);\r\n      digitalWrite(D2, LOW);\r\n    }\r\n    if (bl10 == true) {\r\n      digitalWrite(D10, HIGH);\r\n      delay(1000);\r\n      digitalWrite(D10, LOW);\r\n    }\r\n  }\r\n}\r\n', '', 'webserver');
INSERT INTO `WisdomPreview` (`id`, `tid`, `title`, `content`, `imgtext`, `user`) VALUES
(8012, 20, '割草机吊机模式', '/*\r\n面向车尾   \r\np32  左边电机  左正\r\np33  右边电机  右正\r\np25  左边电机  左反\r\np26  右边电机  右反\r\np27  升   正\r\np14  降   反\r\np12  关发动机  触动3秒后断开\r\nP15  开机通电一直手摸线 可以遥控方向相互转换\r\np4   设置 射频遥控 与 WIFI遥控 切换\r\np21  PWM脚\r\np0   Power8266 输出高电平增加射频遥控 8键射频433遥控\r\n手机要用火狐浏览器\r\n\r\n\r\nP36 前进\r\nP39 后退\r\nP34 左拐弯\r\nP35 右拐弯\r\nP17 移动速度+\r\nP16 移动速度-\r\n*/\r\n#include <WiFi.h>\r\n#include <WebServer.h>\r\n#include <HTTPClient.h>\r\n#include <FS.h>\r\n#include "SPIFFS.h"\r\n#include "ESPmDNS.h"\r\n\r\n#include <Arduino.h>\r\n#include <WiFi.h>\r\n#include <WiFiMulti.h>\r\n#include <WiFiClientSecure.h>\r\n#include <ArduinoJson.h>\r\n#include <WebSocketsClient.h>\r\n\r\nString direction = "/boolStr.txt";\r\nString controlMode="/controlMode.txt";\r\nWebServer webServer(80);  // 创建网络服务器对象，HTTP服务的标准端口为：80\r\nString request = "";\r\n\r\n//方向相互转换\r\nint touch15 = 15;\r\n//射频遥控  感应切换开关\r\nint touch4=4;\r\n//升\r\nint touchUP = 27;\r\n//停\r\nint touchSTOP = 14;\r\n//降\r\nint touchDOWN = 12;\r\nboolean globalBL=false;\r\n\r\n//转换成功指示灯\r\nint light22 = 22;\r\n\r\n//PWM控制\r\nint pwm1 = 21;\r\n//管道esp32有16个管道,0-7为80hz 高速管道  8-16为低速管道\r\nconst int channel1 = 0;\r\n//分辨率  2的8次方 256\r\nconst int resolution = 8;\r\n//PWM频率\r\nconst int freq = 1000;\r\n//初始值 41%\r\nint PwmNow = 137;\r\n//累加数\r\nint fadeAmount = 5;\r\n//接通esp8266电源\r\nint Power8266 = 0;\r\n\r\nWiFiMulti WiFiMulti;\r\nWebSocketsClient webSocket;\r\nDynamicJsonDocument jsonBuffer(100);\r\nJsonObject root;\r\n\r\nvoid hexdump(const void* mem, uint32_t len, uint8_t cols = 16) {\r\n  const uint8_t* src = (const uint8_t*)mem;\r\n  Serial.printf("\\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);\r\n  for (uint32_t i = 0; i < len; i++) {\r\n    if (i % cols == 0) {\r\n      Serial.printf("\\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);\r\n    }\r\n    Serial.printf("%02X ", *src);\r\n    src++;\r\n  }\r\n  Serial.printf("\\n");\r\n}\r\n\r\nString html = String("")+\r\n"<!DOCTYPE html><html lang=\\"en\\">"+\r\n"<head>"+\r\n    "<meta charset=\\"UTF-8\\">"+\r\n    "<meta name=\\"viewport\\" <meta name=\\"viewport\\" content=\\"width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\\" />"+\r\n    "<title>遥控车</title>"+\r\n    "<script>window.onload = function () {"+\r\n            "document.getElementById(\\"xyzUp\\").addEventListener(\\"touchstart\\", function () {"+\r\n                "let xhr = new XMLHttpRequest();"+\r\n                "xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\");"+\r\n                "xhr.send(\\"xyz=↑\\"); xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"xyzLeft\\").addEventListener(\\"touchstart\\", function () {"+\r\n                "let xhr = new XMLHttpRequest(); xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\"); xhr.send(\\"xyz=←\\");"+\r\n                "xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"xyzLeft\\").addEventListener(\\"touchend\\", function () {"+\r\n                "let xhr = new XMLHttpRequest(); xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\"); xhr.send(\\"xyz=■\\");"+\r\n                "xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"xyzStop\\").addEventListener(\\"touchstart\\", function () {"+\r\n                "let xhr = new XMLHttpRequest(); xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\");"+\r\n                "xhr.send(\\"xyz=■\\"); xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"xyzRight\\").addEventListener(\\"touchstart\\", function () {"+\r\n                "let xhr = new XMLHttpRequest(); xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\");"+\r\n                "xhr.send(\\"xyz=→\\"); xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"xyzRight\\").addEventListener(\\"touchend\\", function () {"+\r\n                "let xhr = new XMLHttpRequest();"+\r\n                "xhr.open(\\"POST\\", \\"./xyzgo\\", true); xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\");"+\r\n                "xhr.send(\\"xyz=■\\"); xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"xyzDonw\\").addEventListener(\\"touchstart\\", function () {"+\r\n                "let xhr = new XMLHttpRequest(); xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\");"+\r\n                "xhr.send(\\"xyz=↓\\"); xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"rise\\").addEventListener(\\"touchstart\\", function () {"+\r\n                "let xhr = new XMLHttpRequest();"+\r\n                "xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\");"+\r\n                "xhr.send(\\"xyz=rise\\"); xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"rise\\").addEventListener(\\"touchend\\", function () {"+\r\n                "let xhr = new XMLHttpRequest(); xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\");"+\r\n                "xhr.send(\\"xyz=■\\"); xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"decline\\").addEventListener(\\"touchstart\\", function () {"+\r\n                "let xhr = new XMLHttpRequest(); xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\");"+\r\n                "xhr.send(\\"xyz=decline\\"); xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"decline\\").addEventListener(\\"touchend\\", function () {"+\r\n                "let xhr = new XMLHttpRequest(); xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\"); xhr.send(\\"xyz=■\\");"+\r\n                "xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"TurnOff\\").addEventListener(\\"touchstart\\", function () {"+\r\n                "let xhr = new XMLHttpRequest(); xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\");"+\r\n                "xhr.send(\\"xyz=TurnOff\\");"+\r\n                "xhr.onreadystatechange = function () {"+\r\n                   "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"speedA\\").addEventListener(\\"touchstart\\", function () {"+\r\n                "let xhr = new XMLHttpRequest(); xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\");"+\r\n                "xhr.send(\\"xyz=speedA\\");"+\r\n                "xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n            "document.getElementById(\\"speedB\\").addEventListener(\\"touchstart\\", function () {"+\r\n                "let xhr = new XMLHttpRequest(); xhr.open(\\"POST\\", \\"./xyzgo\\", true);"+\r\n                "xhr.setRequestHeader(\\"Content-Type\\", \\"application/x-www-form-urlencoded\\");"+\r\n                "xhr.send(\\"xyz=speedB\\");"+\r\n                "xhr.onreadystatechange = function () {"+\r\n                    "if (this.readyState == 4 && this.status == 200) {"+\r\n                        "document.getElementById(\\"show\\").innerHTML = this.responseText;"+\r\n                    "}}});"+\r\n        "}</script>"+\r\n"</head>"+\r\n"<style> *{ -moz-user-select: none; -ms-user-select:none; user-select:none; } </style>"+\r\n"<body>"+\r\n    "<div style=\\"width: auto;margin-top:30px;text-align: center;\\" id=\\"show\\"></div>"+\r\n    "<div style=\\"padding: 20px;width:auto;margin: 80px auto auto; background-color: #EEF0F2;\\">"+\r\n        "<p><input type=\\"submit\\" style=\\"margin:auto auto 20% 42%;\\" id=\\"xyzUp\\" value=\\"&nbsp ↑ &nbsp\\"></p>"+\r\n        "<p><input type=\\"submit\\" style=\\"margin-left: 10%;\\" id=\\"xyzLeft\\" value=\\"&nbsp ← &nbsp\\">"+\r\n        "<input type=\\"submit\\" style=\\"margin:auto 17% auto 17%\\" id=\\"xyzStop\\" value=\\"&nbsp ■ &nbsp\\">"+\r\n        "<input type=\\"submit\\" style=\\"margin-right: 10%;\\" id=\\"xyzRight\\" value=\\"&nbsp → &nbsp\\"></p>"+\r\n        "<p></p><input type=\\"submit\\" style=\\"margin:20% auto auto 42%;\\" id=\\"xyzDonw\\" value=\\"&nbsp ↓ &nbsp\\"></p>"+\r\n    "</div>"+\r\n    "<div style=\\"width:auto;margin: 50px auto;text-align: center; background-color: #EEF0F2;\\">"+\r\n        "<p><input type=\\"submit\\" style=\\"float:left;\\" id=\\"rise\\" value=\\"&nbsp 机器升 &nbsp\\"></p>"+\r\n        "<p><input type=\\"submit\\" style=\\"margin-left:50%;\\" id=\\"decline\\" value=\\"&nbsp 机器降 &nbsp\\"><br />"+\r\n        "<p><input type=\\"submit\\" value=\\"速度+\\" id=\\"speedA\\"></p>"+\r\n        "<p><input type=\\"submit\\" value=\\"速度-\\" id=\\"speedB\\"></p><br />"+\r\n        "<p><input type=\\"submit\\" id=\\"TurnOff\\" value=\\"&nbsp 关闭发动机 &nbsp\\"></p>"+\r\n    "</div></body></html>";\r\n\r\nint LeftAdvance = 32;\r\nint RightAdvance = 33;\r\nint LeftRetreat = 25;\r\nint RightRetreat = 26;\r\nint rise = 27;\r\nint decline = 14;\r\n//发动机\r\nint TurnOff = 12;\r\n\r\n//touch 最大65  手摸20以下 但是运行环境 触摸达不到20以下,20-50间,应该设置为50\r\nconst int ConstTouch = 50;\r\nString runState = "■";\r\nString WebSocKetUserName="cart1";\r\n\r\nvoid setup(void) {\r\n  pinMode(LeftAdvance, OUTPUT);\r\n  pinMode(LeftRetreat, OUTPUT);\r\n  pinMode(RightAdvance, OUTPUT);\r\n  pinMode(RightRetreat, OUTPUT);\r\n  pinMode(rise, OUTPUT);\r\n  pinMode(decline, OUTPUT);\r\n  pinMode(TurnOff, OUTPUT);\r\n  pinMode(light22, OUTPUT);\r\n  //pinMode(d5, INPUT_PULLUP);\r\n  //pinMode(d6, INPUT_PULLUP);\r\n\r\n  digitalWrite(LeftAdvance, LOW);\r\n  digitalWrite(LeftRetreat, LOW);\r\n  digitalWrite(RightAdvance, LOW);\r\n  digitalWrite(RightRetreat, LOW);\r\n\r\n  digitalWrite(rise, LOW);\r\n  digitalWrite(decline, LOW);\r\n  digitalWrite(TurnOff, LOW);\r\n  digitalWrite(light22, LOW);\r\n\r\n  pinMode(pwm1, OUTPUT);\r\n  ledcSetup(channel1, freq, resolution);\r\n  ledcAttachPin(pwm1, channel1);\r\n  ledcWrite(channel1, PwmNow);\r\n  pinMode(Power8266, OUTPUT);\r\n  digitalWrite(Power8266, LOW);\r\n\r\n  Serial.begin(115200);\r\n  delay(500);\r\n\r\n  if (!SPIFFS.begin(true)) {\r\n    Serial.println("SPIFFS加载失败");\r\n  }\r\n  if (SPIFFS.exists(direction) == false) {\r\n    //写入数据\r\n    SetSPIFFS(direction, "true");\r\n    delay(300);\r\n  }\r\n\r\n  File dateFile = SPIFFS.open(direction, "r");\r\n  String boolStr;\r\n  for (int i = 0; i < dateFile.size(); i++) {\r\n    //Serial.print((char)dateFile.read());\r\n    boolStr += (char)dateFile.read();\r\n  }\r\n  //去除前后空格\r\n  boolStr.trim();\r\n  Serial.println(boolStr);\r\n  delay(500);\r\n  int intto = touchRead(touch15);\r\n  delay(1000);\r\n  if (intto < ConstTouch) {\r\n    if (boolStr == "true") {\r\n        Serial.println("转换遥控方向成 重");\r\n        SetSPIFFS(direction, "false");\r\n        delay(200);\r\n        globalBL=false;\r\n        ledFlicker();\r\n    } else {\r\n        Serial.println("转换遥控方向成 轻");\r\n        SetSPIFFS(direction, "true");\r\n        delay(200);\r\n        globalBL=true;\r\n        ledFlicker();\r\n    }\r\n  }\r\n  delay(500);\r\n  int intto4 = touchRead(touch4);\r\n  delay(500);\r\n  //touch4 是否触摸操作 true为触摸\r\n  bool touch4BL=false;\r\n  if(intto4 < ConstTouch){\r\n    touch4BL=true;\r\n    if (!SPIFFS.begin(true)) {\r\n      Serial.println("SPIFFS加载失败");\r\n    }\r\n    if (SPIFFS.exists(controlMode) == false) {\r\n      //写入数据  true代表 增加射频遥控 模式\r\n      SetSPIFFS(controlMode, "false");\r\n      delay(300);\r\n    }else{\r\n      String boolStr1;\r\n      File dateFile = SPIFFS.open(controlMode, "r");\r\n      for (int i = 0; i < dateFile.size(); i++) {\r\n      //Serial.print((char)dateFile.read());\r\n      boolStr1 += (char)dateFile.read();\r\n      }\r\n      //去除前后空格\r\n      boolStr1.trim();\r\n      Serial.println(boolStr1);\r\n      //上次是true射频模式 现在就关闭射频模式\r\n      if(boolStr1=="true"){\r\n        Serial.println("关闭射频模式");\r\n        SetSPIFFS(controlMode, "false");\r\n      }else{\r\n        //开户射频模式\r\n        SetSPIFFS(controlMode, "true");\r\n        Serial.println("开启射频模式");\r\n        digitalWrite(Power8266,HIGH);\r\n      }\r\n    }\r\n    ledFlicker();\r\n  }\r\n\r\n  if(touch4BL==false){\r\n    if (!SPIFFS.begin(true)) {\r\n      Serial.println("SPIFFS加载失败");\r\n    }else{\r\n      String boolStr2;\r\n      File dateFile = SPIFFS.open(controlMode, "r");\r\n      for (int i = 0; i < dateFile.size(); i++) {\r\n      //Serial.print((char)dateFile.read());\r\n      boolStr2 += (char)dateFile.read();\r\n      }\r\n      //去除前后空格\r\n      boolStr2.trim();\r\n      Serial.println(boolStr2);\r\n      \r\n      if(boolStr2=="true"){\r\n        digitalWrite(Power8266,HIGH);\r\n      }\r\n    }\r\n  }\r\n\r\n  delay(200);\r\n  ApStart();\r\n  delay(200);\r\n  Serial.println("启动网页遥控AP");\r\n  delay(200);\r\n  WebServerStart();\r\n}\r\n\r\nvoid loop(void) {\r\n  webServer.handleClient();\r\n  int STOP = touchRead(touchSTOP);\r\n  delay(300);\r\n  Serial.println(STOP);\r\n  if (STOP < 30) {\r\n    digitalWrite(LeftRetreat, LOW);\r\n    digitalWrite(LeftAdvance, LOW);\r\n  }else{\r\n\r\n      int DOWN = touchRead(touchDOWN);\r\n      delay(300);\r\n      Serial.println(DOWN);\r\n      if (DOWN < 35) {\r\n        //左轮后退\r\n        LeftAft();\r\n      }else{\r\n        int UP = touchRead(touchUP);\r\n        delay(300);\r\n        Serial.println(UP);\r\n        if (UP < 40) {\r\n          //左轮前进\r\n          LeftFore();\r\n        }\r\n      }\r\n  }\r\n}\r\n\r\n\r\n//------- 展示页面-------\r\nvoid handleRoot() {\r\n  webServer.send(500, "text/html", html);\r\n}\r\nvoid handleNotFound(void) {\r\n  webServer.send(404, "text/plain", "404-The page is not Found!");\r\n}\r\nvoid xyzgo() {\r\n  request = webServer.arg("xyz");\r\n  //Serial.println(request);\r\n  if (request == "↑") {\r\n    if(globalBL==false){\r\n      LeftFore();\r\n      RightFore();\r\n    }else{\r\n      LeftAft();\r\n      RightAft();\r\n    }\r\n    runState = "↑";\r\n    webServer.send(200, "text/plane", request);\r\n    Serial.println("↑");\r\n    return;\r\n  }\r\n  if (request == "↓") {\r\n    if(globalBL==false){\r\n      LeftAft();\r\n      RightAft();\r\n    }else{\r\n      LeftFore();\r\n      RightFore();\r\n    }\r\n    runState = "↓";\r\n    webServer.send(200, "text/plane", request);\r\n    Serial.println("↓");\r\n    return;\r\n  }\r\n  if (request == "■") {\r\n    StopAllExec();\r\n    runState = "■";\r\n    webServer.send(200, "text/plane", request);\r\n    Serial.println("■");\r\n    return;\r\n  }\r\n  if (request == "←") {\r\n      RightFore();\r\n      LeftAft();\r\n    runState = "←";\r\n    webServer.send(200, "text/plane", request);\r\n    Serial.println("←");\r\n    return;\r\n  }\r\n  if (request == "→") {\r\n      LeftFore();\r\n      RightAft();\r\n    \r\n    runState = "→";\r\n    webServer.send(200, "text/plane", request);\r\n    Serial.println("→");\r\n    return;\r\n  }\r\n  if (request == "rise") {\r\n    digitalWrite(decline, LOW);\r\n    digitalWrite(rise, HIGH);\r\n    webServer.send(200, "text/plane", request);\r\n    return;\r\n  }\r\n  if (request == "decline") {\r\n    digitalWrite(rise, LOW);\r\n    digitalWrite(decline, HIGH);\r\n    webServer.send(200, "text/plane", request);\r\n    return;\r\n  }\r\n  if (request == "TurnOff") {\r\n    digitalWrite(TurnOff, HIGH);\r\n    webServer.send(200, "text/plane", request);\r\n    delay(3000);\r\n    digitalWrite(TurnOff, LOW);\r\n    return;\r\n  }\r\n  if (request == "speedA") {\r\n    if (PwmNow >= 178) {\r\n      webServer.send(200, "text/plane", "已达到70%限速,无法继续加速");\r\n    } else {\r\n      PwmNow = PwmNow + fadeAmount;\r\n      ledcWrite(channel1, PwmNow);\r\n      int temp=PwmNow*100/255;\r\n      String tempStr=String(temp)+"%";\r\n      webServer.send(200, "text/plane", tempStr);\r\n      Serial.println("speedA");\r\n    }\r\n    return;\r\n  }\r\n  if (request == "speedB") {\r\n    if (PwmNow <= 77) {\r\n      webServer.send(200, "text/plane", "已达到30%限速,无法继续减速");\r\n    } else {\r\n      PwmNow = PwmNow - fadeAmount;\r\n      ledcWrite(channel1, PwmNow);\r\n      int temp=PwmNow*100/255;\r\n      String tempStr=String(temp)+"%";\r\n      webServer.send(200, "text/plane", tempStr);\r\n      Serial.println("speedB");\r\n    }\r\n\r\n    return;\r\n  }\r\n  //HtmlSetWifi();\r\n}\r\n\r\nvoid ApStart() {\r\n  Serial.begin(115200);\r\n  WiFi.mode(WIFI_AP);\r\n  IPAddress local_IP(192, 168, 168, 2);\r\n  IPAddress gateway(192, 168, 168, 1);\r\n  IPAddress subnet(255, 255, 255, 0);\r\n  WiFi.softAPConfig(local_IP, gateway, subnet);\r\n  String mymac=WiFi.macAddress();\r\n  Serial.println(mymac);\r\n  mymac.replace(":","");\r\n  mymac.toLowerCase();\r\n  String temp1=mymac.substring(0,2);\r\n  String temp2=mymac.substring(10,12);\r\n  String ApPasswd=temp1+temp2;\r\n  Serial.println(ApPasswd);\r\n  //启动AP模式，并设置账号和密码\r\n  boolean result = WiFi.softAP("esp32WebServer192.168.168.2", "www.360xyz.cn");\r\n  if (result) {\r\n    //输出 soft-ap ip地址\r\n    Serial.println(String("Soft-AP IP address = ") + WiFi.softAPIP());\r\n  }\r\n}\r\n//------- 展示页面-------\r\n\r\nvoid WebServerStart() {\r\n  //-----------------启动webserver网络服务--------------------\r\n  webServer.begin();              // 启用网络服务\r\n  webServer.on("/", handleRoot);  // / 在HTTP中，表示请求首页服务，\r\n  webServer.on("/xyzgo", xyzgo);\r\n  webServer.onNotFound(handleNotFound);  // 当服务器没找到所需的服务，调用404函数\r\n  Serial.println("webserver started");\r\n}\r\n\r\nvoid SetSPIFFS(String direction, String str) {\r\n  //写入数据\r\n  SPIFFS.remove(direction);\r\n  delay(500);\r\n  SPIFFS.begin();\r\n  File dataFile = SPIFFS.open(direction, "w");\r\n  dataFile.println(str);\r\n  dataFile.close();\r\n}\r\n//左轮前进\r\nvoid LeftFore() {\r\n  digitalWrite(LeftRetreat, LOW);\r\n  digitalWrite(LeftAdvance, HIGH);\r\n}\r\n//左轮后退\r\nvoid LeftAft() {\r\n  digitalWrite(LeftAdvance, LOW);\r\n  digitalWrite(LeftRetreat, HIGH);\r\n}\r\n//右轮前进\r\nvoid RightFore() {\r\n  digitalWrite(RightRetreat, LOW);\r\n  digitalWrite(RightAdvance, HIGH);\r\n}\r\n//右轮后退\r\nvoid RightAft() {\r\n  digitalWrite(RightAdvance, LOW);\r\n  digitalWrite(RightRetreat, HIGH);\r\n}\r\nvoid StopAllExec() {\r\n  digitalWrite(LeftAdvance, LOW);\r\n  digitalWrite(RightAdvance, LOW);\r\n  digitalWrite(LeftRetreat, LOW);\r\n  digitalWrite(RightRetreat, LOW);\r\n  digitalWrite(rise, LOW);\r\n  digitalWrite(decline, LOW);\r\n  delay(500);\r\n}\r\n//LED 闪烁\r\nvoid ledFlicker(){\r\n  digitalWrite(light22, HIGH);\r\n  delay(500);\r\n  digitalWrite(light22, LOW);\r\n  delay(500);\r\n  digitalWrite(light22, HIGH);\r\n  delay(500);\r\n  digitalWrite(light22, LOW);\r\n}', '', 'webserver'),
(8013, 555, '颈椎病会引起高血压', '脖子僵硬,转头颈椎疼,是由于脖子后面左右两根神经不通,严重是会起床或躺下天旋地转血压升高\r\n注意事项\r\n冷天注意脖子保暖\r\n不要床上看手机,\r\n坐在电脑前30分钟,运动一下脖子,背部肌肉', '', 'webserver');

-- --------------------------------------------------------

--
-- 表的结构 `WisdomText`
--

CREATE TABLE IF NOT EXISTS `WisdomText` (
  `id` int(1) NOT NULL AUTO_INCREMENT,
  `text` text NOT NULL,
  `type` char(32) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- 表的结构 `WisdomToolsName`
--

CREATE TABLE IF NOT EXISTS `WisdomToolsName` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `category` varchar(32) NOT NULL DEFAULT '',
  `name` varchar(32) NOT NULL DEFAULT '',
  `number` int(10) DEFAULT '0',
  `buy` float DEFAULT '0',
  `freight` float NOT NULL DEFAULT '0',
  `date` date NOT NULL,
  `user` varchar(32) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=972 ;

--
-- 转存表中的数据 `WisdomToolsName`
--

INSERT INTO `WisdomToolsName` (`id`, `category`, `name`, `number`, `buy`, `freight`, `date`, `user`) VALUES
(1, '汽车维修', '40件套(内六角十二梅花)', 1, 46, 0, '2019-09-07', 'webserver'),
(3, '家电维修', '电烙铁芯内热式', 1, 10, 1, '2019-09-07', 'webserver'),
(961, '家电维修', '英爵伦电吹风', 1, 27, 0, '2023-08-16', 'webserver'),
(5, '家电维修', '936焊台烙铁芯', 3, 12, 1, '2019-09-07', 'webserver'),
(6, '家电维修', '6寸老虎钳', 1, 7, 1, '2019-09-07', 'webserver'),
(7, '家电维修', '八角锤2.2斤', 1, 13, 1, '2019-09-07', 'webserver'),
(780, '家电维修', '3斤松香', 1, 24, 0, '2020-10-18', 'webserver'),
(9, '家电维修', '烙铁头936电焊台', 1, 5.5, 1, '2019-09-07', 'webserver'),
(10, '家电维修', '汉邦936恒温电烙铁', 1, 59, 0, '2019-09-07', 'webserver'),
(838, '家电维修', '802电动镙丝刀批头 ', 34, 3, 0.5, '2022-04-19', 'webserver'),
(12, '汽车维修', '8寸一字镙丝刀', 1, 8.5, 1, '2019-09-07', 'webserver'),
(13, '家电维修', '8寸十字镙丝刀', 1, 8.5, 1, '2019-09-07', 'webserver'),
(14, '家电维修', '220v电钻', 1, 89, 0, '2019-09-07', 'webserver'),
(874, '家电维修', '17寸双层工具箱', 1, 15, 0, '2022-08-18', 'webserver'),
(839, '家电维修', '936烙铁头5个一套', 1, 13.5, 0.5, '2022-04-19', 'webserver'),
(17, '家电维修', '十字镙丝刀200m', 1, 3.8, 1, '2019-09-07', 'webserver'),
(18, '家电维修', '9v电子称充电电源', 1, 10, 0, '2019-09-07', 'webserver'),
(19, '家电维修', '107吸锡器', 2, 9.6, 1, '2019-09-07', 'webserver'),
(20, '家电维修', '10寸活动板手', 1, 12.8, 1, '2019-09-07', 'webserver'),
(21, '家电维修', '铁皮剪8寸', 1, 11.8, 0, '2019-09-07', 'webserver'),
(22, '家电维修', '热熔胶枪', 1, 14, 0, '2019-09-07', 'webserver'),
(23, '家电维修', '电热熔枪胶棒', 10, 0.8, 1, '2019-09-07', 'webserver'),
(960, '智能家居', '康夫电吹风', 1, 68, 0, '2023-08-16', 'webserver'),
(810, '智能家居', ' 手机遥控电动卷闸门 ', 1, 180, 0, '2021-06-18', 'webserver'),
(26, '家电维修', '12v2000瓦逆变器', 1, 350, 0, '2019-09-07', 'webserver'),
(836, '家电维修', '焊锡丝500克', 1, 39, 0, '2022-03-23', 'webserver'),
(28, '家电维修', '936焊台烙铁头', 2, 6, 1, '2019-09-07', 'webserver'),
(29, '汽车维修', '保险丝30A', 3, 0.5, 0, '2019-09-07', 'webserver'),
(30, '汽车维修', '保险丝20A ', 3, 0.5, 0, '2019-09-07', 'webserver'),
(31, '汽车维修', '保险丝15A', 5, 0.5, 0, '2019-09-07', 'webserver'),
(32, '汽车维修', '72齿弯柄棘轮61件套', 1, 210, 0, '2019-09-07', 'webserver'),
(33, '汽车维修', '12/24脉冲充电器', 1, 92, 0, '2019-09-07', 'webserver'),
(34, '汽车维修', '千斤顶(气压)', 1, 50, 0, '2019-09-07', 'webserver'),
(35, '制冷维修', '飞越真空泵', 1, 265, 0, '2019-09-07', 'webserver'),
(36, '制冷维修', '封口钳', 1, 17, 0, '2019-09-07', 'webserver'),
(37, '制冷维修', '弯管器6/8/10m', 1, 28, 0, '2019-09-07', 'webserver'),
(38, '制冷维修', '扩管器割管刀', 1, 32, 1, '2019-09-07', 'webserver'),
(39, '制冷维修', '雪种万能开瓶', 2, 9, 1, '2019-09-07', 'webserver'),
(40, '制冷维修', '钳形电流表(交流)', 1, 27, 1, '2019-09-07', 'webserver'),
(41, '制冷维修', '2升焊炬双用氧气瓶', 1, 225, 0, '2019-09-07', 'webserver'),
(42, '制冷维修', '500克硼砂', 2, 8, 0, '2019-09-07', 'webserver'),
(43, '制冷维修', '发泡枪', 1, 10, 0, '2019-09-07', 'webserver'),
(44, '制冷维修', '2升液化瓶减压阀', 1, 16, 0, '2019-09-07', 'webserver'),
(45, '制冷维修', '小型割管器', 2, 12, 0, '2019-09-07', 'webserver'),
(46, '制冷维修', '2.5Mpa压力表头', 2, 7, 0, '2019-09-07', 'webserver'),
(868, '制冷维修', 'R134A汽车空调高压接头', 1, 8, 0, '2022-08-13', 'webserver'),
(48, '汽车维修', '12寸活动板手', 1, 15.3, 0, '2019-09-07', 'webserver'),
(49, '家电维修', '6寸尖嘴钳', 1, 9, 0, '2019-09-07', 'webserver'),
(50, '家电维修', '6寸细尖嘴钳', 1, 12, 0, '2019-09-07', 'webserver'),
(51, '家电维修', '尖嘴镊子', 2, 5, 1, '2019-09-07', 'webserver'),
(52, '家电维修', '卷尺', 1, 3, 0, '2019-09-08', 'webserver'),
(53, '家电维修', '802电动镙比刀', 1, 120, 0, '2019-09-08', 'webserver'),
(54, '家电维修', '3米人字梯', 1, 330, 0, '2019-09-08', 'webserver'),
(55, '家电维修', '三路单独开关插座', 1, 30, 0, '2019-09-08', 'webserver'),
(58, '智能家居', '手机遥控定时充电插座', 1, 20, 0, '2019-09-08', 'webserver'),
(939, '智能家居', '7800+4+120g技术电脑', 1, 800, 0, '2023-05-20', 'webserver'),
(61, '智能家居', 'wifi路由器', 1, 98, 0, '2019-09-08', 'webserver'),
(62, '智能家居', '夜视摄像头', 1, 168, 0, '2019-09-08', 'webserver'),
(63, '智能家居', '8升电压力锅', 1, 330, 0, '2019-09-08', 'webserver'),
(64, '智能家居', '空调', 1, 3200, 0, '2019-09-08', 'webserver'),
(65, '智能家居', '冰箱', 1, 1680, 0, '2019-09-08', 'webserver'),
(66, '智能家居', '滚筒洗衣机', 1, 3500, 0, '2019-09-08', 'webserver'),
(67, '智能家居', '电脑桌', 1, 168, 0, '2019-09-08', 'webserver'),
(68, '智能家居', '厨房液化燃气', 1, 200, 0, '2019-09-08', 'webserver'),
(69, '智能家居', '电磁炉', 2, 200, 0, '2019-09-08', 'webserver'),
(970, '智能家居', '浴霸', 1, 70, 0, '2023-12-06', 'webserver'),
(71, '智能家居', '沐浴露', 1, 30, 0, '2019-09-08', 'webserver'),
(73, '智能家居', '洗发水', 1, 30, 0, '2019-09-08', 'webserver'),
(74, '智能家居', '洗衣粉', 1, 20, 0, '2019-09-08', 'webserver'),
(75, '智能家居', '.剃须刀', 1, 20, 0, '2019-09-08', 'webserver'),
(76, '智能家居', '飞科理发器', 1, 100, 0, '2019-09-08', 'webserver'),
(814, '车上必备', '三头剃须刀 ', 1, 19, 0, '2021-06-18', 'webserver'),
(78, '车上必备', '纯净水', 1, 2, 0, '2019-09-08', 'webserver'),
(789, '车上必备', '灭火器', 1, 15, 0.5, '2020-12-28', 'admin'),
(788, '车上必备', '灭火器', 1, 15, 0.5, '2020-12-28', 'webserver'),
(81, '车上必备', '雨伞', 1, 10, 0, '2019-09-08', 'webserver'),
(887, '车上必备', '360行车记录仪', 1, 300, 0.5, '2023-04-29', 'webserver'),
(83, '车上必备', '千斤顶', 1, 50, 0, '2019-09-08', 'webserver'),
(84, '车上必备', '几个大号塑料袋', 1, 1, 0, '2019-09-08', 'webserver'),
(85, '车上必备', '三角板', 1, 0, 0, '2019-09-08', 'webserver'),
(86, '车上必备', '车贴黑膜', 1, 100, 0, '2019-09-08', 'webserver'),
(89, '智能家居', '拖鞋', 1, 20, 0, '2019-09-08', 'webserver'),
(88, '家电维修', '网线钳-测试仪', 1, 25, 0, '2019-09-08', 'webserver'),
(90, '外出必备', '纸巾', 1, 2, 0, '2019-09-08', 'webserver'),
(91, '外出必备', '镜子', 1, 10, 0, '2019-09-08', 'webserver'),
(92, '外出必备', '理发器', 1, 100, 0, '2019-09-08', 'webserver'),
(93, '外出必备', '剃须刀', 1, 20, 0, '2019-09-08', 'webserver'),
(937, '外出必备', '手机', 1, 3000, 0, '2023-05-19', 'webserver'),
(95, '外出必备', '驾驶证', 1, 0, 0, '2019-09-08', 'webserver'),
(96, '外出必备', '手机充电器', 1, 0, 0, '2019-09-08', 'webserver'),
(97, '外出必备', '沐浴露', 1, 30, 0, '2019-09-08', 'webserver'),
(98, '外出必备', '两套换洗', 1, 0, 0, '2019-09-08', 'webserver'),
(99, '外出必备', '拖鞋', 1, 20, 0, '2019-09-08', 'webserver'),
(100, '汽车维修', '拾取器(买工具箱附送)', 1, 0, 0, '2019-09-08', 'webserver'),
(758, '家电维修', '晶思达数字万用表', 1, 80, 0, '2020-05-27', 'webserver'),
(857, '家电维修', '洗衣机捶打扳手', 1, 50, 0, '2022-07-28', 'webserver'),
(942, '家电维修', '4-12mm九层含古钻头', 1, 14.3, 0, '2023-05-26', 'webserver'),
(808, '智能家居', '电动牙刷 充电能用一年', 1, 40, 0, '2021-06-18', 'webserver'),
(107, '水果工具', '4冲程割草机', 1, 420, 0, '2019-09-09', 'webserver'),
(784, '智能家居', '三星256G内存卡-树莓派', 1, 194, 0, '2020-10-30', 'webserver'),
(109, '水果工具', '糖度仪0~32%', 1, 105, 0, '2019-09-09', 'webserver'),
(867, '餐饮小吃', '双层保温桶', 1, 168, 0, '2022-08-12', 'webserver'),
(964, '家电维修', '波轮洗衣机拉钩一对', 1, 4, 0, '2023-08-22', 'webserver'),
(116, '水果工具', '打药管收纳轮(80)', 2, 110, 0, '2019-09-09', 'webserver'),
(114, '水果工具', '打药喷杆', 2, 20, 0, '2019-09-09', 'webserver'),
(936, '遥控工具车', '24VDC继电器6脚 C型', 8, 3, 0, '2023-05-19', 'webserver'),
(732, '水果工具', '1寸18米水带', 5, 33, 0, '2019-10-05', 'admin'),
(746, '餐饮小吃', '测温仪-32到380度', 1, 38, 0, '2019-11-23', 'admin'),
(745, '餐饮小吃', '封口机', 1, 200, 0, '2019-11-23', 'webserver'),
(744, '餐饮小吃', '测温仪-32到380度', 1, 38, 0, '2019-11-23', 'webserver'),
(743, '餐饮小吃', '豆浆奶茶封口机', 1, 200, 0, '2019-11-22', 'admin'),
(741, '餐饮小吃', '不锈钢油炸盆60x40x15', 1, 78, 0, '2019-11-21', 'admin'),
(742, '餐饮小吃', '30L豆浆保温桶', 1, 105, 0, '2019-11-22', 'admin'),
(739, '餐饮小吃', '擀面杖直径3.2cm长度30cm', 1, 13.5, 0, '2019-11-21', 'admin'),
(738, '餐饮小吃', '擀面杖直径3.2cm长度30cm', 1, 13.5, 0, '2019-11-21', 'webserver'),
(737, '餐饮小吃', '不锈钢油炸盆60x40x15', 1, 78, 0, '2019-11-21', 'webserver'),
(735, '车上必备', '灭火器', 1, 70, 0, '2019-11-19', 'admin'),
(736, '水果工具', '汽油抽水泵', 1, 180, 0, '2019-11-19', 'admin'),
(733, '汽车维修', '黑旋封586汽车耐油温密封胶', 1, 10, 0, '2019-10-18', 'webserver'),
(730, '汽车维修', '气门拆装油封钳', 1, 18, 0, '2019-09-30', 'webserver'),
(727, '汽车维修', '气门拆装油封钳', 1, 18, 0, '2019-09-30', 'admin'),
(728, '汽车维修', '棕刚玉150*25*32(粒度80)', 1, 16, 0, '2019-09-30', 'admin'),
(729, '汽车维修', '棕刚玉150*25*32(粒度80)', 1, 16, 0, '2019-09-30', 'webserver'),
(724, '汽车维修', '机油壳扳手', 1, 15, 0, '2019-09-29', 'webserver'),
(723, '汽车维修', '机油壳扳手', 1, 15, 0, '2019-09-29', 'admin'),
(722, '汽车维修', '塞尺', 1, 6, 0, '2019-09-28', 'webserver'),
(721, '汽车维修', '气门工具', 1, 43, 0, '2019-09-28', 'webserver'),
(720, '汽车维修', '塞尺', 1, 6, 0, '2019-09-27', 'admin'),
(719, '汽车维修', '气门工具', 1, 43, 0, '2019-09-27', 'admin'),
(717, '汽车维修', '3吨卧式千斤顶(汽修专用)', 1, 334, 0, '2019-09-12', 'admin'),
(716, '汽车维修', '3吨卧式千斤顶(汽修专用)', 1, 334, 0, '2019-09-12', 'webserver'),
(714, '水果工具', '30升酒壶(装柴油)', 1, 32, 0, '2019-09-09', 'admin'),
(713, '水果工具', '水箱2000斤', 1, 330, 0, '2019-09-09', 'admin'),
(840, '水果工具', 'PVC软管1寸牛筋50米', 2, 169, 0, '2022-04-28', 'webserver'),
(711, '水果工具', '50米抽刚电缆', 1, 45, 0, '2019-09-09', 'admin'),
(710, '水果工具', '至尊电子秤计价30kg', 1, 88, 0, '2019-09-09', 'admin'),
(709, '水果工具', '抽水管50米', 1, 120, 0, '2019-09-09', 'admin'),
(708, '水果工具', '风冷柴油机', 1, 800, 0, '2019-09-09', 'admin'),
(707, '水果工具', '打药管收纳轮(80)', 2, 110, 0, '2019-09-09', 'admin'),
(706, '水果工具', '打药喷杆', 2, 20, 0, '2019-09-09', 'admin'),
(705, '水果工具', '45cm大果剪', 1, 35, 0, '2019-09-09', 'admin'),
(704, '水果工具', '糖度仪0~32%', 1, 105, 0, '2019-09-09', 'admin'),
(703, '水果工具', '60v抽水泵300W', 1, 130, 0, '2019-09-09', 'admin'),
(702, '水果工具', '4冲程割草机', 1, 420, 0, '2019-09-09', 'admin'),
(701, '水果工具', '水箱540斤', 1, 150, 0, '2019-09-09', 'admin'),
(700, '水果工具', ' 水箱660斤', 1, 176, 0, '2019-09-09', 'admin'),
(699, '水果工具', '220v抽水机370w', 1, 188, 0, '2019-09-09', 'admin'),
(698, '水果工具', '200米打药管(65)', 1, 260, 0, '2019-09-09', 'admin'),
(696, '外出必备', '拖鞋', 1, 20, 0, '2019-09-08', 'admin'),
(697, '水果工具', '打药泵', 1, 400, 0, '2019-09-09', 'admin'),
(695, '外出必备', '两套换洗', 1, 0, 0, '2019-09-08', 'admin'),
(694, '外出必备', '沐浴露', 1, 30, 0, '2019-09-08', 'admin'),
(693, '外出必备', '手机充电器', 1, 0, 0, '2019-09-08', 'admin'),
(692, '外出必备', '驾驶证', 1, 0, 0, '2019-09-08', 'admin'),
(691, '外出必备', '手机', 1, 1500, 0, '2019-09-08', 'admin'),
(690, '外出必备', '剃须刀', 1, 20, 0, '2019-09-08', 'admin'),
(689, '外出必备', '理发器', 1, 100, 0, '2019-09-08', 'admin'),
(688, '外出必备', '镜子', 1, 10, 0, '2019-09-08', 'admin'),
(687, '外出必备', '纸巾', 1, 2, 0, '2019-09-08', 'admin'),
(686, '车上必备', '车贴黑膜', 1, 100, 0, '2019-09-08', 'admin'),
(685, '车上必备', '三角板', 1, 0, 0, '2019-09-08', 'admin'),
(684, '车上必备', '几个大号塑料袋', 1, 1, 0, '2019-09-08', 'admin'),
(683, '车上必备', '千斤顶', 1, 50, 0, '2019-09-08', 'admin'),
(682, '车上必备', '行车记录仪', 1, 368, 0, '2019-09-08', 'admin'),
(681, '车上必备', '雨伞', 1, 10, 0, '2019-09-08', 'admin'),
(680, '车上必备', '大功率手机充电器', 1, 40, 0, '2019-09-08', 'admin'),
(679, '车上必备', '.安全套', 1, 30, 0, '2019-09-08', 'admin'),
(678, '车上必备', '纯净水', 1, 2, 0, '2019-09-08', 'admin'),
(677, '车上必备', '.剃须刀', 1, 20, 0, '2019-09-08', 'admin'),
(676, '智能家居', '拖鞋', 1, 20, 0, '2019-09-08', 'admin'),
(675, '智能家居', '飞科理发器', 1, 100, 0, '2019-09-08', 'admin'),
(674, '智能家居', '.剃须刀', 1, 20, 0, '2019-09-08', 'admin'),
(673, '智能家居', '洗衣粉', 1, 20, 0, '2019-09-08', 'admin'),
(672, '智能家居', '洗发水', 1, 30, 0, '2019-09-08', 'admin'),
(671, '智能家居', '沐浴露', 1, 30, 0, '2019-09-08', 'admin'),
(670, '智能家居', '48寸液晶电视机', 1, 4300, 0, '2019-09-08', 'admin'),
(669, '智能家居', '电磁炉', 2, 200, 0, '2019-09-08', 'admin'),
(668, '智能家居', '厨房液化燃气', 1, 200, 0, '2019-09-08', 'admin'),
(667, '智能家居', '电脑桌', 1, 168, 0, '2019-09-08', 'admin'),
(666, '智能家居', '滚筒洗衣机', 1, 3500, 0, '2019-09-08', 'admin'),
(665, '智能家居', '冰箱', 1, 1680, 0, '2019-09-08', 'admin'),
(664, '智能家居', '空调', 1, 3200, 0, '2019-09-08', 'admin'),
(663, '智能家居', '8升电压力锅', 1, 330, 0, '2019-09-08', 'admin'),
(662, '智能家居', '夜视摄像头', 1, 168, 0, '2019-09-08', 'admin'),
(661, '智能家居', 'wifi路由器', 1, 98, 0, '2019-09-08', 'admin'),
(660, '智能家居', '电脑', 1, 1700, 0, '2019-09-08', 'admin'),
(659, '智能家居', '台式电脑下载共享备份机', 1, 400, 0, '2019-09-08', 'admin'),
(658, '智能家居', '手机遥控定时充电插座', 1, 20, 0, '2019-09-08', 'admin'),
(657, '智能家居', '手机遥控电动卷闸门', 1, 50, 0, '2019-09-08', 'admin'),
(656, '汽车维修', '拾取器(买工具箱附送)', 1, 0, 0, '2019-09-08', 'admin'),
(655, '汽车维修', '12寸活动板手', 1, 15.3, 0, '2019-09-07', 'admin'),
(654, '汽车维修', '千斤顶(气压)', 1, 50, 0, '2019-09-07', 'admin'),
(653, '汽车维修', '12/24脉冲充电器', 1, 92, 0, '2019-09-07', 'admin'),
(652, '汽车维修', '72齿弯柄棘轮61件套', 1, 210, 0, '2019-09-07', 'admin'),
(651, '汽车维修', '保险丝15A', 5, 0.5, 0, '2019-09-07', 'admin'),
(650, '汽车维修', '保险丝20A ', 3, 0.5, 0, '2019-09-07', 'admin'),
(649, '汽车维修', '保险丝30A', 3, 0.5, 0, '2019-09-07', 'admin'),
(718, '汽车维修', '40件铁盒套(内6角12梅花)', 1, 46, 0, '2019-09-12', 'admin'),
(648, '汽车维修', '8寸一字镙丝刀', 1, 8.5, 1, '2019-09-07', 'admin'),
(646, '制冷维修', '加长点火棒', 2, 5, 0, '2019-09-07', 'admin'),
(645, '制冷维修', '2.5Mpa压力表头', 2, 7, 0, '2019-09-07', 'admin'),
(643, '制冷维修', '2升液化瓶减压阀', 1, 16, 0, '2019-09-07', 'admin'),
(644, '制冷维修', '小型割管器', 2, 12, 0, '2019-09-07', 'admin'),
(642, '制冷维修', '发泡枪', 1, 10, 0, '2019-09-07', 'admin'),
(641, '制冷维修', '500克硼砂', 2, 8, 0, '2019-09-07', 'admin'),
(640, '制冷维修', '2升焊炬双用氧气瓶', 1, 225, 0, '2019-09-07', 'admin'),
(639, '制冷维修', '钳形电流表(交流)', 1, 27, 1, '2019-09-07', 'admin'),
(638, '制冷维修', '雪种万能开瓶', 2, 9, 1, '2019-09-07', 'admin'),
(637, '制冷维修', '扩管器割管刀', 1, 32, 1, '2019-09-07', 'admin'),
(636, '制冷维修', '弯管器6/8/10m', 1, 28, 0, '2019-09-07', 'admin'),
(635, '制冷维修', '封口钳', 1, 17, 0, '2019-09-07', 'admin'),
(633, '家电维修', '数字万用表', 1, 40, 0, '2019-09-08', 'admin'),
(634, '制冷维修', '飞越真空泵', 1, 265, 0, '2019-09-07', 'admin'),
(632, '家电维修', '网线钳-测试仪', 1, 25, 0, '2019-09-08', 'admin'),
(631, '家电维修', '工作台(自焊接DIY)', 1, 50, 0, '2019-09-08', 'admin'),
(630, '家电维修', '三路单独开关插座', 1, 30, 0, '2019-09-08', 'admin'),
(629, '家电维修', '3米人字梯', 1, 330, 0, '2019-09-08', 'admin'),
(628, '家电维修', '802电动镙比刀', 1, 120, 0, '2019-09-08', 'admin'),
(627, '家电维修', '卷尺', 1, 3, 0, '2019-09-08', 'admin'),
(626, '家电维修', '尖嘴镊子', 2, 5, 1, '2019-09-07', 'admin'),
(625, '家电维修', '6寸细尖嘴钳', 1, 12, 0, '2019-09-07', 'admin'),
(624, '家电维修', '6寸尖嘴钳', 1, 9, 0, '2019-09-07', 'admin'),
(623, '家电维修', '936焊台烙铁头', 2, 6, 1, '2019-09-07', 'admin'),
(622, '家电维修', '焊锡丝350克', 1, 25, 1, '2019-09-07', 'admin'),
(621, '家电维修', '12v2000瓦逆变器', 1, 350, 0, '2019-09-07', 'admin'),
(620, '家电维修', '康夫电吹风', 1, 68, 0, '2019-09-07', 'admin'),
(619, '家电维修', '电热熔枪胶棒', 10, 0.8, 1, '2019-09-07', 'admin'),
(618, '家电维修', '热熔胶枪', 1, 14, 0, '2019-09-07', 'admin'),
(617, '家电维修', '铁皮剪8寸', 1, 11.8, 0, '2019-09-07', 'admin'),
(616, '家电维修', '10寸活动板手', 1, 12.8, 1, '2019-09-07', 'admin'),
(615, '家电维修', '107吸锡器', 2, 9.6, 1, '2019-09-07', 'admin'),
(614, '家电维修', '9v电子称充电电源', 1, 10, 0, '2019-09-07', 'admin'),
(613, '家电维修', '十字镙丝刀200m', 1, 3.8, 1, '2019-09-07', 'admin'),
(612, '家电维修', '电子元件盒', 24, 1.9, 1, '2019-09-07', 'admin'),
(611, '家电维修', '电钻炭刷一对', 1, 1, 1, '2019-09-07', 'admin'),
(610, '家电维修', '220v电钻', 1, 89, 0, '2019-09-07', 'admin'),
(609, '家电维修', '8寸十字镙丝刀', 1, 8.5, 1, '2019-09-07', 'admin'),
(608, '家电维修', '802电动镙丝刀批头', 26, 3, 1, '2019-09-07', 'admin'),
(607, '家电维修', '汉邦936恒温电烙铁', 1, 59, 0, '2019-09-07', 'admin'),
(605, '家电维修', '松香', 11, 0.6, 1, '2019-09-07', 'admin'),
(604, '家电维修', '八角锤2.2斤', 1, 13, 1, '2019-09-07', 'admin'),
(603, '家电维修', '6寸老虎钳', 1, 7, 1, '2019-09-07', 'admin'),
(602, '家电维修', '936焊台烙铁芯', 3, 12, 1, '2019-09-07', 'admin'),
(601, '家电维修', '直柄麻花钻 3MM', 7, 0.5, 1, '2019-09-07', 'admin'),
(600, '家电维修', '电烙铁芯内热式', 1, 10, 1, '2019-09-07', 'admin'),
(747, '制冷维修', '双公透明加液管', 1, 3.5, 0.5, '2019-12-19', 'webserver'),
(748, '制冷维修', '公英透明加液管', 1, 0.5, 0.5, '2019-12-19', 'webserver'),
(750, '制冷维修', '双公透明加液管', 1, 3.5, 0.5, '2019-12-19', 'admin'),
(751, '制冷维修', '公英透明加液管', 1, 3.5, 0.5, '2019-12-19', 'admin'),
(752, '制冷维修', '自制空压机', 1, 150, 0.5, '2019-12-21', 'admin'),
(753, '汽车维修', '黑色防锈漆1L', 1, 32, 0, '2020-01-04', 'admin'),
(757, '水果工具', '139割草机打药机头', 1, 215, 0, '2020-05-25', 'webserver'),
(755, '水果工具', '139汽油机泵头', 1, 170, 0, '2020-05-11', 'admin'),
(756, '水果工具', '斯尔特割草机发动机', 1, 240, 0, '2020-05-25', 'webserver'),
(764, '家电维修', '液晶屏 背光灯测试仪', 1, 55, 0, '2020-06-07', 'webserver'),
(763, '家电维修', '液晶屏 背光灯测试仪', 1, 55, 0, '2020-06-07', 'admin'),
(766, '车上必备', '30L汽油铁桶', 1, 55, 0, '2020-06-16', 'webserver'),
(767, '车上必备', '30L汽油铁桶', 1, 55, 0, '2020-06-16', 'admin'),
(768, '水果工具', '6.8KW油锯', 1, 279, 0, '2020-07-13', 'webserver'),
(769, '水果工具', '6.8KW油锯', 1, 279, 0, '2020-07-13', 'admin'),
(770, '水果工具', '大功率二冲程油锯', 1, 335, 0, '2020-07-19', 'webserver'),
(771, '水果工具', '大功率二冲程油锯', 1, 335, 0, '2020-07-19', 'admin'),
(773, '智能家居', '卫星接收机(71台)', 1, 188, 0, '2020-07-31', 'admin'),
(774, '智能家居', '树莓派4b(4g内存)', 1, 430, 0, '2020-09-23', 'webserver'),
(775, '智能家居', '树莓派4b(4g内存)', 1, 430, 0, '2020-09-23', 'admin'),
(776, '餐饮小吃', '气温 湿度表', 1, 21, 0, '2020-10-11', 'webserver'),
(777, '餐饮小吃', '气温 湿度表', 1, 21, 0, '2020-10-11', 'admin'),
(781, '家电维修', '3斤松香', 1, 24, 0, '2020-10-18', 'admin'),
(779, '餐饮小吃', '温度湿度表', 1, 21, 0, '2020-10-15', 'admin'),
(782, '家电维修', '20卷电工胶布', 1, 14, 0, '2020-10-18', 'webserver'),
(783, '家电维修', '20卷电工胶布', 1, 14, 0, '2020-10-18', 'admin'),
(785, '智能家居', '三星256G内存卡-树莓派', 1, 194, 0, '2020-10-30', 'admin'),
(786, '车上必备', '安全套 ', 1, 22, 0.5, '2020-12-28', 'webserver'),
(787, '车上必备', '安全套 ', 1, 22, 0.5, '2020-12-28', 'admin'),
(791, '车上必备', '剃须刀', 1, 10, 0.5, '2020-12-28', 'admin'),
(792, '车上必备', '30A汽车保险丝', 2, 0.5, 0.5, '2020-12-28', 'webserver'),
(793, '车上必备', '30A汽车保险丝', 2, 0.5, 0.5, '2020-12-28', 'admin'),
(794, '车上必备', '墨镜或眼镜', 1, 10, 0.5, '2020-12-28', 'webserver'),
(795, '车上必备', '墨镜或眼镜', 1, 10, 0.5, '2020-12-28', 'admin'),
(855, '家电维修', '40倍高清放大镜带LED灯', 1, 9, 0.5, '2022-05-12', 'webserver'),
(797, '水果工具', '电动剪刀40cm', 1, 410, 0, '2021-02-23', 'admin'),
(799, '水果工具', '电动剪刀30cm(两电)', 1, 310, 0, '2021-03-04', 'admin'),
(801, '水果工具', '4冲程割草机(用于抽水)', 1, 324, 0, '2021-03-06', 'admin'),
(830, '家电维修', '元件盒子17.3x9.8x2.2', 32, 2, 0.5, '2021-10-11', 'webserver'),
(803, '家电维修', '元件盒子17.3x9.8x2.2', 30, 2, 0.5, '2021-04-18', 'admin'),
(804, '车上必备', '洗车水管水枪', 1, 17, 0, '2021-04-19', 'webserver'),
(805, '车上必备', '洗车水管水枪', 1, 17, 0, '2021-04-19', 'admin'),
(807, '智能家居', '7800+8+120g技术电脑', 2, 1200, 0, '2021-05-21', 'admin'),
(809, '智能家居', '电动牙刷 充电能用一年', 1, 40, 0, '2021-06-18', 'admin'),
(811, '智能家居', ' 手机遥控电动卷闸门 ', 1, 180, 0, '2021-06-18', 'admin'),
(938, '智能家居', '7860+12+240g+机械键盘', 1, 1000, 0, '2023-05-20', 'webserver'),
(813, '智能家居', '7800+8+240g技术电脑 ', 1, 1400, 0, '2021-06-18', 'admin'),
(815, '车上必备', '三头剃须刀 ', 1, 19, 0, '2021-06-18', 'admin'),
(816, '车上必备', '汽车座椅套', 1, 209, 0, '2021-06-18', 'webserver'),
(817, '车上必备', '汽车座椅套', 1, 209, 0, '2021-06-18', 'admin'),
(818, '家电维修', '外热笔式电烙铁', 1, 20, 0, '2021-08-10', 'webserver'),
(819, '家电维修', '外热笔式电烙铁', 1, 20, 0, '2021-08-10', 'admin'),
(820, '车上必备', '鼻毛剪刀', 1, 3, 0, '2021-08-12', 'webserver'),
(821, '车上必备', '鼻毛剪刀', 1, 3, 0, '2021-08-12', 'admin'),
(822, '车上必备', '指甲剪', 1, 2, 0, '2021-08-12', 'webserver'),
(823, '车上必备', '指甲剪', 1, 2, 0, '2021-08-12', 'admin'),
(825, '车上必备', '行车记录仪', 1, 120, 0, '2021-08-12', 'admin'),
(827, '家电维修', '元件盒子17.3x9.8x2.2', 1, 32, 0.5, '2021-10-11', 'admin'),
(829, '家电维修', '元件盒子17.3x9.8x2.2', 32, 2, 0.5, '2021-10-11', 'admin'),
(831, '家电维修', '元件盒子17.3x9.8x2.2', 32, 2, 0.5, '2021-10-11', 'admin'),
(833, '家电维修', '姚工热风枪850无数显', 1, 143, 0.5, '2022-02-24', 'webserver'),
(834, '家电维修', '热风枪焬膏(安立信)30g', 1, 13.8, 2, '2022-03-11', 'webserver'),
(875, '家电维修', '液晶电视维修吸盘', 1, 33, 0, '2022-08-22', 'webserver'),
(842, '家电维修', '鹿仙子维修卡具', 1, 15, 2, '2022-04-29', 'webserver'),
(859, '家电维修', '12号订书(摇头)', 1, 12, 0.5, '2022-07-30', 'webserver'),
(846, '智能家居', '19寸液晶电脑显示器', 1, 200, 0.5, '2022-05-05', 'webserver'),
(940, '智能家居', '7800+8+240g技术电脑-2', 1, 900, 0, '2023-05-20', 'webserver'),
(847, '智能家居', '19寸液晶电脑显示器2', 1, 200, 0.5, '2022-05-05', 'webserver'),
(848, '智能家居', '22寸液晶电脑显示器', 1, 100, 0.5, '2022-05-05', 'webserver'),
(854, '家电维修', '过塑机 齐心F131B', 1, 68, 2, '2022-05-10', 'webserver'),
(853, '家电维修', '惠普2330复印打印机 ', 1, 388, 2, '2022-05-10', 'webserver'),
(856, '家电维修', '卷尺3m', 1, 3, 0, '2022-07-14', 'webserver'),
(858, '制冷维修', 'R134A汽车空调低压接头', 1, 8, 2, '2022-07-29', 'webserver'),
(863, '家电维修', '20寸工具箱', 1, 16, 0, '2022-08-08', 'webserver'),
(864, '家电维修', '8寸一字螺丝刀', 1, 3, 1, '2022-08-12', 'webserver'),
(865, '家电维修', '8寸十字螺丝刀', 1, 3, 1, '2022-08-12', 'webserver'),
(866, '家电维修', '6寸薄爪拉马', 1, 42, 0, '2022-08-12', 'webserver'),
(870, '制冷维修', 'R410接头高', 1, 13, 0, '2022-08-13', 'webserver'),
(871, '制冷维修', 'R410接头低', 1, 13, 0, '2022-08-13', 'webserver'),
(872, '制冷维修', 'R22接头低', 1, 14, 0, '2022-08-13', 'webserver'),
(873, '制冷维修', 'R22接头高', 1, 14, 0, '2022-08-13', 'webserver'),
(876, '家电维修', '液晶屏维修支架6个', 1, 37, 0, '2022-09-09', 'webserver'),
(877, '智能家居', '消毒碗柜', 1, 207, 0, '2022-09-24', 'webserver'),
(878, '家电维修', 'A4切纸机', 1, 31, 1, '2022-11-06', 'webserver'),
(879, '', '冷天暖手袋', 1, 31, 0.5, '2022-12-10', 'webserver'),
(880, '', '冷天暖手袋', 1, 31, 0.5, '2022-12-10', 'webserver'),
(882, '智能家居', '1.6米直径旋转圆桌', 1, 310, 0, '2023-02-01', 'webserver'),
(953, '智能家居', '1.6米餐桌12个凳子', 1, 152, 0, '2023-06-19', 'webserver'),
(884, '智能家居', '200斤电子秤', 1, 138, 0.5, '2023-02-19', 'webserver'),
(886, '智能家居', '搬运车60x40cm', 1, 65.5, 0.5, '2023-03-01', 'webserver'),
(919, '遥控工具车', '禧玛诺18齿内变速齿轮', 2, 10, 0, '2023-05-12', 'webserver'),
(889, '遥控工具车', '38节链条', 2, 9, 5, '2023-05-05', 'webserver'),
(890, '遥控工具车', '36V350W短轴带脚带齿轮', 2, 120, 10, '2023-05-05', 'webserver'),
(891, '遥控工具车', '36VDC继电器6脚 C型', 4, 3.6, 0, '2023-05-05', 'webserver'),
(892, '遥控工具车', '前轴28cm带隔套', 2, 9.5, 0, '2023-05-05', 'webserver'),
(915, '遥控工具车', '沙滩车法兰', 2, 17, 0, '2023-05-12', 'webserver'),
(894, '遥控工具车', '进口6202轴承', 10, 1, 0, '2023-05-05', 'webserver'),
(944, '遥控工具车', '5-6-7-8寸重型万向轮底座', 4, 5.5, 0, '2023-05-30', 'webserver'),
(897, '遥控工具车', '265*185*80mm单片机盒子', 1, 14, 0, '2023-05-05', 'webserver'),
(898, '遥控工具车', '螺丝套8x40mm', 20, 0.7, 0, '2023-05-05', 'webserver'),
(899, '遥控工具车', '中号焊接定位器', 2, 8, 0, '2023-05-05', 'webserver'),
(900, '遥控工具车', '方钢30*30*2mm--6米', 1, 97, 0, '2023-05-05', 'webserver'),
(901, '遥控工具车', '万向轮', 2, 13, 0, '2023-05-05', 'webserver'),
(902, '遥控工具车', 'esp32底座', 1, 9, 0, '2023-05-05', 'webserver'),
(904, '遥控工具车', '13X6.5-6轮胎带轮毂', 2, 75, 0, '2023-05-05', 'webserver'),
(905, '遥控工具车', '两个电机底座（帮打孔）', 2, 13, 0, '2023-05-05', 'webserver'),
(967, '智能家居', '360P1WIFI路由器', 1, 19, 0, '2023-09-18', 'webserver'),
(917, '遥控工具车', '36v800W有刷控制器', 1, 41, 6, '2023-05-12', 'webserver'),
(911, '遥控工具车', '油漆', 1, 20, 0, '2023-05-12', 'webserver'),
(912, '遥控工具车', ' 焊条焊料', 1, 30, 0, '2023-05-12', 'webserver'),
(913, '遥控工具车', 'PCB板腐浊料', 1, 5, 0, '2023-05-12', 'webserver'),
(914, '遥控工具车', '5-38v可调降压模块', 1, 2.5, 1, '2023-05-12', 'webserver'),
(918, '遥控工具车', 'PCB板钻头', 1, 2.5, 0, '2023-05-12', 'webserver'),
(921, '遥控工具车', '6002轴承', 4, 1.82, 0, '2023-05-13', 'webserver'),
(927, '遥控工具车', '30*56*3mm铁片', 6, 1, 0, '2023-05-14', 'webserver'),
(923, '遥控工具车', '2芯纯铜2.5*1000mm', 1, 29, 0, '2023-05-13', 'webserver'),
(924, '遥控工具车', '大型船型开关', 1, 4, 0, '2023-05-14', 'webserver'),
(930, '遥控工具车', '36v12a充电器', 1, 18, 0, '2023-05-18', 'webserver'),
(926, '遥控工具车', '20A紫铜卡扣10个', 1, 5, 0, '2023-05-14', 'webserver'),
(929, '遥控工具车', '嘉立创打样5片PCB', 1, 54, 0, '2023-05-18', 'webserver'),
(943, '遥控工具车', '34*60*3mm圆形铁片10个', 1, 6, 0, '2023-05-30', 'webserver'),
(932, '遥控工具车', '法兰改装转动管', 2, 42, 0, '2023-05-18', 'webserver'),
(933, '遥控工具车', '柳螺母头+10个M5', 1, 10, 0, '2023-05-19', 'webserver'),
(934, '遥控工具车', '拿快递交通费', 1, 100, 0, '2023-05-19', 'webserver'),
(935, '家电维修', '至尊电子秤计价30kg', 1, 88, 0, '2023-05-19', 'webserver'),
(941, '遥控工具车', '请帮电焊50', 1, 50, 0, '2023-05-21', 'webserver'),
(946, '遥控工具车', '405mm一字白钢刀片', 1, 17, 0, '2023-05-30', 'webserver'),
(947, '遥控工具车', '30cm直径26mm+双9齿轮轴', 1, 28, 0, '2023-05-30', 'webserver'),
(948, '遥控工具车', '割草机工作头', 1, 20, 0, '2023-05-30', 'webserver'),
(949, '遥控工具车', '割草机侧挂连接盘26mm9齿', 1, 18, 0, '2023-05-30', 'webserver'),
(952, '遥控工具车', '8路模块配8键遥控器433', 1, 33, 0, '2023-06-14', 'webserver'),
(951, '遥控工具车', 'U型卡扣M20', 1, 6, 1, '2023-06-12', 'webserver'),
(968, '家电维修', '电子元件15格盒子', 40, 2, 0, '2023-11-27', 'webserver'),
(957, '家电维修', '上门维修山地车26寸', 1, 130, 0, '2023-08-05', 'webserver'),
(959, '制冷维修', '空调加氟安全带', 1, 35, 0, '2023-08-08', 'webserver'),
(962, '家电维修', '鹿仙子出锡辅助器', 1, 30, 0, '2023-08-16', 'webserver'),
(963, '车上必备', '手机导航支架', 1, 3, 0, '2023-08-20', 'webserver'),
(965, '家电维修', '晨洲岛12s语音数字万用表', 1, 44.1, 0, '2023-08-24', 'webserver'),
(966, '家电维修', '金属锡线架', 1, 5, 0, '2023-09-07', 'webserver'),
(969, '智能家居', '鑫悦电猫', 1, 58, 0, '2023-12-02', 'webserver'),
(971, '智能家居', '血压仪', 1, 42, 0, '2024-02-24', 'webserver');

-- --------------------------------------------------------

--
-- 表的结构 `WisdomToolsType`
--

CREATE TABLE IF NOT EXISTS `WisdomToolsType` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `category` varchar(32) NOT NULL DEFAULT '',
  `user` varchar(32) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=29 ;

--
-- 转存表中的数据 `WisdomToolsType`
--

INSERT INTO `WisdomToolsType` (`id`, `category`, `user`) VALUES
(1, '家电维修', 'webserver'),
(3, '制冷维修', 'webserver'),
(4, '汽车维修', 'webserver'),
(5, '智能家居', 'webserver'),
(6, '车上必备', 'webserver'),
(7, '外出必备', 'webserver'),
(8, '水果工具', 'webserver'),
(19, '家电维修', 'admin'),
(20, '制冷维修', 'admin'),
(21, '汽车维修', 'admin'),
(22, '智能家居', 'admin'),
(23, '车上必备', 'admin'),
(24, '外出必备', 'admin'),
(25, '水果工具', 'admin'),
(26, '餐饮小吃', 'webserver'),
(27, '餐饮小吃', 'admin'),
(28, '遥控工具车', 'webserver');

