Комнатная метеостанция на STM32L-DISCOVERY

в 17:25, , рубрики: diy или сделай сам, DS18B20, метки:

С детства мечтал о комнатном термометре, гигрометре и барометре (не прошли даром уроки природоведения и биологии). Даже был куплен настенный вариант со стрелочными приборами советского образца типа такого:
Комнатная метеостанция на STM32L DISCOVERY
Но по ошибке был повешен на створку двери и через некоторое время прийдя в негодность, от постоянных сотрясений, начал показывать одно и тоже значение. Психрометр пугал своим видом. Да и записывать каждый день показания — глупая затея. Механические системы были похоронены на совсем с приходом контроллеров.

Долго присматривал различные отладочные платы. По совету знакомого купил я отладочную плату STM32L-Discovery от фирмы ST, подробное описание здесь. Заманчиво звучало то, что это ARM на ядре Cortex-M3. Сердцем платы является STM32L152RBT6. Также на плате есть on-board программатор и отладчик ST-Link и шести сегментный LCD дисплей.
Комнатная метеостанция на STM32L DISCOVERY

Посты и наличие STM32L-Discovery вдохновили на реализацию проекта.

Немного освоившись в Keil загрузил вместо идущего на борту примера, другой пример Temperature project — и вуаля термометр уже готов. Микроконтроллер может измерять Vref. У него также есть свой собственный датчик температуры чипа.

Все бы хорошо но этот датчик показывает температуру кристалла, решил добавить датчик температуры DS18B20, да и one-wire интерфейс хорошо бы освоить. Оказалась чтобы что либо добавить необходимо первым делом избавится от штатного LCD экрана, он со своими 6 символами занимает практически все свободные порты процессора.

В закромах родины завалялся старенький LCD экран собранный на контроллерах Hitachi (8 строк по 25 символов)
Комнатная метеостанция на STM32L DISCOVERY
В выше указанной статье упоминался цифровой датчик влажности воздуха HIH3610, но был приобретен емкостной датчик влажности HCH1000 и барометрический датчик HSF1000.

Итак организовались задачи по подключению оборудования:
1. Подключение и программирование LCD экрана;
2. Подключение и получение данных от RTL;
2. Подключение цифрового датчика температуры DS18B20 и чтение из него данных по шине one-wire;
3. Подключение емкостного датчика HCH1000 и получение данных;
4. Подключение пьезоэлектрического датчика HSF1000 и получение данных;

Вот такое устройство вышло:
Комнатная метеостанция на STM32L DISCOVERY
Комнатная метеостанция на STM32L DISCOVERY

Подключение и программирование LCD экрана

Экземпляр попавший мне в руки оказался настолько старым что документации от него не нашлось. На нем были 4 чипа HD44102CH и 2 HD44102, и 4 дискретных микросхемы описание которых я не нашел.
Reference manual на HD44102 был найден, и было 8 ножек 4 микросхем соединенных между собой и выведенных на разъем — так нашлись D0-D7, питание было найдено по дискретным микросхемам. Оставались сигналы RW,E,CS,R/S, В youtub был найден LCD модуль HLM9301 с виду очень похожий на мой LCD, итальянец на форуме www.lcdstudio.com дал распиновку которая совпадала с собранным мною априором:
1 GND; 2 VCC;
3 contraste ( generalmente terminal medio de potenciometro de 10k colocado entre vcc y gnd) 4 NC (no conectado);
5 NC; 6 CS1;
7 CS2; 8 CS3;
9 NC; 10 E;
11 R/W 12 R/S (DATA/INSTRUCTION)
13 D0; 14 D1;
15 D2; 16 D3
17 D4; 18 D5;
19 D6; 20 D7.
Но при подаче команд матрица не проявляла признаков жизни.
После долгого, не меньшего от предыдущего, поиска по интернетам выяснилось что старым графическим экранам необходимо было отрицательное напряжение для яркости. Был включен преобразователь DC-DC P6AU0505 и между выводом яркости и -5 установлен прецизионный переменный резистор 200кОм.
Команды от HD44102 подошли. Была написана библиотека работы с HLM9301. На форумах ребята утверждали что с Arduino все работало сразу со стандартной библиотекой GLCD.

