Ультразвуковой дальномер на Arduino

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Предисловие

Так получилось, что в университете я изучаю C/C++. Для души пробую делать небольшие проекты на Python. Я много слышал про платформу Arduino, смотрел видео на YouTube, частенько посещал Arduino Project Hub и вот мне стало интересно самому поэкспериментировать, углубясь в разработку под микроконтроллеры. Купив стартовый набор с самой платой и горстью электронных компонентов и попробовав собрать проекты из обучающей брошюры, понял, что надо двигаться дальше. Продумав саму идею следующей самоделки, отправился на просторы Google и обнаружил, что не могу найти всего, что мне нужно на одном ресурсе. Безусловно, мне несложно было посетить несколько сайтитов и блогов с информацией, но я бы сильно сэкономил время, если бы нашел все в одном месте. Так и появилась эта статья-туториал.

Суть проекта

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

Что понадобится?

  • Любая плата Arduino (у меня Uno);

  • Ультразвуковой дальномер HC-SR04;

  • OLED-дисплей на 0,96 дюймов;

  • Соединительные провода;

  • Макетная плата.

Работа с OLED-дисплеем

OLED-дисплей идеально подходит для DIY-устройств. Во-первых, мы имеем достаточно высокое разрешение экрана — 128x64 пикселя. Во-вторых, дисплей работает без модуля подсветки, что обеспечивает низкое потребление энергии. В-третьих, для подключения используется всего четыре разъема — два для питания и два для обмена информацией. Но несмотря на это, у OLED-дисплеев есть и минусы. Со временем пиксели могут тускнеть и перегорать.

Вот таким образом можно подключить дисплей:

Схема подключения
Схема подключения























Есть несколько библиотек для работы с OLED-дисплеями, мне больше нравится OLED_I2C. Мне она кажется очень простой и максимально понятной. Следующим образом выведем классический «Hello, world!» на дисплей:

#include <OLED_I2C.h>                         // Подключаем библиотеку
OLED myOLED(A4, A5, A4);                      // Определяем пины
extern uint8_t SmallFont[];                   // Подключаем шрифт


void setup()
{
    myOLED.begin();                           // Инициализируем дисплей
}

void loop()
{
    myOLED.clrScr();                          // Очищаем буфер дисплея
    myOLED.setFont(SmallFont);                // Инициализируем шрифт
    myOLED.print("Hello, world!", CENTER, 0); // Выводим текст   
    myOLED.printNumI(123, CENTER, 20);        // Выводим целое число
    myOLED.update();                          // Копируем буфер дисплея на дисплей
}

Если функции без параметров понятны сразу и не вызывают вопросов, то с функциями вывода на дисплей могут быть вопросы. Давайте сразу с ними разберемся, их существует всего три вида:

  • print(st, x, y) — печать строки на дисплей.
    Параметры:
    st: строка для печати;
    x: координата верхнего левого угла первого символа по горизонтали;
    y: координата верхнего левого угла первого символа по вертикали.
    В качестве координат можно использовать как сами координаты, так и литералы LEFT, CENTER, RIGHT.

  • printNumI(num, x, y, [length, [filler]]) — печать целого числа на дисплей.
    Параметры:
    num: Число для вывода на экран (от -2147483648 до 2147483647);
    x: координата верхнего левого угла первой цифры/знака по горизонтали;
    y: координата верхнего левого угла первой цифры/знака по вертикали;
    length: <необязательный параметр> минимальное количество цифр для отображения на экране;
    filler: <необязательный параметр> Символ для заполнения, чтобы получить минимальную длину. По умолчанию “ “.
    В качестве координат можно использовать как сами координаты, так и литералы LEFT, CENTER, RIGHT.

  • printNumF(num, dec, x, y, [divider, [length, [filler]]]) — печать числа с плавающей точкой на дисплей.
    Параметры:
    num: Число для вывода на экран (от -2147483648 до 2147483647);
    dec: количество цифр после запятой (в дробной части) (допустимые значения 1-5);
    x: координата верхнего левого угла первой цифры/знака по горизонтали;
    y: координата верхнего левого угла первой цифры/знака по вертикали;
    divider: <необязательный параметр> Одиночный символ для использования в качестве десятичной точки. По умолчанию '.';
    length: <необязательный параметр> минимальное количество цифр для отображения на экране;
    filler: <необязательный параметр> Символ для заполнения, чтобы получить минимальную длину.
    По умолчанию “ “.В качестве координат можно использовать как сами координаты, так и литералы LEFT, CENTER, RIGHT.

