
Тут уже довольно часто рассказывали про датчик mh-z19 и про esp8266, а так же не забывали упоминать и про протокол mqtt.
Я всё это почитал и решил объединить вычитанное в одном устройстве. Собственно на картинке это оно и есть.
Вступление (можно пропустить)
Я уже довольно давно зарегистрирован на Хабре и ещё больше его читаю, но я не особенно активен, однако должен сказать, что почерпнул тут много нового и полезного. И меня периодически гложет мысль, что надо не только использовать, но и надо что-то отдавать и делится. Особо нового я не могу предложить, но я доделал своё проект и он мне показался достаточно интересным для публикации.
Функции/Прошивка
Весь проект построен на esp8266 и соответственно может хорошо общаться с интернетом. Для передачи данных используется протокол mqtt. Я, честно говоря не очень углублялся в устройство протокола, но вещь оказалась очень удобная, для теста дома я использовал брокер mosca, а сейчас я использую cloudmqtt у них есть бесплатные варианты, для такой мелочи само то.
Теперь можно перейти собственно к функциям.
Когда я включаю лампу, то она смотрит есть ли уже сохранённые настройки, если нет, то включает wifi с именем «CO2.box», по адресу «192.168.4.1» показывает страницу с настройками:
Собственно лампа может работать в двух режимах:
1. Подключается к mqtt брокеру, шлёт данные и показывает через LED содержание со2.
2. Показывает только через LED содержание со2 в помещении.
LED может менять своё цвет от зелёного до красного, по идее это RGB, но я у него не подключил синий цвет, поэтому только LED RG. Если содержание со2 составляет 400 ppm (PPM Min в вебгуи), то лампа светит чистым зелёным цветом и при повышении концентрации цвет переходит в красный, когда достигается максимума (PPM Max в вебгуи) начинает мигать красным.
Резет выведен на отдельную кнопку, так-же сделал ещё одну кнопку, если её держать больше одной секунды, то тогда сбрасываются настройки.
// initialise reset button
void BtnInit() {
	// set GPIO 0
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0);
	// enable pullup resitor
	PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO0_U);
	// disable globar interrupt
	ETS_GPIO_INTR_DISABLE();
	// attach interrupt function
	ETS_GPIO_INTR_ATTACH(input_intr_handler, NULL);
	GPIO_DIS_OUTPUT(BTN_CONFIG_GPIO);
	// empty status
	GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(2));
	// enable interrupt
	gpio_pin_intr_state_set(GPIO_ID_PIN(BTN_CONFIG_GPIO), GPIO_PIN_INTR_ANYEDGE);
	// enable global interrupt
	ETS_GPIO_INTR_ENABLE();
	// timer
	os_timer_disarm(&DebounceTimer);
	os_timer_setfn(&DebounceTimer, &debounce_timer_cb, 0);
}
Проверка, сколько была нажата кнопка и сброс настроек
// button reset pressed
void ICACHE_FLASH_ATTR debounce_timer_cb(void *arg){
	//disable globar interrupt
	ETS_GPIO_INTR_DISABLE();
	gpio_pin_intr_state_set(GPIO_ID_PIN(BTN_CONFIG_GPIO), GPIO_PIN_INTR_ANYEDGE);
	ETS_GPIO_INTR_ENABLE();
	//start if button was pressed any age (hight or low)
	if(timepressed){
		timepressed = 0;
		uint32 count = system_get_time() - timecount;
		#ifdef DEBUG
			os_printf("DIFF: %d us\n", count);
		#endif
		//check time between button on/off, if more 1 sec start delete settings in flash
		if(count >= 1000000){
		    if(wipe_flash(DELALLCONF) == 0){
		    	os_timer_disarm(&wifiErrorLedTimer);
		    	os_timer_disarm(&ppmMaxLed);
		    	os_timer_disarm(&SendDataTimer);
		    	os_timer_disarm(&wifiConnCheck);
		    	os_printf("\n");
		    	startMode();
		    }
		}
	} else {
		timepressed = 1;
		timecount = system_get_time();
		#ifdef DEBUG
			os_printf("SYSTEMTIME: %d\n", timecount);
		#endif
	}
}
Для mqtt поддерживается аутентификация пользователя через login/pass. Можно сделать так-же, чтобы данные слались через https, но для этого надо в прошивку вшивать сертификат, что было против концепции — я хотел, чтобы все настройки можно было делать через вебгуи.
Проблема
Я хотел на esp8266 запустить DNS сервер, чтобы он в ответ отдавал всегда свой адрес и не надо было вводить IP адрес. К сожалению в своей версии esp8266 sdk я столкнулся с багом, что он неправильно создаёт Ethernet пакет и там не сходится checksum и ответ у клиента игнорируется. Ошибку я видел через wireshark, а так-же подобную ошибку описывали на форуме espressif. Поэтому я затею оставил.

