Привет!
В этой статье я хочу рассказать о своей небольшой поделке во время карантина – метеостанция на основе STM32 (плата bluepill).
Заранее уточню, что устройство собиралось скорее из желания что-нибудь собрать, нежели чем из реальной необходимости собрать метеостанцию. И уже после сборки метеостанции появилось непреодолимое желание расширить ее скудный функционал и значительно переделать.
Принципиальная схема метеостанции:
В метеостанции я использовал два датчика – АМТ1001 и BMP-180 (плата GY-68). Питается все это от однобаночного Lipo аккумулятора через повышающий до 5В DC-DC преобразователь. Информация с датчиков выводится на дисплей 2004. Выводы настроил следующим образом:
Подключение датчика температуры и влажности AMT1001
Выводы датчика:
Красный — VDD (4.75 – 5.25 В)
Черный – GND
Желтый – выход датчика влажности
Белый – термистор
Считывая напряжение на выводах датчика, можно определить температуру и влажность, соотнеся значение напряжения с таблицами из datasheet. Начнем с влажности:
По графику видно, что зависимость между влажностью и напряжением линейная, а это значит, что значения АЦП можно напрямую преобразовать в значение влажности. Обозначим:
ADC_hum – значение с АЦП;
hum – значение влажности (в %);
V_hum – значение напряжения на датчике.
V_hum = 3.3 В (опорное напряжение АЦП) * ADC_hum / 4095 (кол-во разрядов АЦП).
1 % влажности соответствует 0.3/10 = 0.03 В, то
hum = V_hum / 0.03 = ADC_hum * 0.027
С вычислениями определились, теперь перейдем к коду. Датчик влажности подключен к PA4 (ADC1).
float hum;
uint16_t ADC_hum;
HAL_ADC_Start(&hadc1); // запуск АЦП
HAL_ADC_PollForConversion(&hadc1,100); // ожидание вычисления
ADC_hum = HAL_ADC_GetValue(&hadc1); // запись результата в переменную
HAL_ADC_Stop(&hadc1); // остановка АЦП
hum = ADC_hum;
hum *= 0.027;
Теперь рассмотрим термистор — резистор, сопротивление которого меняется от температуры. С помощью АЦП можно измерить напряжение на элементе, но не его сопротивление. Для работы с термистором необходимо добавить резистор на 10 кОм между выводом термистора (белый провод) и землей. В итоге получим вот такой делитель напряжения (термистор внутри подключен к VCC):
Теперь мы можем измерить сопротивление термистора, воспользовавшись первым правилом Кирхгофа – сумма токов в узле равна 0. Вспомнив школьный курс физики получим:
Untc/ Rntc = U1/R1
Выводом РА5 мы измеряем напряжение на резисторе 10к. В случае с термистором, его сопротивление меняется не пропорционально изменению температуры, в документации приведена огромная таблица значения сопротивлений транзистора при температуре от -40 до +125. Всю таблицу переносить в микроконтроллер та еще задача, я взял диапазон от 10 до 30 градусов (21 значение).
Для того, чтобы микроконтроллеру не нужно было каждый раз вычислять значение сопротивления, я сделал программу в Mathcad. Полученные результаты я перевел в массив:
int out_temp[21] ={2200, 2255, 2315, 2377, 2433, 2497, 2558, 2618, 2680, 2741, 2801, 2862, 2923, 2983, 3041, 3102, 3166, 3215, 3283, 3336, 3396};
Если АЦП покажет значение, близкое к первому элементу массива – температура 10 градусов, если ко второму – 11, и так далее, до 30 градусов. Значение десятых долей градуса можно примерно вычислить, но можно этого и не делать. Ниже представлен код, который вычисляет десятые (примерное их значение), хотя учитывая технологический разброс полагаться на десятые доли не стоит.
float temp;
uint16_t ADC_temp;
HAL_ADC_Start(&hadc2); // запуск АЦП 2
HAL_ADC_PollForConversion(&hadc2,100); // ожидание вычисления
ADC_temp = HAL_ADC_GetValue(&hadc2); // запись результата в переменную
HAL_ADC_Stop(&hadc1); // остановка АЦП
for (int i=0; i<21; i++)
{
if (ADC_temp < out_temp[i+1] && ADC_temp > out_temp[i] )
{
int x = ADC_temp - out_temp[i];
int xx = out_temp[i+1] - out_temp[i];
temp = x;
temp = temp/xx+i+10;
break;
}
}
Дальше я подключил датчик температуры и атмосферного давления GY- 68 (BMP180). Как с ним работать описано тут, код я брал оттуда же.
Для вывода информации я использовал дисплей 2004 с I2C адаптером (про него писал тут)
Соединил все это я следующим примитивным образом – напаял все на макетку, воткнул выключатель в разрыв питания. Датчики и дисплей подключаются через обычную гребенку. Датчики сделал выносными, так как была идея вынуть их за окно, но в таком виде дождя они не переживут.
Вот так выглядит датчик:
Корпус печатал на 3д принтере белым ABS (он хорошо шлифуется и на белом цвете меньше видна слоистость).
Все материалы выкладываю сюда
Автор: Никита