我和一个伙伴一起为Arduino Uno创建了下面的草图,但是我们遇到了问题。代码的目的是从Uno上的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();
}
}
答案 0 :(得分:1)
当您按下机械开关时,触点的电弧或实际弹跳可能导致电路快速连续几次打开和关闭。
我认为问题在于你没有“按下”按钮按下,因此,当你点击一次按钮时,它实际上可以注册为多次连续按下。
在软件中处理此问题的最简单方法是在检测到引脚变为低电平后添加延迟,然后在延迟后再次检查引脚。所以,而不是:
if (digitalRead(button) == LOW)
{
while (digitalRead(button) == LOW) { } // do nothing
...
}
你会做类似的事情:
if (digitalRead(button) == LOW)
{
delay(20);
if (digitalRead(button) == LOW) {
...
}
}
还有更复杂的方法,但我敢打赌,这可以解决您当前的问题。
答案 1 :(得分:0)
根据您在上面提供的信息,这是我对checkButton函数的更新尝试:
void checkButton(int button){
if (digitalRead(button) == LOW)
{
delay(20);
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 btn press worked
pulseLED(yellowLed, brightness, 500);
}
}