简体   繁体   English

爆震伺服电机控制

[英]Servo motor control by knocking

I am working on a project with arduino. 我正在与arduino进行一个项目。 Basically what i want is to open a door by recognising the the knocking pattern of the person ie the door will unlock only when the knock of person matches with that stored in the arduino. 基本上我想要的是通过识别人的敲门方式来打开门,即只有当人的敲门与arduino中存储的敲门相匹配时,门才会解锁。 Now to unlock the door i am using the servo motor. 现在要解锁门,我正在使用伺服电机。 I want to run the motor only when the person enters the correct knock otherwise not,But when i run the code , the servo motor begins to run as soon as the code execute without waiting for the correct knock. 我只想在有人输入正确的敲击声时才运行电动机,否则我就不想运行。但是,当我运行代码时,只要代码执行完毕,伺服电动机就开始运行,而无需等待正确的敲击声。 Can anyone help me to troubleshoot the mistake i am making in the code.Following is the code: 任何人都可以帮助我解决我在代码中犯的错误。以下是代码:

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);
   }

   }

Not being familiar with Arduino, I can't say for sure if you're missing anything specific to the API, but the only way I see it being possible for voltage to be applied to the servo is if your knock validation returns true, or the servo object isn't set up completely correctly. 不熟悉Arduino,我不能肯定地说您是否缺少API特有的任何东西,但是我看到有可能将电压施加到伺服器的唯一方法是,如果敲击验证返回true,或者伺服对象未完全正确设置。

The documentation for servos suggests fairly straightforward setup. 伺服器文档建议设置相当简单。

I would also verify the validateKnock() method and make sure it isn't always returning true - maybe step through it by hand with some sample code. 我还将验证validateKnock()方法,并确保它并不总是返回true-也许通过一些示例代码手动完成它。 I see that your validateKnock method isn't posted, so it's impossible to say why it might not be working if that is the issue. 我看到您的validateKnock方法没有发布,因此无法说出问题所在为什么它可能不起作用。

Are you sure a voltage isn't being applied to the servo as soon as you bind the object to the pin? 将对象绑定到引脚后,是否确定没有向伺服器施加电压? Does the servo object have some properties you are forgetting to set on init? 伺服对象是否具有一些您忘记在init上设置的属性?

change your 0 degree to 1 degree and 180 degrees to 179 degrees. 将0度更改为1度,将180度更改为179度。 It should stop it from running. 它应该停止运行。 if your using a 180 degree servo. 如果您使用180度伺服。 It can't reach it's min/max limits. 它不能达到最大/最小限制。

Have you tried to calibrate the piezo sensor? 您是否尝试过校准压电传感器? Because, most arduino boards use 10 bit ADC meaning 1024 divisions of voltage range (0-5000mV) and looking into your code, it seems like you activate the sensor as soon as the level goes above 10 (ie approx. 50 mV) while this contributes to the sensitivity of the sensor, it also means that any little noise would be registered unless you use an appropriately calibrated Piezo Sensor. 因为,大多数arduino板都使用10位ADC,这意味着1024个电压范围(0-5000mV)并查看您的代码,当电平超过10(即约50 mV)时,您似乎就激活了传感器。有助于提高传感器的灵敏度,这也意味着除非使用经过适当校准的压电传感器,否则几乎不会记录任何噪音。 Also, you need to show the validateKnock code in order to help us help you... 另外,您需要显示validateKnock代码以帮助我们为您提供帮助...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM