Bluetooth термометр на avr (arduino)

Создаем беспроводной термометр на Arduino

Узнайте, как использовать RF модуль 433 МГц совместно с ATMega328P-PU. В данной статье мы соберем схему из датчика DHT11 и радиочастотного передатчика. А также соберем приемное устройство с радиоприемником 433 МГц и LCD дисплеем.

Что нам потребуется

Введение

В данной статье я покажу вам, как собрать устройство, которое измеряет температуру и относительную влажность воздуха и посылает измеренные значения с помощью стандартного радиочастотного модуля 433 МГц. Датчик температуры и влажности, используемый в устройстве, – это DHT11.

Существует множество способов передачи небольшого объема данных с помощью Arduino или контроллеров ATMega. Один из них использует уже готовую библиотеку, подобную RCSwitch, Radiohead или VirtualWire.

Кроме того, можно отправить необработанные данные с помощью встроенного в микроконтроллер модуля UART. Но использовать встроенный модуль UART не рекомендуется, так как приемник будет собирать и все помехи, и микроконтроллер будет работать не так, как предполагалось.

В данной статье для передачи и приема данных я использую библиотеку VirtualWire. Эта библиотека работает с Arduino IDE 1.6.2 и 1.6.5.

Модуль передатчика 433 МГц, когда не передает данные, всё равно излучает радиочастотные колебания и передает шум. Он также может создавать помехи другим радиочастотным устройствам. Чтобы не допустить этого, я включаю его, когда необходимо передать данные, и выключаю его, когда передача закончена.

Аппаратная часть

Нам необходимы две структурные схемы. Одна для передающего устройства, вторая для приемного.

Передатчик

Нам необходимы:

  • способ прошивки микроконтроллера → ISP;
  • датчик для измерения температуры и влажности → DHT11;
  • микроконтроллер для обработки данных → ATMega32p;
  • способ беспроводной передачи данных → радиочастотный модуль 433 МГц.

Приемник

Нам необходимы:

  • способ приема радиосигнала → радиочастотный модуль 433 МГц;
  • способ обработки принятых данных → Arduino Mega;
  • способ отображения температуры и влажности → 16×2 LCD.

Принципиальные схемы

Передатчик

Передающая часть беспроводного термометра на ATMega328p (для увеличения масштаба можно кликнуть по картинке правой кнопкой мыши и выбрать «Открыть ссылку/изображение в новой вкладке/новом окне»)

В данном примере я не буду выводить неиспользуемые выводы микроконтроллера на внешние контакты термометра, после чего их можно было бы использовать для дальнейшего усовершенствования устройства. Здесь мы рассматриваем лишь идею для устройства и соберем его только на макетной плате.

Приемник

Приемная часть беспроводного термометра на Arduino Mega (для увеличения масштаба можно кликнуть по картинке правой кнопкой мыши и выбрать «Открыть ссылку/изображение в новой вкладке/новом окне»)

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

Перечень элементов

Передатчик

Перечень элементов передающей части беспроводного термометра на ATMega328p (для увеличения масштаба можно кликнуть по картинке правой кнопкой мыши и выбрать «Открыть ссылку/изображение в новой вкладке/новом окне»)

Приемник

Перечень элементов приемной части беспроводного термометра на Arduino Mega (для увеличения масштаба можно кликнуть по картинке правой кнопкой мыши и выбрать «Открыть ссылку/изображение в новой вкладке/новом окне»)

Программа

Программа передатчика

Сперва рассмотрим программу передающей части:

// Подключаем необходимые библиотеки #include #include // Определение #define dhtPin 4 #define dhtType DHT11 #define txPowerPin 8 // Использование библиотеки DHT DHT dht(dhtPin, dhtType); // Переменные char msg0[3]; char msg1[3]; int tem = 0; int hum = 0; // Функция первоначальной настройки – выполняется только один раз при включении void setup() { pinMode(txPowerPin, OUTPUT); pinMode(txPowerPin, LOW); vw_setup(4800); // Скорость соединения VirtualWire vw_set_tx_pin(9); // Вывод передачи VirtualWire } // Функция цикла – выполняется всегда void loop() { digitalWrite(txPowerPin, HIGH); hum = dht.readHumidity(); // Переменная хранит влажность tem = dht.readTemperature(); // Переменная хранит температуру itoa(hum, msg1, 10); // Преобразование влажности в массив char itoa(tem, msg0, 10); // Преобразование температуры в массив char strcat(msg0, msg1); // Сложение/объединение двух массивов vw_send((uint8_t *)msg0, strlen(msg0)); // Передача сообщения vw_wait_tx(); // Ждем завершения передачи digitalWrite(txPowerPin, LOW); delay(5000); // Ждем 5 секунд и повторяем всё снова }

Для передачи влажности и температуры в одном сообщении я соединяю их вместе. Сначала данные считываются в переменную как целые числа, потом целые числа преобразовываются в массив символов, а затем они соединяются друг с другом.

На приемной стороне данные будут разделены на отдельные символы. Делая это, я ограничиваю себя двумя цифрами градусов. Если датчик находится в среде с температурой менее 10°C, я буду получать на дисплее символы мусора.

Например, если температура составляет 20°C, а влажность – 45%, то будет передаваться сообщение 2045, и всё хорошо. Если температура равна 9°C, а влажность – 78%, то передастся сообщение 978x, где «x» – случайный символ.

Поэтому, если вы будете собирать данный беспроводной термометр, я советую вам изменить программу для передачи правильных данных, когда температура будет меньше 10°C.

Программа приемника

// Подключаем необходимые библиотеки #include #include // Определение подключение LCD #define RS 9 #define E 10 #define D4 5 #define D5 6 #define D6 7 #define D7 8 LiquidCrystal lcd(RS, E, D4, D5, D6, D7); // Отрисовка символа градусов byte degreesymbol[8] = { B01100, B10010, B10010, B01100, B00000, B00000, B00000, B00000 }; // Переменные int tem = 0; int i; // Функция первоначальной настройки – выполняется только один раз при включении void setup() { lcd.begin(16,2); // Инициализация LCD lcd.createChar(1, degreesymbol); // Создание символа градусов в месте 1 Serial.begin(9600); // Для отладки vw_setup(4800); // Скорость соединения VirtualWire vw_rx_start(); // Готовность для приема vw_set_rx_pin(2); // Вывод приема VirtualWiore lcd.clear(); // Очистить LCD } // Функция цикла – выполняется всегда void loop() { uint8_t buf[VW_MAX_MESSAGE_LEN]; // Переменная для хранения принятых данных uint8_t buflen = VW_MAX_MESSAGE_LEN; // Переменная для хранения длины принятых данных lcd.setCursor(0,0); lcd.print(“Temp: “); if (vw_get_message(buf, &buflen)) // Если данные приняты { for (i=0;i

Источник: https://radioprog.ru/post/128

Цифровой термометр с уличным датчиком на bluetooth модулях

avrki@avrki.ru

Дата: 26 Октября 2015. Автор: Алексей

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

