2

我正在与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);
   }

   }
4

3 回答 3

0

您是否尝试过校准压电传感器?因为,大多数 arduino 板使用 10 位 ADC,这意味着 1024 个电压范围 (0-5000mV) 并查看您的代码,似乎您一旦电平超过 10(即大约 50 mV)就激活传感器,而这有助于传感器的灵敏度,这也意味着除非您使用经过适当校准的压电传感器,否则任何微小的噪声都会被记录下来。此外,您需要显示 validateKnock 代码以帮助我们帮助您...

于 2014-06-26T03:21:42.927 回答
0

将您的 0 度更改为 1 度,将 180 度更改为 179 度。它应该阻止它运行。如果您使用 180 度伺服。它无法达到其最小/最大限制。

于 2013-12-11T21:11:08.987 回答
0

不熟悉 Arduino,我不能确定您是否缺少特定于 API 的任何内容,但我认为可以将电压施加到伺服系统的唯一方法是您的爆震验证是否返回 true,或者伺服对象未完全正确设置。

伺服系统的文档建议相当简单的设置。

我还将验证 validateKnock() 方法并确保它并不总是返回 true - 可能使用一些示例代码手动逐步完成它。我看到你的 validateKnock 方法没有发布,所以如果这是问题,就不可能说为什么它可能不起作用。

您确定将对象绑定到引脚后没有立即向伺服施加电压吗?伺服对象是否有一些您忘记在初始化时设置的属性?

于 2013-05-13T16:27:05.107 回答