在学校的一个项目中,我将一个触摸传感器作为连接到arduino的开/关开关,一旦被触摸,一旦启动电动机,伺服和超声波传感器就会被连接,然后再次触摸该传感器时全部停止。我的问题是我无法进行伺服和超声波重复旋转和计算距离的过程超过一次,而且我无法使用循环,因为我不知道电路将运行多长时间以及我是否知道在第二次按下按钮之后,我将不得不等待插入的循环结束,然后一切也停止。
这是到目前为止的代码:
#include <Servo.h>
Servo servo;
int pos = 0;
const int trigPin = 4;
const int echoPin = 5;
long duration;
int distance;
#define TouchSensor 13
int relay = 2;
// motor one
int enA = 10;
int in1 = 6;
int in2 = 7;
// motor two
int enB = 5;
int in3 = 8;
int in4 = 9;
boolean currentState = LOW;
boolean lastState = LOW;
boolean RelayState = LOW;
void setup() {
Serial.begin(9600);
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
pinMode(TouchSensor, INPUT);
servo.attach(3);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
currentState = digitalRead(TouchSensor);
if (currentState == HIGH && lastState == LOW){
Serial.println("pressed");
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
servo.write(40);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance= duration*0.034/2;
Serial.print("Distance: ");
Serial.println(distance);
delay(500);
servo.write(80);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance= duration*0.034/2;
Serial.print("Distance: ");
Serial.println(distance);
delay(500);
servo.write(120);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance= duration*0.034/2;
Serial.print("Distance: ");
Serial.println(distance);
delay(500);
servo.write(160);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance= duration*0.034/2;
Serial.print("Distance: ");
Serial.println(distance);
delay(500);
delay(1);
if (RelayState == HIGH){
digitalWrite(relay, LOW);
RelayState = LOW;
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
} else {
digitalWrite(relay, HIGH);
RelayState = HIGH;
}
}
lastState = currentState;
}
先谢谢了。对不起,有任何错误,英语不是我的母语。
答案 0 :(得分:1)
与大多数其他语言一样,在C ++中,可以使用break
语句从循环中提前退出,因此您可以执行以下操作:
// A loop condition that will never terminate on its own
while(true)
{
// Exit the loop when the sensor is triggered again
if (sensorPressed()) {
break;
}
// Otherwise, continue doing whatever is needed
}
// After the break, execution will resume here
请注意,您可能还希望有另一个循环,以确保在进入主循环之前,传感器仍不会像触发时那样仍在读数。
答案 1 :(得分:0)
您确实应该考虑使代码更易于阅读。很难遵循。作为一个示例,即使它不是代码编写服务,我也必须使其更具可读性。功能应相同,但不包括为此状态添加的循环。我不能在这里尝试。这不是完美的,但是我已经用了一段时间重写了它,所以希望您能从中得到一些东西。欢呼。
#include <Servo.h>
/*
Here I have added couple of definitions,
like max servo position and speed of sound.
Good rule is to name definitions in capital letters.
*/
#define TOUCHSENSOR 13
#define STEPSIZE 40
#define SPEED_OF_SOUND 0.034
#define MAX_SERVO_POS 160
const int trigPin = 4;
const int echoPin = 5;
int relay = 2;
/*
its good to name variables so they indicate usage if possible,
Here I have renamed motor PIN variables and enable pins.
Not only for others but you will also eventually forget.
*/
int enableMotorOne = 10;
int motorOneTerminalOne = 6;
int motorOneTerminalTwo = 7;
// motor two
int enableMotorTwo = 5;
int motorTwoTerminalOne = 8;
int motorTwoTerminalTwo = 9;
boolean currentState = LOW;
boolean lastState = LOW;
boolean relayState = LOW;
Servo servo;
void setup() {
Serial.begin(9600);
pinMode(enableMotorOne, OUTPUT);
pinMode(motorOneTerminalOne, OUTPUT);
pinMode(motorOneTerminalTwo, OUTPUT);
pinMode(enableMotorTwo, OUTPUT);
pinMode(motorTwoTerminalOne, OUTPUT);
pinMode(motorTwoTerminalTwo, OUTPUT);
pinMode(TOUCHSENSOR, INPUT);
servo.attach(3);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void getDistance()
{
/*
Whole function for getting distance from ultrasonic sensor is moved Here
usage in older implementation was repetitive and unnecessary
*/
long duration;
int distance;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance= duration*(SPEED_OF_SOUND/2);
Serial.print("Distance: ");
Serial.println(distance);
}
void scanState()
{
Serial.println("pressed");
digitalWrite(motorOneTerminalOne, LOW);
digitalWrite(motorOneTerminalTwo, HIGH);
digitalWrite(motorTwoTerminalOne, HIGH);
digitalWrite(motorTwoTerminalTwo, LOW);
while(currentState == HIGH && lastState == LOW)
{
/*
I think this is what you were asking, to loop this functionality
until state pins change state.
*/
for (size_t servoPos = 40; servoPos <= MAX_SERVO_POS; servoPos+=STEPSIZE) {
/*
This code in for loop here should do kinda
same as you old code rows
48-91. Please get familiar.
*/
servo.write(servoPos);
getDistance();
delay(500);
}
if (relayState == HIGH) {
digitalWrite(relay, LOW);
relayState = LOW;
digitalWrite(motorOneTerminalOne, LOW);
digitalWrite(motorOneTerminalTwo, LOW);
digitalWrite(motorTwoTerminalOne, LOW);
digitalWrite(motorTwoTerminalTwo, LOW);
} else {
digitalWrite(relay, HIGH);
relayState = HIGH;
}
}
delay(1);
}
void loop() {
/*
This is your new loop function, much easier to understand what is
going on..
*/
currentState = digitalRead(TOUCHSENSOR);
if (currentState == HIGH && lastState == LOW) {
scanState();
}
lastState = currentState;
}