Отсюда и родилась идея собрать свою “метеостанцию” которая могла бы лишь измерять температуру за окном. Два модуля bluetooth должны соединяться между собой и давать возможность передачи данных. Вот что это за звери. Хотите верьте, хотите нет, но когда я их вытащил из закромов и положил на стол, то я понятия не имел что с ними делать.

Далее интернет, сборка тестовой схемы, подключения, первые АТ команды, связь с телефоном, море восторга и облом. А вот от сюда давайте по подробнее. Как оказалось такие модули имеют четыре названия. HC-03, HC-04, HC-05 и HC-06. Ну и что…

Да вот что, HC-03/05 могут прикидываться как Мастер, так и Слейв, а вот HC-04/06 могут быть только Слейвами. И как на зло у меня именно второй вариант. Тут я бью себя по лбу и вспоминаю что когда покупал, то выбирал HC-06, мол последний вариант самый лучший. Впредь урок, читай сначала мануал, а потом хватай.

Далее при изучении оказалось что данные модули схематикой ничем не отличаются от своих корешей. Значит отличия лишь в прошивке. О да, волшебное слово “перепрошивка”. Значит нам дорога на офсайт. А тут подкрался второй облом. Офсайт закрыт для простых смертных. Даже если пройти дотошную регистрацию, все равно фиквам. Че делать. Зы, мир не без добрых людей.

Теперь у меня есть прошивка и прошивальщик. А теперь все по порядку. Чем данные модули отличаются друг от друга. Слева изображен модуль HC-03/05, а справа HC-04/06. В чем разница. Если посмотреть на оба модуля, то можно заметить что левые стороны и низ одинаковые, а разница только в выводах по правому борту. Так в чем же разница.

У HC-03/05 на один светодиод больше чем у HC-04/06 и вывод KEY расположены по разному. Гы, вот и все. Что данные выводы означают. TX, RX, RESET, 3,3v и GND и так понятны, а вот справа выводы нужны для управления и сигнализации. Вход KEY нужен для управления работы модуля.

Данный модуль при подключении к любому bluetooth устройству по сути прикидывается UART соединением. То есть если к смартфону прицепить данный датчик, то запустив терминалы на компе и смарте, можно переписываться как будто они соединены проводом. А для общение на командном уровне, модуль использует тот же порт что и для связи по радиоканалу.

Поэтому для того чтобы модуль понял как нужно общатся и предназначен данный вход. Если KEY прижать к GND, то модуль перейдет в режим связи по радиоканалу. Если KEY подтянуть к питанию, то модуль бросит все и начнет отвечать на АТ команды. После каждого перехода входа KEY обязательно нужно рестартовать модуль.

Далее идут сигнальные лампочки. У HC-04/05 она всегда моргает и при поиске и при связи. Я не понял в чем секрет, а вот у HC-03/05 есть две лампочки. LED1, если модуль ни скем не связан, то раз в секунду промаргивает как стробоскоп, а при связи с кем-либо моргает с постоянным интервалом.

LED2 самая ценная лампочка, при отсутствии связи на выходе висит GND, но как только модуль с кем-нибудь свяжется, то на этом выходе появится 3,3 вольта. Правда есть одна грабля. Я при проектировании платы заложил чтение этого выхода, дабы распознавать подключения модуля к другому, но после нескольких минут работы он стал постоянно выдавать 0,78 вольт.

В чем прикол не знаю, хотя и в мануале написано что к данному выводу нужно прицепить светодиод с подтягивающим резистором на 470 Ом, я все же рекомендую подключать к МК данный вход через транзистор. Так будет спокойнее. Поехали дальше. Если данный модуль подключить к питанию, а выводы RX, TX к ПК и запустить терминал, то можно пообщаться с модулем.

Главное не забыть KEY подтянуть к плюсу. А теперь веселье, АТ команды. Чем руководствовались программисты при написании прошивок, но явно не благими намерениями.

Прикол вот в чем, в модулях HC-03/05 команды как у SIMCOM должны заканчиваться /r/n, а в модулях HC-04/06 команды должны вводится очень быстро и не более одной раз в секунду. То есть окончания ввода команды определяет временной интервал.

Скорость передачи данных у HC-03/05 по умолчанию 38400 бод, а у HC-04/06 9600 бод. И еще одна грабля замеченная мной. Если изменить командой скорость передачи данных, а потом снять питания и подождать какое-то время, то скорость вернется в состояние по умолчанию. Поэтому дабы не рисковать я пароль не менял.

Да к стати пароль у модулей 1234. Теперь пробежимся по основным АТ командам. За большей информацией милости просим в документацию.)
Для модулей HC-03/05 AT – просто вернет OK AT+RESET – Рестарт модуля AT+ORGL – Хард ресет AT+NAME=Имя модуля – Присвоит имя модулю.

Напр. My_Module AT+NAME? – Узнать имя модуля AT+ROLE – Режим работы 0-Слейв, 1-Мастер AT+PSWD – Установить пароль модулю AT+CMODE=параметр – Подключится к устройству если модуль в режиме мастер. 0 – Подключиться к устройству с фиксированным адресом, 1 – подключиться к любому устройству.

AT+BIND=адрес – Задание адреса устройства к которому нужно подключится. Пример.

Адрес 01:23:45:67:89:ab будет AT+BIND=0123,45,6789ab AT+RMAAD – Удалить все адреса из списка подключенных Для модулей HC-04/06 AT – просто вернет OK AT+NAMEимя – Установка имя устройства AT+PINкод – Установка пароля устройчтва Следующая грабля.

У меня два модуля HC-06, а они не могут быть мастерами, следовательно необходимо перепрошить. Для этого понадобится программатор. Вот его схема. Я сделал такой. ))) А для пошивки собрал по быренькому ПК с WinXP на борту, дабы не было проблем с LPT Портом. А то у меня плохие впечатления от Win7 x64. В итоге вышло так. Далее программа для прошивки и сама прошивка.

Для прошивки нужна программа BlueSuite. Скачать ее можно прямо тут. BlueSuite
После как скачали, распаковываем и устанавливаем. Установщик установит кучу утилит. Нам нужна BlueFlash. Если ее сразу запустить, то вывалится ошибка. Это происходит из-за того что к порту не подключен модуль и программа его не видит.

После установки программы подключаем модуль к LPT порту. Затем качаем прошивку для HC-05 Вот теперь запускаем программу. Должно появится вот такое окно. К сожалению я при перепрошивке не делал скриншоты, а модули уже впаяны, поэтому объясню на скаченной картинке из сети. На картинке выше видно окно программы, если такое окно появилось, значит программа увидела модуль.

Далее укажите где лежит прошивка HC-05 и нажмите на кнопку Stop Processor. После нажатия активируются остальные кнопки. Настоятельно рекомендую слить текущую прошивку на всякий случай нажав на кнопку Dump. Далее сохранив текущую прошивку можно перепрошивать модуль. Вот тут я наступил на еще одну граблю. Почему-то залить прошивку поверх текущей не удается.

