#include <Arduino.h>
#include <esp_task_wdt.h>
#include <menu.h>
#include <menuIO/serialOut.h>
#include <menuIO/chainStream.h>
#include <menuIO/serialIn.h>
#include <Bounce2.h>
#include <LittleFS.h>
#include <ArduinoJson.h>
#include <esp_task_wdt.h>
#include <BluetoothSerial.h>
#pragma region IO设置
#define BTN_START 32 //按钮_启动
#define BTN_LTS_0 16 //按钮_左限位
#define BTN_LTS_1 17 //按钮_右限位
#define STEP0_PUL 18 //步进0_PUL
#define STEP0_DIR 19 //步进0_DIR
#define STEP0_EAN 21 //步进0_EAN
#define RELAY0 27 //继电器_下压
#define RELAY1 26 //继电器_点烫
#define RELAY2 25 //继电器_保留
#define RELAY3 33 //继电器_保留
#pragma endregion
#pragma region RELAYS变量
float _RELAY0_DELAY=0;
float _RELAY0_RUN=1;
float _RELAY0_WAIT=0;
uint8_t _RELAY0_COUNT=1;
float _RELAY1_DELAY=0;
float _RELAY1_RUN=1;
float _RELAY1_WAIT=0;
uint8_t _RELAY1_COUNT=1;
float _RELAY2_DELAY=0;
float _RELAY2_RUN=1;
float _RELAY2_WAIT=0;
uint8_t _RELAY2_COUNT=1;
float _RELAY3_DELAY=0;
float _RELAY3_RUN=1;
float _RELAY3_WAIT=0;
uint8_t _RELAY3_COUNT=1;
#pragma endregion
#pragma region PWM参数
unsigned long _WORK_STEP=1600;//前进到多少位置并返回
// setting PWM properties
const uint32_t freq_PWM = 500;//设置最高频率,控制速度
const uint8_t channel_PWM = 0;//通道号,取值0 ~ 15
const uint8_t resolution_PWM = 10;//PWM分辨率,取值0 ~ 20
#pragma endregion
#pragma region PWM中断
unsigned long i_STEP=255;
//初始化用的中断
void IRAM_ATTR INIT_AXLE_ISR() {
//下降沿触发中断
if(digitalRead(STEP0_DIR)==LOW){
//正在左移
if(digitalRead(BTN_LTS_0)==LOW){
//撞到左限位
ledcWriteTone(channel_PWM,freq_PWM/2);
digitalWrite(STEP0_DIR,HIGH);//右移
}
}
else{
if(digitalRead(BTN_LTS_0)==HIGH){
//离开限位
ledcWriteTone(channel_PWM,0);
i_STEP=0;
detachInterrupt(digitalPinToInterrupt(STEP0_PUL));//关闭中断服务
}
}
}
//步进计数用的中断
void IRAM_ATTR STEP_AXLE_ISR() {
//下降沿触发中断
if(digitalRead(STEP0_DIR)==HIGH){
//正在右移
i_STEP++;
if(i_STEP>=_WORK_STEP || digitalRead(BTN_LTS_1)==LOW){
//移动到位或者撞到右限位
ledcWriteTone(channel_PWM,0);//停止移动
detachInterrupt(digitalPinToInterrupt(STEP0_PUL));//关闭中断服务
xTaskCreatePinnedToCore(INIT_AXLE,"INIT_AXLE",1024,NULL,2,NULL,1);//回到零点
}
}
}
#pragma endregion
#pragma region 菜单与其他参数
using namespace Menu;
#define MAX_DEPTH 3
const char *pin = "1234"; // Change this to more secure PIN.
String device_name = "ESP32-BT-Slave";
BluetoothSerial SerialBT;
Bounce B_BTN_START = Bounce();
#pragma endregion
void INIT_AXLE(void *pvParameters) { //初始化轴
//左移到左限位,如果左限位到低电平后右移至左限位高电平
Serial.println("INIT_AXLE");
digitalWrite(STEP0_DIR, LOW);//左移
ledcWriteTone(channel_PWM,freq_PWM);
attachInterrupt(digitalPinToInterrupt(STEP0_PUL), INIT_AXLE_ISR, FALLING);//打开中断服务
vTaskDelete(NULL);//删除任务
}
void STEP_AXLE (void *pvParameters){ //步进到指定位置
Serial.println("STEP_AXLE");
digitalWrite(STEP0_DIR, HIGH);//右移
ledcWriteTone(channel_PWM,freq_PWM);
attachInterrupt(digitalPinToInterrupt(STEP0_PUL), STEP_AXLE_ISR, FALLING);//打开中断服务
vTaskDelete(NULL);//删除任务
}
void t_RELAY0(void * pvParameters){
vTaskDelay(_RELAY0_DELAY*1000);
for(uint8_t i=0;i<_RELAY0_COUNT;i++){
digitalWrite(RELAY0, HIGH);
vTaskDelay(_RELAY0_RUN*1000);
digitalWrite(RELAY0, LOW);
vTaskDelay(_RELAY0_WAIT*1000);
}
vTaskDelete(NULL);
}
void t_RELAY1(void * pvParameters){
vTaskDelay(_RELAY1_DELAY*1000);
for(uint8_t i=0;i<_RELAY1_COUNT;i++){
digitalWrite(RELAY1, HIGH);
vTaskDelay(_RELAY1_RUN*1000);
digitalWrite(RELAY1, LOW);
vTaskDelay(_RELAY1_WAIT*1000);
}
vTaskDelete(NULL);
}
void t_RELAY2(void * pvParameters){
vTaskDelay(_RELAY2_DELAY*1000);
for(uint8_t i=0;i<_RELAY2_COUNT;i++){
digitalWrite(RELAY2, HIGH);
vTaskDelay(_RELAY2_RUN*1000);
digitalWrite(RELAY2, LOW);
vTaskDelay(_RELAY2_WAIT*1000);
}
vTaskDelete(NULL);
}
void t_RELAY3(void * pvParameters){
vTaskDelay(_RELAY3_DELAY*1000);
for(uint8_t i=0;i<_RELAY3_COUNT;i++){
digitalWrite(RELAY3, HIGH);
vTaskDelay(_RELAY3_RUN*1000);
digitalWrite(RELAY3, LOW);
vTaskDelay(_RELAY3_WAIT*1000);
}
vTaskDelete(NULL);
}
void t_restDog(void * pvParameters){
while(true){
esp_task_wdt_reset();//喂狗
vTaskDelay(1000);
}
}
void INIT_RELAYS(){
Serial.println("INIT_RELAYS");
digitalWrite(RELAY0, LOW);
digitalWrite(RELAY1, LOW);
digitalWrite(RELAY2, LOW);
digitalWrite(RELAY3, LOW);
}
void PROCESS_WORK (void *pvParameters){ //执行工作流程
if(xTaskGetHandle("t_STEP_AXLE")==NULL and
xTaskGetHandle("t_RELAY0")==NULL and
xTaskGetHandle("t_RELAY1")==NULL and
xTaskGetHandle("t_RELAY2")==NULL and
xTaskGetHandle("t_RELAY3")==NULL and
i_STEP==0)
{
Serial.println("PROCESS_WORK");
xTaskCreatePinnedToCore(STEP_AXLE,"t_STEP_AXLE",2048,NULL,2,NULL,1);
xTaskCreatePinnedToCore(t_RELAY0,"t_RELAY0",2048,NULL,2,NULL,1);
xTaskCreatePinnedToCore(t_RELAY1,"t_RELAY1",2048,NULL,2,NULL,1);
xTaskCreatePinnedToCore(t_RELAY2,"t_RELAY2",2048,NULL,2,NULL,1);
xTaskCreatePinnedToCore(t_RELAY3,"t_RELAY3",2048,NULL,2,NULL,1);
}
vTaskDelete(NULL);
}
void setup() {
Serial.begin(115200);
Serial.println("Hello, ESP32!");
B_BTN_START.attach(BTN_START,INPUT_PULLUP); //按钮_启动-含消抖
pinMode(BTN_LTS_0,INPUT_PULLUP); //按钮_左限位
pinMode(BTN_LTS_1,INPUT_PULLUP); //按钮_右限位
pinMode(STEP0_DIR,OUTPUT); //步进0_DIR
pinMode(STEP0_EAN,OUTPUT); //步进0_EAN
pinMode(RELAY0,OUTPUT); //继电器0
pinMode(RELAY1,OUTPUT); //继电器1
pinMode(RELAY2,OUTPUT); //继电器2
pinMode(RELAY3,OUTPUT); //继电器3
INIT_RELAYS();//初始化继电器
ledcSetup(channel_PWM, freq_PWM, resolution_PWM); // 设置通道
ledcAttachPin(STEP0_PUL, channel_PWM); //将 LEDC 通道绑定到指定 IO 口上以实现输出
xTaskCreatePinnedToCore(t_restDog,"restDog",1024,NULL,1,NULL,1);//定时喂狗
xTaskCreatePinnedToCore(INIT_AXLE,"INIT_AXLE",2048,NULL,2,NULL,1);//初始化滑台
}
/* 开机后运行步骤
1:步进滑台左移动至左限位导通
2:步进滑台右移动至左限位不导通,计为0点
按下按钮后运行步骤
->异步处理1
1:向右按脉冲次数移动滑台
2:滑台到位后向左移动至左限位导通
3:滑台右移动至左限位不导通,计为0点
->异步处理2
1:按下按钮后延时N秒继电器A导通N秒后关闭
*/
void loop() {
// put your main code here, to run repeatedly:
B_BTN_START.update();
if(B_BTN_START.rose()){
if(xTaskGetHandle("PROCESS_WORK")==NULL){
xTaskCreatePinnedToCore(PROCESS_WORK,"PROCESS_WORK",1024,NULL,2,NULL,1);
}
}
delay(10);
}