esp-who/components/lcd/test/lcd_thermostat.cpp

371 lines
12 KiB
C++

/* ILI9341_SPI example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
/*
Some info about the ILI9341: It has an C/D line, which is connected to a GPIO here. It expects this
line to be low for a command and high for data. We use a pre-transmit callback to control that line
every transaction has as the user-definable argument the needed state of the D/C line and just
before the transaction is sent, the callback will set this line to the correct state.
Note: If not using ESP WROVER KIT, Users must change the pins by setting macro in file spi_ili.c
To change the fonts style include the header of your desired font from the "component/includes" folder
and simply pass the address of its GFXfont to setFont API
*/
/*C Includes*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*RTOS Includes*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "freertos/semphr.h"
/*SPI Includes*/
#include "driver/spi_master.h"
#include "iot_lcd.h"
#include "Adafruit_GFX.h"
#include "image.h"
#include "lcd_image.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_event_loop.h"
/*Include desired font here*/
#define PROGMEM
#include "FreeSans9pt7b.h"
#include "FreeMono9pt7b.h"
#include "FreeSerif9pt7b.h"
#include "FreeSerifItalic9pt7b.h"
#include "unity.h"
static CEspLcd* tft_obj = NULL;
//-------------TEST CODE-----------------
float target_room_temperature = 23.5;
int color(uint8_t r, uint8_t g, uint8_t b)
{
return ((r & 248) | g >> 5) << 8 | ((g & 28) << 3 | b >> 3);
}
int drawPlaceholder(CEspLcd* tft, int x, int y, int width, int height, int bordercolor, const char* headertext, int header_text_offset, const GFXfont* font)
{
int headersize = 20;
tft->setTextColor(COLOR_GREEN, COLOR_BLACK);
tft->drawRoundRect(x, y, width, height, 3, bordercolor);
if (font) {
tft->setFont(font);
tft->drawString(headertext, x + header_text_offset, y + 1 + 14);
} else {
tft->drawString(headertext, x + header_text_offset, y + 1);
}
tft->drawFastHLine(x, y + headersize, width, bordercolor);
tft->setFont(NULL);
return y + headersize;
}
const GFXfont* title_font = &FreeSerif9pt7b;
const GFXfont* text_font = &FreeSerif9pt7b;
const GFXfont* num_font = &FreeSerif9pt7b;
void update_huminity(CEspLcd* tft, int hum)
{
tft->setFont(num_font);
char dtmp[10];
memset(dtmp, 0, sizeof(dtmp));
sprintf(dtmp, "%d %%", hum);
tft->fillRect(193, 32, 25, 26, COLOR_BLACK);
tft->drawString(dtmp, 195, 50);
}
void update_brightness(CEspLcd* tft, float bright)
{
tft->fillRect(193, 72, 55, 26, COLOR_BLACK);
tft->drawFloat(bright, 1, 195, 90);
}
void drawTargetTemp(CEspLcd* tft, float temp)
{
tft->setTextColor(COLOR_WHITE, COLOR_BLACK);
tft->drawFloatSevSeg(temp, 1, 7, 54, 7);
}
void drawWireFrame(CEspLcd* tft)
{
tft->setTextColor(COLOR_GREEN, COLOR_BLACK);
//Target placeholder
drawPlaceholder(tft, 0, 28, 136, 78, COLOR_RED, "Temperature", 30, title_font);
tft->setFont(NULL);
//Temperatures placeholder
int placeholderbody = drawPlaceholder(tft, 138, 0, 180, 106, COLOR_RED, "Sensor", 60, title_font);
tft->setTextColor(COLOR_WHITE, COLOR_BLACK);
tft->setFont(num_font);
tft->drawBitmap(150, placeholderbody + 5 , (uint16_t*)water_pic_35, 35, 35);
update_huminity(tft, 68);
tft->drawBitmap(150, placeholderbody + 45 , (uint16_t*)brightness_pic_35, 35, 35);
update_brightness(tft, 1536.12);
//Status placeholder
tft->setTextColor(COLOR_GREEN, COLOR_BLACK);
placeholderbody = drawPlaceholder(tft, 0, 140, 319, 97, COLOR_RED, "STATUS", 110, title_font);
tft->setTextColor(COLOR_WHITE, COLOR_BLACK);
tft->setFont(NULL);
tft->drawString("WiFi : ", 6, placeholderbody + 2);
tft->drawString("Signal : ", 6, placeholderbody + 22);
tft->drawString("Status : ", 6, placeholderbody + 42);
}
void setupUI(CEspLcd* tft)
{
tft->setRotation(3);
tft->fillScreen(COLOR_BLACK);
tft->drawBitmap(0, 0, Status_320_240, 320, 240);
vTaskDelay(1000 / portTICK_PERIOD_MS);
while (1) {
tft->fillRect(0, 0, 320, 240, COLOR_BLUE);
vTaskDelay(500 / portTICK_PERIOD_MS);
tft->fillRect(0, 0, 320, 240, COLOR_GREEN);
vTaskDelay(500 / portTICK_PERIOD_MS);
tft->invertDisplay(1);
tft->drawBitmap(0, 0, Status_320_240, 320, 240);
vTaskDelay(500 / portTICK_PERIOD_MS);
tft->fillScreen(COLOR_BLACK);
tft->drawBitmap(0, 0, esp_logo, 137, 26);
drawWireFrame(tft);
drawTargetTemp(tft, target_room_temperature);
vTaskDelay(500 / portTICK_PERIOD_MS);
break;
}
tft->invertDisplay(0);
tft->fillScreen(COLOR_BLACK);
tft->drawBitmap(0, 0, esp_logo, 137, 26);
drawWireFrame(tft);
drawTargetTemp(tft, target_room_temperature);
}
//=======================================
//--------- SENSOR ----------
#include "driver/i2c.h"
#include "iot_i2c_bus.h"
#include "iot_hts221.h"
#include "iot_bh1750.h"
#define I2C_MASTER_SCL_IO GPIO_NUM_27 /*!< gpio number for I2C master clock */
#define I2C_MASTER_SDA_IO GPIO_NUM_26 /*!< gpio number for I2C master data */
#define I2C_MASTER_NUM I2C_NUM_1 /*!< I2C port number for master dev */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
#define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */
static i2c_bus_handle_t i2c_bus = NULL;
static hts221_handle_t hts221 = NULL;
static bh1750_handle_t bh1750 = NULL;
void hts221_test_task()
{
uint8_t hts221_deviceid;
iot_hts221_get_deviceid(hts221, &hts221_deviceid);
printf("hts221 device ID is: %02x\n", hts221_deviceid);
hts221_config_t hts221_config;
iot_hts221_get_config(hts221, &hts221_config);
hts221_config.avg_h = HTS221_AVGH_32;
hts221_config.avg_t = HTS221_AVGT_16;
hts221_config.odr = HTS221_ODR_1HZ;
hts221_config.bdu_status = HTS221_DISABLE;
hts221_config.heater_status = HTS221_DISABLE;
iot_hts221_set_config(hts221, &hts221_config);
iot_hts221_set_activate(hts221);
}
/**
* @brief i2c master initialization
*/
void i2c_sensor_init()
{
// int i2c_master_port = I2C_MASTER_NUM;
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = I2C_MASTER_SDA_IO;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = I2C_MASTER_SCL_IO;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
i2c_bus = iot_i2c_bus_create(I2C_MASTER_NUM, &conf);
hts221 = iot_hts221_create(i2c_bus, HTS221_I2C_ADDRESS);
uint8_t hts221_deviceid;
iot_hts221_get_deviceid(hts221, &hts221_deviceid);
printf("hts221 device ID is: %02x\n", hts221_deviceid);
hts221_config_t hts221_config;
iot_hts221_get_config(hts221, &hts221_config);
printf("avg_h is: %02x\n", hts221_config.avg_h);
printf("avg_t is: %02x\n", hts221_config.avg_t);
printf("odr is: %02x\n", hts221_config.odr);
printf("bdu_status is: %02x\n", hts221_config.bdu_status);
printf("heater_status is: %02x\n", hts221_config.heater_status);
printf("irq_level is: %02x\n", hts221_config.irq_level);
printf("irq_output_type is: %02x\n", hts221_config.irq_output_type);
printf("irq_enable is: %02x\n", hts221_config.irq_enable);
hts221_config.avg_h = HTS221_AVGH_32;
hts221_config.avg_t = HTS221_AVGT_16;
hts221_config.odr = HTS221_ODR_1HZ;
hts221_config.bdu_status = HTS221_DISABLE;
hts221_config.heater_status = HTS221_DISABLE;
iot_hts221_set_config(hts221, &hts221_config);
iot_hts221_set_activate(hts221);
bh1750 = iot_bh1750_create(i2c_bus, 0x23);
hts221_test_task();
}
// -------------------------
#define LCD_DATA_TEMP (1)
#define LCD_DATA_HUM (2)
#define LCD_DATA_BRI (3)
QueueHandle_t lcd_data_queue = NULL;
typedef struct
{
int type;
union
{
float temp;
int hum;
float brightness;
};
} lcd_data_t;
extern "C" void demo_lcd_init()
{
if (lcd_data_queue == NULL) {
lcd_data_queue = xQueueCreate(10, sizeof(lcd_data_t));
}
/*Initialize LCD*/
lcd_conf_t lcd_pins = {
.lcd_model = LCD_MOD_AUTO_DET,
.pin_num_miso = GPIO_NUM_25,
.pin_num_mosi = GPIO_NUM_23,
.pin_num_clk = GPIO_NUM_19,
.pin_num_cs = GPIO_NUM_22,
.pin_num_dc = GPIO_NUM_21,
.pin_num_rst = GPIO_NUM_18,
.pin_num_bckl = GPIO_NUM_5,
.clk_freq = 30000000,
.rst_active_level = 0,
.bckl_active_level = 0,
.spi_host = HSPI_HOST,
.init_spi_bus = true,
};
if (tft_obj == NULL) {
tft_obj = new CEspLcd(&lcd_pins);
}
setupUI(tft_obj);
}
void lcd_update_task(void* arg)
{
lcd_data_t data;
while (1) {
int ret = xQueueReceive(lcd_data_queue, &data, portMAX_DELAY);
if (ret == pdTRUE) {
switch (data.type) {
case LCD_DATA_TEMP:
printf("val recv: %f\n", data.temp);
drawTargetTemp(tft_obj, data.temp);
break;
case LCD_DATA_HUM:
printf("recv hum: %d\n", data.hum);
update_huminity(tft_obj, data.hum);
break;
case LCD_DATA_BRI:
printf("recv bri: %f\n", data.brightness);
update_brightness(tft_obj, data.brightness);
break;
default:
printf("data type error: %d\n", data.type);
}
}
}
}
void demo_sensor_read_task(void* arg)
{
int16_t temperature, temperature_last = 0;
int16_t humidity, humidity_last = 0;
float bh1750_data, bh1750_data_last = 0;
lcd_data_t data;
while (1) {
printf("\n********HTS221 HUMIDITY&TEMPERATURE SENSOR********\n");
iot_hts221_get_humidity(hts221, &humidity);
printf("humidity value is: %2.2f\n", (float)humidity / 10);
iot_hts221_get_temperature(hts221, &temperature);
printf("temperature value is: %2.2f\n", (float)temperature / 10);
if (temperature_last != temperature) {
data.type = LCD_DATA_TEMP;
data.temp = (float) temperature / 10;
printf("send temp: %f\n", data.temp);
xQueueSend(lcd_data_queue, &data, portMAX_DELAY);
temperature_last = temperature;
}
if (humidity_last != humidity) {
data.type = LCD_DATA_HUM;
data.hum = humidity / 10;
printf("send hum: %d\n", data.hum);
xQueueSend(lcd_data_queue, &data, portMAX_DELAY);
humidity_last = humidity;
}
iot_bh1750_power_on(bh1750);
iot_bh1750_set_measure_mode(bh1750, BH1750_ONETIME_4LX_RES);
vTaskDelay(30 / portTICK_RATE_MS);
iot_bh1750_get_data(bh1750, &bh1750_data);
printf("brightness: %f\n", bh1750_data);
if (bh1750_data_last != bh1750_data) {
data.type = LCD_DATA_BRI;
data.brightness = bh1750_data;
printf("send hum: %f\n", data.brightness);
xQueueSend(lcd_data_queue, &data, portMAX_DELAY);
bh1750_data_last = bh1750_data;
}
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
TEST_CASE("LCD thermostat test", "[lcd_demo][iot]")
{
i2c_sensor_init();
demo_lcd_init();
xTaskCreate(lcd_update_task, "lcd_update_task", 2048 * 2, NULL, 10, NULL);
xTaskCreate(demo_sensor_read_task, "demo_sensor_read_task", 2048, NULL, 10, NULL);
}