При возникновении чрезвычайных ситуаций значительную часть аварийно-спасательных работ по их ликвидации приходится проводить в условиях большой задымлённости, высокой температуры, маленьких проходов, загрязненности территорий и атмосферы. В таких условиях повышается актуальность задачи снижения риска для жизни спасателей. Более широкое применения современных роботов повысит эффективность противопожарных работ и будет способствовать сохранению жизни личному составу.
Создание роботов-пожарных не только сбережет человеческие ресурсы, но и позволит точно определять место самой высокой температуры (а, значит, и самого сильного возгорания), а также определять точную температуру тех мест, где огонь чуть тлеет, и его невозможно определить визуально.
Цель: создание действующей модели робота-пожарного, который может автоматически распознавать место с максимально высокой температурой на основе датчика ИК-излучения.
Задачи:
изучить историю ИК излучения, свойства ИК излучения, применение;
создать программу на языке программирования С++;
собрать модель робота-пожарного и провести испытания;
исследовать способность робота на основе датчикаMLX90614 к распознаванию объектов с максимально высокой температурой;
исследовать способности робота к распознаванию объектов с максимально высокой температурой через различные препятствия.
Гипотеза:
Робот-пожарный, используя ИК-датчик, сможет автоматически определить место с максимальной температурой, несмотря на некоторые виды препятствий, показать это место, а затем в ручном режиме подъехать к нему и затушить пожар.
Теоретическая часть Глава 1. История изучения инфракрасного излучения и общая характеристика. Свойства ИК излученияВ 1800 г году астрономом У. Гершель проводил опыты по уменьшению нагрева оптических линз телескопа: расположил термометры около разложенного на отдельные цвета света, и обнаружил, что термометр с максимальной температурой находится за красным цветом (приложение 2). Такой вид излучения и назвали инфракрасным (от латин. infra - ниже и слова красный).
С этого опыта началось изучение инфракрасного излучения.
Инфракрасное излучение — это электромагнитные волны, которое испускает любое тело, температурой выше абсолютного нуля - 273.15 °C (эта та температура, при которой прекращается тепловое движение молекул в веществе). Инфракрасное излучение занимает в спектре электромагнитных волн область между красным светом (его окончанием) и микроволновым излучением (приложение 3).
Инфракрасное излучение часто называют «тепловым излучением», так, источники инфракрасных волн (батарея центрального отопления, разогретый духовой шкаф и т.д.) воспринимаются кожей человека как источник тепла, мы его чувствуем, хотя человеческое зрение не в состоянии видеть в этой части спектра.
Самый известный естественный источник инфракрасных лучей на нашей Земле - это Солнце, а самый известный на Руси искусственный источник длинноволновых инфракрасных лучей - это русская печь.
Свойства инфракрасного излучения – хорошо поглощаются телами, изменяют электрическое сопротивление, действуют на термоэлементы и фотоматериалы, хорошо проходят сквозь туман и другие непрозрачные тела. Это излучение невидимо. (приложение 4)
Глава 2. Применение ИК излученияЧеловечество издавна применяло инфракрасное излучение. Практически народов, которые проживают в климатическом поясе с ярко выраженным холодным периодом, есть устройства, с помощью которых люди согревались, просушивали одежду, заготавливали продукты. Так, у русских – это незаменимая русская печь, которая занимала центральное место, как в избе, так и в жизни, у корейцев – «ондоль» - теплый воздух идет по полостям под полом, у народов Крайнего Севера – в центре яранги очаг с открытым пламенем.
В настоящее время инфракрасное излучение нашло широчайшее применение во многих отраслях человеческой жизни.
Инфракрасным излучением заинтересовались военные. Инфракрасные лучи невидимы, но в то же время позволяют зафиксировать объекты с температурой выше абсолютного нуля, вести наблюдение, слежение. Инфракрасные датчики используются в системах наведения ракет, в приборах ночного видения.
Инфракрасное излучение широко применяется в медицине, есть специальные приборы и инфракрасные сауны (приложение №7). В астрономии, с помощью инфракрасного излучения, появляется возможность заглянуть за пределы Солнечной Системы и увидеть далекие галактики. Фотографии в инфракрасном свете позволяют узнать температуру объектов вне Солнечной системы и сделать выводы о процессах, происходящих в них (приложение №8).
В повседневной жизни мы также часто сталкиваемся с инфракрасным излучением. Всем известный пульт дистанционного управления управляет теле-видео, аудиоаппаратурой. Постановка-снятие машины на сигнализацию, запуск мотора также осуществляется с помощью инфракрасного порта. Также инфракрасное излучение применяется в охранных системах, сотовых телефонах. (приложение № 5).
Инфракрасная сушка применяется для сушки лакокрасочных поверхностей.
Инфракрасное излучение применяется для обогрева внутренних помещений
Инфракрасный свет активно используется в научных нуждах. Инфракрасные приборы фиксируют животных, которые активны только в ночное время суток. (приложение №10)
Глава 3. Принцип работы ИК датчика температурыВсе вокруг, если это не объект с температурой абсолютного нуля, становится источником инфракрасного излучения.
В веществах, молекулы которых состоят из множества атомов, атомы колеблются по отношению друг другу или общего центра тяжести. При повышении температуры эти колебания усиливаются. При колебательных процессах появляются электромагнитные волны.
В ИК датчиках температуры электромагнитная волна попадает на чувствительную фотопластину и преобразует ее в напряжение несколько милливольт, а затем преобразует в значение температуры, можно в Кельвинах, Цельсиях или по Фаренгейту.
Инфракрасные датчики бывают контактные и бесконтактные. Принцип работы у них немного отличается.
В контактных ИК датчиках температуры есть открытые концы. Термоэлементы в одной точке соединяются. Если есть разница температур на концах и точкой контакта, то между открытыми концами возникает напряжение.
В нашей работе используется бесконтактный датчик. При бесконтактном способе измерения температуры повышение температуры точки вызывается за счет попадания в эту точку инфракрасного излучения. Каждый объект излучает инфракрасный свет, причем энергия этого света повышается с повышением температуры объекта. ИК датчики температуры измеряют излучаемую мощность и таким образом с высокой точностью определяют температуру объекта (приложение №11).
В нашей работе применяется пироэлектрический датчик MLX90614, фиксирующий инфракрасные лучи в диапазоне от 5,5 до 14 мкм.
Для того, чтобы создать робота-пожарного, необходимо собрать непосредственно робота и написать компьютерную программу по управлению блоками. Затем провести испытания и эксперимент.
Практическая часть Глава 1. Сборка роботаНаш робот собирался на базе программируемого микроконтроллера Ардуино (приложение№13). Для того, чтобы робот-пожарный был мобильным, используем полноприводную колесную базу (приложение№ 12). Для управления двигателями использовалась плата управления моторами постоянного тока (приложение №14). Соединяем эту плату с каждым двигателем и вставляем в Ардуино. Для того, чтобы наш робот мог плавно «поворачивать» датчик температуры, используем сервопривод (приложение №24). В нашем проекте использовался ИК датчик mlx 90614-DCI (приложение 20). Чтобы наглядно было видно, где датчик определил самую высокую температуру, используем лазер (приложение №21). Датчик температуры и лазер скрепляем вместе для точного показа места наибольшей температуры. Мы использовали изоленту. Нам важно знать, какая найдена наибольшая температура, используем для этих целей ЖК индикатор QC1602A (приложение №23). Прикрепляем его на опорных столбиках и соединяем с Ардуино с помощью проводов. Для управления Ардуино со смартфона используем программу Arduino IO Control.Для передачи данных использовался Bluetooth – модуль (приложение №17). В качестве источника постоянного тока использовалась аккумуляторная батарея 12 v (приложение №18). Для управления насосом использовалось реле 5В (приложение №16). Для питания платы Ардуино использовался преобразователь напряжения постоянного тока 12В/9В (приложение №15). Для питания лазерного диода использован преобразователь напряжения постоянного тока 12В/5В (приложение №19). Включение/выключение лазерного диода организовано также через реле 5В (приложение №16). Для питания ИК датчика mlx 90614-DCI использовался встроенный в плату Ардуино преобразователь напряжения на 3,3В. Для тушения использовался насос 12В (приложение №22) и в качестве шлангов 2 упаковки капельниц.
Глава 2. Структурная схема робота-пожарногоРобот-пожарный собран (приложение №25).
Глава 3. Компьютерная программа для роботаДля того чтобы написать программу, необходимо знать алгоритм того, что будет делать робот.
Питание включается.
Инфракрасный датчик температуры включается.
Инфракрасный датчик температуры начинает сканировать помещение.
Находит место с наибольшей температурой.
Запоминает его.
Включает подачу воды.
Корректируем цель и в ручном режиме тушим огонь.
Для того чтобы писать программу сразу в контроллер Ардуино, было решено использовать язык программирования СИ. У этого языка программирования есть большое преимущество: программа пишется сразу на контроллер. Сложности в этом языке представляет то, что все команды надо набирать по буквам, и на английском языке. Такие программы для Ардуино называют скетчем. Затем скетч компилируется (преобразуется в код, понятный контроллеру) и прошивается (прописывается) в память контроллера.
Программа написана (приложение, часть №2) и залита в контроллер Ардуино (приложение №13)
Глава 4. ИспытанияИспытания выявили факторы, влияющие на работу ИК датчика.
ИК датчик измеряет температуру окружающих предметов, при этом находя максимальную температуру. Если в поле зрения попадает человек - то максимальная температура у человека. Если отопительные приборы – то датчик показывает у них максимальную температуру. Если человек и отопительные приборы (батарея центрального отопления) появляются в поле зрения датчика – максимальная температура у отопительной батареи (если, конечно, она горячей человека). Значит, при работе ИК датчика температуры необходимо изолировать дополнительные источники ИК излучения. В домашних условиях мы закрывали батарею центрального отопления поролоновыми матами.
У датчика имеется «поле зрения», так называемая средняя температура пятна. Так, если в поле зрения попадала горящая свеча, температура пламени выводилась как 50-60 градусов, при этом известно, что температура пламени свечи достигает 1400 градусов. Чем больше объект заполняет «поле зрения», тем точнее выводится температура. В нашем случае свеча хоть и была небольшая, но ее температура была явно выше окружающих предметом, поэтому датчик ее фиксировал. Если бы была возможность провести эксперимент с горящей бумагой или древесиной, скорее всего, датчик выводил температуру уже гораздо выше 200С-300С.
Дуло водяной пушки находится на высоте 16 см, этой мощностью насоса гасится огонь свечи высотой 11 см на расстоянии 65-70 см. При увеличении расстояния брызги и струи воды гасят огонь свечи уже меньшего размера. При расстоянии более 1 метра свеча остается незатушенной. Можно нарисовать баллистическую кривую.
Датчик ИК находится на высоте 17,5 см, лазерный прицел на высоте 17 см, дуло на высоте 16 см, оказалось, очень сложным так откалибровать, чтобы они «смотрели» в одну точку. Для точного определения места с максимальной температурой необходимо, чтобы лазерный прицел и ИК датчик составляли одно целое, другими словами, были друг с другом на одной оси.
Результаты испытаний:
При работе ИК датчика температуры необходимо изолировать дополнительные источники ИК излучения.
Чем больше объект заполняет «поле зрения», тем точнее выводится температура.
Для точного определения места с максимальной температурой необходимо, чтобы лазерный прицел и ИК датчик составляли одно целое.
Условия эксперимента: температура окружающего воздуха 26С.
Эксперимент№1
Пропускная способность различных материалов для ИК излучения.
Материалы для эксперимента: пластмасса (непрозрачная), толщиной 1 мм.
Ход эксперимента: между датчиком и источником температуры (лампа накаливания), расположенными на расстоянии 40 см между собой, помещали посередине пластик.
Результат эксперимента: температура лампы >265, через пластик датчик выдавал температуру 230С.
Вывод: Пластмасса толщиной 1 мм поглощает часть ИК излучения. Эксперимент №2
Пропускная способность прозрачных материалов для ИК излучения.
Материалы: прозрачный упаковочный пластик, толщиной 0,5 мм, половина оставлена прозрачной, половина закрашена черным перманентным маркером.
Ход эксперимента: между датчиком и источником температуры (лампа накаливания), расположенными на расстоянии 40 см между собой, помещали посередине сначала прозрачную половину, а затем непрозрачную, закрашенную в черный цвет.
Результат эксперимента: температура лампы датчик воспринимает >265С, через пластик датчик выдавал температуру 220С, а через закрашенный пластик 215С.
Вывод: черный цвет поглотил часть ИК излучения (поглощение составило 2.28 %)
Эксперимент №3
Пропускная способность материалов для ИК излучения в зависимости от их толщины.
Материалы: листы бумаги А4.
Ход эксперимента: между датчиком и источником температуры (лампа накаливания), расположенными на расстоянии 40 см между собой, помещали посередине сначала 1 лист бумаги, затем 2-ой, 3-ий.
Количество листов |
1 лист |
2 листа |
3 листа |
4 листа |
Температура, в градусах |
33 |
28 |
26 |
26 |
Построим соответствующий график.
График зависимости температуры, фиксируемой датчиком и количества листов
Результат эксперимента: каждый последующий лист бумаги уменьшает температуру, воспринимаемую датчиком. 3 и 4 листа становятся преградой для ИК излучения.
Вывод: пропускная способность ИК излучения зависит от толщины материала. Чем толще, тем пропускная способность ниже.
Эксперимент №4
Пропускная способность пара для ИК излучения.
Материалы: парообразующая установка (небулайзер для ингаляций).
Ход эксперимента: между датчиком и источником температуры (лампа накаливания), расположенными на расстоянии 40 см между собой, помещали непосредственно рядом с датчиком источник пара.
Результат: температура лампы через пар 221-227С.
Вывод: пар пропускает ИК излучения, поглощая часть.
Эксперимент №5
Пропускная способность воды для ИК излучения.
Материалы: 500 гр. банка с водой (температура воды 15С ), диаметр 10 см.
Ход эксперимента: между датчиком и источником температуры (лампа накаливания), расположенными на расстоянии 40 см между собой, помещали посередине банку с водой.
Результат: температура лампы через банку с водой 15С (температура воды)
Вывод: вода не пропускает ИК излучение.
Выводы по проведенным экспериментам:Пропускная способность ИК-излучения зависит от материала, через который пропускают ИК излучение, его прозрачности, цвета и толщины.
Пар рассеивает ИК-излучение.
Вода не пропускает ИК излучение.
В процессе экспериментов я пришел к следующим выводам:
Пропускная способность ИК-излучения зависит от материала, через который пропускают ИК излучение, его прозрачности, цвета и толщины.
Пар рассеивает ИК-излучение.
Вода не пропускает ИК излучение.
Моя гипотеза подтвердилась: модель робота-пожарного, оснащенная датчиком ИК-излучения, способна определять место с самой высокой температурой на расстоянии до метра, несмотря на различные препятствия.
У нас в Перми существует робот-пожарный, который управляется человеком с пульта. Мы с одноклассниками были на экскурсии в пожарной части и могли наблюдать его работу. Отличие моего робота в том, что он сам автоматически находит место пожара, используя датчик ИК-излучения. То есть, его можно запускать в помещения, заполненные дымом, опасным для людей. Он сможет найти источник пожара и затушить его.
Заниматься программированием микроконтроллера Ардуино и интересно, но в то же время сложно. Моя задача на будущее: создать полностью автоматизированного робота-пожарного и участвовать на «Урал- РОБОФЕСТЕ-2018» в состязаниях роботов-пожарных.
В дальнейшем я буду создавать новые, интересные и полезные проекты.
Список литературы и интернет-источниковhttp://arduino-projects.ru/ Видео демонстрация проектов на ардуино. arduino библиотеки к модулям. Онлайн уроки arduino.
http://cppstudio.com/ СИ+ для начинающих программистов.
http://www.aif.ru/society/safety/permskiy_valli_robot-pozharnyy_kotoryy_ne_boitsya_dyma_i_ognya. Робот Валли у пермских пожарных.
http://www.rentamatic.ru/ms/megasensor/temperatura/ik-datchiki-HL-Planar/princip-raboty-IK-datchikov-temperatury/index.html принцип работы ИК датчика температуры.
http://arduino.ru/Reference/Modulo программирование на Ардуино.
Физика. Справочник школьника. М., 1995.
Физика и техника инфракрасного излучения. Под ред. Н.В. Васильченко, М., 1965.
Брамсон . М.А. Инфракрасное излучение нагретых тел. М., 1964.
Приложение № 1. Эксперимент Гершеля в 1900 г. |
|
Приложение № 2 Фредерик Уильям Гершель (15 ноября 1738 г.- 25 августа 1822 г.) |
|
Приложение № 3 Электромагнитный спектр. |
|
Приложение № 4 ИК излучение проходит через туман. |
|
Приложение №5 Применение ИК излучения. |
Продолжение Приложения № 1
Приложение № 6 ИК сушка. ИК спектрограф. |
|
Приложение №7 Применение ИК излучения в медицине |
|
Приложение №8 Применение ИК излучения в астрономии |
|
Приложение №9 Применение ИК излучение в военных целях. |
Приложение №10. Фотографии в ИК диапазоне. |
||
Приложение №11. Принцип работы ИК датчика температуры |
||
Приложение №12. Колёсная база с электродвигателями постоянного тока. |
||
Приложение №13 Плата микроконтроллера ARDUINO MEGA 2560. |
||
Приложение №14. Плата управления моторами постоянного тока. |
||
Приложение №15. Преобразователь напряжения постоянного тока 12В/9В. |
||
Приложение №16. Блок реле. |
||
Приложение №17. Bluetooth модуль HC-05. |
||
Приложение №18. Аккумулятор. |
||
Приложение №19. Преобразователь напряжения постоянного тока 12В/5В. |
||
Приложение № 20. ИК датчик mlx90614-DCI |
||
Приложение №21. Лазер. |
||
Приложение №22. Насос. |
||
Приложение №23. ЖК индикатор QC1602A. |
||
Приложение №24. Сервопривод. |
||
Приложение №25. Общий вид робота-пожарного. |
Использованные библиотеки.
#include // Библиотека ARDUINO
#include // Библиотека для шины I2C (для датчика MLX90614)
#include // Библиотека для датчика MLX90614
#include // Библиотека для индикатора
#include // Библиотека для управления двигателями шасси
#include //Библиотека для управления серводвигателями
Настройки.
//-------------- Шасси ----------------------------------------------
#define SPEED_MIN 0 // минимальная скорость двигателей шасси
#define SPEED_MAX 255 // максимальная скорость двигателей шасси
AF_DCMotor motorForwardLeft(3); // номер электродвигателя для переднего левого колеса
AF_DCMotor motorForwardRight(4);// номер электродвигателя для переднего правого колеса
AF_DCMotor motorBackwardLeft(1);// номер электродвигателя для заднего левого колеса
AF_DCMotor motorBackwardRight(2);// номер электродвигателя для заднего правого колеса
// ----------- Блок реле ------------------------------------------
byte PinRel_Pump = 22;// 12В Насос
byte PinRel_2 = 23;// 12В Резерв
byte PinRel_3 = 24;// 5В Резерв
byte PinRel_Lazer = 25; // 5В Лазерный диод
//------------- Индикатор ------------------------------------------
LiquidCrystal lcd(41, 39, 37, 35, 33, 31); // (RS, E, DB4, DB5, DB6, DB7)
//------------- Датчик температуры --------------------------------
MLX90614 mlx = MLX90614(MLX90614_BROADCASTADDR); // *** опрос по адресу "0" (датчик должен быть один на шине) ***
Управление сервоприводом (сканер температуры, функция веера)
enum ScanStates { Start, Scaning, End, Error, Veer };//
class ScanerTemperature
{
Servo servo; // сервопривод
int pinFhotoRez ;// вывод к которому подключен Фоторезистор
float TempMax; //максимальное значение температуры за скан
int posMax; //позиция сервопривода при максимальном значении температуры за скан
float TempMin; //минимальное значение температуры за скан
int posMin; //позиция сервопривода при минимальном значении температуры за скан
float TempCure;//текущее значение температуры
ScanStates ScanState;// состояние сканирования
int pos; // текущее положение сервы
int increment; // увеличиваем перемещение на каждом шаге
int updateInterval; // промежуток времени между обновлениями
unsigned long lastUpdate; // последнее обновление положения
unsigned long startScan; // время запуска сканирования
int delayStartScan = 1000; // задержка для возврата сервы в исходное
unsigned long EndScan; // время окончания сканирования
int delayEndScan = 1000; // задержка для возврата сервы
// Функция Веер
int veerWidth = 2; // Ширина веера (отклонение в градусах)
int veerDelay= 50; // задержка между крайними положениями веера, мс
int veerTime; // время работы веера, с
unsigned long timeStartVeer; // время старта функции веер
int veerCount; //счётчик веера
public:
ScanerTemperature(int interval,int pinFR) // конструктор
{
updateInterval = interval;
pinFhotoRez = pinFR;
increment = 1;
ScanState = End;
pinMode(pinFhotoRez, INPUT);
TempMax = 0;
TempMin = 0;
posMax = 0;
posMin = 0;
}
void Attach(int pin)
{
servo.attach(pin);
}
void Detach()
{
servo.detach();
}
void ScanStart()
{
ScanState = Start;
}
void VeerStart(int width, int delay, int worktime)
{
ScanState = Veer;
veerWidth = width;
veerDelay = delay;
veerTime = worktime;
veerCount = 0;
timeStartVeer = millis();
}
void Update()
{
int znak;
if (ScanState == Start) {
//Serial.println("Scan: Start");
pos = 0;
servo.write(pos); ScanState = Scaning;
TempMax = -70;
TempMin = 380;
posMax = 0;
posMin = 0;
digitalWrite(PinRel_Lazer, HIGH);
startScan = millis();
};
if (ScanState == Scaning && (millis() > (startScan + delayStartScan))) {
//Serial.println("Scan: Scaning");
if ((millis() - lastUpdate) > updateInterval) // время обновлять
{
lastUpdate = millis();
pos += increment;
servo.write(pos);// поворачиваем на следующий угол
TempCure = float(mlx.readTemp(MLX90614::MLX90614_SRCO1, MLX90614::MLX90614_TK)-273);
lcd.setCursor(7, 1); // Устанавливаем курсор в начало 2 строки
lcd.print(TempCure); // Выводим
if (TempCure > TempMax) { TempMax = TempCure; posMax = pos; }
if (TempCure < TempMin) {TempMin = TempCure;posMin = pos; }
Serial.print(TempCure);Serial.print(" ");Serial.print(pos);Serial.print(" ");Serial.print(TempMax);Serial.print(" ");Serial.println(posMax);
//Serial.println(pos);
if ((pos >= 180) || (pos (EndScan + delayEndScan)) {
TempCure = float(mlx.readTemp(MLX90614::MLX90614_SRCO1, MLX90614::MLX90614_TK) - 273);
lcd.setCursor(7, 1); // Устанавливаем курсор в начало
lcd.print(TempCure); // Выводим
Serial1.print("to ");Serial1.println(TempCure);
EndScan = millis();
}
}
if (ScanState == Veer && (millis() < (timeStartVeer + veerTime*1000))) {
if (millis() > (timeStartVeer + veerDelay*veerCount)) {
if (veerCount % 2 == 0) znak = (-1); else znak = 1;
servo.write(posMax + znak*veerWidth);
veerCount++;
}
else
if (ScanState == Veer && (millis() > (timeStartVeer + veerTime * 1000))) { ScanState = End; }
}
}
void TurnMax() {
servo.write(TempMax);
};
void TurnMin() {
servo.write(TempMin);
};
};
Мигание светодиодом.
ClasFlasher
{
// Переменные - члены класса
// Инициализируются при запуске
int ledPin; // номер пина со светодиодом
long OnTime; // время включения в миллисекундах
long OffTime; // время, когда светодиод выключен
// Текущее состояние
int ledState; // состояние ВКЛ/ВЫКЛ
unsigned long previousMillis; // последний момент смены состояния
// Конструктор создает экземпляр Flasher и инициализирует
// переменные-члены класса и состояние
public:
Flasher(int pin, long on, long off)
{
ledPin = pin;
pinMode(ledPin, OUTPUT);
OnTime = on;
OffTime = off;
ledState = LOW;
previousMillis = 0;
}
void Update()
{
// выясняем не настал ли момент сменить состояние светодиода
unsigned long currentMillis = millis(); // текущее время в миллисекундах
if ((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
{
ledState = LOW; // выключаем
previousMillis = currentMillis; // запоминаем момент времени
digitalWrite(ledPin, ledState); // реализуем новое состояние
int TempCure = analogRead(A9);
}
else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
{
ledState = HIGH; // выключаем
previousMillis = currentMillis; // запоминаем момент времени
digitalWrite(ledPin, ledState); // реализуем новое состояние
}
}
};
Обмен по COM порту (выполнение команд от смартфона).
class ComObmen
{
// Переменные - члены класса
ScanerTemperature* st;
int Com; // номер Сом порта (0,1,2,3)
//----------------- Связь по bluetooth---------------------------------------------
int switcher; // Переменная для очередности отправки данных с Arduino на Android
unsigned long lastmillis;
unsigned long lastpost; // Пауза между отправкой сообщений, миллисекунд (рекомендуется не меньше 50)
int SpeedForwardLeft = 0; // обнуление скоростей для колёс
int SpeedForwardRight = 0;
int SpeedBackwardLeft = 0;
int SpeedBackwardRight = 0;
boolean bool1 = false;
String s = ""; // Переменная приема команды
unsigned long startPumpOn; // момент включения Насоса
int timePumpOn = 5000; // время работы насоса
public:
ComObmen(ScanerTemperature* a_st)
{
st = a_st;
switcher = 0; // Переменная для очередности отправки данных с Arduino на Android
lastmillis = 0;
lastpost = 1000; // Пауза между отправкой сообщений, миллисекунд (рекомендуется не меньше 50)
motorForwardLeft.setSpeed(255);
motorForwardRight.setSpeed(255);
motorBackwardLeft.setSpeed(255);
motorBackwardRight.setSpeed(255);
motorForwardLeft.run(RELEASE);
motorForwardRight.run(RELEASE);
motorBackwardLeft.run(RELEASE);
motorBackwardRight.run(RELEASE);
}
void Update()
{
//
unsigned long currentMillis = millis(); // текущее время в миллисекундах
// Выключение насоса
if (digitalRead(PinRel_Pump) && (millis() > (startPumpOn + timePumpOn)))
{
digitalWrite(PinRel_Pump, LOW);
//Serial.println("Насос вЫключен");
}
//получение символов от программы IO Control
while (Serial1.available() > 0) {
char c = Serial1.read(); // Очередной символ в строке
//Serial.write(c);
if (c != 'n') s += c; // Если это не символ конца строки, то добавляем его в строку
else bool1 = true;
}
if (bool1) { // Если получен символ конца строки то разбор строки на ключ - значение и сравнение с готовыми
String key = "", value = ""; // ключ, значение String key ="" , value = ""; //kljuch, znachenie
int i = 0;
Serial.println(s);
while (s.length() > i) {
if (s[i] == ' ') break;
key += s[i];
i++;
}
while (s.length() > i) {
value += s[i];
i++;
}
s = "";
bool1 = false;
// Разбор ключей
//Джойстик
if (key == "d") { // команда от джойстика "d X Y" (X- положение джойстика по горизонтали
int Len = value.length();// Y- положение джойстика по вертикали)
if (Len 255)SpeedForwardLeft = 255;if (SpeedForwardLeft < -255)SpeedForwardLeft = -255;
SpeedForwardRight = (int)(SPEED_MIN + ((SPEED_MAX - SPEED_MIN) / 10)*param2 + ((SPEED_MAX - SPEED_MIN) / 10)*param1);
if (SpeedForwardRight > 255)SpeedForwardRight = 255;if (SpeedForwardRight < -255)SpeedForwardRight = -255;
SpeedBackwardLeft = (int)(SPEED_MIN + ((SPEED_MAX - SPEED_MIN) / 10)*param2 - ((SPEED_MAX - SPEED_MIN) / 10)*param1);
if (SpeedBackwardLeft > 255)SpeedBackwardLeft = 255;if (SpeedBackwardLeft < -255)SpeedBackwardLeft = -255;
SpeedBackwardRight = (int)(SPEED_MIN + ((SPEED_MAX - SPEED_MIN) / 10)*param2 + ((SPEED_MAX - SPEED_MIN) / 10)*param1);
if (SpeedBackwardRight > 255)SpeedBackwardRight = 255;if (SpeedBackwardRight < -255)SpeedBackwardRight = -255;
if ((param2 != 0) || (param1 != 0)) { // движение
if (SpeedForwardLeft > 0) { motorForwardLeft.run(BACKWARD);motorForwardLeft.setSpeed(abs(SpeedForwardLeft)); }
if (SpeedForwardLeft < 0) { motorForwardLeft.run(FORWARD);motorForwardLeft.setSpeed(abs(SpeedForwardLeft)); }
if (SpeedForwardRight > 0) { motorForwardRight.run(BACKWARD);motorForwardRight.setSpeed(abs(SpeedForwardRight)); }
if (SpeedForwardRight < 0) { motorForwardRight.run(FORWARD);motorForwardRight.setSpeed(abs(SpeedForwardRight)); }
if (SpeedBackwardLeft > 0) { motorBackwardLeft.run(BACKWARD);motorBackwardLeft.setSpeed(abs(SpeedBackwardLeft)); }
if (SpeedBackwardLeft < 0) { motorBackwardLeft.run(FORWARD);motorBackwardLeft.setSpeed(abs(SpeedBackwardLeft)); }
if (SpeedBackwardRight > 0) { motorBackwardRight.run(BACKWARD);motorBackwardRight.setSpeed(abs(SpeedBackwardRight)); }
if (SpeedBackwardRight < 0) { motorBackwardRight.run(FORWARD);motorBackwardRight.setSpeed(abs(SpeedBackwardRight)); }
}
else
{
if (param2 == 0 && param1 == 0) { // СТОП
motorForwardLeft.run(RELEASE);
motorForwardLeft.setSpeed(0);
motorForwardRight.run(RELEASE);
motorForwardRight.setSpeed(0);
motorBackwardLeft.run(RELEASE);
motorBackwardLeft.setSpeed(0);
motorBackwardRight.run(RELEASE);
motorBackwardRight.setSpeed(0);
}
}
}
}
// Лазерный диод
if (key == "lazer_on") {
int pred = digitalRead(PinRel_Lazer);
if (pred) digitalWrite(PinRel_Lazer, LOW);
else digitalWrite(PinRel_Lazer, HIGH);
}
// Запуск сканера
if (key == "scan_on") {
st->ScanStart();
}
// Включение насоса
if (key == "pump_on") {
startPumpOn=millis();
digitalWrite(PinRel_Pump, HIGH);
//Serial.println("Насос включен");
}
// Запуск веера
if (key == "veer_on") {
st->VeerStart(2,50,5);
startPumpOn = millis();
digitalWrite(PinRel_Pump, HIGH);
}
}
}
};
Начальная инициализация и главный цикл.
ScanerTemperature scanTemp1(100, A9); // создаём объект сканера (1градус за 100мс)
ComObmen pult(&scanTemp1); // создаём объект обмена со смартфоном
Flasher led1(13, 500, 500);//создаём объект мигающий светодиод (13 пин 500мс горим 500 нет)
const int pinPhoto = A9;
int raw = 0;
void setup()
{
Serial.begin(9600); // COM порт для вывода отладочных сообщений
Serial1.begin(9600); // COM порт для обмена данными по Bluetooth
printf_begin();
//
mlx.begin();
scanTemp1.Attach(9); // Задаём пин для сервы
scanTemp1.ScanStart(); // При включении сразу запускаем скан
lcd.begin(16, 2); // Задаем размерность экрана
lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
lcd.print("VODOMET"); // Выводим текст
lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
lcd.print("Temp="); // Выводим текст
pinMode(PinRel_Pump, OUTPUT); // насос
pinMode(PinRel_2, OUTPUT); // РЕЗЕРВ
pinMode(PinRel_3, OUTPUT); //РЕЗЕРВ
pinMode(PinRel_Lazer, OUTPUT);// лазерный диод
}
void loop()
{
pult.Update();
scanTemp1.Update();
led1.Update