С детства мечтал о комнатном термометре, гигрометре и барометре (не прошли даром уроки природоведения и биологии). Даже был куплен настенный вариант со стрелочными приборами советского образца типа такого:
Но по ошибке был повешен на створку двери и через некоторое время прийдя в негодность, от постоянных сотрясений, начал показывать одно и тоже значение. Психрометр пугал своим видом. Да и записывать каждый день показания — глупая затея. Механические системы были похоронены на совсем с приходом контроллеров.
Было несколько разработок на Atmel S51, внешнем АЦП и терморезисторе, дальше на Microchip PIC16F86, программирование этих устройств было без отладочных плат, чуда программирования было мало. Были какие-то пытки и мучения: травил платы, делал программаторы, писал в текстовом, компилировал командной строкой, прошивал 3-м средством, постоянно переставляешь микросхему с программатора в устройство. Словом Ад. Быстро надоедает, при этом на работе все в рамках одного IDE, решаешь непростые задачи, никуда не отвлекаешься.
Долго присматривал разные отладочные платы, цена кусалась, как для хобби. По совету знакомого купил я отладочную плату STM32L-Discovery от фирмы ST, подробное описание здесь. Она в виду своей слабой популярности не дорога, распиаренный Arduino выходит дороже (для Киева). Заманчиво звучало еще то, что это ARM на ядре Cortex-M3. Сердцем платы является STM32L152RBT6. Также на плате есть on-board программатор и отладчик ST-Link.
Благодаря постам (спасибо автору) и наличии STM32L-Discovery приступил к реализации.
Немного освоившись в Keil загрузил вместо идущего на борту примера Temperature project — и вуаля термометр уже готов. Микроконтроллер может измерять Vref. У микроконтроллера также есть свой собственный датчик температуры чипа.
Все бы хорошо но он показывает температуру кристалла, решил добавить датчик температуры DS18B20, да и one-wire интерфейс хорошо бы освоить. Оказалась чтобы что либо добавить необходимо первым делом избавится от штатного LCD экрана, он со своими 6 символами занимает практически все свободные порты процессора.
В закромах родины завалялся старенький LCD экран собранный на контроллерах Hitachi (8 строк по 25 символов)
В выше указанной статье упоминался датчик влажности воздуха HIH3610, хороший цифровой датчик, но весьма не бюджетный. Был приобретен на порядок дешевле датчик влажности HCH1000 и барометрический датчик HSF1000. HCH1000 это емкостной датчик влажности. HSF1000 это мостовой резистивный пьезоэлектрический датчик абсолютного давления.
Итак организовались задачи по подключению оборудования:
1. Подключение и программирование LCD экрана;
2. Подключение и получение данных от RTL;
2. Подключение цифрового датчика температуры DS18B20 и чтение из него данных по шине one-wire;
3. Подключение емкостного датчика HCH1000 и получение данных;
4. Подключение пьезоэлектрического датчика HSF1000 и получение данных;
Вот такое устройство вышло:
Подключение и программирование LCD экрана:
Экземпляр попавший мне в руки оказался настолько старым что документации от него не нашлось. На нем были 4 чипа HD44102CH и 2 HD44102, и 4 дискретных микросхемы описание которых я не нашел.
Reference manual на HD44102 был найден, и было 8 ножек 4 микросхем соединенных между собой и выведенных на разъем — так нашлись D0-D7, питание было найдено по дискретным микросхемам. Оставались сигналы RW,E,CS,R/S, В youtub был найден LCD модуль с виду очень похожий на мой HLM9301 LCD, итальянец на форуме http://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
Подключение емкостного датчика HCH1000
Измерять емкость можно по-разному, самый простой метод зарядить и следить за падением напряжения, посчитав время вычислить емкость, либо по сопротивлению переменному току оценивать емкость. Honeywell любезно предоставило datasheet в котором датчик был задающей величиной в генераторе на 555. К последнему методу я и прибег собрав простой генератор:
Вычислить частоту оказалось не трудно 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В.