Парктроник на Arduino: HC-SR04 и зуммер
Парктроник — тот случай, когда даже заводская вещь понятна за один вечер: ультразвуковой датчик меряет расстояние до препятствия, а зуммер переводит его в звук — чем ближе, тем писк чаще и выше, а вплотную превращается в сплошной вой. Фабричный парктроник в бампере делает ровно это, только датчиков у него четыре. Один HC-SR04 с Arduino повторяет механику целиком: импульс 10 микросекунд на TRIG, эхо возвращается на ECHO, длительность эха делим на 58 — получаем сантиметры.
В нашем симуляторе парктроник звучит глазами: карточка HC-SR04 из палитры «Макетка» держит дистанцию ползунком, рантайм честно исполняет pulseIn — длительность эха равна сантиметрам, умноженным на 58 микросекунд, — а карточка зуммера показывает частоту в каждый момент. Serial печатает дистанцию на каждом цикле измерения. Ниже — проверенный скетч с частотной шкалой и разбор граблей.
Звуковая шкала: как расстояние становится частотой
Заводской парктроник кодирует расстояние двумя способами: частота писка растёт с приближением, а интервал между писками сокращается до непрерывного тона. Обе шкалы собираются в скетче одним ветвлением: ближе 20 сантиметров — тон 2000 Гц без паузы; от 20 до 100 — частота линейно растёт от 800 Гц вверх по мере приближения (по 12 Гц на каждый сантиметр); дальше метра — тишина, ехать можно не думая.
Измерение — стандартная тройка digitalWrite: два микросекунды тишины, десять микросекунд импульса, тишина — и сразу pulseIn(ECHO, HIGH), который ждёт подъёма эха и возвращает его длину в микросекундах. Деление на 58 — это скорость звука, свёрнутая в константу: 343 метра в секунду туда и обратно дают 58 микросекунд на сантиметр. Частота опроса — раз в 250 миллисекунд: быстрее машина не едет, а чаще спрашивать pulseIn не имеет смысла.
const int TRIG = 5;const int ECHO = 6;const int PIN_ZUMMER = 8; void setup() { pinMode(TRIG, OUTPUT); pinMode(ECHO, INPUT); pinMode(PIN_ZUMMER, OUTPUT); Serial.begin(9600);} void loop() { digitalWrite(TRIG, LOW); delayMicroseconds(2); digitalWrite(TRIG, HIGH); delayMicroseconds(10); digitalWrite(TRIG, LOW); long dur = pulseIn(ECHO, HIGH); // длительность эха, микросекунды int sm = dur / 58; // 58 мкс = 1 см Serial.print("dist="); Serial.println(sm); if (sm < 20) { tone(PIN_ZUMMER, 2000, 80); // близко — сплошной писк } else if (sm < 100) { tone(PIN_ZUMMER, 800 + (100 - sm) * 12, 60); // чем ближе, тем выше } delay(250);}Прогон в симуляторе: качаете ползунок карточки HC-SR04 — Serial печатает дистанцию каждые 250 миллисекунд, зуммерная карточка показывает частоту: 60 сантиметров — «tone: 1280 Гц», 12 сантиметров — «tone: 2000 Гц» уже сплошным потоком, дальше метра — тишина. TRIG и ECHO рантайм распознаёт сам по вашему скетчу: pulseIn видит, на каком пине вы ждали эхо, и привязывает датчик без ручной настройки.
Честная граница: что исполняет симулятор
| Проверка | Симулятор | Только железо |
|---|---|---|
| pulseIn(ECHO, HIGH) | исполняется: длительность = см × 58 | то же самое |
| delayMicroseconds и таймаут pulseIn | уважаются рантаймом | то же самое |
| tone с частотой от дистанции | исполняется, частота на карточке | слышно ухом |
| Ползунок дистанции 2–400 см | да, карточка HC-SR04 | реальное препятствие |
| Звук в браузере | нет: частоту видно, не слышно | да |
| Слепая зона 2 см и мёртвый эхо на ткани | не моделируется | да — датчик честно слепнет |
Грабли: нули, слепая зона и мёртвый эхо
- Показания 0 — это не «очень далеко», а потерянное эхо: pulseIn не дождался ответа и вернул 0 после таймаута. На живой плате причина — угол датчика на открытое пространство или мягкая поверхность, которая гасит ультразвук: ковёр, ткань, поролон.
- Слепая зона HC-SR04 — первые 2 сантиметра: датчик не успевает «услышать» эхо после своего же импульса. Бампер закрывает как раз эту зону, поэтому у настоящих парктроников датчики выносятся наружу.
- Деление на 58 — упрощение: скорость звука плавает от температуры (зимой до 62 мкс/см). Для гаража неважно, для точного прибора в дату вводится поправка.
- tone() один на весь скетч: параллельную мелодию вторым зуммером не сыграть. Зато частота писка — это и есть «мелодия» парктроника, второй канал не нужен.
- Датчик в бампере живёт в грязи и реагирует на капли дождя как на препятствие: уличную версию прикрывают сеткой и периодически протирают — у настоящих парктроников та же болезнь. В палитре «Макетка» капель нет: ползунок всегда чистый.