c++ - 根据数组检查值时 Arduino 出错

标签 c++ arduino arduino-uno

我和一个伙伴一起为 Arduino Uno 创建了下面的草图,但我们遇到了一个问题。代码的目的是从 Uno 上的引脚 1-6 的 6 个按钮读取按钮按下,然后对照存储的数组检查存储的按钮按下,看它是否正确。

当您按下按钮时,黄色 LED 会亮起。当您输入五个按钮时,它会检查数组并在您输入错误时给您一个红色 LED。如果你是正确的,它会给你一个绿色的 LED,然后触发一个继电器打开。

我们的代码间歇性地工作,但不是每次都工作。我不认为这是接线问题,因为每次我按下按钮时,它都能正常工作。

我无法确定错误的原因。我在使用的时候一直无法重现错误,但是一直报错。一旦出错,我必须重新启动 Arduino 才能让它再次工作。

我的期望是按钮按下的存储方式,或者计数器在循环中启动和重新启动的方式。我无法培训用户,所以可能是他们按住按钮或类似的东西导致错误。

我希望这是一个简单的答案,但我不擅长编码,所以我希望得到一些帮助。

// Button pins
const int button1 = 1;
const int button2 = 2;
const int button3 = 3;
const int button4 = 4;
const int button5 = 5;
const int button6 = 6;
const int grnLed = 11;
const int redLed = 9;
const int yellowLed = 10;
const int openRelay = 7;

const int brightness = 300;

// How long is our code, kind of personal
const int codelen = 5;

// Pin code values must match button pin values
char PIN[codelen] = {
  '4', '1', '5', '3', '2'
};

// Attempted combination
char attempt[codelen] = {
  '0', '0', '0', '0' ,'0'
};

// Attempt count
int z = 0;

void setup() {

  // You've been set up
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(button3, INPUT_PULLUP);
  pinMode(button4, INPUT_PULLUP);
  pinMode(button5, INPUT_PULLUP);
  pinMode(button6, INPUT_PULLUP);
  //pinMode(openRelay, OUTPUT);

  // Set pullup resistor for buttons
  digitalWrite(button1, HIGH);
  digitalWrite(button2, HIGH);
  digitalWrite(button3, HIGH);
  digitalWrite(button4, HIGH);
  digitalWrite(button5, HIGH);
  digitalWrite(button6, HIGH);
  //digitalWrite(openRelay, LOW);
}


void correctPIN()
{
  pulseLED(grnLed, brightness, 3000);
  pulseLED(openRelay, brightness, 1500);
  //analogWrite(openRelay, HIGH);
  //delay(2000);
  //analogWrite(openRelay, LOW);
  z = 0;
}

void incorrectPIN()
{
  pulseLED(redLed, brightness, 2000);

  z = 0;
}

void checkPIN()
{
  int correct = 0;
  int i;
  for (i = 0; i < codelen; i++)
  {

    if (attempt[i] == PIN[i])
    {
      correct++;
    }
  }
  if (correct == codelen)
  {
    correctPIN();
  }
  else
  {
    incorrectPIN();
  }

  for (int zz = 0; zz < codelen; zz++)
  {
    attempt[zz] = '0';
  }
}


void checkButton(int button){

  if (digitalRead(button) == LOW)
  {
    while (digitalRead(button) == LOW) { } // Do nothing

    // Convert int to string for tracking/compare
    char buttStr = button + '0';
    attempt[z] = buttStr;
    z++;

    //Light up LED so we know botton press worked
    pulseLED(yellowLed, brightness, 500);
  }
}


void pulseLED(int ledpin, int brightness, int msec) {
  analogWrite(ledpin, brightness);
  delay(msec);
  analogWrite(ledpin, LOW);
}


void loop() {

  // Check buttons
  checkButton(button1);
  checkButton(button2);
  checkButton(button3);
  checkButton(button4);
  checkButton(button5);
  checkButton(button6);

  // If number of buttons pressed, z, matches code/pin length then check
  if (z >= codelen)
  {
    checkPIN();
  }
}

最佳答案

当您按下机械开关时,可能会出现电弧或触点的实际弹跳,从而导调用路快速连续多次打开和关闭。

我认为问题在于您没有对按钮按下进行“去抖动”,因此,当您单击一次按钮时,它实际上可以注册为多次连续按下。

在软件中处理此问题的最简单方法是在检测到引脚变低后添加延迟,然后在延迟后再次检查引脚。所以,而不是:

if (digitalRead(button) == LOW)
{ 
    while (digitalRead(button) == LOW) { } // do nothing
    ...
}

你会做类似的事情:

if (digitalRead(button) == LOW)
{
    delay(20);
    if (digitalRead(button) == LOW) {
        ...
    }
}

还有更复杂的方法,但我敢打赌这可以解决您眼前的问题。

关于c++ - 根据数组检查值时 Arduino 出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43052026/

相关文章:

c++ - 中断创建arduino库

c++ - Arduino 立体声音量表

arduino - 使用 Ada 对 Arduino 进行编程

java - 处理白屏?

c - Atmega328P 中奇怪的延迟行为

c++ - 与系统命令相比,execve如何防止漏洞

c++ - 如何在 OpenGL(GLUT) 场景中创建静态背景图像?

c++ - C++中关于常量初始化和零初始化的顺序的矛盾定义

c++ - 非虚拟接口(interface)? (需要非常高效的低级抽象)

c++ - Arduino IDE中自定义库类的.h文件编译错误的原因是什么