Видео демонстрирует прочитанные данные из внутренних RTC и термометра.

Подключение и получение данных от RTL

Инициализация RTC происходит так:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_SYSCFG, ENABLE);
PWR_RTCAccessCmd(ENABLE);
RCC_LSEConfig(RCC_LSE_ON); //do not touch LSE to prevent RTC calendar reset
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {}
RCC_RTCCLKCmd(ENABLE);

Проблема: при сбросе сбрасывался и RTC. Фрагмент кода взятый из демонстрационного примера что-то делал с LSE — этим и сбрасывался RTC.
Чтение данных:

RTC_DateTypeDef RTCDateStr;
RTC_TimeTypeDef RTCTimeStr;
RTC_GetTime(RTC_Format_BIN, &RTCTimeStr);
RTC_GetDate(RTC_Format_BIN, &RTCDateStr);
sprintf(strDisp, "%02d/%02d/%02d %02d:%02d:%02d", RTCDateStr.RTC_Year, RTCDateStr.RTC_Month, RTCDateStr.RTC_Date, RTCTimeStr.RTC_Hours, RTCTimeStr.RTC_Minutes, RTCTimeStr.RTC_Seconds);

Тут то получились две новые задачи «или»: в цепь питания микросхемы включить ионистор и при падении напряжения питания переходить в «спящий режим», или прицепить внешний RTC. Думаю попробовать оба метода…

Подключение цифрового датчика температуры DS18B20

Благодаря статьям Stm32 + 1-wire + DMA (продолжение) и Stm32 + 1-wire + DMA добавлена библиотека onewire.c но для процессора STM32L152 инициализация портов выглядит немного по-другому:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);          
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOA, &GPIO_InitStructure);          
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);

Схема подключения взята из datasheet:
Комнатная метеостанция на STM32L DISCOVERY
При помощи статьи «Поиск устройств» была добавлена возможность подключения нескольких устройств на шину one-wire. Разрешение у DS18B20 при считывании всех 12 бит 0,0625 градуса по Цельсию.

Подключение емкостного датчика HCH1000

Измерять емкость можно по-разному, самый простой метод зарядить и следить за падением напряжения, посчитав время вычислить емкость, либо по сопротивлению переменному току оценивать емкость. Honeywell любезно предоставило datasheet в котором датчик был задающей величиной в генераторе на 555. К последнему методу я и прибег собрав простой генератор:
Комнатная метеостанция на STM32L DISCOVERY
Вычислить частоту оказалось не трудно STM32L152 имеет несколько таймеров которые могут работать в режиме захвата параметров PWM сигнала. Подробо здесь.
Отличием оказалось, как и в случае с one-wire конфигурация портов:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;                               
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);

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

Подключение пьезоэлектрического датчика HSF1000

Подключил датчик на Vref, GND и ко входу АЦП. Опыт показал, что точности 12 разрядного АЦП оказалось мало чтоб оценить полезный сигнал. Подключение инструментального усилителя AD8555 по стандартной схеме к датчику дало свои плоды. Усиления в 10 раз вполне хватило чтоб поднять уровень сигнала до 0,7В.
Комнатная метеостанция на STM32L DISCOVERY

Вот главный экран устройства

значения по строкам:
1. дата время из внутреннего RTL;
2. скважность и период сигнала с генератора, также количество найденных устройств one-wire;
3. емкость датчика влажности и влажность;
4. идентификатор one-wire;
5. значение температуры;
6. значение напряжения;
7. значение температуры кристала;
8. значение давления.

Исходники проекта здесь

Автор: tarasii

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js