我正在修改按钮系统的防监听代码,在该按钮中,将监视瞬时按钮的短按和长按以执行某些操作。我在Typedef中使用代码时遇到了麻烦,尽管它似乎没有按我预期的那样工作。谁能帮我解释我所缺少的吗?具体来说,我正在修改代码以适用于多个按钮。
在设置中,我有'buttons [i] .dimmer = dimmer [i];'使用“ buttons [i] .dimmer”,我以为是在typedef中建立的,但似乎无法填充它?当我运行代码时,不会读取任何输入,我正在尝试弄清这里可能发生的情况。
完整代码:
// detectButtonPress
// Use millis to detect a short and long button press
// See baldengineer.com/detect-short-long-button-press-using-millis.html for more information
// Created by James Lewis
#define PRESSED LOW
#define NOT_PRESSED HIGH
int value = 0;
const byte numberButtons = 5;
const int debounce = 10;
int pin[numberButtons] = {2, 3, 4, 7, 8}; //not used with multiple buttons?**
int dimmer[numberButtons] = {A0, A1, A0, A0, 0}; //which dimmer is associated with which button
int output[numberButtons] = {10, 10, 11, 11, 0}; //which output pin to send signal
//variables for timing long button press
unsigned long startMillis;
unsigned long currentMillis;
unsigned long timerMillis;
const unsigned long period = 4000; //the value is a number of milliseconds, ie 4000=4 second
int longPressOutput = 0; //which dimmer to monitor with long press
int longPressDimmer = 0; //dimmer pin for long press
const unsigned long shortPress = 100;
const unsigned long longPress = 500;
bool monitorDimmer = false; //whether to monitor dimmer or not
int dimValue = 0; //dimmer value initialized
typedef struct Buttons {
const int debounce = 10;
unsigned long counter=0;
bool prevState = NOT_PRESSED;
bool currentState;
bool lightState = false;
bool prevLightState = false;
int pin[numberButtons] = {2, 3, 4, 7, 8}; //not used with multiple buttons?**
int dimmer[numberButtons] = {A0, A1, A0, A0, 0}; //which dimmer is associated with which button
int output[numberButtons] = {10, 10, 11, 11, 0}; //which output pin to send signal
} Button;
//array of button objects
Buttons buttons[numberButtons];
void setup() {
Serial.begin(9600); //start Serial in case we need to print debugging info
startMillis = millis(); //initial start time
bool monitorDimmer = false; //initial monitorDimmer status
//initialize each button in the array
for (int i = 0; i < numberButtons; i++) {
buttons[i].pin = pin[i]; //initialize pin number for this buttons
buttons[i].dimmer = dimmer[i];
buttons[i].output = output[i]; //this one doesn't work but the above does?
buttons[i].debounce = debounce;
pinMode(buttons[i].pin, INPUT_PULLUP);
//Serial.println(buttons[i].pin);
}
}
void loop() {
timerMillis = millis();
for (int i = 0; i < numberButtons; i++) {
// check the button
buttons[i].currentState = digitalRead(buttons[i].pin);
// has it changed?
if (buttons[i].currentState != buttons[i].prevState) {
delay(buttons[i].debounce);
// update status in case of bounce
buttons[i].currentState = digitalRead(buttons[i].pin);
if (buttons[i].currentState == PRESSED) {
// a new press event occured
// record when button went down
buttons[i].counter = millis();
}
if (buttons[i].currentState == NOT_PRESSED) {
// but no longer pressed, how long was it down?
unsigned long currentMillis = millis();
if ((currentMillis - buttons[i].counter >= shortPress) && !(currentMillis - buttons[i].counter >= longPress)) {
// short press detected.
buttons[i].prevLightState = buttons[i].lightState; //Set prev to current, then change
buttons[i].lightState != buttons[i].lightState; //flip state
if (buttons[i].lightState = true) {
analogWrite(buttons[i].output, 180); //set pin to roughly 70% brightness**
value = 5;
Serial.println(value);
}else {
analogWrite(buttons[i].output, 0);
value = 4;
Serial.println(value);
}
//specifically for off button - above will only turn off pin 10, this gets pin 11
if (i == 4) {
analogWrite(11, 0);
}
}
if ((currentMillis - buttons[i].counter >= longPress)) {
// the long press was detected
analogWrite(buttons[i].pin, 180); //turn light on immediately
longPressDimmer = buttons[i].dimmer; //set monitor value for dimmer pin
longPressOutput = buttons[i].output; //set which output to watch
startMillis = millis();
monitorDimmer = true; //set true so dimmer loop
//handleLongPress(); //go to long press function to monitor dimmer
//specifically for off button - above will only turn off pin 10, this gets pin 11
if (i == 4) {
analogWrite(11, 0); //turn off main
analogWrite(10, 0); //turn off bed
}
}
}
// used to detect when state changes
buttons[i].prevState = buttons[i].currentState;
}
}
if (monitorDimmer == true) {
if (timerMillis - startMillis <= period) { //until period is reached do this
dimValue = analogRead(longPressDimmer);
analogWrite(longPressOutput,dimValue); //set light to value of dimmer
}
else {
monitorDimmer = false; //if time is up, stop checking
}
}
}
您有“ numberButtons”按钮,每个按钮都有“ numberButtons”输出。这意味着您有numberButtons * numberButtons输出,这听起来是错误的。如果这是预期的,则需要这样的循环
for (int b_idx = 0; b_idx < numberButtons; ++b_idx) // once per button
for (int o_idx = 0; o_idx < numberButtons; ++o_idx) // once per button
button[b_idx].output[o_idx] = init_value;
但是,从代码中的注释中,很可能您的错误确实在结构中
struct Button {
const int debounce = 10;
unsigned long counter=0;
bool prevState = NOT_PRESSED;
bool currentState;
bool lightState = false;
bool prevLightState = false;
int pin {-1}; // Each button has only one pin
int dimmer {-1}; // Each button has only one dimmer
int output {-1}; // Each button has only one output
};
//array of button objects
Button buttons[numberButtons];
现在您的设置功能就有意义了。
首先,在C ++中不需要typedef
!那是C的事情。允许,但实际上没有任何有用的效果。
似乎您正在尝试创建一个类,并希望初始化一个全局数组以引用该类中的元素。因为C ++是基于values而不是引用,所以这行不通。您可以在类中使用指针指向全局数组以修改它们。
constexpr或template不是typedef等
// ..
#include <windows.h>
const byte numberButtons = 5;
// ...
int dimValue = 0; //dimmer value initialized
template<DIM>
struct Buttons {
const int debounce = 10;
unsigned long counter=0;
bool prevState = NOT_PRESSED;
bool currentState;
bool lightState = false;
bool prevLightState = false;
int pin[DIM] = {2, 3, 4, 7, 8}; //not used with multiple buttons?**
int dimmer[DIM] = {A0, A1, A0, A0, 0}; //which dimmer is associated with which button
int output[DIM] = {10, 10, 11, 11, 0}; //which output pin to send signal
}
typedef Button BUT;
int main ( ) {
//array of button objects
BUT<numberButtons> buttons;
for (int i=0; i<15; ++i)
cout<< buttons.pin[i] <<"\n";
}