Управление двумя ультразвуковыми датчиками без блокировки другого
У меня есть ультразвуковой датчик расстояния. Когда этот датчик измеряет расстояние менее 25 см, второй датчик должен измерять расстояние менее 5 см. Если нет, то должен быть промежуток времени в одну минуту, после которого динамик должен издавать шум, пока второй датчик не измеряет расстояние менее 5 см.
У меня проблемы с этим. Первый датчик имеет много кода, он также должен работать, поэтому использование цикла while для ожидания одной минуты для другого датчика и создания шума после этого невозможно.
Как решить эту дилемму? Я читал прерывания в Arduino, но, к сожалению, не знаю, как заставить это работать.
@andrew, 👍0
Обсуждение2 ответа
Лучший ответ:
Я настоятельно рекомендую вам использовать прерывания и убедиться, что датчики находятся в цилиндрическом конусе, чтобы максимально предотвратить помехи друг другу.
Вот фрагмент кода, который может дать вам представление о том, как устанавливаются и используются прерывания. Я считаю, что вы можете адаптировать его к себе. Он взят с форума Arduino (ссылка), авторство "cattledog".
volatile unsigned long LastPulseTimeA;
volatile unsigned long LastPulseTimeB;
int durationA;
int durationB;
//беззнаковое длинное startTime;
#define trigPinA 7
#define echoPinA 2
#define trigPinB 8
#define echoPinB 3
void setup() {
Serial.begin (9600);
pinMode(trigPinA, OUTPUT);
pinMode(echoPinA, INPUT);
pinMode(trigPinB, OUTPUT);
pinMode(echoPinB, INPUT);
attachInterrupt(digitalPinToInterrupt(echoPinA), EchoPinA_ISR, CHANGE); // Прерывание контакта 2 при любом изменении
attachInterrupt(digitalPinToInterrupt(echoPinB),EchoPinB_ISR, CHANGE); // Прерывание Pin3 при любом изменении
}
void loop(){
digitalWrite(trigPinA, LOW);
digitalWrite(trigPinB, LOW);
delayMicroseconds(2);
digitalWrite(trigPinA, HIGH);
digitalWrite(trigPinB, HIGH);
delayMicroseconds(10);
digitalWrite(trigPinA, LOW);
digitalWrite(trigPinB, LOW);
Serial.print("Sensor A ");
Serial.print(LastPulseTimeA);
Serial.print('\t');
Serial.print((LastPulseTimeA/2) / 29.1,1);
Serial.println("cm");
Serial.print("Sensor B ");
Serial.print(LastPulseTimeB);
Serial.print('\t');
Serial.print((LastPulseTimeB/2) / 29.1,1);
Serial.println("cm");
delay(1000);
}
void EchoPinA_ISR() {
static unsigned long startTimeA;
if (digitalRead(echoPinA)) // Ушел ВЫСОКИЙ
startTimeA = micros();
else // Ушел НИЗКИЙ уровень
LastPulseTimeA = micros() - startTimeA;
}
void EchoPinB_ISR() {
static unsigned long startTimeB;
if (digitalRead(echoPinB)) // стал ВЫСОКИМ
startTimeB = micros();
else // Ушел НИЗКИЙ уровень
LastPulseTimeB = micros() - startTimeB;
}
Спасибо, я попробую. Вопрос, однако, будет ли достаточно времени для запуска остальной части программы, поскольку я предполагаю, что контакты будут постоянно менять значение, прерывая программу 24/7?, @andrew
Насколько я вижу из спецификаций, эхо будет занимать некоторое время до 25 мс в зависимости от расстояния, может быть даже больше, если нет препятствия, и тогда может занять до 38 мс. Так что загруженности не будет. Но, конечно, это также то, что вы хотите сделать с эхо-данными. Затем вы можете подумать о переключении Arduino Mega или даже Cortex-M0 или выше., @Sener
довольно просто:
if (time_is_up_for_sensor1()) read_sensor1(); // читаем датчик1, если время истекло
if (time_is_up_for_sensor2()) read_sensor2(); //читаем датчик2, если время истекло
в time_is_up_for_sensor1/2() обновить для следующего раунда чтения:
int time_is_up_for_sensor1(void) {
static uint32_t millis_next = 0; //следующий миллисекунд
if (millis() >= millis_next) { //время для датчика1 истекло
millis_next += INTERVAL_SENSOR1; // переход к следующему времени измерения
return 1; //нужно считать датчик1
} else return 0;
}
аналогично для датчика2
millis_next += INTERVAL_SENSOR1; ... if (millis() >= millis_next)...
метод неправильно вычисляет, когда millis() переполняется. Чтобы избежать этого, вместо этого напишите millis_prev = millis();
(или, возможно, millis_prev += INTERVAL_SENSOR1;
), а затем проверьте с помощью if (millis()-millis_prev > INTERVAL_SENSOR1)...
, @James Waldby - jwpat7
что именно делает static uint32_t millis_next = 0;
? (я новичок в C++/Arduino), @andrew
- Проблема прерываний с датчиком потока
- Проблема стабильности кода прерываний, связанного с датчиком расхода
- Какова работа pulseIn?
- Сколько датчиков может поддерживать один модуль Arduino?
- Получение BPM из данного кода
- Как подключить более 10 датчиков к Arduino uno r3
- Программа arduino выдаёт ошибку expected //primary-expression before ')' token error: //expected ';' before '}' token E
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
посмотрите на пример «мигать без промедления»; вам нужно сделать то же самое во время «ожидания» на датчиках., @dandavis