我正在与arduino合作一个项目。基本上我想要的是通过识别人的敲门模式来打开门,即只有当人的敲门与arduino中存储的敲门相匹配时,门才会解锁。现在要解锁门,我正在使用伺服电机。我只想在人输入正确的敲门声时才运行电机,否则不会,但是当我运行代码时,伺服电机在代码执行后立即开始运行,而无需等待正确的敲门声。谁能帮我解决我在代码中犯的错误。以下是代码:
const int knockSensor = 0; // Piezo sensor on pin 0.
const int programSwitch = 2; // If this is high we program a new code.
const int lockMotor = 3; // Gear motor used to turn the lock.
const int redLED = 4; // Status LED
const int greenLED = 5; // Status LED
// Tuning constants. Could be made vars and hoooked to potentiometers for soft configuration, etc.
const int threshold = 10; // Minimum signal from the piezo to register as a knock
const int rejectValue = 25; // If an individual knock is off by this percentage of a knock we don't unlock..
const int averageRejectValue = 15; // If the average timing of the knocks is off by this percent we don't unlock.
const int knockFadeTime = 150; // milliseconds we allow a knock to fade before we listen for another one. (Debounce timer.)
const int lockTurnTime = 500; // milliseconds that we run the motor to get it to go a half turn.
const int maximumKnocks = 50; // Maximum number of knocks to listen for.
const int knockComplete = 1200; // Longest time to wait for a knock before we assume that it's finished.
// Variables.
int secretCode[maximumKnocks] = {50, 25, 25, 50, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Initial setup: "Shave and a Hair Cut, two bits."
int knockReadings[maximumKnocks]; // When someone knocks this array fills with delays between knocks.
int knockSensorValue = 0; // Last reading of the knock sensor.
int programButtonPressed = false; // Flag so we remember the programming button setting at the end of the cycle.
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int pos = 0;
void setup() {
pinMode(lockMotor, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(programSwitch, INPUT);
myservo.attach(8); // attaches the servo on pin 9 to the servo object
Serial.begin(9600); // Uncomment the Serial.bla lines for debugging.
Serial.println("Program start."); // but feel free to comment them out after it's working right.
digitalWrite(greenLED, HIGH); // Green LED on, everything is go.
}
void loop() {
// Listen for any knock at all.
knockSensorValue = analogRead(knockSensor);
if (digitalRead(programSwitch)==HIGH){ // is the program button pressed?
programButtonPressed = true; // Yes, so lets save that state
digitalWrite(redLED, HIGH); // and turn on the red light too so we know we're programming.
} else {
programButtonPressed = false;
digitalWrite(redLED, LOW);
}
if (knockSensorValue >=threshold){
listenToSecretKnock();
}
}
// Records the timing of knocks.
void listenToSecretKnock(){
Serial.println("knock starting");
int i = 0;
// First lets reset the listening array.
for (i=0;i<maximumKnocks;i++){
knockReadings[i]=0;
}
int currentKnockNumber=0; // Incrementer for the array.
int startTime=millis(); // Reference for when this knock started.
int now=millis();
digitalWrite(greenLED, LOW); // we blink the LED for a bit as a visual indicator of the knock.
if (programButtonPressed==true){
digitalWrite(redLED, LOW); // and the red one too if we're programming a new knock.
}
delay(knockFadeTime); // wait for this peak to fade before we listen to the next one.
digitalWrite(greenLED, HIGH);
if (programButtonPressed==true){
digitalWrite(redLED, HIGH);
}
do {
//listen for the next knock or wait for it to timeout.
knockSensorValue = analogRead(knockSensor);
if (knockSensorValue >=threshold){ //got another knock...
//record the delay time.
Serial.println("knock.");
now=millis();
knockReadings[currentKnockNumber] = now-startTime;
currentKnockNumber ++; //increment the counter
startTime=now;
// and reset our timer for the next knock
digitalWrite(greenLED, LOW);
if (programButtonPressed==true){
digitalWrite(redLED, LOW); // and the red one too if we're programming a new knock.
}
delay(knockFadeTime); // again, a little delay to let the knock decay.
digitalWrite(greenLED, HIGH);
if (programButtonPressed==true){
digitalWrite(redLED, HIGH);
}
}
now=millis();
//did we timeout or run out of knocks?
} while ((now-startTime < knockComplete) && (currentKnockNumber < maximumKnocks));
//we've got our knock recorded, lets see if it's valid
if (programButtonPressed==false){ // only if we're not in progrmaing mode.
if (validateKnock() == true){
triggerDoorUnlock();
} else {
Serial.println("Secret knock failed.");
digitalWrite(greenLED, LOW); // We didn't unlock, so blink the red LED as visual feedback.
for (i=0;i<4;i++){
digitalWrite(redLED, HIGH);
delay(100);
digitalWrite(redLED, LOW);
delay(100);
}
digitalWrite(greenLED, HIGH);
}
} else { // if we're in programming mode we still validate the lock, we just don't do anything with the lock
validateKnock();
// and we blink the green and red alternately to show that program is complete.
Serial.println("New lock stored.");
digitalWrite(redLED, LOW);
digitalWrite(greenLED, HIGH);
for (i=0;i<3;i++){
delay(100);
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
delay(100);
digitalWrite(redLED, LOW);
digitalWrite(greenLED, HIGH);
}
}
}
// Runs the motor (or whatever) to unlock the door.
void triggerDoorUnlock(){
Serial.println("Door unlocked!");
int i=0;
// turn the motor on for a bit.
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay (5000); // Wait a bit.
}
digitalWrite(greenLED, HIGH); // And the green LED too.
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(5000); // waits 15ms for the servo to reach the position
} // Turn the motor off.
// Blink the green LED a few times for more visual feedback.
for (i=0; i < 5; i++){
digitalWrite(greenLED, LOW);
delay(100);
digitalWrite(greenLED, HIGH);
delay(100);
}
}