我最近制作了一个低压10级磁阻线圈炮,卡在了控制程序上,由于本人esp32使用的多,花了一点时间使用arduino写了一个控制程序,现在分享出来,给大家一点思路,理论可以把gpio引脚全部使用上。
开发环境:arduino
单片机:esp32s3
主频:240mhz
可能主频高的原因,输出时序误差1.5us内
按键功能
单击单发
长按连发
如何修改时许
更改pulseConfigs[]数组,我引用时间轴作为开启 关闭判断,
举例说明:
{ 1000, 9, HIGH }, 当扳机按下到1000us 设置gpio9为HIGH(开启)
{ 1500, 9, LOW}, 当扳机按下到1500us 设置gpio9为LOW(关闭)
这样gpio9开启时间为1500us-1000us=500us
如果要多级运行的话,pulseConfigs[] 数组中,时间轴位置必须由小到大
补充说明
单片机时序控制有的时候后级开启时,前级还没有关闭
只需要更改一下时间轴的位置即可
举例说明:
{ 1000, 9, HIGH },
{ 1200, 10, HIGH },
{ 1500, 9, LOW },
{ 2500, 10, LOW },
程序
C++// 定义脉冲波的结构体,包含时间间隔、引脚和状态
struct PulseConfig {
unsigned long interval; // 脉冲波的时间在时间轴上位置(单位:微秒)
int pin; // 脉冲波输出引脚
int state; // 脉冲波输出状态 (HIGH/LOW)
};
// 定义脉冲波的配置(时间轴位置、引脚、脉冲波输出状态 (HIGH/LOW))
PulseConfig pulseConfigs[] = {
{ 1000, 9, HIGH },
{ 1500, 9, LOW },
{ 2000, 10, HIGH },
{ 2500, 10, LOW },
{ 3000, 11, HIGH },
{ 3500, 11, LOW },
{ 4000, 12, HIGH },
{ 4500, 12, LOW },
{ 5000, 13, HIGH },
{ 5500, 13, LOW },
{ 6000, 14, HIGH },
{ 6500, 14, LOW },
{ 7000, 21, HIGH },
{ 7500, 21, LOW },
{ 8000, 47, HIGH },
{ 8500, 47, LOW },
{ 9000, 48, HIGH },
{ 9500, 48, LOW },
{ 10000, 45, HIGH },
{ 10500, 45, LOW },
};
int pulseConfigs_Size = sizeof(pulseConfigs) / sizeof(pulseConfigs[0]); //获取数组元素个数
int TRIGGER_PIN = 8; // 定义TRIGGER引脚
int SHORT_PRESS_TIME = 200; // 短按长按分隔时间(毫秒)
int lastState = LOW; // 上一次按钮状态
unsigned long pressedTime = 0; // 记录按下时间
bool isLongPressing = false; // 标记是否处于长按状态
int BURST_INTERVAL = 100; // 定义连发间隔(单位:毫秒)
void setup() {
Serial.begin(115200); // 串口初始化
pinMode(TRIGGER_PIN, INPUT_PULLUP); // TRIGGER_PIN设置上拉输入
for (int i = 0; i < pulseConfigs_Size; i++) {
pinMode(pulseConfigs[i].pin, OUTPUT); // 设置引脚为输出模式
digitalWrite(pulseConfigs[i].pin, LOW); // 设置引脚为低电平
}
delay(500);
}
void loop() {
TRIGGER_PD(); // TRIGGER单击长按判断
if (isLongPressing) { // 连击判断
generatePulse();
}
}
// 生成脉冲波
void generatePulse() {
unsigned long startTime = micros();
for (int i = 0; i < pulseConfigs_Size; i++) { // 确保处理所有20个脉冲波
// 设置引脚状态
digitalWrite(pulseConfigs[i].pin, pulseConfigs[i].state);
// 如果不是最后一个脉冲,计算下一个脉冲的时间间隔
if (i < pulseConfigs_Size - 1) {
unsigned long interval = pulseConfigs[i + 1].interval - pulseConfigs[i].interval;
if (interval > 0) {
delayMicroseconds(interval);
}
}
}
// 恢复所有引脚到低电平
for (int i = 0; i < pulseConfigs_Size; i++) {
digitalWrite(pulseConfigs[i].pin, LOW);
}
Serial.println("<sA>"); // 调试信息
}
// 单击长按判断
void TRIGGER_PD() {
int currentState = digitalRead(TRIGGER_PIN);
// 按钮按下
if (lastState == HIGH && currentState == LOW) {
pressedTime = millis(); // 记录按下时间
isLongPressing = false; // 重置长按状态
}
// 按钮保持按下状态
if (currentState == LOW) {
if (!isLongPressing && (millis() - pressedTime > SHORT_PRESS_TIME)) {
Serial.println("长按开始");
isLongPressing = true; // 标记为长按状态
}
}
// 按钮释放
if (lastState == LOW && currentState == HIGH) {
if (!isLongPressing && (millis() - pressedTime < SHORT_PRESS_TIME)) {
generatePulse(); // 发送一次脉冲
Serial.println("单击");
} else if (isLongPressing) {
Serial.println("长按结束");
isLongPressing = false; // 重置长按状态
}
}
lastState = currentState;
}
[修改于 2天5时前 - 2025/04/03 22:21:22]