大家好,我正在开发一个工业用途的Arduino项目。其作用是设定继电器的动作时间。现在我遇到的问题是操作员需要访问这些活动的值并更改它们。也就是说,它可以改变继电器的活动持续时间和休息时间。 我总共有八个数字变量,十进制数字如 2.3(以秒为单位),我必须创建类似七段菜单的东西,以便可以在没有程序的情况下再次更改这些数字。 ** 我用于这项工作的是一个四位七段和一些按钮**(我可以根据需要增加或减少它们)。例如,我想要,当按下键 1(例如,连接到 Arduino 的数字引脚 8)3 秒时,p1(例如,直到 p4 和 f1 到 f4 以及最后 o0 的其余变量)将是显示并使用其他两个键(连接到数字引脚 9 和 10)能够在这些变量之间移动,当用户想要更改一个时,再次按 k1 并使用其他两个键再次增加或减少值,然后通过再按一次k1,进入第一个菜单。返回 如果在菜单中按下 k1 三秒钟,将应用设置,并且程序将以新的更改运行。 这是我当前的代码:
#include <TM1637Display.h>
#define CLK 2
#define DIO 3
TM1637Display display(CLK, DIO);
int relayPins[] = {4, 5, 6, 7};
int onTimes[] = {2000, 4000, 5000, 3000};
int offTimes[] = {1000, 2000, 1000, 3000};
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], LOW);
}
display.setBrightness(0x0f);
}
void loop() {
for (int i = 0; i < 4; i++) {
digitalWrite(relayPins[i], HIGH);
for (int j = onTimes[i] / 1000; j > 0; j--) {
display.showNumberDec(j, false, 2, 0);
delay(1000);
}
digitalWrite(relayPins[i], LOW);
for (int j = offTimes[i] / 1000; j > 0; j--) {
display.showNumberDec(j, false, 2, 0);
delay(1000);
}
}
}
但是,我不知道如何编写这部分(我是 Arduino 和 C 的新手),我真的很感谢你的帮助!
为了方便工作,如果你想模拟当前的代码,请将之前的代码放在https://wokwi.com/projects/new/arduino-uno。在diagram.json部分中输入此内容以向您展示电路(同时安装TM1637库):
{
"version": 1,
"author": "Yogesh R",
"editor": "wokwi",
"parts": [
{ "type": "wokwi-arduino-uno", "id": "uno", "top": 442.2, "left": -672.6, "attrs": {} },
{ "type": "wokwi-led", "id": "led2", "top": -138, "left": 51.8, "attrs": { "color": "red" } },
{
"type": "wokwi-resistor",
"id": "r1",
"top": -207.25,
"left": 115.2,
"attrs": { "value": "220" }
},
{ "type": "wokwi-relay-module", "id": "relay1", "top": 489.8, "left": -364.8, "attrs": {} },
{ "type": "wokwi-relay-module", "id": "relay2", "top": 624.2, "left": -364.8, "attrs": {} },
{ "type": "wokwi-relay-module", "id": "relay3", "top": 422.6, "left": -364.8, "attrs": {} },
{ "type": "wokwi-relay-module", "id": "relay4", "top": 557, "left": -364.8, "attrs": {} },
{
"type": "wokwi-tm1637-7segment",
"id": "sevseg1",
"top": 297.56,
"left": -607.37,
"attrs": { "color": "red" }
}
],
"connections": [
[ "relay3:GND", "relay1:GND", "black", [ "h0" ] ],
[ "relay1:GND", "relay4:GND", "black", [ "h0" ] ],
[ "relay4:GND", "relay2:GND", "black", [ "h0" ] ],
[ "relay3:VCC", "relay1:VCC", "red", [ "h0" ] ],
[ "relay4:VCC", "relay1:VCC", "red", [ "h0" ] ],
[ "relay4:VCC", "relay2:VCC", "red", [ "h0" ] ],
[ "relay3:VCC", "uno:5V", "red", [ "h0" ] ],
[ "relay2:GND", "uno:GND.2", "black", [ "h0" ] ],
[ "relay3:IN", "uno:4", "green", [ "h0" ] ],
[ "relay1:IN", "uno:5", "green", [ "h0" ] ],
[ "relay4:IN", "uno:6", "green", [ "h0" ] ],
[ "relay2:IN", "uno:7", "green", [ "h0" ] ],
[ "sevseg1:CLK", "uno:2", "green", [ "h57.6", "v124.8" ] ],
[ "sevseg1:DIO", "uno:3", "green", [ "h28.8", "v57.6", "h-42.4" ] ],
[ "sevseg1:VCC", "uno:5V", "red", [ "v144", "h-80.6" ] ],
[ "sevseg1:GND", "uno:GND.3", "black", [ "h28.8", "v316.8", "h-86.4" ] ]
],
"dependencies": {}
}
我写不出来
当然!您需要创建一个菜单系统来使用按钮更改开启和关闭时间。下面是一个简化的示例,可帮助您开始使用可编辑菜单系统,使用长按和短按检测连接到数字引脚 8 的按钮,以及引脚 9 和 10 上的递增和递减按钮。
#include <TM1637Display.h>
#define CLK 2
#define DIO 3
#define MENU_BUTTON_PIN 8
#define INCREMENT_BUTTON_PIN 9
#define DECREMENT_BUTTON_PIN 10
#define LONG_PRESS_TIME 3000 // 3 seconds
TM1637Display display(CLK, DIO);
int relayPins[] = {4, 5, 6, 7};
float onTimes[] = {2.0, 4.0, 5.0, 3.0};
float offTimes[] = {1.0, 2.0, 1.0, 3.0};
int currentVar = 0; // Current variable to adjust
bool inEditMode = false;
unsigned long buttonPressTime = 0;
bool isLongPress = false;
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], LOW);
}
pinMode(MENU_BUTTON_PIN, INPUT_PULLUP);
pinMode(INCREMENT_BUTTON_PIN, INPUT_PULLUP);
pinMode(DECREMENT_BUTTON_PIN, INPUT_PULLUP);
display.setBrightness(0x0f);
}
void displayMenu() {
// We assume only one variable is displayed and editable at a time
// Update display based on current variable selected
if (currentVar < 4) {
display.showNumberDecEx(onTimes[currentVar] * 10, 0b11100000, true, 3, 0);
} else {
display.showNumberDecEx(offTimes[currentVar - 4] * 10, 0b11100000, true, 3, 0);
}
}
void updateSelectedVar(float increment) {
if (currentVar < 4) {
onTimes[currentVar] += increment;
} else {
offTimes[currentVar - 4] += increment;
}
}
void checkButtons() {
if (digitalRead(MENU_BUTTON_PIN) == LOW) {
if (buttonPressTime == 0) {
buttonPressTime = millis();
} else if ((millis() - buttonPressTime) > LONG_PRESS_TIME) {
isLongPress = true;
}
} else {
if (buttonPressTime != 0) {
if (isLongPress) {
// Long press detected, toggle edit mode or apply new settings
if (inEditMode) {
// Apply settings and exit edit mode
inEditMode = false;
// Here you might save the settings, e.g., to EEPROM if you want them to be persistent
} else {
inEditMode = true;
currentVar = 0; // Start at the first variable
}
isLongPress = false; // Reset the long press flag
} else {
// Short press detected, navigate the menu or adjust values
if (inEditMode) {
// Adjust the curent variable
currentVar = (currentVar + 1) % 8; // Cycle through variables p1 to p4 and f1 to f4 (assuming 8 total variables)
}
}
buttonPressTime = 0; // Reset the button press timer
}
}
if (inEditMode && digitalRead(INCREMENT_BUTTON_PIN) == LOW) {
updateSelectedVar(0.1); // Increment the current variable
delay(200); // Debounce delay
}
if (inEditMode && digitalRead(DECREMENT_BUTTON_PIN) == LOW) {
updateSelectedVar(-0.1); // Decrement the current variable
delay(200); // Debounce delay
}
}
void loop() {
if (inEditMode) {
displayMenu();
} else {
// Your existing relay logic and display code goes here
}
checkButtons();
}
请注意:此代码是一个简单的基础示例,演示如何开始构建菜单系统以使用按钮调整变量。去抖动逻辑是基于延迟的原始逻辑,这可能不适合您的生产环境。您可能需要改进用户体验、如何更改值、通过软件或硬件添加去抖以及处理变量最小/最大约束等。
请记住,如果没有其余逻辑,此代码将无法编译,并且需要在不阻塞处理器的情况下与继电器控制代码明智地集成。此外,您可能希望将这些设置存储在 EEPROM(非易失性存储器)中,以便它们在重新启动之间保持不变。
单独测试此代码,然后将其逐步集成到您的项目中,确保您了解每个部分的工作原理。