Функция 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");
  
} 

, 👍3


1 ответ


5

Это вполне вероятно из - за блокировки. Описание функции pulseIn() в справочном разделе сайта Arduino гласит:

Считывает импульс (ВЫСОКИЙ или НИЗКИЙ) на выводе. Например, если значение ВЕЛИКО, pulseIn() ждет перехода вывода от НИЗКОГО к ВЫСОКОМУ, запускает синхронизацию, затем ждет перехода вывода от НИЗКОГО к ВЫСОКОМУ и останавливает синхронизацию. Возвращает длину импульса в микросекундах или сдается и возвращает 0, если в течение таймаута не было получено ни одного полного импульса.

Можете ли вы ограничить диапазон, в пределах которого вы хотите остановить автомобиль? Попробуйте установить тайм-аут в pulseIn (), который вернет управление по истечении максимального времени прохождения звука. Может быть, это даст вам достаточную реакцию, чтобы исправить рулевое управление автомобиля. Поможет и замедление скорости автомобиля (он не сможет так же быстро отклониться от своего пути).

В противном случае вам, вероятно, понадобится неблокирующий эквивалент pulseIn().

,

Здесь есть статья на эту тему https://roboticsbackend.com/arduino-pulsein-with-interrupts/, @RowanP

Большое вам спасибо! этот ответ действительно помог и, наконец, устранил проблему, используя ваш совет. Еще раз спасибо!, @Princess Wilson