【问题标题】:How to use typedef to create multiple arrays?如何使用 typedef 创建多个数组?
【发布时间】:2019-12-26 21:52:00
【问题描述】:

我正在修改按钮系统的 decounce 代码,其中将监视瞬时按钮的短按和长按以执行某些操作。我在使用 Typedef 中的代码时遇到了麻烦,因为它似乎没有像我预期的那样工作。任何人都可以帮助解释我所缺少的吗?具体来说,我正在修改代码以适用于多个按钮。

在设置中我有 'buttons[i].dimmer = dimmer[i];'使用我认为在 typedef 中建立的“buttons [i] .dimmer”,但我似乎无法填充它?当我运行代码时,没有读取任何输入,我试图弄清楚这里可能发生了什么。

完整代码:

// 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
  }
}
}

【问题讨论】:

    标签: c++ arrays typedef preprocessor


    【解决方案1】:

    您有“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;
    

    但是,从代码中的 cmets 来看,您的错误很可能确实在您的结构中

    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];
    

    现在你的设置函数有意义了。

    【讨论】:

    • 你是对的!结构是问题所在。谢谢!
    【解决方案2】:

    首先,typedef 在 C++ 中是不需要的!那是C的事情。是允许的,但实际上并没有什么用处。

    您似乎正在尝试创建一个类并希望初始化一个全局数组以引用该类中的元素。这是行不通的,因为 C++ 是基于 values 而不是引用。你可以在你的类中使用指针来指向全局数组来修改这些。

    【讨论】:

      【解决方案3】:

      constexpr模板
      不是类型定义

      // ...
      #include <windows.h> // for byte type:
      const byte numberButtons = 5;
      
      // ...
      
      int dimValue = 0;         //dimmer value initialized
      
      template<byte 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 Buttons<numberButtons> BUT;
      
      int main ( ) {
      
         //array of button objects
         BUT buttons;
      
       for (int i=0; i<15; ++i)
          cout<< buttons.pin[i] <<"\n";
      }
      

      【讨论】:

        猜你喜欢
        • 2021-03-03
        • 2021-09-22
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 2021-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多