2022-12-19 20:16:02 +03:00
|
|
|
|
/*
|
|
|
|
|
Unitemp - Universal temperature reader
|
2023-01-18 19:51:10 +03:00
|
|
|
|
Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n)
|
2022-12-19 20:16:02 +03:00
|
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
#ifndef UNITEMP_SENSORS
|
|
|
|
|
#define UNITEMP_SENSORS
|
|
|
|
|
#include <furi.h>
|
|
|
|
|
#include <input/input.h>
|
|
|
|
|
|
|
|
|
|
//Маски бит для определения типов возвращаемых значений
|
|
|
|
|
#define UT_TEMPERATURE 0b00000001
|
|
|
|
|
#define UT_HUMIDITY 0b00000010
|
|
|
|
|
#define UT_PRESSURE 0b00000100
|
2023-06-08 00:26:10 +03:00
|
|
|
|
#define UT_CO2 0b00001000
|
2022-12-19 20:16:02 +03:00
|
|
|
|
|
|
|
|
|
//Статусы опроса датчика
|
|
|
|
|
typedef enum {
|
|
|
|
|
UT_DATA_TYPE_TEMP = UT_TEMPERATURE,
|
|
|
|
|
UT_DATA_TYPE_TEMP_HUM = UT_TEMPERATURE | UT_HUMIDITY,
|
|
|
|
|
UT_DATA_TYPE_TEMP_PRESS = UT_TEMPERATURE | UT_PRESSURE,
|
|
|
|
|
UT_DATA_TYPE_TEMP_HUM_PRESS = UT_TEMPERATURE | UT_HUMIDITY | UT_PRESSURE,
|
2023-06-08 00:26:10 +03:00
|
|
|
|
UT_DATA_TYPE_TEMP_HUM_CO2 = UT_TEMPERATURE | UT_HUMIDITY | UT_CO2,
|
2022-12-19 20:16:02 +03:00
|
|
|
|
} SensorDataType;
|
|
|
|
|
|
|
|
|
|
//Типы возвращаемых данных
|
|
|
|
|
typedef enum {
|
|
|
|
|
UT_SENSORSTATUS_OK, //Всё хорошо, опрос успешен
|
|
|
|
|
UT_SENSORSTATUS_TIMEOUT, //Датчик не отозвался
|
|
|
|
|
UT_SENSORSTATUS_EARLYPOOL, //Опрос раньше положенной задержки
|
|
|
|
|
UT_SENSORSTATUS_BADCRC, //Неверная контрольная сумма
|
|
|
|
|
UT_SENSORSTATUS_ERROR, //Прочие ошибки
|
|
|
|
|
UT_SENSORSTATUS_POLLING, //В датчике происходит преобразование
|
|
|
|
|
UT_SENSORSTATUS_INACTIVE, //Датчик на редактировании или удалён
|
|
|
|
|
|
|
|
|
|
} UnitempStatus;
|
|
|
|
|
|
|
|
|
|
//Порт ввода/вывода Flipper Zero
|
|
|
|
|
typedef struct GPIO {
|
|
|
|
|
const uint8_t num;
|
|
|
|
|
const char* name;
|
|
|
|
|
const GpioPin* pin;
|
|
|
|
|
} GPIO;
|
|
|
|
|
|
|
|
|
|
typedef struct Sensor Sensor;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Указатель функции выделения памяти и подготовки экземпляра датчика
|
|
|
|
|
*/
|
|
|
|
|
typedef bool(SensorAllocator)(Sensor* sensor, char* args);
|
|
|
|
|
/**
|
|
|
|
|
* @brief Указатель на функцию высвобождении памяти датчика
|
|
|
|
|
*/
|
|
|
|
|
typedef bool(SensorFree)(Sensor* sensor);
|
|
|
|
|
/**
|
|
|
|
|
* @brief Указатель функции инициализации датчика
|
|
|
|
|
*/
|
|
|
|
|
typedef bool(SensorInitializer)(Sensor* sensor);
|
|
|
|
|
/**
|
|
|
|
|
* @brief Указатель функции деинициализации датчика
|
|
|
|
|
*/
|
|
|
|
|
typedef bool(SensorDeinitializer)(Sensor* sensor);
|
|
|
|
|
/**
|
|
|
|
|
* @brief Указатель функции обновления значения датчика
|
|
|
|
|
*/
|
|
|
|
|
typedef UnitempStatus(SensorUpdater)(Sensor* sensor);
|
|
|
|
|
|
|
|
|
|
//Типы подключения датчиков
|
|
|
|
|
typedef struct Interface {
|
|
|
|
|
//Имя интерфейса
|
|
|
|
|
const char* name;
|
|
|
|
|
//Функция выделения памяти интерфейса
|
|
|
|
|
SensorAllocator* allocator;
|
|
|
|
|
//Функция высвыбождения памяти интерфейса
|
|
|
|
|
SensorFree* mem_releaser;
|
|
|
|
|
//Функция обновления значения датчика по интерфейсу
|
|
|
|
|
SensorUpdater* updater;
|
|
|
|
|
} Interface;
|
|
|
|
|
|
|
|
|
|
//Типы датчиков
|
|
|
|
|
typedef struct {
|
|
|
|
|
//Модель датчика
|
|
|
|
|
const char* typename;
|
|
|
|
|
//Полное имя с аналогами
|
|
|
|
|
const char* altname;
|
|
|
|
|
//Тип возвращаемых данных
|
|
|
|
|
SensorDataType datatype;
|
|
|
|
|
//Интерфейс подключения
|
|
|
|
|
const Interface* interface;
|
|
|
|
|
//Интервал опроса датчика
|
|
|
|
|
uint16_t pollingInterval;
|
|
|
|
|
//Функция выделения памяти для датчика
|
|
|
|
|
SensorAllocator* allocator;
|
|
|
|
|
//Функция высвыбождения памяти для датчика
|
|
|
|
|
SensorFree* mem_releaser;
|
|
|
|
|
//Функция инициализации датчика
|
|
|
|
|
SensorInitializer* initializer;
|
|
|
|
|
//Функция деинициализация датчика
|
|
|
|
|
SensorDeinitializer* deinitializer;
|
|
|
|
|
//Функция обновления значения датчка
|
|
|
|
|
SensorUpdater* updater;
|
|
|
|
|
} SensorType;
|
|
|
|
|
|
|
|
|
|
//Датчик
|
|
|
|
|
typedef struct Sensor {
|
|
|
|
|
//Имя датчика
|
|
|
|
|
char* name;
|
|
|
|
|
//Температура
|
|
|
|
|
float temp;
|
2023-06-25 00:38:26 +03:00
|
|
|
|
float heat_index;
|
2022-12-19 20:16:02 +03:00
|
|
|
|
//Относительная влажность
|
|
|
|
|
float hum;
|
|
|
|
|
//Атмосферное давление
|
|
|
|
|
float pressure;
|
2023-06-08 00:26:10 +03:00
|
|
|
|
// Концентрация CO2
|
|
|
|
|
float co2;
|
2022-12-19 20:16:02 +03:00
|
|
|
|
//Тип датчика
|
|
|
|
|
const SensorType* type;
|
|
|
|
|
//Статус последнего опроса датчика
|
|
|
|
|
UnitempStatus status;
|
|
|
|
|
//Время последнего опроса датчика
|
|
|
|
|
uint32_t lastPollingTime;
|
|
|
|
|
//Смещение по температуре (x10)
|
|
|
|
|
int8_t temp_offset;
|
|
|
|
|
//Экземпляр датчика
|
|
|
|
|
void* instance;
|
|
|
|
|
} Sensor;
|
|
|
|
|
|
|
|
|
|
extern const Interface SINGLE_WIRE; //Собственный однопроводной протокол датчиков DHTXX и AM23XX
|
|
|
|
|
extern const Interface ONE_WIRE; //Однопроводной протокол Dallas
|
|
|
|
|
extern const Interface I2C; //I2C_2 (PC0, PC1)
|
2023-01-18 22:25:39 +03:00
|
|
|
|
extern const Interface SPI; //SPI_1 (MOSI - 2, MISO - 3, CS - 4, SCK - 5)
|
2022-12-19 20:16:02 +03:00
|
|
|
|
|
|
|
|
|
/* ============================= Датчик(и) ============================= */
|
|
|
|
|
/**
|
|
|
|
|
* @brief Выделение памяти под датчик
|
|
|
|
|
*
|
|
|
|
|
* @param name Имя датчика
|
|
|
|
|
* @param type Тип датчика
|
|
|
|
|
* @param args Указатель на строку с парамерами датчика
|
|
|
|
|
* @return Указатель на датчик в случае успешного выделения памяти, NULL при ошибке
|
|
|
|
|
*/
|
|
|
|
|
Sensor* unitemp_sensor_alloc(char* name, const SensorType* type, char* args);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Высвыбождение памяти конкретного датчка
|
|
|
|
|
* @param sensor Указатель на датчик
|
|
|
|
|
*/
|
|
|
|
|
void unitemp_sensor_free(Sensor* sensor);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Обновление данных указанного датчика
|
|
|
|
|
* @param sensor Указатель на датчик
|
|
|
|
|
* @return Статус опроса датчика
|
|
|
|
|
*/
|
|
|
|
|
UnitempStatus unitemp_sensor_updateData(Sensor* sensor);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Проверка наличия датчика в памяти
|
|
|
|
|
*
|
|
|
|
|
* @param sensor Указатель на датчик
|
|
|
|
|
* @return Истина если этот датчик уже загружен, ложь если это новый датчик
|
|
|
|
|
*/
|
|
|
|
|
bool unitemp_sensor_isContains(Sensor* sensor);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Получить датчик из списка по индексу
|
|
|
|
|
*
|
|
|
|
|
* @param index Индекс датчика (0 - unitemp_sensors_getCount())
|
|
|
|
|
* @return Указатель на датчик при успехе, NULL при неудаче
|
|
|
|
|
*/
|
|
|
|
|
Sensor* unitemp_sensor_getActive(uint8_t index);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Загрузка датчиков с SD-карты
|
|
|
|
|
* @return Истина если загрузка прошла успешно
|
|
|
|
|
*/
|
|
|
|
|
bool unitemp_sensors_load();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Функция перезагрузки датчиков с SD-карты
|
|
|
|
|
*/
|
|
|
|
|
void unitemp_sensors_reload(void);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Сохранение датчиков на SD-карту
|
|
|
|
|
* @return Истина если сохранение прошло успешно
|
|
|
|
|
*/
|
|
|
|
|
bool unitemp_sensors_save(void);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Удаление датчика
|
|
|
|
|
*
|
|
|
|
|
* @param sensor Указатель на датчик
|
|
|
|
|
*/
|
|
|
|
|
void unitemp_sensor_delete(Sensor* sensor);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Инициализация загруженных датчиков
|
|
|
|
|
* @return Истина если всё прошло успешно
|
|
|
|
|
*/
|
|
|
|
|
bool unitemp_sensors_init(void);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Деинициализация загруженных датчиков
|
|
|
|
|
* @return Истина если всё прошло успешно
|
|
|
|
|
*/
|
|
|
|
|
bool unitemp_sensors_deInit(void);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Высвыбождение памяти всех датчиков
|
|
|
|
|
*/
|
|
|
|
|
void unitemp_sensors_free(void);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Обновить данные всех датчиков
|
|
|
|
|
*/
|
|
|
|
|
void unitemp_sensors_updateValues(void);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Получить количество загруженных датчиков
|
|
|
|
|
* @return Количество датчиков
|
|
|
|
|
*/
|
|
|
|
|
uint8_t unitemp_sensors_getCount(void);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Добавить датчик в общий список
|
|
|
|
|
* @param sensor Указатель на датчик
|
|
|
|
|
*/
|
|
|
|
|
void unitemp_sensors_add(Sensor* sensor);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Получить списк доступных типов датчиков
|
|
|
|
|
* @return Указатель на список датчиков
|
|
|
|
|
*/
|
|
|
|
|
const SensorType** unitemp_sensors_getTypes(void);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Получить количество доступных типов датчиков
|
|
|
|
|
* @return Количество доступных типов датчиков
|
|
|
|
|
*/
|
|
|
|
|
uint8_t unitemp_sensors_getTypesCount(void);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Получить тип сенсора по его индексу
|
|
|
|
|
* @param index Индекс типа датчика (от 0 до SENSOR_TYPES_COUNT)
|
|
|
|
|
* @return const SensorType*
|
|
|
|
|
*/
|
|
|
|
|
const SensorType* unitemp_sensors_getTypeFromInt(uint8_t index);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Преобразовать строчное название датчка в указатель
|
|
|
|
|
*
|
|
|
|
|
* @param str Имя датчика в виде строки
|
|
|
|
|
* @return Указатель на тип датчика при успехе, иначе NULL
|
|
|
|
|
*/
|
|
|
|
|
const SensorType* unitemp_sensors_getTypeFromStr(char* str);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Получить количество активных датчиков
|
|
|
|
|
*
|
|
|
|
|
* @return Количество активных датчиков
|
|
|
|
|
*/
|
|
|
|
|
uint8_t unitemp_sensors_getActiveCount(void);
|
|
|
|
|
|
|
|
|
|
/* ============================= GPIO ============================= */
|
|
|
|
|
/**
|
|
|
|
|
* @brief Конвертация номера порта на корпусе FZ в GPIO
|
|
|
|
|
* @param name Номер порта на корпусе FZ
|
|
|
|
|
* @return Указатель на GPIO при успехе, NULL при ошибке
|
|
|
|
|
*/
|
|
|
|
|
const GPIO* unitemp_gpio_getFromInt(uint8_t name);
|
|
|
|
|
/**
|
|
|
|
|
* @brief Конвертация GPIO в номер на корпусе FZ
|
|
|
|
|
* @param gpio Указатель на порт
|
|
|
|
|
* @return Номер порта на корпусе FZ
|
|
|
|
|
*/
|
|
|
|
|
uint8_t unitemp_gpio_toInt(const GPIO* gpio);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Блокировка GPIO указанным интерфейсом
|
|
|
|
|
* @param gpio Указатель на порт
|
|
|
|
|
* @param interface Указатель на интерфейс, которым порт будет занят
|
|
|
|
|
*/
|
|
|
|
|
void unitemp_gpio_lock(const GPIO* gpio, const Interface* interface);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Разблокировка порта
|
|
|
|
|
* @param gpio Указатель на порт
|
|
|
|
|
*/
|
|
|
|
|
void unitemp_gpio_unlock(const GPIO* gpio);
|
|
|
|
|
/**
|
|
|
|
|
* @brief Получить количество доступных портов для указанного интерфейса
|
|
|
|
|
* @param interface Указатель на интерфейс
|
|
|
|
|
* @return Количество доступных портов
|
|
|
|
|
*/
|
|
|
|
|
uint8_t unitemp_gpio_getAviablePortsCount(const Interface* interface, const GPIO* extraport);
|
|
|
|
|
/**
|
|
|
|
|
* @brief Получить указатель на доступный для интерфейса порт по индексу
|
|
|
|
|
* @param interface Указатель на интерфейс
|
|
|
|
|
* @param index Номер порта (от 0 до unitemp_gpio_getAviablePortsCount())
|
|
|
|
|
* @param extraport Указатель на дополнительный порт, который будет принудительно считаться доступным. Можно указать NULL если не требуется
|
|
|
|
|
* @return Указатель на доступный порт
|
|
|
|
|
*/
|
|
|
|
|
const GPIO*
|
|
|
|
|
unitemp_gpio_getAviablePort(const Interface* interface, uint8_t index, const GPIO* extraport);
|
|
|
|
|
|
|
|
|
|
/* Датчики */
|
|
|
|
|
//DHTxx и их производные
|
|
|
|
|
#include "./interfaces/SingleWireSensor.h"
|
|
|
|
|
//DS18x2x
|
|
|
|
|
#include "./interfaces/OneWireSensor.h"
|
|
|
|
|
#include "./sensors/LM75.h"
|
2023-02-02 14:01:23 +03:00
|
|
|
|
//BMP280, BME280, BME680
|
2022-12-19 20:16:02 +03:00
|
|
|
|
#include "./sensors/BMx280.h"
|
2023-02-02 14:01:23 +03:00
|
|
|
|
#include "./sensors/BME680.h"
|
2022-12-19 20:16:02 +03:00
|
|
|
|
#include "./sensors/AM2320.h"
|
2022-12-21 14:23:26 +03:00
|
|
|
|
#include "./sensors/DHT20.h"
|
2022-12-26 23:15:10 +03:00
|
|
|
|
#include "./sensors/SHT30.h"
|
2023-01-01 23:14:32 +03:00
|
|
|
|
#include "./sensors/BMP180.h"
|
2023-01-07 18:42:38 +03:00
|
|
|
|
#include "./sensors/HTU21x.h"
|
|
|
|
|
#include "./sensors/HDC1080.h"
|
2023-01-18 22:25:39 +03:00
|
|
|
|
#include "./sensors/MAX31855.h"
|
2023-02-02 14:01:23 +03:00
|
|
|
|
#include "./sensors/MAX6675.h"
|
2023-06-08 00:26:10 +03:00
|
|
|
|
#include "./sensors/SCD30.h"
|
2023-06-25 00:31:23 +03:00
|
|
|
|
#include "./sensors/SCD40.h"
|
2022-12-19 20:16:02 +03:00
|
|
|
|
#endif
|