所以我使用我的步进电机和我的按钮传感器(我希望按下按钮时让电机停止;我大部分都想到了)。但是,为了简化我的代码,我设法让我的电机完全停止运动。在下面的代码中,这个想法是通过将大多数动作包含在一个单一内容中来浓缩电机的主要动作(将平台升高到玻璃,拍照,然后降低后退并重复该过程) if声明,以便计算机能够像我预期的那样更好地阅读它。
#include <AccelStepper.h>
const int buttonPin=4; //number of the pushbutton pin
const int opto_shoot=2; // Pin that controls the shoot function
int maxDistance=-12000; //intial distance for motor to move
int button_state=0;
int sensorPin=0; //select input pin for the photocell
int sensorValue=0; //variable to store the vaule coming from the photocell
int motorSpeed = 9600; //maximum steps per second (about 3rps / at 16 microsteps)
int motorAccel = 80000; //steps/second/second to accelerate
int motorDirPin = 8; //digital pin 8
int motorStepPin = 9; //digital pin 9
//set up the accelStepper intance
//the "1" tells it we are using a driver
AccelStepper stepper(1, motorStepPin, motorDirPin);
void setup(){
pinMode(buttonPin,INPUT); //set that the button is an input
pinMode(opto_shoot,OUTPUT); // set the pin that controls the shoot function
stepper.setMaxSpeed(motorSpeed);
stepper.setSpeed(motorSpeed);
stepper.setAcceleration(motorAccel);
}
void loop(){
stepper.moveTo(maxDistance); //move 2000 steps (gets close to the top)
stepper.run();
if (digitalRead(buttonPin) == HIGH){
stepper.stop();
stepper.runToPosition();
digitalWrite(opto_shoot,HIGH); //SHOOT
delay(500);
digitalWrite(opto_shoot,LOW);
delay(1);
goto Lower; }
// for(int i=0;i<36;i++)
// Serial.read();
//
else{
if(stepper.distanceToGo() == 0){
stepper.stop();
stepper.runToPosition();
stepper.moveTo(maxDistance);
}
}
Lower:{
maxDistance=-1*(maxDistance+500);
stepper.moveTo(maxDistance);}
//these must be called as often as possible to ensure smooth operation
//any delay will cause jerky motion
stepper.run();
}
请帮我理解这段代码出错的地方。
答案 0 :(得分:1)
我要改变的一件事是对数字引脚使用中断。我现在没有设置我的Arduino,但我相信attachInterrupt
方法可行。这将允许您仅在发生特定事件时运行代码块(即按下按钮)。
int isPressed = 0; // Init to off state
// Other init stuff goes here.
void setup(){
// Other setup code...
// Set up the interrupt so that when the button is pressed, myISR function
// runs. I opted to run it on the rising edge (i.e. low to high).
attachInterrupt(buttonPin, myISR, RISING);
}
void loop(){
// Check the state of isPressed.
if (isPressed == 0){
// Do stuff, let the motor move.
}
else{
// This runs when the button has been pressed.
// Turn off the flag so this runs just once.
isPressed = 0;
// Then stop the motor until further notice.
stepper.stop();
stepper.runToPosition();
// Do other stuff now that it's off.
}
}
// ISR = interrupt service routine
void myISR() {
// Set the state of isPressed to ON.
isPressed = 1;
}
另外,也许你想重新打开电机?所以只需设置另一个ISR,可能是attachInterrupt(anotherButtonPin, anotherISR, RISING);
,当anotherISR
被按下时会调用anotherButtonPin
(即一个引脚与一个不同的引脚将其关闭)。
最后,在问your other question之后,你有什么工作吗?我建议单独保存破碎的代码并返回到有效的状态。试着了解有什么不同。另一个建议是创建最简单的代码,停止移动电机,比如经过一段时间后。然后尝试集成中断,以便控制电机的停止。祝你好运!
编辑:我还注意到您正在使用goto Lower;
而不是将Lower
作为一个函数并将其称为Lower();
。 goto
命令通常被认为是不好的做法。有关详细信息,请参阅GOTO still considered harmful?。