Программа сначала начинает заливать, а потом просто виснет и вываливается. Проблема решилась банально и просто. Сначала стираем все что есть в модуле нажав на кнопку Flash Erase, а затем заливаем прошивку нажав на кнопку Download. После всех манипуляций HC-06 превращается в HC-05.

Теперь можно настраивать мастер для связи со слевом.
Как это сделать. Подключаемся к модулю в режиме АТ команд и кидаем команды.

AT+ORGL Делаем хард ресет AT+RMAAD Стираем все устройства из памяти AT+ROLE=1 Переводим модуль в режим Мастер AT+RESET Рестартуем модуль AT+PSWD=1234 Задаем пароль слейва AT+BIND=1234,56,abcdef Задаем адрес устройства* AT+CMODE=0 Разрешаем соединятся только с нашим слейвом * Как узнать адрес слейва. Есть два способа. Первый подключить слейв к ноутбуку, ПК, смартфону и т.д., а затем посмотреть в свойства устройства. Для моего слейва адрес будет вот такой. Способ второй, подключаемся к модулю в режиме АТ команд и кидаем команду.
AT+BIND? Модуль вернет адрес устройства.
После того как модуль перевели в режим мастера и задали необходимые параметры, можно немного с ними поиграться. Включаем питание на обоих модулях и встаем на каждый модуль своим терминалом. Далее ожидаем подключения и переписываемся сообщениями. Если данные пошли, то приступаем к сборке модулей термометра, а если нет, то переходим в начало статьи и ищем ошибки.
И так. Радиотермометр состоит из двух модулей. Тот что висит за окном я назвал передатчик, так как он передает температуру. Bluetooth модуль на нем стоит Слейв. Модуль который выводит температуру на индикатор я назвал приемник и соответственно на нем Bluetooth модуль Мастер. Начнем с передатчика. Схема. По крупнее.

Как видно из схемы я использовал микроконтроллер ATmega8A. Кварц на 7,3728МГц взят не спроста, он отлично подходит для UART и дает 0% ошибок. На вход PC0 подключен датчик температуры DS1820. Температуру я беру только целую часть, как правило никого не интересует 0,5 градусов сейчас или 0,0. Мало кто заметит на улице пол градуса. На выход PC2 подключен транзистор, который подает питание на модуль. На вход PB0 подключена схема контроля освещения на базе отечественного оптотранзистора ФТ-1К. Данная схема необходима для экономии питания. Я думаю мало кому интересна температура в 2 часа ночи, поэтому с наступлением темноты микроконтроллер выключает модуль Bluetooth и прекращает передачу данных. Так же на схеме добавлен джампер для выбора работы Bluetooth модуля и выведены ножки UART. Так что можно пообщаться с модулем если что не так.

Вот как выглядит 3D модель передатчика. А это уже в корпусе. Теперь давайте поговорим о приемнике. По крупнее.

Рассматривая эту схему можно так же убедится что для управления был взят так же микроконтроллер ATmega8A. Линия PC0 управляет питанием Bluetooth модуля. Также выведены джампер для выбора работы Bluetooth модуля и пины для UART. На вход PD3 подключена схема контроля освещения.

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

Управление индикатором, за неимением такого большого количества ног на МК, был взят на вооружение сдвиговый регистр с защелкой 74HC595. Из-за малого места и наличие сдвоенных индикаторов подключить по регистру к разряду не удалось, поэтому было решено использовать динамическую индикацию.

Приемник изначально планировалось питать от батарейки крона, поэтому в схеме питания используется микросхема LM2576 +5.0 для питания индикатора и LM1117 3.3 для Bluetooth модуля. Но в дальнейшем произошла аказия. Индикатор выжрал крону за пол дня и поэтому план питания перешел на розеточное.

Так что можно подключать питание от трансформатора сразу 5 вольт на LM1117 3.3, а схему с LM2776 +5.0 выкинуть. Для модулей были выбраны корпуса G519G(BC), так как имеют отсек для установки батареек типа АА или Крона.

Теперь про алгоритм. Программы для модулей написаны таким образом: Передатчик раз в секунду измеряет температуру и если она отличается от предыдущей, то отсылает ее приемнику. Приемник в свою очередь читает данные из порта и выводит на индикатор. Самое замороченное это как передается температура. Передача осуществляется одним байтом. Самый старший разряд передает знак, если ноль то плюс, а если единица, то минус. Оставшиеся семь разрядов передают температуру. После сна, модуль включает Bluetooth и начинает получать данные. По умолчанию при просыпании модуль записывает в температуру 0xFF. Это говорит об ошибке связи. Данная ошибка будет выводить на индикатор сообщение Err. Данное сообщение будет выводится до тех пор пока передатчик не скинет температуру. Так же приемник после пробуждения насильно кидает в порт команду 0xAA которая заставляет передатчик, независимо от предыдущего измерения, передать температуру. Вот вроде и все.
Программа для перепрошивки Bluetooth модуля.
Прошивка HC-05 для Bluetooth модуля.
Документация на HC-05.
Проекты модулей приемника и передатчика.
Исходники. 

Добрый день! Получается, что HC-05 нормально работает от двух батареек по 1,5В? Есть у вас опыт наблюдения, при каком минимальном напряжении разряженных батареек (в сумме) передатчик был работоспособен и передавал корректную температуру?

Работает но не долго. Даже если на ночь отключать все равно максимум неделя. Сейчас переделываю на ИК передачу. Собственно через стекло главное температуру передать, а по комнате можно и проводом. Блутуз хорошо работает на АКБ, а АКБ при минусе быстро дохнет.

Я бы попробовал для снижения потребления передатчика отправлять температуру раз в минуту, а не в секунду, вряд ли она меняется так резко. А вот измерять можно раз в несколько секунд для усреднения и исключения влияния всяких дуновений…))

Пытаюсь перепрошить HC-06. у меня проблема программатор проверил раз 10, блю модуль подпоял правильино, вин хр 32, LPT — EPP. Скачал bluesuite 2.4. blue flash пишет NO SPITRANSPORTS FOUND. Не могу понять в чем дело. Схема сдесь silabs.org.ua/hcxx_fw.htm

разица в резистораделителя, это может влиять?

Может, так как LPT выдает 5 вольт на единицу, а модулю нужно 3,3. Делитель делает 3,2 вольта.

у меня на входе модуля 3.34в. Это много или нормально?

3.34в если на входе делителя 5в. замерил ЛПТ выход – 3.27, с делителя на модуль

уровень 2.18в. Это нормально?

Низковато. Нужно от 3,2 до 3,3.

Алексей здравствуйте! А вы случайно не делали видео с написанием и объяснением программного кода для этого проекта? Если да, то поделитесь ссылкой на него)

А если нет, то вы не собирались делать такое?

Нет, видео я не снимал. После разных тестов я перешел на wifi модули и на радиомодули на частоте 433МГц. Вот по нтм планируется и видео и статью.

