Ультро звуковой датчик расстояния HC-SR04


• О проекте
• Обратная связь
• Полезные ссылки
• Полезные программы
• Друзья сайта


Последние комментарии

Аби: Подключение микроконтроллеров к шине RS-485
написано просто о...

Анатолий: Джойстик для денди на stm32
Автору 100500 рес...




           

Библиотека для AVR





AXLIB Генератор





Помощь сайту


				

Ультро звуковой датчик расстояния HC-SR04

	
	
	

Дата: 2 Апреля 2015. Автор: Алексей

	
	
Наконец-то я собрал все железяки в кучу и начал писать программу для управления водоснабжением. Но вот не задача. Для тестирования программы работы с датчиком уровня воды мне пришлось использовать стакан с водой и купать в нем щупы. Все вроде бы шло хорошо, но через пару часов вода стала мутнеть, а к концу дня стала чуть ли не молоко. Че за фигня? А проблема скрылась в протекании тока через воду. Из под крана течет не дистиллят, а все же как не как питьевая. А как всем известно, питьевая вода насыщена разными минеральными удобрениями элементами. А они в свою очередь и сделали свое черное дело. Не будем разбираться в химии, но пакость есть пакость. Если бы конечно мне нужно было контролировать воду в бочке для полива, да и черт бы с ним, а у меня это для питья. Да и еще у нас вода местная содержит очень много железа. Я представляю что там бы произошло. Короче датчик уровня воды отпал сам собой. Обидно, но нужно искать замену. Я по началу делал датчик из герконов, но мне не понравилось что там геркон срабатывает три раза за проход через него магнита. Но с учетом невозможности использовать щупы я решил вернутся к нему. Опять пихать в питьевую воду трубку с герконами, да еще кусок пенопласта с магнитом. Не, нехорошо. Полез гулять по интернету. Чаще всего попадались промышленные УЗ датчики. Все бы хорошо, но цена!!! Короче решил я посмотреть репертуар всеми любимой ARDUINO. Гы. Есть вариант. Ультрозвуковой датчик расстояния HC-SR04. В принципе какая разница как проверять уровень. Замеряем расстояние от крышки до воды и из этих данных понимаем сколько воды в бочке. Сказано, сделано. Слетал как всегда в ЧипРезистор и прикупил там данный девайс.

Датчик расстояния HC-SR04

Тыкс. Теперь как оно работает. Смотрим даташит (если кому интересно его можно взять тут). И внимательно читаем. Для того чтобы измерить росстояние, нужно сначало подать импульс на ножку Trig длительностью не менее 10 мкс, а затем смотреть на состояние ножки Echo. Как только датчик гаркнет своими 40 КГц в эфир, то сразу же выставит на этой ножке единицу и будет ее держать до тех пор пока звук не вернется. Как только датчик получет свой звук обратно, тут же прижмет ножку Echo к нулю. Собственно вот и все. Далее нам нужно из этих данных получить расстояние. А как? Смотрим снова даташит. Там написано что для получения расстояния в сантиметрах, нужно посчитать сколько микросекунд держалась единица на ножке Echo, а потом разделить его на 58. Теперь давайте подумаем как нам этот огород реализовать в МК. Первое что нужно, так это режим вывода данных. Мы же не терминаторы и подключатся к UART пальцем не можем (конечно можно, но мало что из этого выйдет). Поэтому давайте выводить данные на ЖК дисплей. По мне это самый простой способ. Из расчета того что я управляющий МК для водопровода взял ATmega128A, будем тестить датчик на нем. Если все же у вас другой, то расстраиваться не надо. Данный код подойдет для практически любого AVR МК, будь это ATmega8 или Tiny2313. Лишь бы был вход внешнего прерывания INTx. И так, с железом разобрались, теперь переходим к программе. Не. Давайте ка сначала перейдем к алгоритму.


Это самый приближенный алгоритм что мы будем использовать. Далее по тексту я буду описывать только самое необходимое для работы датчика, а всю программу можно будет скачать в конце статьи. Проект написан в шестой студии и закоментирован на смерть. Так что любой разберется для чего нужна та или иная строка. И так:

Блин. А про схему-то я забыл. :)


Я надеюсь питание и управление контрастностью подключите сами, не маленькие коль до данной статьи дошли. Кварц я использовал на 8 МГц. Пару слов про подключение датчика. Ножка PE3 настраивается как выход. Ей будем дергать Trig. Ножка PE4 это вход внешнего прерывания INT4. Если у вас другой МК, то можно перевесить на любой другой INT0...7.

Для начала давайте создадим два псевдонима START и STOP.

#define START 0
#define STOP 1

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

volatile unsigned int distance = 0x00;
volatile unsigned char status = START;

Первая нужна для сохранения количества микросекунд, а вторая как раз для определения состояния датчика. Напомню, если требуется использовать глобальные переменные в обработчике прерывания, всегда объявляйте ее как volatile, а иначе долго будите искать косяк, почему переменная не обрабатывается в прерывавании. Далее настраиваем периферию.

// Настройка таймемера на 1 МГц (Значит один тик равен одной микросекунде)
TCCR1A = 0x00;
TCCR1B |= (1 << CS11);
TCNT1H = 0x00;
TCNT1L = 0x00;