Работа с ультразвуковым дальномером

Ультразвуковой датчик расстояния работает по принципу эхолокации — посылает пучок ультразвука и получает его отражение с некоторой задержкой, с помощью которой и можно высчитать расстояние до объекта. Работает датчик от напряжения в 5V на расстоянии от 2 до 400 сантиметров.

Для получения данных с датчика необходимо:

  • Подать на выход Trig импульс длительностью 10 микросекунд;

  • Трансмиттер отправит 8 импульсов с частотой 40 кГц;

  • Когда импульсы отразятся от препятствия и будут приняты ресивером, то на выходе Echo образуется входной сигнал;

  • С помощью формулы данные преобразуются в расстояние. Чтоб получить расстояние в сантиметрах, нам необходимо разделить ширину импульса на 58, для получения расстояния в дюймах — на 148.

Подключить датчик к плате можно следующим образом:

Схема подключения
Схема подключения

Финальный проект

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

Подключим все элементы к плате следующим образом:

Схема проекта
Схема проекта

Скетч проекта:

#include <OLED_I2C.h>
OLED myOLED(A4, A5, A4);
extern uint8_t SmallFont[];

// Инициализируем пины
int echoPin = 2;
int trigPin = 3;

void setup()
{
  myOLED.begin();

  // Определяем ввод и вывод 
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop()
{
  int duration, cm, inch;

  // Генерация короткого импульса длительностью 2 микросекунды
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // В течении 10 микросекунд датчик посылает сигналы в 40 кГц
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Получаем время задержки с выхода Echo
  duration = pulseIn(echoPin, HIGH);

  // Находим расстояние в сантиметрах и дюймах
  cm = duration / 58;
  inch = duration / 148;

  // Выводим информацию на дисплей
  myOLED.clrScr();
  myOLED.setFont(SmallFont);
  myOLED.print("Centimeters:", CENTER, 10);
  myOLED.printNumI(cm, CENTER, 20);
  myOLED.print("Inches:", CENTER, 40);
  myOLED.printNumI(inch, CENTER, 50);
  myOLED.update();
}

Финальный проект в работе выглядит следующим образом:

Что дальше?

Проект дальномера готов и прекрасно работает, но несмотря на все, он не является идеальным законченным решением. Можно поработать над улучшениями, и сделать следующие:

  • Перенести все на монтажную плату и избавиться от макетки. Тогда получится цельное устройства без торчащих проводов;

  • Перейти на Arduino Nano ради более компактного размера;

  • Добавить автономное питание для работы без кабеля;

  • Изготовить корпус.

Источник: https://habr.com/ru/post/567074/


Интересные статьи

Интересные статьи

Пришла зима, короткий день, домашней пальме мало света. Нужно организовать подсветку. Готовую лампу покупать как-то неловко, да и надо ж чем-то заняться долгими зимними в...
Ранее в одном из наших КП добавление задач обрабатывалось бизнес-процессами, сейчас задач стало столько, что бизнес-процессы стали неуместны, и понадобился инструмент для массовой заливки задач на КП.
Однажды мне в голову пришла бредовая идея свести 500 лазерных указок в одно место. Я потратил много времени и сделал это. Получилось зрелищно и бесполезно, но мне понравилось. Полгода назад м...
Вам приходилось сталкиваться с ситуацией, когда сайт или портал Битрикс24 недоступен, потому что на диске неожиданно закончилось место? Да, последний бэкап съел все место на диске в самый неподходящий...
Всем привет. На данный момент я разработал прототип детского интерактивного тира в виде конструктора, которую я назвал “демоническая карусель”. Задумка была реализовать конструктор в области ...