Ясно, жаль. Буду ждать об wifi и радио- модулях. . Просто я так и не нашел откуда в коде приемника берется usart_old_in(); и usart_old_out(); ((

Извините, Анонимом написал

Алексей, расскажите пожалуйста, если вы помните, в в файле приемника main.c есть вызов функций usart_old_in(); и usart_old_out(); но в подключенных файлах библиотеки они не описаны нигде((

Где же мне взять описание этих функций?

Алексей, ну пожааалуйста подскажите )))

Пошукаю.)))

ОО)) спасибо большое, буду ждать с нетерпением))

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

Эхх) жаль( а библиотеки AXLIB версии до 1.0 (0.7 0.8 0.9) не завалялось в архивах?)

Не. Там было много ошибок и я после исправления не сохранил начальную версию.

Источник: http://www.avrki.ru/articles/content/bluetooth_termometr/

Термометр с выводом данных на ЖХ-дисплей на основе Arduino Uno

В этом уроке мы покажем вам как сделать ЖК-термометр на основе Arduino UNO и аналогового температурного датчика LM35/36.

Этот проект очень хорошо подойдет для начинающих, он не требует каких-либо специальных технических навыков или навыков программирования, и вам понадобится достаточно немного времени для реализации проекта.

Вот что нам нужно для создания термометра:

Arduino UNO

1x макетная плата

ЖК-дисплей 16×2

LM35 или LM36 аналоговый температурный датчик

10К  потенциометр для регулировки яркости дисплея (можете использовать и 50К)

19 перемычек для подключения всего

Вы можете заказать это всё на официальной сайте Arduino или в любом интернет-магазине, который продает всё для радиолюбителей. Вы можете купить всё отдельно в следующих магазинах: Adafruit, SparkFun, Aliexpress, Banggood и т.д.

Шаг 2: Собираем схему

Следуя приведенной выше схеме Fritzing, подключите ЖК-дисплей к макету, а затем подключите его к плате Arduino с помощью перемычек. После этого вставьте потенциометр и датчик в макет, соедините левый и правый выводы с землей и + 5 В, а средний – с ЖК-дисплеем.

Затем подключите датчик к земле и к + 5 В и к Arduino, но будьте очень осторожны, потому что, если вы подключите его неправильно, датчик нагреется до 280+ C (540 F) и может повредиться. После того, как вы подключили все, переходите к следующему шагу.

Шаг 3: Программирование Arduino

Вы должны использовать один из двух скетчей ниже. Загрузите его в Arduino, используя интегрированную среду разработки IDE, которую вы можете скачать с официальной страницы Arduino.

Если вы ничего не видите на ЖК-дисплее или видите прямоугольники, поверните потенциометр против или по часовой стрелке пока не увидите, что всё очищено. Теперь у вас есть термометр и вы сможете измерять температуру воздуха вокруг вас, внутри вашего дома или снаружи.

Код 1

1234567891011121314151617181920212223242526272829 // initialize the library with the numbers of the interface pinsLiquidCrystal lcd(12, 11, 5, 4, 3, 2);// initialize our variablesint sensorPin = 0;int tempC, tempF;void setup() {// set up the LCD's number of columns and rows:lcd.begin(16, 2);}void loop() {tempC = get_temperature(sensorPin);tempF = celsius_to_fahrenheit(tempC);lcd.setCursor(0,0);lcd.print(tempF); lcd.print(” “); lcd.print((char)223); lcd.print(“F”);delay(200);}int get_temperature(int pin) {// We need to tell the function which pin the sensor is hooked up to. We're using// the variable pin for that above// Read the value on that pinint temperature = analogRead(pin);

Источник: https://ArduinoPlus.ru/termometr-displei-arduino-uno/

Температурный датчик с выводом значения на смартфон

Статья расскажет о проекте термометра, основным отличием от похожих проектов будет то, что показания датчика температуры будут передаваться на смартфон по Bluetooth и отображаться на его экране. Такой датчик температуры можно разместить в недоступном месте, например за окошком, в холодильнике.

И вы всегда сможете проверить температуру без визуального контакта с этим датчиком. Вы запускаете мобильное приложение, подключаетесь к датчику и на экране Смартфона или планшета контролируете температуру. Сам датчик будет реализован с помощью Arduino.

Для реализации передачи значения температуры на смартфон мы используем библиотеку RemoteXY.

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

Термистор подойдет на любое сопротивление от 1 до 100 кОм, но в этом случае сопротивление резистора должно быть аналогичным. Ниже приведена схема подключения всех элементов конструкции.

Мы же все это собрали на макетной плате.

Термистор включен в цепь делителя напряжения, во втором плече которого находится постоянное сопротивление. Таким образом, при изменении температуры будет изменяться сопротивление термистора, а значит и одного плеча делителя напряжения. Напряжение делителя будет изменяться в след за температурой. Среднюю точку делителя напряжения мы подключили к аналоговому входу Arduino с номером A5.

Разработку программы мы начнем с калибровки нашего датчика. Калибровку мы выполним по двум точкам, и для этого нам понадобится эталонная температура. У меня в комнате стоит термометр, который показывает 25 градусов Цельсия, это будет первая эталонная температура.

Так же я знаю что температура моего тела составляет 36.6 градусов Цельсия, и это будет вторая эталонная температура. Так же примем, что сопротивление нашего термистора в определенных пределах изменяется по линейному закону в зависимости от температуры.

По этому, в дальнейшем, для вычисления текущей температуры будем использовать линейную интерполяцию.

Для выполнения калибровки нам необходимо определить, какое значение выдает АЦП Arduino при температурах датчика, которые мы выбрали эталонными. Используем Serial и монитор порта, для того что бы передавать значение АЦП на компьютер, что бы мы могли посмотреть, какое же оно при наших эталонных температурах. Для этого нам потребуется загрузить в Arduino следующий простой скетч.

void setup()   {    Serial.begin(9600);    }  void loop()   {     int sensorValue = analogRead(A5);   Serial.println(sensorValue);   delay(1);  }

Данный скетч в каждом цикле программы измеряет напряжение аналогового вывода A5, оцифровывает его и отправляет в Serial. Вы можете подключиться монитором порта (Сервис/Монитор порта) и посмотреть, какие значения передаются. Теперь нам необходимо записать значения АЦП при выбранных эталонных температурах датчика.

Первую эталонную температуру вы получаете сразу, если ваш термистор достаточно долго находился в комнате. Для получения второй эталонной температуры приложите термистор к своему телу и подержите его несколько минут. Перепишите значения АЦП, которые передаются в монитор порта при этих температурах.

У нас получились следующие значения:

T=25.0°C АЦП=580

T=36.6°C АЦП=514

Заходим в онлайн редактор RemoteXY и создаем интерфейс управления. Он состоит из текстового поля, через которое будет передаваться измеряемая температура, и текстовой метки.

Длина текстового поля, задаваемая в настройках, определяется максимальной длиной передаваемой строки. В нашем случае это могут быть значения “-40.0” или “100.0”. То есть длина строки не может превышать 5 символов.

