Давайте рассмотрим скетч. В первую очередь подключаю библиотеку для работы с дисплейчиком. Затем мы видим две новые библиотеки. Библиотека Wire предназначена, собственно, для работы с I2C, которая используется для работы с Multiservo шилдом, и библиотека Multiservo, которую точно так же, как библиотеку Quad Display, я взял на сайте производителя, то есть у «Амперки». Вы можете поступить точно так же. Дальше я начинаю прописывать пины: 2 пина для дальномера, пин для дисплея. Напомню, что я убрал их со 2-го и 3-го пинов, потому что Iskra использует 2-й и 3-й пины для работы I2C. Затем 9-й и 8-й пины Multiservo шилда используются для подключения двух сервомоторчиков: один для сканирования, другой для прожектора. Я здесь подпишу букву M. Это не те же 8-й и 9-й пины, что пины Arduino. Затем 8-й пин Arduino мы используем для подключения светодиода, то есть прожектора. И затем два числа обозначают начало и конец диапазона сканирования. Затем я создал два объекта типа Multiservo. Для нас это выглядит точно так же, как работа с обычной библиотекой Servo, только Multiservo. Затем я завел 3 переменных, в которых буду сохранять угол, где находится ближайший объект, угол поворота сканера. Затем – одну переменную для хранения расстояния и переменную для хранения расстояния до ближайшего объекта. В нее я поместил значение 500, потому что наша функция measure, как вы помните, ограничивает измерение 3-мя метрами, поэтому 500 см (5 м) заведомо больше, чем диапазон измерений. Соответственно, ближайший объект не может быть на таком расстоянии. И зачем это нужно, сейчас дальше вы поймете. Затем внутри сетапа я пишу Wire.begin (это необходимо для работы с I2C) и начинаю настраивать пины, как обычно, для ультразвукового дальномера, выход для дисплея, выход для светодиода прожектора. Затем подключаются 2 сервомотора таким же методом attach, как в обычной библиотеке Servo, только на этот раз он берется из библиотеки Multiservo. Ну и я устанавливал связь с компьютером во время отладки. Затем в основном цикле, в лупе, все происходит довольно лаконично. У нас есть один цикл, который пробегает от указанного начала диапазона измерений до указанного конца диапазона измерений по единичке. И затем вызывается самодельная функция scan, которую мы сейчас рассмотрим, и в нее передается текущее значение счетчика, то есть угла поворота на самом деле. Затем происходит то же самое, только в обратном направлении, от конца диапазона сканирования до его начала. Также вызывается scan, в который передается счетчик, а затем переменную с ближайшим расстоянием я вновь приравниваю к 500-м, чтобы освежить в памяти радара, что у него кончилось сканирование в обе стороны, и будем заново искать ближайший объект. Затем идет уже неоднократно использованная нами самодельная функция measure. Да, вот я сейчас упоминал, что мы ограничиваем диапазон сканирования 3-мя метрами вот из-за этой строчки. Ну а затем написана новая функция scan, в которую я вынес все, что многократно повторяется в лупе – в цикле, идущем в одну сторону, и в цикле, идущем в другую сторону. Для начала мы принимаем параметр angle (угол). Как вы помните, мы только что туда передавали переменную счетчик, и, соответственно, здесь мы этот угол используем для поворота сервы с ультразвуковым дальномером. В каждом положении мы измеряем расстояние до объекта и сохраняем в переменную distance, выводим ее на дисплей, делаем маленькую задержку, чтобы не слишком быстро изнашивать редуктор сервомоторчика. Вот здесь вот происходит мой отладочный вывод в последовательный порт. Мы сейчас даже не будем смотреть туда. И затем я разбираюсь с тем, что же мы измерили. Я сравниваю переменную, где хранится ближайшее расстояние, с текущим расстоянием. Как вы помните, изначально в ней лежит 500. Затем я проверяю, не равно ли расстояние одному. А расстояние у нас будет равно одному, только если pulseIn в функции measure вернет ноль, а затем мы с помощью констрейна в конце measure сузим диапазон до одного. Практически невозможна ситуация, когда мы будем измерять расстояние до объекта, который находится так близко. То есть 1 см – это скорее всего значит то, что мы ничего не видим. Так вот, мы хотим отбросить эту ситуацию, поэтому проверяем, не равна ли дистанция одному? И только в случае если эти события наступили одновременно, а именно текущее расстояние не равно одному, и то расстояние, которое мы считаем ближайшим, оказалось больше текущего, то есть текущее меньше, мы выполняем сразу несколько действий. Во-первых, запоминаем, что ближайшее расстояние – это текущее расстояние. Запоминаем, что угол, где находится ближайшее расстояние, где находится объект, до которого ближайшее расстояние, равен текущему углу. И затем сразу же используем эту переменную для того, чтобы на второй сервомоторчик, в котором установлен прожектор, отправить этот же угол, чтобы прожектор повернулся и подсветил ближайший объект. Ну и здесь мы проверяем, больше ли единицы расстояние до ближайшего объекта, то есть а на самом деле подразумеваем, не дальше ли 3-х метров этот объект. И включаем пин со светодиодом, то есть прожектор, а иначе – выключаем. Ну потому что зачем нам подсвечивать пустоту? Скорее всего никакой враг не подкрался. Зачем тратить электроэнергию? Вот таким вот образом будет работать обновленный прожектор типа «всевидящее око», и за его работой мы сейчас и понаблюдаем. Вот так вот начал сканировать радар пространство, увидел меня и повернул в меня прожектор, потому что сейчас я ближе всего к нему. Теперь я ему подставлю руку, и он следит за ней. Подставлю руку с другой стороны, и он ее догоняет. Враг теперь точно не пройдет, а мы закончили третью неделю, в ходе которой вы узнали, как измерять расстояние разными способами, столкнулись с тем, что при измерениях могут возникать шумы. Но вы знаете, что с ними можно бороться, и сделали фильтр вида «скользящая средняя». Затем вы научились создавать собственные функции, использовать чужие библиотеки, массивы, научились использовать широтно-импульсную модуляцию для имитации аналогового сигнала на выходе. Также вы узнали, что Интернет полон полезных сведений, которые вам помогут при создании устройств, и чуть ближе посмотрели на процессинг – инструмент, который позволяет красиво визуализировать получаемые данные. Ну а я с вами прощаюсь до следующей недели!