Как использовать две функции pulseIn() одновременно в Arduino?

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

, 👍2

Обсуждение

В нынешнем виде вопрос может быть перенесен в Arduino stackexchange., @gbulmer


2 ответа


3

Вы не можете использовать pulseIn (), если хотите использовать оба ультразвуковых датчика одновременно.

Так что либо:

  • не используйте pulseIn, а вместо этого сделайте это самостоятельно,используя , например, digitalRead,
  • используйте ультразвуковые датчики последовательно, один, затем другой, или
  • используйте прерывания смены контактов для определения возврата импульса сигнала.

Самый простой подход-использовать ультразвуковые датчики последовательно. В этом случае используйте форму pulseIn(PIN, значение, тайм-аут);, где тайм-аутв микросекундах задает максимальное время ожидания импульса.

Это практично, если вы знаете, что реалистичная дальность находится в пределах пары метров. Скорость звука составляет 343,2 метра в секунду, или 0,3432 метра в миллисекунду. Поэтому, если тайм-аут установлен на 3000 микросекунд (3 миллисекунды), он будет ждать эха на расстоянии (примерно) 0,5 метра.

Изменить: Расстояние до объекта, измеренное с помощью временной задержки, составляет половину общего пройденного расстояния, потому что звук доходит до объекта, а затем возвращается обратно к датчику.
Т. е. расстояние до объекта = общее расстояние, пройденное звуком / 2

Альтернативой является то, что делает pulseIn, но для более чем одного контакта. Это проще, чем реальный код pulseIn, но иллюстрирует идею:

int inPin1 = ...;
int inPin2 = ...;

void setup() {
  // ... другие вещи, затем настройте PIN
  pinMode(inPin1, INPUT);
  pinMode(inPin2, INPUT);
}

void loop() {
  // start ultrasound 1
  // start ultrasound 2
  // дождитесь, пока ультразвук 1 пошлет импульс
  // дождитесь, пока ультразвук 1 пошлет импульс
  long startTime = micros();
  while (digitalRead(inPin1)==LOW && digitalRead(inPin1)==LOW) {
    ; // do nothing
  }

  long stop1st = micros();
  int firstBack = -1;
  while (digitalRead(inPin2)==LOW) { // wait for the other if it was 1 first
    firstBack = inPin1; // remember pin 1 returned first
  }
  while (digitalRead(inPin1)==LOW) { // wait for the other if it was 2 first
    firstBack = inPin2; // remember pin 2 returned first
  }
  long stop2nd = micros();

  // now have the two return times, and the pin which returned first
}

Вы могли бы прочитать источник pulseIn() и написать лучший код, чем этот.

Третий вариант, использовать внешние прерывания или прерывания для смены контактов, зависит от того, какой Arduino вы используете. Обычный ATmega328 имеет пару контактов 2 и 3, которые имеют свои собственные "внешние" процедуры обслуживания прерываний (т. Е. каждый вывод имеет "функцию", которая вызывается, когда аппаратное обеспечение обнаруживает изменение сигнала на выводе). Чтобы узнать, как их прикрепить, см. раздел Прикрепление.

Другие контакты также можно использовать с прерыванием "смена контактов", но каждое прерывание должно определить, какой из портов (до 8 контактов) запустил его, поэтому это не так быстро и просто.

Идея здесь состоит в том, чтобы запустить ультразвуковые датчики точно так же, как и раньше, сэкономить время их запуска, точно так же, как и раньше, но позволить процедуре короткого прерывания зафиксировать время, в течение которого возвращающийся эхо-импульс запускает вывод.

Необходимо немного позаботиться о том, чтобы время было зафиксировано, а основной цикл был просигнализирован.

Вы можете выбрать таймер для измерения ультразвука в оба конца, если хотите получить более высокое разрешение и меньшее дрожание, чем обычный таймер на 4 микросекунды. Микросекунда составляет около 0,34 мм, поэтому ошибка в 4 микросекунды составляет около 1,3 мм.

,

"Таким образом, если тайм-аут установлен на 3000 микросекунд (3 миллисекунды), то он будет ждать эха на расстоянии (примерно) 0,5 метра". Это должно быть близко к ~1,02 метра. я прав?, @Mat_python

@Mat_python - звук распространяется на 0,3432 м/миллисекунду, поэтому за 3 миллисекунды он пролетит около 1 метра. Ультразвуковой датчик работает за счет *отраженного* звука, поэтому звук должен перемещаться к объекту, а затем возвращаться. Таким образом, вы измеряете время в оба конца, следовательно, расстояние до объекта равно общему расстоянию/2., @gbulmer

Спасибо. Я так и думал. Я пытаюсь обнаружить движущийся объект, то есть футбольный мяч. Я работаю над созданием счетчика голов. Проблема с ультразвуковым датчиком в том, что он иногда не достает до мяча. Я использовал два ультразвуковых датчика для обнаружения футбольного мяча, который мог двигаться очень быстро, но он обнаруживался в 8 случаях из 10. в чем может быть проблема? Есть ли какие-либо другие датчики, которые я могу использовать для обнаружения футбольного мяча, проходящего на расстоянии 0-1, 5 метров от датчика. Я также пробовал датчик PIR, но он плохо работает для неживых объектов., @Mat_python

@Mat_python - если все, что вы хотите сделать, - это счетчик футбольных мячей, будет ли полезно обнаружить что-то, пересекающее линию? Это может быть легко сделать. Или ты имеешь в виду гонять по полю, считая мячи? Вам нужно будет четко сформулировать проблему, и, возможно, стоит написать новый вопрос., @gbulmer

ДА. Я хочу сделать счетчик футбольных мячей, и обнаружение чего-либо, пересекающего линию, будет работать. Я попробовал использовать ультразвуковой датчик. Но он промахивается, если мяч летит слишком быстро. каковы другие альтернативы? Я также написал новую тему вопроса по этому поводу здесь : http://arduinoprosto.ru/q/29748, @Mat_python


1

вот как я исправил проблему для моей личности -5 лет спустя я делаю это по-своему, запустив pulsein код дважды в пределах того же цикла функция работать не будет, я получил вокруг этого, добавив второй отдельной части, ИДК имя, если ее функция или библиотека...но вот мой пример кода просто создает для измерения расстояний от 2-х различных датчиков. я надеюсь, что это поможет

const int trigPin =6;
const int echoPin =5;
const int trigPin2 = 11;
const int echoPin2 = 10;

long duration2;
long distance2;
long duration;
int distance;
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
pinMode(trigPin2, OUTPUT); 
pinMode(echoPin2, INPUT); 
Serial.begin(9600); // Starts the serial communication
}
void loop() {
digitalWrite(trigPin, LOW);// Clears the trigPin
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance= duration*0.034/2;
Serial.println(distance2);
test();
}

void test()
{
digitalWrite(trigPin2, LOW);// Clears the trigPin
delayMicroseconds(2);
digitalWrite(trigPin2, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin2, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration2 = pulseIn(echoPin2, HIGH);
distance2= duration2*0.034/2;
}

мой код печатает только расстояние второго датчика, а не оба, как вы можете видеть...не идеально, это был быстрый скетч, который я сделал

,