Можно оставить предлагаемую по умолчанию системой длину в 10 символов.

Выбираем в настройках проекта целевую платформу Arduino (SoftwareSerial), library version и формируем исходный код нашего интерфейса. Не забудьте загрузить библиотеку RemoteXY и подключить ее к Arduino IDE (Скетч/Импортировать библиотеку/Add library…).

Для передачи значения температуры на экран смартфона мы должны получить текущее значение АЦП, получить значение текущей температуры, используя линейную интерполяцию по двум известным точкам, преобразовать полученное значение в строку и записать ее в поле text_1 структуры RemoteXY. Для преобразования числа типа double в строку используем функцию:

dtostrf (floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf)

Задачу линейной интерполяции мы решим используя простую формулу:

Собрав все воедино мы получаем следующий исходный код – скетч для Arduino:

/////////////////////////////////////////////  //        RemoteXY include library         //  /////////////////////////////////////////////  /* определение режима соединения и подключение библиотеки RemoteXY */  #define REMOTEXY_MODE__SOFTWARESERIAL  #include   #include   /* настройки соединения */  #define REMOTEXY_SERIAL_RX 2  #define REMOTEXY_SERIAL_TX 3  #define REMOTEXY_SERIAL_SPEED 9600  /* конфигурация интерфейса  */   unsigned char RemoteXY_CONF[] =    { 0,11,27,0,1,5,67,0,24,23   ,54,16,2,11,129,0,23,12,39,9   ,0,84,101,109,112,44,32,194,176,67   ,0 };      /* структура определяет все переменные вашего интерфейса управления */ struct {      /* output variable */   char text_1[11];  /* =строка оканчивающаяся нулем UNICODE */     /* other variable */   unsigned char connect_flag;  /* =1 if wire connected, else =0 */ } RemoteXY;  /////////////////////////////////////////////  //           END RemoteXY include          //  /////////////////////////////////////////////  /* первое замеренное значение – первая точка */ #define SENS_1_VAL 514 #define SENS_1_TMP 36.6 /* второе замеренное значение – вторая точка */ #define SENS_2_VAL 580 #define SENS_2_TMP 25.0 void setup()   {    RemoteXY_Init ();         Serial.begin(9600);    }  void loop()   {     RemoteXY_Handler ();    /* получаем значение АЦП */   int sensorValue = analogRead(A5);       /*      вычисляем текущую температуру используя      линейную интерполяцию по двум известным точкам    */   double temp = SENS_1_TMP + (SENS_2_TMP – SENS_1_TMP) /             (SENS_2_VAL – SENS_1_VAL) * (sensorValue – SENS_1_VAL);       /*      преобразуем значение температуры в строку      и помещаем ее сразу в поле text_1 структуры RemoteXY    */   dtostrf(temp, 0, 1, RemoteXY.text_1);      /*      отправляем значение  АЦП в Serial для того      что бы мы могли проверить значения    */   Serial.println(sensorValue);   delay(1);        }

В данном коде вы должны изменить определяемые значения SENS_1_VAL, SENS_1_TMP, SENS_2_VAL, SENS_2_TMP, подставив вместо них ваши, которые вы получили при измерениях значений для калибровки.

Загрузите скетч в вашу Arduino. Загрузите в ваш смартфон или планшет приложение RemoteXY. И можете контролировать температуру находясь на удалении от изготовленного вами датчика, используя Bluetooth.

Источник: http://remotexy.com/ru/examples/temperature/

Цифровой термометр DS18B20 и ARDUINO UNO

Казалось бы, что может быть интересного и нового в измерении температуры при помощи Ардуино? Написаны сотни статей, объемом десятки мегабайт, может чуть меньше, а может и чуть больше скетчей… А вот еще и моя статья.

Зачем? Честно говоря, я тоже думал, что вопрос этот «разжеван вдоль и поперек», пока сам не столкнулся с измерением температуры. А тут полезло. Что-то не работает, что-то работает не так, возникает масса вопросов, на которые ответы приходится «выцарапывать» перерывая половину интернета, причем не только русскоязычного.

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

Зачем, собственно измерять температуру чем-то новым, когда термометров продается – на любой вкус и кошелек? А дело в том, что температуру, зачастую, приходится не только измерять, но потом, на основе полученных данных что-то делать, либо просто регистрировать с целью отслеживания изменений.

Соединив, при помощи Ардуино, термодатчик с релейным блоком получим простейший терморегулятор, а если данный терморегулятор сможет отслеживать температуру по нескольким точкам (зонам) и действовать по определенному алгоритму получим довольно серьезный прибор, промышленный аналог которого стоит сопоставимо со стоимостью неплохого ноутбука. Однако, целью данной статьи не является создание заумно-сложных устройств. Цель в другом – предложить новичку простое, проверенное на практике, решение для измерения температуры. Также, как и предыдущие статьи эта будет состоять из частей. В каждой из которых будет рассмотрен свой вопрос. Части будут идти по возрастанию сложности.

Часть первая. Простейшая, но тоже полезная

Итак, от слов к делу! Для реализации данного проекта на первом этапе нам понадобится цифровой термодатчик DS18B20, ARDUINO UNO, резистор на 4,7 кОм (мощность особого значения не имеет, от 0,125 до 2 Вт целиком подходит, но имеет значение точность, чем точнее – тем лучше), кусочек 3-жильного провода (и отдельные проводки на этапе эксперимента тоже подойдут), а еще – несколько штырьков для платы. Хотя и без них тоже можно, если аккуратно, конечно. Выбор данного датчика не случаен. Дело в том, что он может отслеживать температуру в диапазоне от -55оС до +125оС с точностью в основной части диапазона 0,5оС, что вполне хватает для управления, как бытовым отоплением, так и разнообразными морозильными и холодильными установками, а также банями, саунами, теплицами, инкубаторами, рассадниками и прочим. Напоминаю, что ARDUINO UNO можно свободно приобрести здесь: arduino-kit.com.ua/uno-r3-new.html или здесь: arduino-kit.com.ua/arduino-leonardo-original-italiya-new-rev3.html , термодатчик DS18B20 – arduino-kit.com.ua/18b20-sensor-datchik-temperatury-dlya-arduino.html , хотя лично у меня – такой:arduino-kit.com.ua/cifrovoy-datchik-temperatury-odnozhilnyy-ds18b20.html достоинство моего – малые размеры, сопоставимые с размерами кабеля. Недостатки – отсутствие платы, что в некоторых условиях отрицательно сказывается на удобстве монтажа и жизнеспособности датчика. Также – у датчика arduino-kit.com.ua/18b20-sensor-datchik-temperatury-dlya-arduino.html встроен резистор и больше никаких резисторов паять не нужно, зато исчезает возможность подключить несколько датчиков «цепочкой». Подключение датчика к Ардуино видно на Рис. 1 и указано в Таблице 1. На термодатчике определить контакты просто. Нужно взять его так, чтобы смотреть на срез с цифрами, а ножки были внизу. Крайняя левая ножка будет GND, средняя DQ, а крайняя правая VDD. 

