【发布时间】:2020-04-20 21:02:26
【问题描述】:
我正在考虑用废弃的汽车零件制造一辆 DIY 卡丁车越野型汽车。作为电子产品,我计划使用我的 Arduino Uno 来控制所有东西。所以我只是做了一个齿轮显示,让我知道我目前在哪个齿轮上。还有一个简单的停车传感器。
如果我离物体太近,停车传感器蜂鸣器会闪烁。而且我不能用 delay() 函数闪烁,因为如果我在闪烁时尝试向上移动,输入将不会注册,因为延迟是一个阻塞函数。所以我尝试改用millis,但似乎它也没有注册。
这个概念很简单。我的变速杆两侧各有两个按钮。当我向上移动时,按钮被按下,因此 7 段显示器增加了一个。另一个用于降档。
我还没有加倒档,但是当倒车雷达功能起作用的时候,我仍然很长时间无法按下按钮。
我希望你们能理解我想说的话。我刚开始用 Arduino 编码,所以我没有足够的经验。我将 .ino 文件作为代码块保留。我试图解释代码中的所有内容。希望有人知道解决方案。提前谢谢...
// Setting up the pins for 7-Segment-Display.
const int E = 13;
const int D = 12;
const int C = 11;
const int DP = 10;
const int G = 9;
const int F = 8;
const int A = 7;
const int B = 6;
// Setting up the counter for gear shifting.
int gearCount = 0;
// Setting up the button states and button pin for state-change detectors.
int buttonAddPin = 5;
int buttonAddState = 0;
int previousButtonAddState = 0;
// And this is for downshifting.
int buttonSubstractPin = 4;
int buttonSubstractState = 0;
int previousButtonSubstractState = 0;
// Adding buzzer for parking sensor.
const int buzzerPin = 3;
int buzzerTone = 0;
// Adding parking sensor.
const int trigPin = 2;
const int echoPin = 1;
long duration;
int distance;
// Adding non-delay blinker with millis for buzzer to blink when sensor detects an object.
unsigned long previousTime = 0;
/*---------------------------------- FUNCTIONS FOR SHIFTING -------------------------------------------------*/
// "zero" function is the series of commands for displayıng 0 on the 7-Segment corresponding to neutral gear.
void zero()
{
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(C, LOW);
digitalWrite(D, LOW);
digitalWrite(E, LOW);
digitalWrite(F, LOW);
digitalWrite(G, HIGH);
digitalWrite(DP, HIGH);
}
// "one" function is the series of commands for displaying 1 on the 7-Segment-Display corresponding to 1st gear.
void one()
{
digitalWrite(A, HIGH);
digitalWrite(B, LOW);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);
digitalWrite(E, HIGH);
digitalWrite(F, HIGH);
digitalWrite(G, HIGH);
digitalWrite(DP, HIGH);
}
// "two" function is the series of commands for displaying 2 on the 7-Segment-Display corresponding to 2nd gear.
void two()
{
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(D, LOW);
digitalWrite(E, LOW);
digitalWrite(F, HIGH);
digitalWrite(G, LOW);
digitalWrite(DP, HIGH);
}
// "three" function is the series of commands for displaying 3 on the 7-Segment-Display corresponding to 3rd gear.
void three()
{
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(C, LOW);
digitalWrite(D, LOW);
digitalWrite(E, HIGH);
digitalWrite(F, HIGH);
digitalWrite(G, LOW);
digitalWrite(DP, HIGH);
}
// And now the main function that we are going to call in "void loop" to determine which gear we are on.
void gearDisplay()
{
buttonAddState = digitalRead(buttonAddPin); // And now the button state change detector for shifting up is ready. As you can see when I push the button
// program adds 1 to gearCount variable. So now gearCount is 1. Therefore the 7-Segment-Display will show
if(buttonAddState != previousButtonAddState){ // 1 on it. We will do this a bit later.
if(buttonAddState == HIGH){
gearCount++;
}
delay(50);
}
previousButtonAddState = buttonAddState;
// Now for downshifting.
buttonSubstractState = digitalRead(buttonSubstractPin);
if(buttonSubstractState != previousButtonSubstractState) {
if(buttonSubstractState == HIGH){
gearCount--;
}
delay(50);
}
previousButtonSubstractState = buttonSubstractState;
// Now we will call one of the 7-Segment-Display number functions according to the gearCount variable.
if(gearCount == 0){
zero();
}
else if(gearCount == 1){
one();
}
else if(gearCount == 2){
two();
}
else if(gearCount == 3){
three();
}
else if(gearCount > 3){ // Just making sure if we press buttons accidentally more than enough, it sets gearCount back to closest gear available.
gearCount--;
}
else if(gearCount < 0){ // Same with this one.
gearCount++;
}
}
// That was al for the gear panel. Now the hard part. The parking sensor.
/*---------------------------------------------- SHIFTING DONE ----------------------------------------------------*/
/*--------------------------------------------- PARKING SENSOR ------------------------------------------------------*/
void parkingSensor()
{
digitalWrite(trigPin, LOW); // Resetting trigPin
delayMicroseconds(2); // Delaying to prevent any issiues. ( I saw this online, most people do it like this so I also did.)
digitalWrite(trigPin, HIGH); // Creating a short soundwave.
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH); // Detecting the time that passes for the soundwave to reach back to the receiver.
distance = duration*0.034/2; // Simple math for calculating the distance between the obstacle and sensor.
unsigned long currentTime = millis(); // Store the current time for blinking the buzzers.
if((distance > 0) && (distance < 31)){ // If the distance is in between 0-31 buzz non-stop.
buzzerTone = 1000;
tone(buzzerPin, buzzerTone);
}
else if((distance > 30) && (distance < 76)){ // If the distance is between 30-76 buzz every 100 miliseconds.
if(currentTime - previousTime >= 100){
previousTime = currentTime;
if(buzzerTone == 1000){
buzzerTone = 0;
}
else {
buzzerTone = 1000;
}
tone(buzzerPin, buzzerTone);
}
}
else if((distance > 75) && (distance < 101)){ // If the distance is between 75-101 buzz every 300 miliseconds.
if(currentTime - previousTime >= 300){
previousTime = currentTime;
if(buzzerTone == 1000){
buzzerTone = 0;
}
else {
buzzerTone = 1000;
}
tone(buzzerPin, buzzerTone);
}
}
else if(distance > 100){ // If the distance is more than 100 don't buzz.
buzzerTone = 0;
tone(buzzerPin, buzzerTone);
}
}
/*------------------------------- PARKING SENSOR DONE -----------------------------------*/
// And this was, I guess, all I had to do but unfortunately it's not working...
void setup() {
pinMode(A, OUTPUT);
pinMode(B, OUTPUT);
pinMode(C, OUTPUT);
pinMode(D, OUTPUT);
pinMode(E, OUTPUT);
pinMode(F, OUTPUT);
pinMode(G, OUTPUT);
pinMode(DP, OUTPUT);
pinMode(buttonAddPin, INPUT);
pinMode(buttonSubstractPin, INPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
gearDisplay();
parkingSensor();
}
编辑:原来pulseIn() 的默认持续时间是 1 秒。它也是一个阻止功能,可阻止按钮在每个循环上注册输入 1 秒。将其更改为较小的值,例如在我的情况下为 10ms,就足够了并且解决了这个问题。所有功劳归于解决此问题的@CherryDT。非常感谢。
顺便说一句,这就是代码在 10 毫秒内的样子:
pulseIn(echoPin, HIGH, 10000)
// 请注意pulseIn() 中的持续时间以微秒为单位。
【问题讨论】:
-
“基本上控制一切” - 您可能希望将工作分解为两个不同的问题:1. 上下移动并在 LCD 上显示活动档位; 2. 根据压电或扬声器发出声音到感应到的距离。获取 1. 和 2. 以使用基于非阻塞 millis() 的代码。然后将两者结合起来。
标签: function arduino sensors arduino-uno multitasking