Прошивка получилась в целом неплохо, но к примеру я так и не нашел/понял, как правильно закрыть tcp соединение, поэтому когда я из браузера отсылаю данные, то он (браузер) ждёт чего-то и не закрывает соединение.
В целом качество кода, по моему мнению, получилось не очень высокое (точнее ужастное), это объясняется тем, что это мой второй проект на с (первым проектом были часы), а так-же тем, что SDK какая-то не очень понятная и часто документация не очень помогала и приходилось искать примеры.
Например я хотел вынести запись во флешь в отдельный файл, но после этого настройки перестали записываться во флешь. Я так и не нашел почему.
Железная сторона
Тут я попытался отделаться минимальным набором комплектующих, вроде получилось неплохо. Сначала я хотел использовать esp8266 первую версию, я нашел в интернете способ, как можно управлять сдвиговым регистром только одним пином. В протеусе всё работало, но в живую нет. Я думаю у меня проблема была в том, что я не нашел подходящие конденсаторы.

Я использовал ESP8266 12e, так как у неё 4мб памяти и семь пинов, которые можно использовать. В начале и почти до конца проекта я хотел использовать дополнительно четыре семисегментных дисплея, которые были подключены через четыре сдвиговых регистра 74hc595, но позже, когда я стал разводить плату, то мне это всё показалось несколько громоздким и избыточным. В общем я их убрал, но в комитах есть ещё тот код, где был экран. Поэтому если кому надо, то там можно взять нужную часть.
Так же я хотел чтобы всё это могло работать от usb, прямо от компьютерного usb либо через блок питания (как у телефона). Я взял блок питания от старой нокии (n900), он выдаёт 1А, так что этого хватило за глаза, но надо было понизить напряжение для esp8266 до 3,3в.
Для этого я использовал asm1117 и тут меня поджидала первая проблема, он почему-то выдавал только 3в, esp8266 от него работало, но не стабилоно и появлялись очень странные ошибки при работе.
Например он esp8266 не мог писать данные во флеш, просто перезагружался, мне довольно много времени понадобилось, пока я понял откуда появляются ошибки, чуть ли с бубном вокруг не прыгал.
Сам asm1117 выдавал положенные 3.3-3.5в, но на esp8266 было только 2,8-3,1в. В принципе я проблему толком так и не решил, я так подозреваю, что оно (напряжение) падало на проводах. Потом я переделал как на картинке ниже и всё стало стабильно работать.

Так же были нужны 5в только для со2 датчика, его я кстати смог завести на 3,3в. Но появилась проблемы, что он повышал свои значения где-то за час набегало до 2000ppm, но если его просто отключал и снова включал, то значения сразу падали.

К GPIO2 подключён вывод логов, если вдруг будет что-то не работать. Общение с датчиком со2 происходит стандартно — через uart.
Ну дальше вроде как не было ничего особо сложного. Из той схемы, что была на картинке выше я развёл плату. Опыт уже был, я до этого на часах тренировался и там всё было несколько сложнее. В общем получилось вот так:
К сожалению у меня тут ошибка (помечена красным), которую я заметил только в конце. К этому пину подключается земля со2 датчика, но эта земля не подключена к остальной и в таком виде датчик не работал, пришлось приделать в том месте мост.
Лутим, крутим, сверлим, пилим
Из картинки выше видно, что всё делалось лутом. Я использовал метод с лимонной кислотой, я про него вычитал на радиокоте. Там пишут, что самая хорошая реакция получается.
Мой набор инструментов для лута, собственно в зелённой коробочке справа всё и происходит.

После того как я развёл раствор, я помещал тару в раковину с тёплой водой, вода не должна быть горячее 40-45 градусов.