Таблица 1.

Пин Ардуино Уно Пин DS18B20 Примечание
GND GND «-»
+5V VDD +5V, также подпаивается одна ножка резистора 4,7 кОм.
10 DQ Цифровой ввод, также подпаивается вторая ножка резистора 4,7 кОм.

Рисунок 1. Подключение одного термодатчика.

На рисунке видно, что было использовано два резистора. Это связано с тем, что найденный мной резистор с маркировкой «4К7», на самом деле имел довольно высокую погрешность, которую и пришлось компенсировать вторым резистором.

Общее сопротивление данной сборки составило 4,695 кОм, что я считаю вполне приемлемым. Также на рисунке можно видеть, что датчик не подпаян непосредственно к проводам (обрезок шлейфа), а вставлен в разъем. Сделано это было из соображений развития эксперимента.

Паять данные датчики настоятельно рекомендуется. Сам скетч также получился довольно компактным:

Файл DS18B20.ino

Всего 14 строчек кода с комментариями. Любому новичку будет по силам разобраться. В результате работы программа выдаст нечто подобное:

 
Рисунок 2. Результат работы с одним датчиком.

Часть вторая. Немного усложненная

Усложним мы эту часть тем, что добавим еще один датчик. Предположим, что нам нужно измерять температуру на улице и в помещении. Для этого всего лишь допаиваем один датчик «в цепочку». Очень напоминает параллельное подключение. Знатоки электрики поймут, о чем я. Но отличие есть: в данном случае выводы от центрального провода должны быть как можно короче. 

 
Рисунок 3. Плата с двумя датчиками.

Скетч вырос всего на 3 строчки. Теперь в нем 17 строк:

Файл DS18B20_2.ino

Результаты работы этого скетча видно на Рисунке 4. 

 
Рисунок 4. Работа с двумя датчиками.

Часть третья. Заключительная

А теперь подключим к Ардуино светодиод, который будет загораться при достижении определенной температуры. Такой себе «пороговый сигнализатор». Для этого нужен обычный светодиод и токоограничивающий резистор.

Мне под руку попался на 100 Ом, его я и использовал, подключив к 7-у контакту Ардуино. Длинную ножку светодиода (анод) подпаиваем к резистору, а короткую (катод) подключаем к контакту GND Ардуино.

Должно получиться, примерно, как на рисунке 5. 

Скетч также вырос совсем не на много:

Файл DS18B20_2_plus_diod.ino

Работа данной программы на компьютере отображается точно также, как показано на Рисунке 4. Естественно переменной sensors.getTempCByIndex(1) можно оперировать в очень широких пределах и управление светодиодиком лишь самый простой пример из всех возможных.

И в заключение данной статьи еще один шаг. Сейчас я расскажу, как к одной Ардуинке подключить несколько «гирлянд» данных устройств. Дело в том, что длина «гирлянды» не может быть бесконечной, более того – она очень сильно ограничена.

В идеальных условиях – 300 метров, но создание «идеальных» условий – довольно дорогостоящее удовольствие. В реальных условиях – не рекомендуется превышать 10 метров. Для обычного «комнатного» термометра этого более чем достаточно, но если речь идет о каком-либо более серьезном оборудовании – этого катастрофически мало.

Тем более, что для стабильной работы необходимо, чтобы датчики располагались как можно ближе к проводникам шины – «гирляндой». Отводить, конечно, тоже можно, но точность и помехозащищенность в этом случае будут крайне низкими.

Итак, подключаем мы несколько «гирлянд» именно для того, чтобы собрать информацию с большого числа точек, при этом сохранив достаточную точность и помехозащищенность. Добавляем контакты согласно таблице 2:

Пин Ардуино Уно Пин DS18B20 Примечание
GND GND «-»
+5V VDD +5V, также подпаивается одна ножка резисторов 4,7 кОм.
10 DQ Цифровой ввод, также подпаивается вторая ножка резистора 4,7 кОм.
8 DQ Цифровой ввод, также подпаивается вторая ножка резистора 4,7 кОм.

Как видно из таблицы – ничего сложного нет, точно такая же шина, только на другой цифровой вод. Не стал паять на 9-й контакт только из соображений удобства и скорости пайки.

Скетч:
Файл DS18B20_2_plus_1.ino

Вряд ли скетч нуждается в излишних комментариях.

Результат работы скетча выглядит так:

 
Рисунок 6. Работа одновременно двух линий датчиков.

А плата с подключенными двумя линиями выглядит так: 

 
Рисунок 7. Плата с двумя шинами.

Из рисунка видно, что резистор 4,7кОм для повышения точности также выполнен составным. 

Библиотеки, примененные для написания скетчей рассмотренных в статье находятся здесь: 

OneWire.h
DallasTemperature.h 

Обзор подготовил Павел Сергеев

Источник: http://arduino-kit.com.ua/tsifrovoy-termometr-ds18b20-i-arduino-uno.html

Термометр на ATmega8 и датчике DS18B20

Доброго дня уважаемые друзья!
Приветствую Вас на сайте «Мир микроконтроллеров»

Схема термометра на ATmega8 и DS18B20
Микроконтроллер ATmega8
Цифровой термометр DS18B20
Семисегментный светодиодный индикатор
Алгоритм программы термометра
Программа цифрового термометра на DS18B20

Термометр по своим характеристикам очень прост, и его можно использовать только как термометр для измерения «комнатной» температуры. Использовать в этой конструкции микроконтроллер с памятью 8 килобайт конечно расточительно, можно применить микроконтроллер и попроще.

Но дело в том, что эта конструкция — основа для дальнейшего развития проекта с использованием цифрового датчика температуры DS18B20.

В следующей статье будет опубликована конструкция другого термометра — на двух датчиках DS18B20, что позволит измерять температуру не только в комнате, но и «за бортом». Естественно, будет добавлена возможность измерять и отрицательные температуру.

В дальнейшем в конструкцию будет добавлена функция термостата, часы, возможность работы с различными нагрузками, что позволит уже собрать несложную конструкцию — основу «умного дома». Ну а сегодня первая статья из этой серии.

Схема термометра на ATmega8 и датчике температуры DS18B20

Давайте посмотрим на схему термометра:

Как видите, схема очень проста, используется только необходимый минимум деталей.
В схеме, для индикации показаний, применен семисегментный трехразрядный светодиодный индикатор (описание и подключение семисегментных индикаторов к микроконтроллеру).

Напряжение питания конструкции — 5 вольт.

Если вы примените микроконтроллер с низковольтным питанием (линейка микроконтроллеров ATmega), то можно и понизить питающее напряжение конструкции, но в этом случае, возможно придется уменьшить номинал гасящих сопротивлений в сегментах индикатора. Приблизительно номиналы сопротивлений можно брать: — при питании 5 вольт — 200-300 Ом — при питании 2,7 — 3 вольта — 100-150 Ом

(здесь вы можете ознакомиться с расчетом гасящих сопротивлений для семисегментных индикаторов)

