Pull to refresh

CO2-Лампа (mh-z19)

Reading time7 min
Views23K
co2-lampe-main

Тут уже довольно часто рассказывали про датчик 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 в вебгуи) начинает мигать красным.

Резет выведен на отдельную кнопку, так-же сделал ещё одну кнопку, если её держать больше одной секунды, то тогда сбрасываются настройки.

Код для кнопки
Инициализация кнопки (GPIO0)
// 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 первую версию, я нашел в интернете способ, как можно управлять сдвиговым регистром только одним пином. В протеусе всё работало, но в живую нет. Я думаю у меня проблема была в том, что я не нашел подходящие конденсаторы.

esp12e


Я использовал 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 лет не живу в русско-говорящей стране и поэтому часто не знаю, как называются некоторые вещи по-русски.
Tags:
Hubs:
Total votes 36: ↑35 and ↓1+34
Comments27

Articles