// Настройка внешнего прерывания по любому изменению
EICRB |= (1 << ISC00);
EIMSK |= (1 << INT4);
	
// Разрешаем глобальные прерывания
sei();

// Нога на выход для тригера
PORTE = 0x00;
DDRE |= (1 << DDRE3); 

Теперь давайте напишем тело обработчика внешнего прерывания.

ISR(INT4_vect) // Обработчик прерывания по изменению на ножке INT4
{
    // Если пришла единица сбрасываем таймер и ставим состояние старта
преобразования
    if(PINE & (1 << PINE4)) 
	{
		TCNT1 = 0x00;
		status = START; 
	}
    // Если пришел ноль, значит звук вернулся. Записываем количества микросекунд 
и выставляем состояние на конец преобразования
    else 
	{
		distance = TCNT1;
		status = STOP;
	}
}

Как это работает. Изначально мы настроили таймер на тиканье раз в 1мкс. То есть каждый раз когда пройдет 1 мкс, таймер приплюсует к регистру TCNT1 единицу. Он это будет делать бесконечно. Так как данный регистр 16 битный, то он досчитав до 65535 перевалит в ноль и все заново. Что происходит дальше. Как только на ножке Echo появляется 1, для внешнего прерывания это значит событие. МК прекращает обрабатывать основную программу, пихает в стек последний арес команды и бежит обрабатывать прерывание. Как только он пришел в обработчик, он смотрит, а что у нас на ножке Echo? Если единица, значит датчик гаркнул в эфир и нужно обнулить таймер, так как там сейчас бог знает что. После выставляем состояние в START. Теперь основная программа знает в каком состоянии датчик. Проделав эту операцию МК возвращается со спокойной душой к работе с основной программой. А тем временем пока звук бегает до цели и обратно, тикает таймер увеличивая свое значение на единицу раз в 1 мкс. Как только звук пришел на приемник, на ножке Echo появляется ноль. О, но это тоже событие для внешнего прерывания. МК снова пихает текущий адрес команды в стек и несется сломя голову в обработчик прерывания. Там снова смотрит что на ноге Echo, а там ноль. О, значит нам нужно сохранить значение регистра счетчика и поставить состояние в STOP. Теперь основная программа знает что у нас есть свежие данные по расстоянию.

// Если состояние датчика STOP
if(status)
	{
		lcd_xy(0,1); // Переходим на нижнюю строку
		sprintf(str, "%.1f cm    ", (float)distance/58); // Создаем 
форматированную строку для вывода.
		lcd_putsf(str); // Выводим строку
		status = START; // Выставляем состояние на Старт для 
следующего преобразования
		_delay_ms(1000); // Для удобства восприятия ЖК задерживаемся
на 1 секунду.
	}

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

Проект для ATmega128A AtmelStudio 6.2

JW Player goes here



АНОНИМ    09.04.15 07:29

>Алексей 16.02.15 08:12 С коррозией проблем не будет. Хочу использовать либо алюминиевые, либо нержовейку щупы. На работе используем промышленный РОС-301. На его принципе и отталкивался. У него щупы из нержовейки и ни один не ржавеет. >Короче датчик уровня воды отпал сам собой. Бгы гы гы

Алексей    09.04.15 08:31

А с коррозией проблем нет. Проблемы с реакциями минералов в воде и проходящего тока через него. Если контроль вести не питьевой воды, то можно на это забить. А мне нужно контролировать питьевую воду. Вот я и перешёл на УЗ. Теперь вопрос сколько проживут УЗ головки. Они открытые. Замена на герметичные ничего не дала, модуль перестал работать. Пока оставлю эти, а со временем напишу свою программу конкретно под УЗ головки.

Юрий    08.05.16 19:38

Давно побороли эту проблему с металлическими датчиками - нужно собирать своего рода генератор - таким образом пропуская через воду при замерах "переменку". Иными словами полярность на электродах все время меняется и электролиза не будет!!!! нержавейку конечно использовать предпочтительнее но только с точки зрения коррозии самих электродов.

Алексей    08.05.16 20:44

Ну я в принципе на герконах собрал. Второй сезон пошел, пока все работает как часы.

Юрий    08.05.16 22:00

Герконы, механика - HC-SR04 все таки получше. Хотя мы в своем проекте и контактные используем. Но когда нужна более плавная градация - ультразвук самое то.

Юрий    08.05.16 22:15

Кстати по поводу замены УЗ головок на закрытые - попробовали? Как работает? В плане точности измерений различия есть?

Алексей    09.05.16 00:44

После замены на закрытые, модуль вообще перестал работать. Упрпаляется все китайской нонеймовской микросхемой, поэтому изучение схемы ни к чему не привело. Смотрел готовые модули, работают от 150 мм против 20 мм открытых.




Чтобы вставить ссылку используйте форму вида[url]http://www.адрес.ru[/url][text]текст ссылки[/text]
Чтобы вставить код используйте форму вида[code]код[/code]

Имя:   





  







Рейтинг@Mail.ru Яндекс.Метрика