arduino程序
parent
8800ffc367
commit
884fd67f77
|
@ -0,0 +1,301 @@
|
|||
<html lang="zh-cn">
|
||||
<head>
|
||||
<title>Air Pump Control</title>
|
||||
<meta charset="utf-8">
|
||||
<meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||
<style>
|
||||
/*input框*/
|
||||
input,
|
||||
button {
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.tl-input {
|
||||
width: 100%;
|
||||
border: 1px solid #ccc;
|
||||
padding: 7px 0;
|
||||
background: #F4F4F7;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
padding-left: 5px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
|
||||
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s
|
||||
}
|
||||
|
||||
.tl-input:focus {
|
||||
border-color: #66afe9;
|
||||
outline: 0;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6)
|
||||
}
|
||||
|
||||
.ant-btn {
|
||||
line-height: 1.499;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
font-weight: 400;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
-webkit-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
|
||||
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
|
||||
cursor: pointer;
|
||||
-webkit-transition: all .3s cubic-bezier(.645, .045, .355, 1);
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1);
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-ms-touch-action: manipulation;
|
||||
touch-action: manipulation;
|
||||
height: 32px;
|
||||
padding: 0 15px;
|
||||
font-size: 14px;
|
||||
border-radius: 4px;
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
background-color: #fff;
|
||||
border-color: #d9d9d9;
|
||||
}
|
||||
|
||||
.ant-btn-primary {
|
||||
color: #fff;
|
||||
background-color: #1890ff;
|
||||
border-color: #1890ff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
|
||||
-webkit-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
|
||||
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
|
||||
}
|
||||
|
||||
.ant-btn-red {
|
||||
color: #fff;
|
||||
background-color: #FF5A44;
|
||||
border-color: #FF5A44;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
|
||||
-webkit-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
|
||||
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
|
||||
}
|
||||
|
||||
/* 这里不考虑浏览器的兼容性 */
|
||||
#control input {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
margin: 20px 0;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#control input[type="text"] {
|
||||
width: 100%;
|
||||
font-size: 25px;
|
||||
appearance: none;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 3px solid #ededed;
|
||||
color: #ededed;
|
||||
}
|
||||
|
||||
#control input[type="range"] {
|
||||
width: 100%;
|
||||
-webkit-appearance: none;
|
||||
/* background-color: silver; */
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
background: -webkit-linear-gradient(#ffa200, #ffa200) no-repeat white;
|
||||
background-size: 50% 100%;
|
||||
}
|
||||
|
||||
#control input[type="range"]::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
background-color: #aaa;
|
||||
width: 8px;
|
||||
height: 20px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#control input[type="range"]::-webkit-slider-thumb:hover {
|
||||
background: #666;
|
||||
}
|
||||
|
||||
#control #voltage {
|
||||
background-size: 0% 100%;
|
||||
}
|
||||
|
||||
#control #speed {
|
||||
background: linear-gradient(to right, #ffa200, white 0%, white);
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
#control input[type="button"] {
|
||||
padding: 5px;
|
||||
margin: 5px 0;
|
||||
background: linear-gradient(to bottom right, red 10%, white 90%);
|
||||
border: 0px;
|
||||
width: 100%;
|
||||
color: white;
|
||||
font-weight: white;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
var running_type = ["无", "篮球", "摩托车", "汽车", "自行车", "自定义"];
|
||||
var pressure_type = [0, 0.6, 2.4, 2.5, 3.9, 2.4];
|
||||
function loadXMLDoc(path,element)
|
||||
{
|
||||
var xmlhttp;
|
||||
if (window.XMLHttpRequest)
|
||||
{
|
||||
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
|
||||
xmlhttp=new XMLHttpRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
// IE6, IE5 浏览器执行代码
|
||||
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
xmlhttp.onreadystatechange=function()
|
||||
{
|
||||
if (xmlhttp.readyState==4 && xmlhttp.status==200)
|
||||
{
|
||||
document.getElementById(element).innerHTML=xmlhttp.responseText;
|
||||
}
|
||||
}
|
||||
xmlhttp.open("GET",path,true);
|
||||
xmlhttp.send();
|
||||
}
|
||||
|
||||
function UpdateInfo()
|
||||
{
|
||||
var xmlhttp;
|
||||
if (window.XMLHttpRequest)
|
||||
{
|
||||
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
|
||||
xmlhttp=new XMLHttpRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
// IE6, IE5 浏览器执行代码
|
||||
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
xmlhttp.onreadystatechange=function()
|
||||
{
|
||||
if (xmlhttp.readyState==4 && xmlhttp.status==200)
|
||||
{
|
||||
var arr=xmlhttp.responseText.split(",");
|
||||
|
||||
document.getElementById('bat_voltage').innerHTML=arr[1];
|
||||
if(arr[3]==1){
|
||||
document.getElementById('CurrentMillis').innerHTML="已启动:"+arr[0];
|
||||
}else{
|
||||
document.getElementById('CurrentMillis').innerHTML="未启动";
|
||||
}
|
||||
document.getElementById('running_type').innerHTML=arr[4];
|
||||
document.getElementById('running_pressure_type').value=arr[5];
|
||||
running_type5(arr[4]);
|
||||
if(arr[2]=="-1.00"){
|
||||
document.getElementById('pressure_val').innerHTML="<font color='red'>传感器异常</font>";
|
||||
document.getElementById('running_type_html').innerHTML=document.getElementById('running_type_html').innerHTML+" <font color='red'>传感器异常,启动会限制执行1分钟</font>";
|
||||
}else{
|
||||
document.getElementById('pressure_val').innerHTML=arr[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlhttp.open("GET",'/update',true);
|
||||
xmlhttp.send();
|
||||
}
|
||||
|
||||
|
||||
function MyAutoRun()
|
||||
{
|
||||
UpdateInfo();
|
||||
}
|
||||
setInterval("MyAutoRun()",1000);
|
||||
|
||||
|
||||
function checkNum(obj) {
|
||||
if (isNaN(obj.value)) { //检查是否是非数字值
|
||||
obj.value = "";
|
||||
}
|
||||
if (obj != null) { //检查小数点后是否对于两位
|
||||
if ( obj.value.toString().split(".").length > 1 && obj.value.toString().split(".")[1].length > 2 ) { //alert("小数点后多于两位!");
|
||||
obj.value = Number(obj.value).toPrecision(2);
|
||||
}
|
||||
if(obj.value<0){
|
||||
obj.value = 0-obj.value;
|
||||
}
|
||||
if(obj.value>6){
|
||||
obj.value = 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function running_type5(obj){
|
||||
document.getElementById('running_type_html').innerHTML=running_type[obj];
|
||||
document.getElementById('running_type').value=obj;
|
||||
if(obj!="5"){
|
||||
document.getElementById('running_pressure_type').value=pressure_type[obj];
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body style="background-color:black;color:white">
|
||||
|
||||
<div>
|
||||
<font size=6>微型气泵状态监控</font>
|
||||
</div>
|
||||
<div id="OperationHit"><h2></h2></div>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td height="50"></font> <span id=CurrentMillis></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td height="50">
|
||||
<div>气压:<span id=pressure_val>0</span>Bar 电压:<span id=bat_voltage>0</span>V</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td height="50">
|
||||
<button type="button" class="ant-btn ant-btn-primary" onclick="running_type5(this.value);loadXMLDoc('/Control?Type=2&Index='+this.value+'&Operation='+document.getElementById('running_pressure_type').value,'OperationHit');" value="1">篮球</button>
|
||||
<button type="button" class="ant-btn ant-btn-primary" onclick="running_type5(this.value);loadXMLDoc('/Control?Type=2&Index='+this.value+'&Operation='+document.getElementById('running_pressure_type').value,'OperationHit');" value="2">摩托车</button>
|
||||
<button type="button" class="ant-btn ant-btn-primary" onclick="running_type5(this.value);loadXMLDoc('/Control?Type=2&Index='+this.value+'&Operation='+document.getElementById('running_pressure_type').value,'OperationHit');" value="5">自定义</button> <br><br>
|
||||
<button type="button" class="ant-btn ant-btn-primary" onclick="running_type5(this.value);loadXMLDoc('/Control?Type=2&Index='+this.value+'&Operation='+document.getElementById('running_pressure_type').value,'OperationHit');" value="3">汽车</button>
|
||||
<button type="button" class="ant-btn ant-btn-primary" onclick="running_type5(this.value);loadXMLDoc('/Control?Type=2&Index='+this.value+'&Operation='+document.getElementById('running_pressure_type').value,'OperationHit');" value="4">自行车</button>
|
||||
</td>
|
||||
<td align="center">
|
||||
<table border="0" cellspacing="0" cellpadding="0" id="diy_show">
|
||||
<tr>
|
||||
<td>
|
||||
<input class="tl-input" type="text" name="running_pressure_type" id="running_pressure_type" size="2" onchange="checkNum(this);loadXMLDoc('/Control?Type=2&Index=5&Operation='+document.getElementById('running_pressure_type').value,'OperationHit');">
|
||||
<button type="button" class="ant-btn ant-btn-primary" onclick="running_type5(5);document.getElementById('running_pressure_type').value=(Number(document.getElementById('running_pressure_type').value)+0.1).toPrecision(2);checkNum(document.getElementById('running_pressure_type'));loadXMLDoc('/Control?Type=2&Index=5&Operation='+document.getElementById('running_pressure_type').value,'OperationHit');">+</button>
|
||||
<button type="button" class="ant-btn ant-btn-primary" onclick="running_type5(5);document.getElementById('running_pressure_type').value=(Number(document.getElementById('running_pressure_type').value)-0.1).toPrecision(2);checkNum(document.getElementById('running_pressure_type'));loadXMLDoc('/Control?Type=2&Index=5&Operation='+document.getElementById('running_pressure_type').value,'OperationHit');">-</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td height="50">
|
||||
<input value="0" id="running_type" hidden>
|
||||
当前充气类型:<span id="running_type_html">无</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td height="50">
|
||||
<button type="button" class="ant-btn ant-btn-red" onclick="loadXMLDoc('/Control?Type=1&Index='+document.getElementById('running_type').value+'&Operation='+document.getElementById('running_pressure_type').value,'OperationHit')">气泵启停</button>
|
||||
<button type="button" class="ant-btn ant-btn-red" onclick="loadXMLDoc('/Control?Type=0&Index=0&Operation=2','OperationHit')">系统重启</button>
|
||||
<button type="button" class="ant-btn ant-btn-red" onclick="loadXMLDoc('/Control?Type=0&Index=0&Operation=0','OperationHit')">传感器重置</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,44 @@
|
|||
#include <Wire.h>
|
||||
#include <WiFi.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include <WebServer.h>
|
||||
#include <FS.h>
|
||||
#include "SPIFFS.h"
|
||||
|
||||
#define LIGHT_NUMBER 3 //节点开关数量
|
||||
|
||||
#define LIGHT_1_PIN 23
|
||||
#define LIGHT_2_PIN 22
|
||||
#define LIGHT_3_PIN 21
|
||||
|
||||
//触摸指示led
|
||||
#define TOUCHLED_1_PIN 27
|
||||
#define TOUCHLED_2_PIN 26
|
||||
#define TOUCHLED_3_PIN 25
|
||||
|
||||
//外部开关输入引脚
|
||||
#define CONTROL_1_PIN 34
|
||||
#define CONTROL_2_PIN 35
|
||||
#define CONTROL_3_PIN 32
|
||||
|
||||
#define SDA_PIN 16
|
||||
#define SCL_PIN 17
|
||||
|
||||
//#define INPUT_VOLTAGE_SENSE_PIN 33
|
||||
|
||||
double R1_VOLTAGE = 68000; //68K
|
||||
double R2_VOLTAGE = 10000; // 10K
|
||||
|
||||
//一定要修改这里,使用自己的wifi信息
|
||||
char mac_tmp[6];
|
||||
const char *ssid = mac_tmp; //Wifi名称
|
||||
const char * password = "12345678"; //Wifi密码
|
||||
|
||||
const char* username = "admin"; //web用户名
|
||||
const char* userpassword = "12345678"; //web用户密码
|
||||
|
||||
const char * ServerName = "ESP32-air-pump";
|
||||
|
||||
|
||||
#include "esp32_air_pump_main.h"
|
|
@ -0,0 +1,56 @@
|
|||
/* CS1237充气气泵控制板控制程序
|
||||
* 气压传感器DSH700,数模模块CS1237
|
||||
* 1毫米水柱=9.8066135802帕斯卡 液体压强计算公式P=ρgh可知:代入常数值:ρ=1000kg/m^3,g=9.8m/s^2=9.8N/kg
|
||||
* 1巴(bar)=100千帕(kPa)=1000百帕(hPa)=1000毫巴(mbar)=100000帕斯卡
|
||||
* 1psi=6.895kPa=0.0689476bar =0.006895MPa
|
||||
1标准大气压(atm)=14.696磅/英寸2(psi)
|
||||
1巴(bar)=100千帕(kPa)
|
||||
1达因/厘米2 (dyn/cm2)=0.1帕(Pa)
|
||||
1托(Torr)=133.322帕(Pa)
|
||||
1毫米汞柱(mmHg)=133.322帕(Pa)
|
||||
1毫米水柱(mmH2O)=9.80665帕(Pa)
|
||||
1工程大气压=98.0665千帕(kPa)
|
||||
1千帕(kPa)=0.145磅力/英寸2(psi)=0.0102千克力/厘米2(kgf/cm2)=0.0098大气压(atm)
|
||||
1磅力/英寸2(psi)=6.895千帕(kPa)=0.0703千克力/厘米2(kgf/cm2) =0.0689巴(bar)=0.068大气压(atm)
|
||||
1标准大气压(atm)=101.325千帕(kPa)=14.696磅/英寸2(psi)=1.0133巴(bar)=760毫米汞柱(mmHg)
|
||||
* 屏显版:选择充气气压,按键开启充气,显示当前气压,达到目标值停止充气
|
||||
* 简单版:4个led显示4种气压选择,按键开启充气
|
||||
*
|
||||
* 927384 0.3
|
||||
* 1026141 0.4
|
||||
* 1305485 0.6 篮球
|
||||
* 2080369 1.2
|
||||
* 2224276 1.29
|
||||
* 2539945 1.5
|
||||
* 3113765 1.9
|
||||
* 3188414 2
|
||||
* 3234954 2.04
|
||||
* 3375692 2.15
|
||||
* 3762277 2.43 摩托车
|
||||
* 3839579 2.5 汽车
|
||||
* 3902948 2.53
|
||||
* 4273014 2.8
|
||||
* 4419500 2.95
|
||||
* 4480105 2.97
|
||||
* 4580560 3.05
|
||||
* 4966855 3.3
|
||||
* 5237358 3.5
|
||||
* 5691781 3.9 自行车
|
||||
* 5797899 4.0
|
||||
* 5890198 4.03
|
||||
* 6124920 4.22
|
||||
* 7168366 5.1
|
||||
* 7701561 5.4
|
||||
* 8276554 5.85
|
||||
* ESP32 16; 17;
|
||||
* ESP8266 D1 = GPIO5; D2 = GPIO4;
|
||||
*
|
||||
* 值得买上有大神分享了制作过程,并且分享了arduino的代码,这里感谢大神 https://zhiyou.smzdm.com/member/4580489080/
|
||||
* 传感器最大压力值6bar
|
||||
* 参考各种换算方法,1psi=6.895kPa=0.0689476bar,按照这个计算出来基本准确
|
||||
* 如果有更好的算法,希望不吝赐教
|
||||
* CS1237充气气泵控制板[未验证] - 立创EDA开源硬件平台 https://oshwhub.com/muyan2020/cs1237-chong-qi-qi-beng
|
||||
*
|
||||
*/
|
||||
|
||||
#include "esp32_air_pump.h"
|
|
@ -0,0 +1,597 @@
|
|||
|
||||
void StartWebServer();
|
||||
|
||||
unsigned char RelayPin[LIGHT_NUMBER]; // = {RELAY1,RELAY2};
|
||||
unsigned char TOUCHLED_PIN[LIGHT_NUMBER]; //触摸按键pin
|
||||
unsigned char CONTROL_PIN[LIGHT_NUMBER]; //按键开关pin
|
||||
unsigned char CONTROL_STAT[LIGHT_NUMBER]; //按键开关状态处理
|
||||
|
||||
const int threshold_top = 20; //触摸顶部阈值
|
||||
const int threshold_bottom = 1; //触摸底部阈值,越接近数值越小
|
||||
const int threshold_count = 4; //触摸计数器有效值,通常会有意外的自动触发
|
||||
|
||||
int touchread[4] = {100, 100, 100, 100}; //初始化触摸读取值为100,无触摸
|
||||
int touchDetected[4] = {}; //通过touchdetected持续计数判断是否按键,防止无触碰触发
|
||||
|
||||
bool touch_touched[4] = {}; //单击判断,作为灯开关的判断
|
||||
int touch_touched_times[4] = {}; //单击次数,单击切换模式,双击
|
||||
int touch_touching_time[4] = {}; //持续触摸秒数,用于判断长按事件,长按关闭,长按开启,开启状态长按调光,
|
||||
bool touch_STATE[4] = {0, 0, 0, 0}; // 定义按键触发对象状态变量初始值,true开启
|
||||
|
||||
const double min_voltage = 6; //电池检测最低电压
|
||||
double bat_voltage;
|
||||
int running_type = 0; //运行状态 0不运行 1篮球 2摩托车 3汽车 4自行车 5自定义
|
||||
uint32_t running_time;
|
||||
double pressure_val = -1; //气压数据 如果设置初始值为-1则不检测气压 传感器强制执行
|
||||
int pressure_type[6] = {600000, 1305485, 3762277, 3839579, 5691781, 1305485}; //气压类型 0不运行 1篮球 2摩托车 3汽车 4自行车
|
||||
float running_pressure_type;
|
||||
|
||||
int ndrdy = SDA_PIN; //SDA
|
||||
int clck = SCL_PIN; //SCL
|
||||
|
||||
unsigned long TenthSecondsSinceStart = 0;
|
||||
void TenthSecondsSinceStartTask();
|
||||
void OnTenthSecond();
|
||||
void OnSecond();
|
||||
|
||||
WebServer ESP32Server(80);
|
||||
|
||||
double return_voltage_value(int pin_no)
|
||||
{
|
||||
double tmp = 0;
|
||||
double ADCVoltage = 0;
|
||||
double inputVoltage = 0;
|
||||
double avg = 0;
|
||||
for (int i = 0; i < 150; i++)
|
||||
{
|
||||
tmp = tmp + analogRead(pin_no);
|
||||
}
|
||||
avg = tmp / 150;
|
||||
ADCVoltage = ((avg * 3.3) / (4095)) + 0.112;
|
||||
inputVoltage = ADCVoltage / (R2_VOLTAGE / (R1_VOLTAGE + R2_VOLTAGE)); // formula for calculating voltage in i.e. GND
|
||||
return inputVoltage;
|
||||
}
|
||||
|
||||
//触摸感应处理
|
||||
void touchAttach(int touchID, uint8_t touchPin) {
|
||||
touchread[touchID] = touchRead(touchPin);
|
||||
if ( touchread[touchID] <= threshold_top && touchread[touchID] > threshold_bottom ) { //达到触发值的计数
|
||||
delay(38); // 0.038秒
|
||||
touchDetected[touchID]++; //持续触摸计数
|
||||
if ( (touchDetected[touchID] >= threshold_count) && digitalRead(TOUCHLED_PIN[touchID]) == HIGH ) { //达到触发值的,灯不亮则亮灯
|
||||
//digitalWrite(TOUCHLED_PIN[touchID], LOW);
|
||||
}
|
||||
} else if (touchread[touchID] > threshold_top) { //无触摸处理
|
||||
if ( digitalRead(TOUCHLED_PIN[touchID]) == LOW ) { //灭触摸灯
|
||||
//digitalWrite(TOUCHLED_PIN[touchID], HIGH);
|
||||
}
|
||||
if ( touchDetected[touchID] >= threshold_count ) { //检测无触摸之前的有效计数,触摸过则标记
|
||||
touch_touched[touchID] = true;
|
||||
touch_touched_times[touchID]++; //触摸计数+1
|
||||
}
|
||||
touch_touching_time[touchID] = 0; //持续触摸时间清零
|
||||
touchDetected[touchID] = 0; //持续触摸计数清零
|
||||
}
|
||||
}
|
||||
|
||||
//按键开关的防抖处理判断
|
||||
void controlAttach(int touchID, int touch_type = 0) { // 0 常开或常闭开关 1 轻触开关
|
||||
//按键开关,根据是否跟上一次状态相同作出判断,如果当前相同则不动作
|
||||
if ( CONTROL_STAT[touchID] == !digitalRead(CONTROL_PIN[touchID])) {
|
||||
|
||||
int val1 = digitalRead(CONTROL_PIN[touchID]);
|
||||
delay(38); // 0.038秒
|
||||
int val11 = digitalRead(CONTROL_PIN[touchID]);
|
||||
if (val11 != val1) {
|
||||
delay(15);
|
||||
val11 = digitalRead(CONTROL_PIN[touchID]);
|
||||
}
|
||||
delay(168); // 故意不要连续读取
|
||||
if (val1 == val11) { // 确定不是抖动
|
||||
if ( CONTROL_STAT[touchID] == !digitalRead(CONTROL_PIN[touchID])) {
|
||||
touch_touched[touchID] = true;
|
||||
touch_touched_times[touchID]++;
|
||||
if (touch_type == 0) //常开或常闭开关更新状态,轻触开关则不更新
|
||||
CONTROL_STAT[touchID] = digitalRead(CONTROL_PIN[touchID]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long readADC()
|
||||
{
|
||||
if (digitalRead(ndrdy))
|
||||
return -1;
|
||||
|
||||
long result = 0;
|
||||
|
||||
for (int i = 0; i < 24; i++)
|
||||
{
|
||||
digitalWrite(clck, HIGH);
|
||||
delayMicroseconds(1);
|
||||
int new_bit = digitalRead(ndrdy);
|
||||
digitalWrite(clck, LOW);
|
||||
delayMicroseconds(1);
|
||||
result <<= 1;
|
||||
result |= new_bit;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
digitalWrite(clck, HIGH);
|
||||
delayMicroseconds(1);
|
||||
digitalWrite(clck, LOW);
|
||||
delayMicroseconds(1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
delay(50);
|
||||
|
||||
Serial.begin(115200);
|
||||
Serial.println("");
|
||||
|
||||
while (!Serial) {}
|
||||
|
||||
if (pressure_val != -1) {
|
||||
pinMode(ndrdy, INPUT);
|
||||
digitalWrite(ndrdy, LOW);
|
||||
|
||||
pinMode(clck, OUTPUT);
|
||||
digitalWrite(clck, LOW);
|
||||
|
||||
while (digitalRead(ndrdy)) {}
|
||||
while (!digitalRead(ndrdy)) {}
|
||||
}
|
||||
|
||||
CONTROL_PIN[0] = CONTROL_1_PIN; //按键
|
||||
CONTROL_PIN[1] = CONTROL_2_PIN;
|
||||
CONTROL_PIN[2] = CONTROL_3_PIN;
|
||||
TOUCHLED_PIN[0] = TOUCHLED_1_PIN; //指示灯
|
||||
TOUCHLED_PIN[1] = TOUCHLED_2_PIN;
|
||||
TOUCHLED_PIN[2] = TOUCHLED_3_PIN;
|
||||
for (byte i = 0; i < LIGHT_NUMBER; i++)
|
||||
{
|
||||
//机械开关 接地 低电平触发
|
||||
pinMode(CONTROL_PIN[i], INPUT_PULLUP); //设置按键管脚上拉输入模式
|
||||
pinMode(TOUCHLED_PIN[i], OUTPUT);
|
||||
digitalWrite(TOUCHLED_PIN[i], HIGH); //低电平有效
|
||||
CONTROL_STAT[i] = digitalRead(CONTROL_PIN[i]); //开关所在状态读取,当前可能为高或者低
|
||||
}
|
||||
|
||||
RelayPin[0] = LIGHT_1_PIN;
|
||||
RelayPin[1] = LIGHT_2_PIN;
|
||||
RelayPin[2] = LIGHT_3_PIN;
|
||||
|
||||
for (byte i = 0; i < LIGHT_NUMBER; i++)
|
||||
{
|
||||
pinMode(RelayPin[i], OUTPUT);
|
||||
digitalWrite(RelayPin[i], HIGH); //低电平有效
|
||||
}
|
||||
|
||||
uint32_t chipId = 0;
|
||||
for (int i = 0; i < 17; i = i + 8) {
|
||||
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
|
||||
}
|
||||
Serial.printf("Chip ID: %d\r\n", chipId);
|
||||
|
||||
Serial.printf("ESP32 Chip ID = %04X", (uint16_t)(ESP.getEfuseMac() >> 32)); //print High 2 bytes
|
||||
Serial.printf("%08X\r\n", (uint32_t)ESP.getEfuseMac()); //print Low 4bytes.
|
||||
|
||||
Serial.printf("Chip model = %s Rev %d\r\n", ESP.getChipModel(), ESP.getChipRevision());
|
||||
Serial.printf("This chip has %d cores CpuFreqMHz = %u\r\n", ESP.getChipCores(), ESP.getCpuFreqMHz());
|
||||
Serial.printf("get Cycle Count = %u\r\n", ESP.getCycleCount());
|
||||
Serial.printf("SDK version:%s\r\n", ESP.getSdkVersion()); //获取IDF版本
|
||||
|
||||
//获取片内内存 Internal RAM
|
||||
Serial.printf("Total heap size = %u\t", ESP.getHeapSize());
|
||||
Serial.printf("Available heap = %u\r\n", ESP.getFreeHeap());
|
||||
Serial.printf("Lowest level of free heap since boot = %u\r\n", ESP.getMinFreeHeap());
|
||||
Serial.printf("Largest block of heap that can be allocated at once = %u\r\n", ESP.getMaxAllocHeap());
|
||||
|
||||
//SPI RAM
|
||||
Serial.printf("Total Psram size = %u\t", ESP.getPsramSize());
|
||||
Serial.printf("Available Psram = %u\r\n", ESP.getFreePsram());
|
||||
Serial.printf("Lowest level of free Psram since boot = %u\r\n", ESP.getMinFreePsram());
|
||||
Serial.printf("Largest block of Psram that can be allocated at once = %u\r\n", ESP.getMinFreePsram());
|
||||
|
||||
|
||||
sprintf(mac_tmp, "%02X\r\n", (uint32_t)(ESP.getEfuseMac() >> (24) ));
|
||||
sprintf(mac_tmp, "ESP32-%c%c%c%c%c%c", mac_tmp[4], mac_tmp[5], mac_tmp[2], mac_tmp[3], mac_tmp[0], mac_tmp[1] );
|
||||
//wifi初始化
|
||||
WiFi.mode(WIFI_AP);
|
||||
while (!WiFi.softAP(ssid, password)) {}; //启动AP
|
||||
Serial.println("AP启动成功");
|
||||
Serial.println("Ready");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.softAPIP());
|
||||
byte mac[6];
|
||||
WiFi.macAddress(mac);
|
||||
WiFi.setHostname(ServerName);
|
||||
Serial.printf("macAddress 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
|
||||
//以下是启动OTA,可以通过WiFi刷新固件
|
||||
ArduinoOTA.setHostname(ServerName);
|
||||
ArduinoOTA.onStart([]() {
|
||||
String type;
|
||||
if (ArduinoOTA.getCommand() == U_FLASH) {
|
||||
type = "sketch";
|
||||
} else { // U_SPIFFS
|
||||
type = "filesystem";
|
||||
}
|
||||
|
||||
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
|
||||
Serial.println("Start updating " + type);
|
||||
});
|
||||
ArduinoOTA.onEnd([]() {
|
||||
Serial.println("\nEnd");
|
||||
});
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
|
||||
});
|
||||
ArduinoOTA.onError([](ota_error_t error) {
|
||||
Serial.printf("Error[%u]: ", error);
|
||||
if (error == OTA_AUTH_ERROR) {
|
||||
Serial.println("Auth Failed");
|
||||
} else if (error == OTA_BEGIN_ERROR) {
|
||||
Serial.println("Begin Failed");
|
||||
} else if (error == OTA_CONNECT_ERROR) {
|
||||
Serial.println("Connect Failed");
|
||||
} else if (error == OTA_RECEIVE_ERROR) {
|
||||
Serial.println("Receive Failed");
|
||||
} else if (error == OTA_END_ERROR) {
|
||||
Serial.println("End Failed");
|
||||
}
|
||||
});
|
||||
ArduinoOTA.begin();
|
||||
Serial.println("ATO Ready");
|
||||
|
||||
Serial.println("");
|
||||
|
||||
// 启动闪存文件系统
|
||||
if (SPIFFS.begin())
|
||||
{
|
||||
Serial.println("SPIFFS Started.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("SPIFFS Failed to Start.");
|
||||
}
|
||||
|
||||
StartWebServer();
|
||||
Serial.println("System ready");
|
||||
Serial.println("-----------------------------------------------");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
ArduinoOTA.handle();
|
||||
|
||||
ESP32Server.handleClient();
|
||||
delay(2);
|
||||
TenthSecondsSinceStartTask();
|
||||
|
||||
//触摸感应处理
|
||||
touchAttach(0, T4);
|
||||
touchAttach(1, T3);
|
||||
touchAttach(2, T2);
|
||||
|
||||
for (byte i = 0; i < LIGHT_NUMBER; i++)
|
||||
{
|
||||
controlAttach(i, 1); //按键开关处理
|
||||
if (touch_touched[i]) {
|
||||
Serial.print(i);
|
||||
Serial.print(" control touched\t");
|
||||
running_type = touch_touched_times[i] % 6;
|
||||
Serial.println(running_type);
|
||||
|
||||
switch (i) {
|
||||
case 0: //启停控制
|
||||
if ( running_type > 0 && !touch_STATE[i]) { //有类型选择且未运行
|
||||
touch_STATE[i] = 1; //启动状态修改
|
||||
digitalWrite(RelayPin[i], LOW);
|
||||
running_time = millis();
|
||||
Serial.println(" Start Running ");
|
||||
} else {
|
||||
touch_STATE[i] = 0;
|
||||
digitalWrite(RelayPin[i], HIGH);
|
||||
Serial.println(" Sop Running ");
|
||||
}
|
||||
break;
|
||||
case 1: //灯控制
|
||||
switch (running_type) {
|
||||
case 0: // 全暗不启动
|
||||
digitalWrite(TOUCHLED_PIN[2], HIGH);
|
||||
digitalWrite(TOUCHLED_PIN[1], HIGH);
|
||||
digitalWrite(TOUCHLED_PIN[0], HIGH);
|
||||
break;
|
||||
case 1: //篮球 0.6bar
|
||||
digitalWrite(TOUCHLED_PIN[2], LOW);
|
||||
digitalWrite(TOUCHLED_PIN[1], HIGH);
|
||||
digitalWrite(TOUCHLED_PIN[0], HIGH);
|
||||
break;
|
||||
case 2: //汽车2.5
|
||||
digitalWrite(TOUCHLED_PIN[2], HIGH);
|
||||
digitalWrite(TOUCHLED_PIN[1], LOW);
|
||||
digitalWrite(TOUCHLED_PIN[0], HIGH);
|
||||
break;
|
||||
case 3: //摩托车
|
||||
digitalWrite(TOUCHLED_PIN[2], LOW);
|
||||
digitalWrite(TOUCHLED_PIN[1], LOW);
|
||||
digitalWrite(TOUCHLED_PIN[0], HIGH);
|
||||
break;
|
||||
case 4: //自行车
|
||||
digitalWrite(TOUCHLED_PIN[2], HIGH);
|
||||
digitalWrite(TOUCHLED_PIN[1], HIGH);
|
||||
digitalWrite(TOUCHLED_PIN[0], LOW);
|
||||
break;
|
||||
case 5: //自定义
|
||||
digitalWrite(TOUCHLED_PIN[2], LOW);
|
||||
digitalWrite(TOUCHLED_PIN[1], LOW);
|
||||
digitalWrite(TOUCHLED_PIN[0], LOW);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
touch_touched[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pressure_val != -1) { //传感器正常
|
||||
long adcValue = readADC();
|
||||
pressure_val = adcValue / 100000 * 0.0689476;
|
||||
pressure_type[5] = running_pressure_type*100000 / 0.0689476;
|
||||
|
||||
if (adcValue > 600000 ) {
|
||||
Serial.print("ADC reading: ");
|
||||
Serial.print(adcValue);
|
||||
Serial.print("\t");
|
||||
Serial.print(pressure_val);
|
||||
Serial.print("bar\t");
|
||||
Serial.println(pressure_type[5]);
|
||||
}
|
||||
|
||||
if (touch_STATE[0]) { //启动 充气执行超过3分钟自动停止
|
||||
if (adcValue >= pressure_type[running_type] || ((millis() - running_time) / 1000) > 180 ) //气压达到设定值则停机
|
||||
{
|
||||
touch_STATE[0] = 0;
|
||||
delay(500);
|
||||
digitalWrite(RelayPin[0], HIGH);
|
||||
Serial.println(" End of Run ");
|
||||
delay(500);
|
||||
}
|
||||
}
|
||||
} else { //无传感器强制启动,设定时间1分钟停机
|
||||
if (touch_STATE[0]) {
|
||||
if ( ((millis() - running_time) / 1000) > 60 ){
|
||||
touch_STATE[0] = 0;
|
||||
delay(500);
|
||||
digitalWrite(RelayPin[0], HIGH);
|
||||
Serial.println(" End of Run ");
|
||||
delay(500);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long LastMillis = 0;
|
||||
void TenthSecondsSinceStartTask() //100ms
|
||||
{
|
||||
unsigned long CurrentMillis = millis();
|
||||
if (abs(int(CurrentMillis - LastMillis)) > 100)
|
||||
{
|
||||
LastMillis = CurrentMillis;
|
||||
TenthSecondsSinceStart++;
|
||||
OnTenthSecond();
|
||||
}
|
||||
}
|
||||
|
||||
bool battery_low = 0;
|
||||
void OnSecond()
|
||||
{
|
||||
#if defined(BAT_VOLTAGE_SENSE_PIN) //电池电压检测
|
||||
bat_voltage = return_voltage_value(INPUT_VOLTAGE_SENSE_PIN);
|
||||
if (bat_voltage < min_voltage && !battery_low) {
|
||||
battery_low = 1;
|
||||
digitalWrite(RelayPin[0], HIGH); //关闭电机
|
||||
while (battery_low) { //电池电压低闪灯
|
||||
if (millis() % 500 < 250) {
|
||||
digitalWrite(TOUCHLED_PIN[2], HIGH);
|
||||
digitalWrite(TOUCHLED_PIN[1], HIGH);
|
||||
digitalWrite(TOUCHLED_PIN[0], HIGH);
|
||||
} else {
|
||||
digitalWrite(TOUCHLED_PIN[2], LOW);
|
||||
digitalWrite(TOUCHLED_PIN[1], LOW);
|
||||
digitalWrite(TOUCHLED_PIN[0], LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OnTenthSecond() // 100ms 十分之一秒
|
||||
{
|
||||
|
||||
if (TenthSecondsSinceStart % 10 == 0) //10次为1秒
|
||||
{
|
||||
OnSecond();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String TimeString(int TimeMillis) {
|
||||
|
||||
String stringTime;
|
||||
|
||||
stringTime += int(TimeMillis / 60 / 60);
|
||||
stringTime += ":";
|
||||
stringTime += int(TimeMillis / 60 % 60);
|
||||
stringTime += ":";
|
||||
stringTime += TimeMillis % 60;
|
||||
|
||||
return stringTime;
|
||||
}
|
||||
|
||||
String ProcessUpdate() //页面更新
|
||||
{
|
||||
//自动生成一串用“,”隔开的字符串。
|
||||
//HTML脚本会按照“, ”分割,形成一个字符串数组。
|
||||
//并把这个数组填个表格的相应部分。
|
||||
String ReturnString;
|
||||
if (touch_STATE[0]) {
|
||||
ReturnString += TimeString((millis() - running_time) / 1000);
|
||||
} else {
|
||||
ReturnString += "0";
|
||||
}
|
||||
ReturnString += ",";
|
||||
ReturnString += bat_voltage; //电压值
|
||||
ReturnString += ",";
|
||||
ReturnString += pressure_val; //气压值
|
||||
ReturnString += ",";
|
||||
ReturnString += touch_STATE[0]; //运行状态
|
||||
ReturnString += ",";
|
||||
ReturnString += running_type; //运行方式
|
||||
ReturnString += ",";
|
||||
ReturnString += running_pressure_type; //运行气压自定义
|
||||
|
||||
//Serial.println(ReturnString);
|
||||
return ReturnString;
|
||||
}
|
||||
|
||||
void PocessControl(int DeviceType, int DeviceIndex, int Operation, float Operation2)
|
||||
{
|
||||
String ReturnString;
|
||||
|
||||
if (DeviceType == 0)
|
||||
{
|
||||
int SysIndex = Operation / 3;
|
||||
|
||||
if (Operation % 3 == 0)
|
||||
{ //重新设置传感器
|
||||
pressure_val =0;
|
||||
pinMode(ndrdy, INPUT);
|
||||
digitalWrite(ndrdy, LOW);
|
||||
|
||||
pinMode(clck, OUTPUT);
|
||||
digitalWrite(clck, LOW);
|
||||
|
||||
while (digitalRead(ndrdy)) {}
|
||||
while (!digitalRead(ndrdy)) {}
|
||||
|
||||
}
|
||||
else if (Operation % 3 == 1)
|
||||
{
|
||||
|
||||
}
|
||||
else if (Operation % 3 == 2)
|
||||
{
|
||||
ReturnString += "系统重启,请等待重新连接";
|
||||
printf("Reboot...");
|
||||
esp_restart();
|
||||
}
|
||||
}
|
||||
if (DeviceType == 1) //启停
|
||||
{
|
||||
if (Operation == 0)
|
||||
{
|
||||
running_pressure_type = Operation2;
|
||||
touch_touched[0] = 1; //启停按过
|
||||
touch_touched_times[0] = DeviceIndex;
|
||||
touch_touched[1] = 1;
|
||||
touch_touched_times[1] = DeviceIndex;
|
||||
}
|
||||
}
|
||||
if (DeviceType == 2) //类型选择
|
||||
{
|
||||
running_pressure_type = Operation2;
|
||||
touch_touched[1] = 1;
|
||||
touch_touched_times[1] = DeviceIndex;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool handleFileRead(String path) { //处理主页访问
|
||||
String contentType = "text/html";
|
||||
|
||||
if (SPIFFS.exists(path)) { // 如果访问的文件可以在SPIFFS中找到
|
||||
File file = SPIFFS.open(path, "r"); // 则尝试打开该文件
|
||||
ESP32Server.streamFile(file, contentType); // 并且将该文件返回给浏览器
|
||||
file.close(); // 并且关闭文件
|
||||
return true; // 返回true
|
||||
}
|
||||
return false; // 如果文件未找到,则返回false
|
||||
}
|
||||
|
||||
void handleNotFound()
|
||||
{
|
||||
// 获取用户请求网址信息
|
||||
String webAddress = ESP32Server.uri();
|
||||
int AutheTimes = 0;
|
||||
|
||||
if (!ESP32Server.authenticate(username, userpassword)) //校验用户是否登录
|
||||
{
|
||||
if (AutheTimes == 3) {
|
||||
ESP32Server.send(404, "text/plain", "Bye");
|
||||
} else {
|
||||
AutheTimes++;
|
||||
return ESP32Server.requestAuthentication(); //请求进行用户登录认证
|
||||
}
|
||||
}
|
||||
|
||||
//打印出请求
|
||||
if (webAddress != "/update")
|
||||
{
|
||||
printf("%s\n", webAddress.c_str());
|
||||
}
|
||||
|
||||
//如果是主页请求,则发送FLASH中的index.html文件
|
||||
if (webAddress.endsWith("/")) { // 如果访问地址以"/"为结尾
|
||||
webAddress = "/index.html"; // 则将访问地址修改为/index.html便于SPIFFS访问
|
||||
|
||||
// 通过handleFileRead函数处处理用户访问
|
||||
handleFileRead(webAddress);
|
||||
}
|
||||
else if (webAddress.endsWith("update"))
|
||||
{
|
||||
ESP32Server.send(200, "text/plain", ProcessUpdate());
|
||||
}
|
||||
else if (webAddress.startsWith("/Control"))
|
||||
{
|
||||
if (ESP32Server.args() == 3)
|
||||
{
|
||||
int DeviceType = ESP32Server.arg(0).toInt();
|
||||
int DeviceIndex = ESP32Server.arg(1).toInt();
|
||||
int Operation = ESP32Server.arg(2).toInt();
|
||||
float Operation2 = ESP32Server.arg(2).toFloat();
|
||||
if (DeviceType == 1) {
|
||||
Operation = 0;
|
||||
}
|
||||
|
||||
printf("DeviceType:%d DeviceIndex:%d Operation:%d Operation2:%.2f\n", DeviceType, DeviceIndex, Operation, Operation2 );
|
||||
|
||||
PocessControl(DeviceType, DeviceIndex, Operation, Operation2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP32Server.send(404, "text/plain", "404 Not Found");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP32Server.send(404, "text/plain", "404 Not Found");
|
||||
}
|
||||
}
|
||||
|
||||
void StartWebServer()
|
||||
{
|
||||
ESP32Server.begin();
|
||||
ESP32Server.onNotFound(handleNotFound);//将所有请求导向自己处理的代码
|
||||
}
|
Loading…
Reference in New Issue