(здесь вы можете ознакомиться с маркировкой микроконтроллеров)
Транзисторы — любые, маломощные, структуры NPN.
Датчик температуры — DS18B20 (ознакомиться с датчиком температуры DS18B20)
Семисегментный индикатор — любой трехразрядный с общим катодом. Если вы захотите применить другие, с общим анодом, тогда придется заменить транзисторы на PNP и внести изменения в программу (заменить массив двоичных кодов для вывода цифр на индикатор). Я применил индикатор красного цвета свечения, и заодно, для следующей схемы, приготовил такой-же, но голубого цвета свечения.

Источник: https://microkontroller.ru/shemyi-konstruktsii-na-mikrokontrollerah/termometr-na-atmega8-i-datchike-ds18b20/

Web-термометр

“Погодная станция своими руками” – вот как можно было бы назвать статью, но я решил пока просто рассказать о том, как соорудить web-термометр, подключить его к домашней LAN  и наблюдать показания через браузер 😉

Для этого нам потребуется Arduino-совместимая плата, поддержка Ethernet и несколько температурных датчиков.
По традиции, я использовал то, что оказалось под руками:

  1. Arduino-совместимая плата: Angelino с ATmega328P. Конечно, начать отлаживаться можно на любой Arduino-совместимой плате, с USB.

    Но в конечном итоге устройство будет жить где-то в кладовке, где ему уже не потребуется USB. Тоже самое относится и к схеме автоматического выбора питания, и к красивым перемигивающимся светодиодам на пинах RX/TX (их тоже никто не увидит).

    Памяти процессора ATmega328P как раз хватит и для управления Ethernet, и для считывания информации с датчиков;

  2. В качестве Ethernet-контроллера – Freeduino EtherCard R1. Если нет необходимости в SD и скорости в 100Мб, вполне подойдет.

    Стоит он дешевле классического Ethernet+SD шилда, а поддержку SD-карт при необходимости можно добавить с помощью microSD shield;

  3. Датчики температуры – цифровые DS18B20. Работать с ними удобно, все датчики имеют уникальный идентификатор.

    Могут висеть на одном проводке, поэтому сколько их там будет – один, два или десять, можно практически не задумываться. 

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

И мало того, что существует масса Arduino-совместимых плат и Ethernet-шилдов от других производителей, но особо упорные все детали могут приобрести по-отдельности и самостоятельно собрать в единое устройство – в основном, благодаря тому, что контроллер Ethernet ENC28J60 выпускается в DIP-корпусе.

Как выглядит процесс прототипизации на базе Arduino? Примерно так:

Сначала набросаем схему.

Пока всё просто – Arduino соединен с Ethernet-шилдом, обмен идет по шине SPI. Выбор устройства (он же – сигнал SS) для EtherCard находится на пине D10.

Для коммуникации с сетью датчиков DS18B20 используется свободный пин D9, который в соответствии с требованиями однопроводной шины подтянут к VCC через резистор 4K7.

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

Настало время набросать первый скетч, в основном для проверки работы нашей схемы. Берем библиотеки EtherCard, OneWire – распаковываем их в sketchook/libraries. Если у нас изначально Angelino, на время экспериментов потребуется USB-TTL переходник (для заливки скетчей и получения отладочной информации через Serial Monitor).

Для начала определимся с сетевыми адресами нашего будущего устройства – нам нужно придумать шестибайтный MAC-адрес, он должен быть уникален в пределах сети до ближайшего роутера и его можно выбрать практически “наугад”.

Если все-таки есть сомнения, попробуйте понаблюдать за адресами с помощью Wireshark – отличный инструмент, чтобы покопаться в сетевых пакетах, бегающих в вашей локалке.Далее, нам потребуется IP-адрес: на случай, если в сети не окажется сервера DHCP, прописываем статический адрес прямо в скетче.

Следите, чтобы он  тоже был уникальным и желательно в одной подсети с целевым компьютером (например, если у компьютера, с которого вы будете подключаться к Arduino, IP = 192.168.0.2 с маской 255.255.255.0, можно выбрать для Arduino 192.168.0.3 или 192.168.0.222).

Если же Arduino получит динамический IP-адрес, потребуется каким-то образом его узнать – по логам DHCP-сервера или, что гораздо проще, через Serial Monitor.Второй момент – это опрос температурного датчика и вывод результатов.

По счастью, Dallas Semiconductors (ныне является подразделением Maxim Integrated Products) снабжает все датчики уникальным ROM-кодом, нам остается только последовательно получить все их адреса на шине, а затем вывести полученные значения в тексте HTML-странички, которую будет генерировать на лету, при каждом обращении к web-серверу Arduino. 

Тестовый скетч выглядит так:

#include 
#include  // настройки Ethernet #define BUF_SIZE 512 byte mac[] = { 0x00, 0x04, 0xA3, 0x21, 0xCA, 0x38 }; // MAC-адрес byte fixed = false; // =false: пробовать получить адрес по DHCP,
                    // в случае неудачи использовать статический;
                    // =true: сразу использовать статический uint8_t ip[] = { 169, 254, 8, 200 };     // Статический IP-адрес
uint8_t subnet[] = { 255, 255, 0, 0 };   // Маска подсети
uint8_t gateway[] = { 192, 168, 1, 20 }; // Адрес шлюза
uint8_t dns[] = { 192, 168, 1, 20 };     // Адрес DNS-сервера (необязателен) byte Ethernet::buffer[BUF_SIZE];
static BufferFiller bfill; // настройки OneWire #define DS18B20PIN  9
OneWire ds(DS18B20PIN); void setup(void)
{
    Serial.begin(57600);
    delay(2000);     // Проверяем, что контроллер Ethernet доступен для работы
    Serial.println(“Initialising the Ethernet controller”);
    if (ether.begin(sizeof Ethernet::buffer, mac, 10) == 0) {
        Serial.println( “Ethernet controller NOT initialised”);
        while (true);
    }     // Пытаемся получить адрес динамически
    Serial.println(“Attempting to get an IP address using DHCP”);
    if (ether.dhcpSetup()) {
        ether.printIp(“Got an IP address using DHCP: “, ether.myip);
    } else {
        // Если DHCP не доступен, используем статический ip-адрес
        ether.staticSetup(ip, gateway, dns);
        ether.printIp(“DHCP FAILED, using fixed address: “, ether.myip);
        fixed = true;
    }
} char okHeader[] PROGMEM =
  “HTTP/1.0 200 OK

  “Content-Type: text/html

  “Pragma: no-cache

; char authorLink[] PROGMEM =
  “Read about me here”
