Функция Pulsein() блокирует одновременное выполнение других задач
Я использую zumo bot с датчиком отражения, используемым для следования за черной линией. Я хочу использовать arduino, чтобы заставить бота zumo остановиться, как только он отойдет на определенное расстояние от препятствия.
У меня есть ультразвуковой датчик (HC-SR04), который я подключил к боту.
Обе эти задачи работают независимо друг от друга, но как только я объединяю код вместе(так что он следует за линией, а также останавливается, когда обнаруживает объект с помощью ультразвукового датчика), он не работает должным образом.. (бот zumo больше не следует за линией)
Я ДУМАЮ, что это связано с функцией pulsein (), блокирующей любые другие задачи, но не уверен.
Мой код приведен ниже. Кто-нибудь может помочь, пожалуйста?
#include <Wire.h>
#include <ZumoShield.h>
ZumoBuzzer buzzer;
ZumoReflectanceSensorArray reflectanceSensors;
ZumoMotors motors;
Pushbutton button(ZUMO_BUTTON);
int lastError = 0;
// This is the maximum speed the motors will be allowed to turn.
// (400 lets the motors go at top speed; decrease to impose a speed limit)
const int MAX_SPEED = 400;
#define echoPin A4
#define trigPin A5
// defines variables
long duration; // variable for the duration of sound wave travel
int distance; // variable for the distance measurement
void setup()
{
reflectanceSensors.init();
pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT
// Initialize the reflectance sensors module
// Wait for the user button to be pressed and released
button.waitForButton();
// Turn on LED to indicate we are in calibration mode
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
// Wait 1 second and then begin automatic sensor calibration
// by rotating in place to sweep the sensors over the line
delay(1000);
int i;
for(i = 0; i < 80; i++)
{
if ((i > 10 && i <= 30) || (i > 50 && i <= 70))
motors.setSpeeds(-200, 200);
else
motors.setSpeeds(200, -200);
reflectanceSensors.calibrate();
// Since our counter runs to 80, the total delay will be
// 80*20 = 1600 ms.
delay(20);
}
motors.setSpeeds(0,0);
// Turn off LED to indicate we are through with calibration
digitalWrite(13, LOW);
// Wait for the user button to be pressed and released
button.waitForButton();
Serial.begin(9600); // // Serial Communication is starting with 9600 of baudrate speed
Serial.println("Ultrasonic Sensor HC-SR04 Test"); // print some text in Serial Monitor
Serial.println("with Arduino UNO R3");
}
void loop()
{
unsigned int sensors[6];
// Get the position of the line. Note that we *must* provide the "sensors"
// argument to readLine() here, even though we are not interested in the
// individual sensor readings
int position = reflectanceSensors.readLine(sensors);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin HIGH (ACTIVE) for 10 microseconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Our "error" is how far we are away from the center of the line, which
// corresponds to position 2500.
int error = position - 2500;
// Get motor speed difference using proportional and derivative PID terms
// (the integral term is generally not very useful for line following).
// Here we are using a proportional constant of 1/4 and a derivative
// constant of 6, which should work decently for many Zumo motor choices.
int speedDifference = error / 4 + 6 * (error - lastError);
lastError = error;
// Get individual motor speeds. The sign of speedDifference
// determines if the robot turns left or right.
int m1Speed = MAX_SPEED + speedDifference;
int m2Speed = MAX_SPEED - speedDifference;
if (m1Speed < 0)
m1Speed = 0;
if (m2Speed < 0)
m2Speed = 0;
if (m1Speed > MAX_SPEED)
m1Speed = MAX_SPEED;
if (m2Speed > MAX_SPEED)
m2Speed = MAX_SPEED;
motors.setSpeeds(m1Speed, m2Speed);
//if (distance <20){
// motors.setSpeeds(0,0);
// }
////////////////////////////////////////////
// Calculating the distance
distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
// Displays the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
}
@Princess Wilson, 👍3
1 ответ
Это вполне вероятно из - за блокировки. Описание функции pulseIn()
в справочном разделе сайта Arduino гласит:
Считывает импульс (ВЫСОКИЙ или НИЗКИЙ) на выводе. Например, если значение ВЕЛИКО, pulseIn() ждет перехода вывода от НИЗКОГО к ВЫСОКОМУ, запускает синхронизацию, затем ждет перехода вывода от НИЗКОГО к ВЫСОКОМУ и останавливает синхронизацию. Возвращает длину импульса в микросекундах или сдается и возвращает 0, если в течение таймаута не было получено ни одного полного импульса.
Можете ли вы ограничить диапазон, в пределах которого вы хотите остановить автомобиль? Попробуйте установить тайм-аут в pulseIn ()
, который вернет управление по истечении максимального времени прохождения звука. Может быть, это даст вам достаточную реакцию, чтобы исправить рулевое управление автомобиля. Поможет и замедление скорости автомобиля (он не сможет так же быстро отклониться от своего пути).
В противном случае вам, вероятно, понадобится неблокирующий эквивалент pulseIn()
.
- Какова работа pulseIn?
- Подключение датчика Winsen ZE11-C2H4 к Arduino
- Запускаю робота с двумя передними датчиками, но он тормозит
- Сколько датчиков может поддерживать один модуль Arduino?
- Получение BPM из данного кода
- Как подключить более 10 датчиков к Arduino uno r3
- Как использовать два ультразвуковых датчика для управления двигателем 5 Вольт?
- Чтение датчика давления от 4 до 20 мА с использованием uno
Здесь есть статья на эту тему https://roboticsbackend.com/arduino-pulsein-with-interrupts/, @RowanP
Большое вам спасибо! этот ответ действительно помог и, наконец, устранил проблему, используя ваш совет. Еще раз спасибо!, @Princess Wilson