Получилось в принципе неплохо, к сожалению у меня есть фотографии только первой версии, но там были ошибки.
Была некоторая проблема с usb, я решил для уменьшения использовать micro usb, у меня было несколько штук, но я не знал как их крепить. Выглядит он вот так:
Как видно, тут нету ничего, чем его можно закрепить к плате, можно только за два боковых выступа припаять, что я и сделал. Крепление оказалось очень слабым и ещё при тестировании всё оторвалось.
Потом я заказал маленькие платы, где уже был приделан микро юсб. Что-то вроде такого:
Всё это я прикрутил болтами — это было хорошее решение, работает до сих пор.
В конце это выглядело так


Корпус
В домашних поделках это часто большая проблема, всё сделать аккуратно и красиво. Когда я начал проект, то у меня ещё не было 3д принтера, но я с самого начала хотел напечатать корпус. Думал что его можно где-нибудь заказать. При поиске, где можно напечатать корпус, я решил, что лучше купить себе 3д принтер. В принципе каких-то особых требований не было, главное чтобы нормально печатал и не стоил много. Остановился на «Anet A8». На удивление хорошо печатает, правда долго.
Потом я создал 3д модель корпуса, удачным я признал лишь третий вариант.

Это 3д-модели, которые я сделал для корпуса. Внутри корпуса лежит утяжелитель, как противовес сфере сверху, поэтому корпус получился несколько высокий.

Всё вместе это выглядит так:

Фото крышки. Её пришлось в корпус практически забивать. Два небольших отверстия сверху нужны чтобы можно было давить на кнопки. Решение не очень удачное, надо что-то тонкое и длинное и к тому же надо ещё кнопки внутри найти на ощуп. В принципе я нахожу без проблем, но кому-то без тренировки будет тяжело.

Так у меня держится RGB LED в шаре сверху:




Заключение
Даже сначала не знал, что бы такое умное написать. Думал может проблемы какие-то перечислить, их было много.
На самом деле проект получился больше для тренировки. Когда я только начал его делать, где-то в прошлом году летом, то мне это казалось полезным устройством и с некоторой претензией на дизайн и вообще должно было быть красиво. Но теперь когда сделал, как-то и не очень нужная вещь оказалась, хотя и выглядит вроде ничего (жене нравится), стоит теперь в углу (выключенным).
Саму прошивку я закончил где-то в начале декабря и уже из всего написанного много чего забыл, так-что в плане потренироваться тоже какой-то спорный момент получился.
Сейчас я бы не стал так делать, вместо шара я бы приделал что-то маленькое, типа морского маяка.
Весь проект лежит на гитхабе. Там и разведённая плата и код, а так-же 3д модели (если кто-то захочет всё это напечатать). Трубки кстати имеют размер М10х20мм.
P.S: Несколько моментов про меня лично:
1. Это моя первая статья, может я тут и много перечитал, но всё же отнеситесь с пониманием.
2. Прошивка написана не очень хорошо, может кто-то захочет переделать.
3. Я заранее извиняюсь, за обилие английских слов, я уже с 16 лет не живу в русско-говорящей стране и поэтому часто не знаю, как называются некоторые вещи по-русски.
Комментарии (27)
 - HurrTheDurr01.04.2017 00:46- Простая, хорошая идея и приятное исполнение. Думаю, может неплохо зайти на кикстартере, если добавите к лампе поддержку каких-то популярных протоколов для умных домов, чтобы можно было сделать автоматическое открывание окон при превышении уровня СО2.  - de1m01.04.2017 12:09- Лампа может подлючаться к wifi и слать свои данные через протокол MQTT брокеру. MQTT довольно известный протокол и сделан специально для таких вещей(для пересылки небольших данных) 
 
 - ABy01.04.2017 01:45- На регуляторе напряжения правда нужны такие емкие конденсаторы (100mf)? 
 Светодиоды питаются напрямую от пинов esp8266?? - Iv3801.04.2017 07:13- По поводу LM1117, по рекомендуемой даташитом схеме: 10 ?F на входе, 22-100 ?F на выходе (разные производители, разные даташиты), но увеличение входного конденсатора параметры не должно портить. 
  - Iv3801.04.2017 07:21+1- А что касается светодиодов, непонятно почему они без токоограничительных резисторов. Протеусу плевать, а настоящим светодиодам — не очень. Да и esp8266 не хорошо. 
 
 - x897301.04.2017 13:04- Прошу прощения, а можно марку светодиода узнать? Честно говоря, первый раз вижу такой светодиод.  - de1m01.04.2017 13:56- Я честно говоря не помню где их покупал. Я купил сразу 25шт. На пачке написано LED-80RGB_D-CA-E25 diff 6000mcd. 
 У них общий плюс, поэтому были с ШИМом проблемы, так-как esp8266 ШИМ работает только в диапазоне 0-90% и поэтому у меня он полностью не выключался. Пришлось искать другой ШИМ, который выключал диод полностью.
 Так что для данного случая они были не фонтан. - x897301.04.2017 14:12- Общий анод это даже хорошо — к земле тянуть проще, чем к питанию. Но к сожалению беглый поиск по наименованию ничего не дал. 
 Просто мне для одного текущего проекта нужно светить RGB-светодиодом на 360 градусов в стороны и по-минимуму — вверх и вниз. Для таких целей светодиод в виде трубки (если я правильно понял, у вас он именно такой) подошел бы лучше всего. - de1m01.04.2017 23:36+1- Помоему вы что-то проглидели, там LED не сама оранжевая штука, а белый колпачёк на самом конце, он немного с белым корпусом сферы сливается. 
 
 
 
 - dron_k01.04.2017 17:58- Корпус подставки неплох, 
 корпус для датчика как-то ну совсем не вписывается в сферо-округлый дизайн,
 и обязательно ли наличие пластика на фасаде датчика?
 
 Я просто с некоторым недопониманием отношусь когда люди печатают прямоугольные коробки на 3D принтере,
 при наличии возможности печати корпусов практически любой формы под задуманный дизайн.
 - dron_k01.04.2017 18:03- Еще маленькая идея: возможно шов на шаре смотрелся бы интереснее под углом 45 градусов, или другим более пологим, аля Сатурн. 
 - alk0v01.04.2017 23:09- Где-то читал, что датчик в напечатанном корпусе может давать неправильные показания из-за паров от самого пластика. К тому же в датчике есть нагревательный элемент. 
 - alexpp02.04.2017 11:29+1- Автор — молодец. Сделал свою платку для есп-шки. Я для своих поделок так и не освоил ЛУТ, потому использовал вначале готовые модули NodeMCU, на которых уже все распаяно для подключения обвеса и прошивки, а сейчас перешел на WeMos D1 mini — размером чуть больше, чем сам модуль esp8266, но уже полностью готов к употреблению — нужно только припаять пару гребенок. Может кому пригодится тоже, на заметку. 
 Скрытый текст  - alex_vesna03.04.2017 16:49- Никогда у меня не было столько траха с разьемами, как при возне с ESPшками. Просто кошмар и ужас, когда разводку делают не под 2.54 или 1.27 а под SO-16. 
 Из найденных неожиданно решений, ESP-10 это самая тупая и безотказная вещь, — 5 пинов, даже GP0 приходиться пилить с ноги и притягивать проводком для прошивки, но зато более простой и предсказуемой ESP просто нет. Так вот, она идеально входит в RJ-45 тютелька в тютельку. Ну а на его базе уже собрать интерфейс для работы с ней, — дело 5 минут. Не передать словами насколько ускорилась возня с ESPшками, когда я это обнаружил. :-)
  - SOvA1303.04.2017 20:29- Товарищ de1m, для web gui уже давно придумано руско(косно)язычное слово — вебморда.  - de1m03.04.2017 20:29- Слово мне знакомо, но я не был уверен стоит ли его тут применять. - Igor_34_rus05.04.2017 17:32- Конечно не стоит 
 web gui — устоявшийся термин. На этом ресурсе не домохозяйки, нужно использовать нормальную терминологию.
 
 sarcasm on // Следующая статья будет в таком духе- Заказал приблуду, накодил прогу с вебмордой, залил и всё. Стоит и пашет… 
 sarcasm off //
 
 
  - osmanpasha06.04.2017 22:36- Если использовать Arduino core для ESP8266 (Arduino-обвязка над родной SDK), то можно использовать готовую библиотеку для поднятия точки доступа и автоматической переадресации на страницу конфигурации. Как-то так: https://github.com/tzapu/WiFiManager 
 
 А вообще, очень симпатиный конечный продукт вышел!
 
 
           
 
handicraftsman
Где фото включенной лампы?
de1m
Снимал только что при свете лампы, поэтому цвет несколько странный получился.
Могу ещё добавить, что лампа не даёт много света, столько, чтобы только осветить шар
Картинка с включённой лампой
handicraftsman
Хорошо. Теперь добавь в КДПВ, что-бы все видели.