; static void homePage (BufferFiller& buf) {
  
  buf.emit_p(PSTR(“$F

    “Arduino web-thermometr”
    ”

DS18B20 Network:


    “”), okHeader);
  
  byte counter = 0;   byte addr[8];   ds.reset_search();
  delay(250);
  while (ds.search(addr)) {
    buf.emit_p(PSTR(“$D: “),++counter);
    for (byte i=0; i

Источник: http://mk90.blogspot.com/2013/05/web.html

Ссылка на основную публикацию
Adblock
detector
",css:{backgroundColor:"#000",opacity:.6}},container:{block:void 0,tpl:"
"},wrap:void 0,body:void 0,errors:{tpl:"
",autoclose_delay:2e3,ajax_unsuccessful_load:"Error"},openEffect:{type:"fade",speed:400},closeEffect:{type:"fade",speed:400},beforeOpen:n.noop,afterOpen:n.noop,beforeClose:n.noop,afterClose:n.noop,afterLoading:n.noop,afterLoadingOnShow:n.noop,errorLoading:n.noop},o=0,p=n([]),h={isEventOut:function(a,b){var c=!0;return n(a).each(function(){n(b.target).get(0)==n(this).get(0)&&(c=!1),0==n(b.target).closest("HTML",n(this).get(0)).length&&(c=!1)}),c}},q={getParentEl:function(a){var b=n(a);return b.data("arcticmodal")?b:(b=n(a).closest(".arcticmodal-container").data("arcticmodalParentEl"),!!b&&b)},transition:function(a,b,c,d){switch(d=null==d?n.noop:d,c.type){case"fade":"show"==b?a.fadeIn(c.speed,d):a.fadeOut(c.speed,d);break;case"none":"show"==b?a.show():a.hide(),d();}},prepare_body:function(a,b){n(".arcticmodal-close",a.body).unbind("click.arcticmodal").bind("click.arcticmodal",function(){return b.arcticmodal("close"),!1})},init_el:function(d,a){var b=d.data("arcticmodal");if(!b){if(b=a,o++,b.modalID=o,b.overlay.block=n(b.overlay.tpl),b.overlay.block.css(b.overlay.css),b.container.block=n(b.container.tpl),b.body=n(".arcticmodal-container_i2",b.container.block),a.clone?b.body.html(d.clone(!0)):(d.before("
"),b.body.html(d)),q.prepare_body(b,d),b.closeOnOverlayClick&&b.overlay.block.add(b.container.block).click(function(a){h.isEventOut(n(">*",b.body),a)&&d.arcticmodal("close")}),b.container.block.data("arcticmodalParentEl",d),d.data("arcticmodal",b),p=n.merge(p,d),n.proxy(e.show,d)(),"html"==b.type)return d;if(null!=b.ajax.beforeSend){var c=b.ajax.beforeSend;delete b.ajax.beforeSend}if(null!=b.ajax.success){var f=b.ajax.success;delete b.ajax.success}if(null!=b.ajax.error){var g=b.ajax.error;delete b.ajax.error}var j=n.extend(!0,{url:b.url,beforeSend:function(){null==c?b.body.html("
"):c(b,d)},success:function(c){d.trigger("afterLoading"),b.afterLoading(b,d,c),null==f?b.body.html(c):f(b,d,c),q.prepare_body(b,d),d.trigger("afterLoadingOnShow"),b.afterLoadingOnShow(b,d,c)},error:function(){d.trigger("errorLoading"),b.errorLoading(b,d),null==g?(b.body.html(b.errors.tpl),n(".arcticmodal-error",b.body).html(b.errors.ajax_unsuccessful_load),n(".arcticmodal-close",b.body).click(function(){return d.arcticmodal("close"),!1}),b.errors.autoclose_delay&&setTimeout(function(){d.arcticmodal("close")},b.errors.autoclose_delay)):g(b,d)}},b.ajax);b.ajax_request=n.ajax(j),d.data("arcticmodal",b)}},init:function(b){if(b=n.extend(!0,{},a,b),!n.isFunction(this))return this.each(function(){q.init_el(n(this),n.extend(!0,{},b))});if(null==b)return void n.error("jquery.arcticmodal: Uncorrect parameters");if(""==b.type)return void n.error("jquery.arcticmodal: Don't set parameter \"type\"");switch(b.type){case"html":if(""==b.content)return void n.error("jquery.arcticmodal: Don't set parameter \"content\"");var e=b.content;return b.content="",q.init_el(n(e),b);case"ajax":return""==b.url?void n.error("jquery.arcticmodal: Don't set parameter \"url\""):q.init_el(n("
"),b);}}},e={show:function(){var a=q.getParentEl(this);if(!1===a)return void n.error("jquery.arcticmodal: Uncorrect call");var b=a.data("arcticmodal");if(b.overlay.block.hide(),b.container.block.hide(),n("BODY").append(b.overlay.block),n("BODY").append(b.container.block),b.beforeOpen(b,a),a.trigger("beforeOpen"),"hidden"!=b.wrap.css("overflow")){b.wrap.data("arcticmodalOverflow",b.wrap.css("overflow"));var c=b.wrap.outerWidth(!0);b.wrap.css("overflow","hidden");var d=b.wrap.outerWidth(!0);d!=c&&b.wrap.css("marginRight",d-c+"px")}return p.not(a).each(function(){var a=n(this).data("arcticmodal");a.overlay.block.hide()}),q.transition(b.overlay.block,"show",1*")),b.overlay.block.remove(),b.container.block.remove(),a.data("arcticmodal",null),n(".arcticmodal-container").length||(b.wrap.data("arcticmodalOverflow")&&b.wrap.css("overflow",b.wrap.data("arcticmodalOverflow")),b.wrap.css("marginRight",0))}),"ajax"==b.type&&b.ajax_request.abort(),p=p.not(a))})},setDefault:function(b){n.extend(!0,a,b)}};n(function(){a.wrap=n(document.all&&!document.querySelector?"html":"body")}),n(document).bind("keyup.arcticmodal",function(d){var a=p.last();if(a.length){var b=a.data("arcticmodal");b.closeOnEsc&&27===d.keyCode&&a.arcticmodal("close")}}),n.arcticmodal=n.fn.arcticmodal=function(a){return e[a]?e[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?void n.error("jquery.arcticmodal: Method "+a+" does not exist"):q.init.apply(this,arguments)}}(jQuery)}var debugMode="undefined"!=typeof debugFlatPM&&debugFlatPM,duplicateMode="undefined"!=typeof duplicateFlatPM&&duplicateFlatPM,countMode="undefined"!=typeof countFlatPM&&countFlatPM;document["wri"+"te"]=function(a){let b=document.createElement("div");jQuery(document.currentScript).after(b),flatPM_setHTML(b,a),jQuery(b).contents().unwrap()};function flatPM_sticky(c,d,e=0){function f(){if(null==a){let b=getComputedStyle(g,""),c="";for(let a=0;a=b.top-h?b.top-h{const d=c.split("=");return d[0]===a?decodeURIComponent(d[1]):b},""),c=""==b?void 0:b;return c}function flatPM_testCookie(){let a="test_56445";try{return localStorage.setItem(a,a),localStorage.removeItem(a),!0}catch(a){return!1}}function flatPM_grep(a,b,c){return jQuery.grep(a,(a,d)=>c?d==b:0==(d+1)%b)}function flatPM_random(a,b){return Math.floor(Math.random()*(b-a+1))+a}