Initial import
This commit is contained in:
commit
6e5975dd4b
9 changed files with 3127 additions and 0 deletions
125
docs/README.md
Normal file
125
docs/README.md
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
# Bitcoin Dashboard for Elecrow 7-inch HMI Display
|
||||||
|
|
||||||
|
A real-time financial dashboard displaying cryptocurrency, precious metals, stocks, and market indices on the Elecrow 7.0-inch ESP32 HMI Display.
|
||||||
|
|
||||||
|
## Hardware
|
||||||
|
|
||||||
|
- **Display**: Elecrow 7.0-inch ESP32 HMI Display (Advance series)
|
||||||
|
- **Resolution**: 800x480 RGB parallel interface
|
||||||
|
- **Touch**: GT911 capacitive touch controller
|
||||||
|
- **MCU**: ESP32-S3 with N4R8 module (4MB Flash, 8MB PSRAM)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Real-time price data from Yahoo Finance API
|
||||||
|
- Auto-refresh every 5 minutes
|
||||||
|
- Touch to manual refresh
|
||||||
|
- WiFi credentials stored in persistent memory
|
||||||
|
- Antialiased fonts (DejaVu family)
|
||||||
|
|
||||||
|
## Displayed Assets
|
||||||
|
|
||||||
|
| Column | Assets |
|
||||||
|
|--------|--------|
|
||||||
|
| Hard Money | Bitcoin (BTC/USD), Gold, Silver |
|
||||||
|
| Stocks | MSTR, STRC |
|
||||||
|
| Indices | NASDAQ, DOW, S&P 500 |
|
||||||
|
|
||||||
|
## Color Scheme
|
||||||
|
|
||||||
|
| Asset | Color | Hex |
|
||||||
|
|-------|-------|-----|
|
||||||
|
| Bitcoin | Orange | `#F7931A` |
|
||||||
|
| Gold | Gold | `#FFD700` |
|
||||||
|
| Silver | Silver | `#C0C0C0` |
|
||||||
|
| Stocks/Indices | Dollar Green | `#00A86B` |
|
||||||
|
| Status Bar | Bitcoin Orange | `#F7931A` |
|
||||||
|
|
||||||
|
## Software Stack
|
||||||
|
|
||||||
|
- **Framework**: Arduino (PlatformIO)
|
||||||
|
- **Display Library**: LovyanGFX v1.2.19
|
||||||
|
- **Fonts**: DejaVu (antialiased)
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/chad/Documents/PlatformIO/Projects/bitcoin_dashboard
|
||||||
|
pio run -t upload
|
||||||
|
```
|
||||||
|
|
||||||
|
## PlatformIO Configuration
|
||||||
|
|
||||||
|
- **Platform**: espressif32@6.8.1
|
||||||
|
- **Board**: esp32-s3-devkitc-1
|
||||||
|
- **Partition**: huge_app.csv (3MB app, no OTA)
|
||||||
|
- **Flash Mode**: QIO @ 80MHz
|
||||||
|
- **PSRAM**: OPI (8MB)
|
||||||
|
|
||||||
|
## Data Source
|
||||||
|
|
||||||
|
Yahoo Finance API:
|
||||||
|
```
|
||||||
|
https://query1.finance.yahoo.com/v8/finance/chart/{SYMBOL}?interval=1d&range=1d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Symbol Mapping
|
||||||
|
|
||||||
|
| Display | Yahoo Symbol |
|
||||||
|
|---------|--------------|
|
||||||
|
| Bitcoin | BTC-USD |
|
||||||
|
| Gold | GC=F |
|
||||||
|
| Silver | SI=F |
|
||||||
|
| MSTR | MSTR |
|
||||||
|
| STRC | STRC |
|
||||||
|
| NASDAQ | ^IXIC |
|
||||||
|
| DOW | ^DJI |
|
||||||
|
| S&P 500 | ^GSPC |
|
||||||
|
|
||||||
|
## Pin Configuration
|
||||||
|
|
||||||
|
### RGB Display Interface
|
||||||
|
|
||||||
|
| Signal | GPIO |
|
||||||
|
|--------|------|
|
||||||
|
| D0-D15 | 15, 7, 6, 5, 4, 9, 46, 3, 8, 16, 1, 14, 21, 47, 48, 45 |
|
||||||
|
| HSYNC | GPIO 39 |
|
||||||
|
| VSYNC | GPIO 40 |
|
||||||
|
| DE | GPIO 41 |
|
||||||
|
| PCLK | GPIO 0 |
|
||||||
|
| Backlight | GPIO 2 |
|
||||||
|
|
||||||
|
### Touch Controller (GT911)
|
||||||
|
|
||||||
|
| Signal | GPIO |
|
||||||
|
|--------|------|
|
||||||
|
| SDA | GPIO 19 |
|
||||||
|
| SCL | GPIO 20 |
|
||||||
|
| I2C Address | 0x14 |
|
||||||
|
|
||||||
|
## WiFi Setup
|
||||||
|
|
||||||
|
WiFi credentials are stored in ESP32 preferences (persistent storage):
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
preferences.begin("wifi", true);
|
||||||
|
preferences.putString("ssid", "your_ssid");
|
||||||
|
preferences.putString("password", "your_password");
|
||||||
|
preferences.end();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
bitcoin_dashboard/
|
||||||
|
├── src/
|
||||||
|
│ └── main.cpp # Main application
|
||||||
|
├── docs/
|
||||||
|
│ └── README.md # This file
|
||||||
|
├── platformio.ini # PlatformIO configuration
|
||||||
|
└── .gitignore
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
108
include/lgfx_config.hpp
Normal file
108
include/lgfx_config.hpp
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
/**
|
||||||
|
* LGFX Display Configuration for Elecrow 7-inch HMI Display
|
||||||
|
* Based on working Arduino example
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LGFX_CONFIG_HPP
|
||||||
|
#define LGFX_CONFIG_HPP
|
||||||
|
|
||||||
|
#define LGFX_USE_V1
|
||||||
|
#include <LovyanGFX.hpp>
|
||||||
|
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
|
||||||
|
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>
|
||||||
|
#include <driver/i2c.h>
|
||||||
|
|
||||||
|
class LGFX : public lgfx::LGFX_Device {
|
||||||
|
public:
|
||||||
|
lgfx::Bus_RGB _bus_instance;
|
||||||
|
lgfx::Panel_RGB _panel_instance;
|
||||||
|
lgfx::Light_PWM _light_instance;
|
||||||
|
lgfx::Touch_GT911 _touch_instance;
|
||||||
|
|
||||||
|
LGFX(void) {
|
||||||
|
{
|
||||||
|
auto cfg = _panel_instance.config();
|
||||||
|
cfg.memory_width = 800;
|
||||||
|
cfg.memory_height = 480;
|
||||||
|
cfg.panel_width = 800;
|
||||||
|
cfg.panel_height = 480;
|
||||||
|
cfg.offset_x = 0;
|
||||||
|
cfg.offset_y = 0;
|
||||||
|
_panel_instance.config(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto cfg = _bus_instance.config();
|
||||||
|
cfg.panel = &_panel_instance;
|
||||||
|
|
||||||
|
cfg.pin_d0 = GPIO_NUM_15;
|
||||||
|
cfg.pin_d1 = GPIO_NUM_7;
|
||||||
|
cfg.pin_d2 = GPIO_NUM_6;
|
||||||
|
cfg.pin_d3 = GPIO_NUM_5;
|
||||||
|
cfg.pin_d4 = GPIO_NUM_4;
|
||||||
|
cfg.pin_d5 = GPIO_NUM_9;
|
||||||
|
cfg.pin_d6 = GPIO_NUM_46;
|
||||||
|
cfg.pin_d7 = GPIO_NUM_3;
|
||||||
|
cfg.pin_d8 = GPIO_NUM_8;
|
||||||
|
cfg.pin_d9 = GPIO_NUM_16;
|
||||||
|
cfg.pin_d10 = GPIO_NUM_1;
|
||||||
|
cfg.pin_d11 = GPIO_NUM_14;
|
||||||
|
cfg.pin_d12 = GPIO_NUM_21;
|
||||||
|
cfg.pin_d13 = GPIO_NUM_47;
|
||||||
|
cfg.pin_d14 = GPIO_NUM_48;
|
||||||
|
cfg.pin_d15 = GPIO_NUM_45;
|
||||||
|
|
||||||
|
cfg.pin_henable = GPIO_NUM_41;
|
||||||
|
cfg.pin_vsync = GPIO_NUM_40;
|
||||||
|
cfg.pin_hsync = GPIO_NUM_39;
|
||||||
|
cfg.pin_pclk = GPIO_NUM_0;
|
||||||
|
cfg.freq_write = 12000000;
|
||||||
|
|
||||||
|
cfg.hsync_polarity = 0;
|
||||||
|
cfg.hsync_front_porch = 40;
|
||||||
|
cfg.hsync_pulse_width = 48;
|
||||||
|
cfg.hsync_back_porch = 40;
|
||||||
|
|
||||||
|
cfg.vsync_polarity = 0;
|
||||||
|
cfg.vsync_front_porch = 1;
|
||||||
|
cfg.vsync_pulse_width = 31;
|
||||||
|
cfg.vsync_back_porch = 13;
|
||||||
|
|
||||||
|
cfg.pclk_active_neg = 1;
|
||||||
|
cfg.de_idle_high = 0;
|
||||||
|
cfg.pclk_idle_high = 0;
|
||||||
|
|
||||||
|
_bus_instance.config(cfg);
|
||||||
|
}
|
||||||
|
_panel_instance.setBus(&_bus_instance);
|
||||||
|
|
||||||
|
{
|
||||||
|
auto cfg = _light_instance.config();
|
||||||
|
cfg.pin_bl = GPIO_NUM_2;
|
||||||
|
_light_instance.config(cfg);
|
||||||
|
}
|
||||||
|
_panel_instance.light(&_light_instance);
|
||||||
|
|
||||||
|
{
|
||||||
|
auto cfg = _touch_instance.config();
|
||||||
|
cfg.x_min = 0;
|
||||||
|
cfg.x_max = 799;
|
||||||
|
cfg.y_min = 0;
|
||||||
|
cfg.y_max = 479;
|
||||||
|
cfg.pin_int = -1;
|
||||||
|
cfg.pin_rst = -1;
|
||||||
|
cfg.bus_shared = false;
|
||||||
|
cfg.offset_rotation = 0;
|
||||||
|
cfg.i2c_port = I2C_NUM_1;
|
||||||
|
cfg.pin_sda = GPIO_NUM_19;
|
||||||
|
cfg.pin_scl = GPIO_NUM_20;
|
||||||
|
cfg.freq = 400000;
|
||||||
|
cfg.i2c_addr = 0x14;
|
||||||
|
_touch_instance.config(cfg);
|
||||||
|
_panel_instance.setTouch(&_touch_instance);
|
||||||
|
}
|
||||||
|
setPanel(&_panel_instance);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LGFX_CONFIG_HPP
|
||||||
145
include/lv_conf.h
Normal file
145
include/lv_conf.h
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
/**
|
||||||
|
* LVGL Configuration for Bitcoin Dashboard
|
||||||
|
* Target: Elecrow 7-inch HMI Display (800x480)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LV_CONF_H
|
||||||
|
#define LV_CONF_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define LV_COLOR_DEPTH 16
|
||||||
|
#define LV_COLOR_16_SWAP 0
|
||||||
|
|
||||||
|
#define LV_HOR_RES_MAX 800
|
||||||
|
#define LV_VER_RES_MAX 480
|
||||||
|
|
||||||
|
#define LV_DPI_DEF 100
|
||||||
|
|
||||||
|
#define LV_DISP_DEF_REFR_PERIOD 16
|
||||||
|
|
||||||
|
#define LV_TICK_CUSTOM 1
|
||||||
|
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h"
|
||||||
|
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis())
|
||||||
|
|
||||||
|
#define LV_MEM_CUSTOM 1
|
||||||
|
#define LV_MEM_CUSTOM_INCLUDE "Arduino.h"
|
||||||
|
#define LV_MEM_CUSTOM_ALLOC malloc
|
||||||
|
#define LV_MEM_CUSTOM_FREE free
|
||||||
|
|
||||||
|
#define LV_MEM_SIZE (64 * 1024U)
|
||||||
|
#define LV_MEM_ADR 0
|
||||||
|
|
||||||
|
#define LV_DRAW_CPU_ARM_ALIGN 4
|
||||||
|
|
||||||
|
#define LV_USE_DRAW_MASKS 1
|
||||||
|
#define LV_USE_DRAW_SW 1
|
||||||
|
#define LV_DRAW_SW_DRAW_UNIT_CNT 2
|
||||||
|
#define LV_USE_DRAW_SW_COMPLEX_GRADIENTS 1
|
||||||
|
#define LV_USE_DRAW_SW_SHADOW 1
|
||||||
|
#define LV_USE_DRAW_SW_BLUR 1
|
||||||
|
#define LV_USE_DRAW_SW_ARGB_TO_RGB565 1
|
||||||
|
|
||||||
|
#define LV_USE_ASSERT_NULL 1
|
||||||
|
#define LV_USE_ASSERT_MALLOC 1
|
||||||
|
|
||||||
|
#define LV_USE_MSG 1
|
||||||
|
#define LV_USE_FS_STDIO 0
|
||||||
|
#define LV_USE_FS_FATFS 0
|
||||||
|
#define LV_USE_FS_LITTLEFS 0
|
||||||
|
#define LV_USE_LODEPNG 0
|
||||||
|
#define LV_USE_LIBPNG 0
|
||||||
|
#define LV_USE_BMP 0
|
||||||
|
#define LV_USE_RLE 0
|
||||||
|
#define LV_USE_QRCODE 0
|
||||||
|
#define LV_USE_BARCODE 0
|
||||||
|
#define LV_USE_TJPGD 0
|
||||||
|
#define LV_USE_GIF 0
|
||||||
|
|
||||||
|
#define LV_USE_FLEX 1
|
||||||
|
#define LV_USE_GRID 1
|
||||||
|
|
||||||
|
#define LV_USE_SNAPSHOT 1
|
||||||
|
#define LV_USE_SYSMON 0
|
||||||
|
#define LV_USE_PERF_MONITOR 0
|
||||||
|
#define LV_USE_MEM_MONITOR 0
|
||||||
|
|
||||||
|
#define LV_THEME_DEFAULT_DARK 0
|
||||||
|
#define LV_THEME_DEFAULT_GROW 1
|
||||||
|
|
||||||
|
#define LV_USE_THEME_DEFAULT 1
|
||||||
|
#define LV_USE_THEME_BASIC 1
|
||||||
|
#define LV_USE_THEME_MONO 1
|
||||||
|
|
||||||
|
#define LV_USE_ARC 1
|
||||||
|
#define LV_USE_BAR 1
|
||||||
|
#define LV_USE_BTN 1
|
||||||
|
#define LV_USE_BTNMATRIX 1
|
||||||
|
#define LV_USE_CALENDAR 1
|
||||||
|
#define LV_USE_CANVAS 1
|
||||||
|
#define LV_USE_CHART 1
|
||||||
|
#define LV_USE_CHECKBOX 1
|
||||||
|
#define LV_USE_DROPDOWN 1
|
||||||
|
#define LV_USE_IMG 1
|
||||||
|
#define LV_USE_IMGBTN 1
|
||||||
|
#define LV_USE_KEYBOARD 1
|
||||||
|
#define LV_USE_LABEL 1
|
||||||
|
#define LV_LABEL_TEXT_SELECTION 1
|
||||||
|
#define LV_LABEL_LONG_TXT_HINT 1
|
||||||
|
#define LV_USE_LED 1
|
||||||
|
#define LV_USE_LINE 1
|
||||||
|
#define LV_USE_LIST 1
|
||||||
|
#define LV_USE_MENU 1
|
||||||
|
#define LV_USE_METER 1
|
||||||
|
#define LV_USE_MSGBOX 1
|
||||||
|
#define LV_USE_ROLLER 1
|
||||||
|
#define LV_USE_SCALE 1
|
||||||
|
#define LV_USE_SLIDER 1
|
||||||
|
#define LV_USE_SPAN 1
|
||||||
|
#define LV_USE_SPINBOX 1
|
||||||
|
#define LV_USE_SPINNER 1
|
||||||
|
#define LV_USE_SWITCH 1
|
||||||
|
#define LV_USE_TABVIEW 1
|
||||||
|
#define LV_USE_TABLE 1
|
||||||
|
#define LV_USE_TEXTAREA 1
|
||||||
|
#define LV_USE_TILEVIEW 1
|
||||||
|
#define LV_USE_WIN 1
|
||||||
|
|
||||||
|
#define LV_FONT_MONTSERRAT_12 1
|
||||||
|
#define LV_FONT_MONTSERRAT_14 1
|
||||||
|
#define LV_FONT_MONTSERRAT_16 1
|
||||||
|
#define LV_FONT_MONTSERRAT_18 1
|
||||||
|
#define LV_FONT_MONTSERRAT_20 1
|
||||||
|
#define LV_FONT_MONTSERRAT_22 1
|
||||||
|
#define LV_FONT_MONTSERRAT_24 1
|
||||||
|
#define LV_FONT_MONTSERRAT_26 1
|
||||||
|
#define LV_FONT_MONTSERRAT_28 1
|
||||||
|
#define LV_FONT_MONTSERRAT_30 1
|
||||||
|
#define LV_FONT_MONTSERRAT_32 1
|
||||||
|
#define LV_FONT_MONTSERRAT_34 1
|
||||||
|
#define LV_FONT_MONTSERRAT_36 1
|
||||||
|
|
||||||
|
#define LV_FONT_FMT_TXT_LARGE 1
|
||||||
|
#define LV_USE_FONT_COMPRESSED 1
|
||||||
|
#define LV_FONT_DEFAULT &lv_font_montserrat_14
|
||||||
|
|
||||||
|
#define LV_TXT_ENC_UTF8 1
|
||||||
|
#define LV_TXT_BREAK_CHARS " ,.;:-_)]}"
|
||||||
|
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
||||||
|
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||||
|
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||||
|
#define LV_TXT_COLOR_CMD "#"
|
||||||
|
|
||||||
|
#define LV_USE_INDEV_SCROLLBAR 1
|
||||||
|
#define LV_USE_INDEV_BUTTON 1
|
||||||
|
#define LV_USE_INDEV_KEYPAD 1
|
||||||
|
#define LV_USE_INDEV_ENCODER 1
|
||||||
|
|
||||||
|
#define LV_USE_GROUP 1
|
||||||
|
|
||||||
|
#define LV_USE_ANIM 1
|
||||||
|
#define LV_ANIM_HOLD_COUNT 1
|
||||||
|
|
||||||
|
#define LV_GRADIENT_MAX_STOPS 2
|
||||||
|
|
||||||
|
#endif // LV_CONF_H
|
||||||
145
lv_conf.h
Normal file
145
lv_conf.h
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
/**
|
||||||
|
* LVGL Configuration for Bitcoin Dashboard
|
||||||
|
* Target: Elecrow 7-inch HMI Display (800x480)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LV_CONF_H
|
||||||
|
#define LV_CONF_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define LV_COLOR_DEPTH 16
|
||||||
|
#define LV_COLOR_16_SWAP 0
|
||||||
|
|
||||||
|
#define LV_HOR_RES_MAX 800
|
||||||
|
#define LV_VER_RES_MAX 480
|
||||||
|
|
||||||
|
#define LV_DPI_DEF 100
|
||||||
|
|
||||||
|
#define LV_DISP_DEF_REFR_PERIOD 16
|
||||||
|
|
||||||
|
#define LV_TICK_CUSTOM 1
|
||||||
|
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h"
|
||||||
|
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis())
|
||||||
|
|
||||||
|
#define LV_MEM_CUSTOM 1
|
||||||
|
#define LV_MEM_CUSTOM_INCLUDE "Arduino.h"
|
||||||
|
#define LV_MEM_CUSTOM_ALLOC malloc
|
||||||
|
#define LV_MEM_CUSTOM_FREE free
|
||||||
|
|
||||||
|
#define LV_MEM_SIZE (64 * 1024U)
|
||||||
|
#define LV_MEM_ADR 0
|
||||||
|
|
||||||
|
#define LV_DRAW_CPU_ARM_ALIGN 4
|
||||||
|
|
||||||
|
#define LV_USE_DRAW_MASKS 1
|
||||||
|
#define LV_USE_DRAW_SW 1
|
||||||
|
#define LV_DRAW_SW_DRAW_UNIT_CNT 2
|
||||||
|
#define LV_USE_DRAW_SW_COMPLEX_GRADIENTS 1
|
||||||
|
#define LV_USE_DRAW_SW_SHADOW 1
|
||||||
|
#define LV_USE_DRAW_SW_BLUR 1
|
||||||
|
#define LV_USE_DRAW_SW_ARGB_TO_RGB565 1
|
||||||
|
|
||||||
|
#define LV_USE_ASSERT_NULL 1
|
||||||
|
#define LV_USE_ASSERT_MALLOC 1
|
||||||
|
|
||||||
|
#define LV_USE_MSG 1
|
||||||
|
#define LV_USE_FS_STDIO 0
|
||||||
|
#define LV_USE_FS_FATFS 0
|
||||||
|
#define LV_USE_FS_LITTLEFS 0
|
||||||
|
#define LV_USE_LODEPNG 0
|
||||||
|
#define LV_USE_LIBPNG 0
|
||||||
|
#define LV_USE_BMP 0
|
||||||
|
#define LV_USE_RLE 0
|
||||||
|
#define LV_USE_QRCODE 0
|
||||||
|
#define LV_USE_BARCODE 0
|
||||||
|
#define LV_USE_TJPGD 0
|
||||||
|
#define LV_USE_GIF 0
|
||||||
|
|
||||||
|
#define LV_USE_FLEX 1
|
||||||
|
#define LV_USE_GRID 1
|
||||||
|
|
||||||
|
#define LV_USE_SNAPSHOT 1
|
||||||
|
#define LV_USE_SYSMON 0
|
||||||
|
#define LV_USE_PERF_MONITOR 0
|
||||||
|
#define LV_USE_MEM_MONITOR 0
|
||||||
|
|
||||||
|
#define LV_THEME_DEFAULT_DARK 0
|
||||||
|
#define LV_THEME_DEFAULT_GROW 1
|
||||||
|
|
||||||
|
#define LV_USE_THEME_DEFAULT 1
|
||||||
|
#define LV_USE_THEME_BASIC 1
|
||||||
|
#define LV_USE_THEME_MONO 1
|
||||||
|
|
||||||
|
#define LV_USE_ARC 1
|
||||||
|
#define LV_USE_BAR 1
|
||||||
|
#define LV_USE_BTN 1
|
||||||
|
#define LV_USE_BTNMATRIX 1
|
||||||
|
#define LV_USE_CALENDAR 1
|
||||||
|
#define LV_USE_CANVAS 1
|
||||||
|
#define LV_USE_CHART 1
|
||||||
|
#define LV_USE_CHECKBOX 1
|
||||||
|
#define LV_USE_DROPDOWN 1
|
||||||
|
#define LV_USE_IMG 1
|
||||||
|
#define LV_USE_IMGBTN 1
|
||||||
|
#define LV_USE_KEYBOARD 1
|
||||||
|
#define LV_USE_LABEL 1
|
||||||
|
#define LV_LABEL_TEXT_SELECTION 1
|
||||||
|
#define LV_LABEL_LONG_TXT_HINT 1
|
||||||
|
#define LV_USE_LED 1
|
||||||
|
#define LV_USE_LINE 1
|
||||||
|
#define LV_USE_LIST 1
|
||||||
|
#define LV_USE_MENU 1
|
||||||
|
#define LV_USE_METER 1
|
||||||
|
#define LV_USE_MSGBOX 1
|
||||||
|
#define LV_USE_ROLLER 1
|
||||||
|
#define LV_USE_SCALE 1
|
||||||
|
#define LV_USE_SLIDER 1
|
||||||
|
#define LV_USE_SPAN 1
|
||||||
|
#define LV_USE_SPINBOX 1
|
||||||
|
#define LV_USE_SPINNER 1
|
||||||
|
#define LV_USE_SWITCH 1
|
||||||
|
#define LV_USE_TABVIEW 1
|
||||||
|
#define LV_USE_TABLE 1
|
||||||
|
#define LV_USE_TEXTAREA 1
|
||||||
|
#define LV_USE_TILEVIEW 1
|
||||||
|
#define LV_USE_WIN 1
|
||||||
|
|
||||||
|
#define LV_FONT_MONTSERRAT_12 1
|
||||||
|
#define LV_FONT_MONTSERRAT_14 1
|
||||||
|
#define LV_FONT_MONTSERRAT_16 1
|
||||||
|
#define LV_FONT_MONTSERRAT_18 1
|
||||||
|
#define LV_FONT_MONTSERRAT_20 1
|
||||||
|
#define LV_FONT_MONTSERRAT_22 1
|
||||||
|
#define LV_FONT_MONTSERRAT_24 1
|
||||||
|
#define LV_FONT_MONTSERRAT_26 1
|
||||||
|
#define LV_FONT_MONTSERRAT_28 1
|
||||||
|
#define LV_FONT_MONTSERRAT_30 1
|
||||||
|
#define LV_FONT_MONTSERRAT_32 1
|
||||||
|
#define LV_FONT_MONTSERRAT_34 1
|
||||||
|
#define LV_FONT_MONTSERRAT_36 1
|
||||||
|
|
||||||
|
#define LV_FONT_FMT_TXT_LARGE 1
|
||||||
|
#define LV_USE_FONT_COMPRESSED 1
|
||||||
|
#define LV_FONT_DEFAULT &lv_font_montserrat_14
|
||||||
|
|
||||||
|
#define LV_TXT_ENC_UTF8 1
|
||||||
|
#define LV_TXT_BREAK_CHARS " ,.;:-_)]}"
|
||||||
|
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
||||||
|
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||||
|
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||||
|
#define LV_TXT_COLOR_CMD "#"
|
||||||
|
|
||||||
|
#define LV_USE_INDEV_SCROLLBAR 1
|
||||||
|
#define LV_USE_INDEV_BUTTON 1
|
||||||
|
#define LV_USE_INDEV_KEYPAD 1
|
||||||
|
#define LV_USE_INDEV_ENCODER 1
|
||||||
|
|
||||||
|
#define LV_USE_GROUP 1
|
||||||
|
|
||||||
|
#define LV_USE_ANIM 1
|
||||||
|
#define LV_ANIM_HOLD_COUNT 1
|
||||||
|
|
||||||
|
#define LV_GRADIENT_MAX_STOPS 2
|
||||||
|
|
||||||
|
#endif // LV_CONF_H
|
||||||
30
platformio.ini
Normal file
30
platformio.ini
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
; PlatformIO Project Configuration File
|
||||||
|
; Bitcoin Dashboard for Elecrow 7-inch HMI Display
|
||||||
|
; Based on working Arduino example
|
||||||
|
|
||||||
|
[env:elecrow_7inch_hmi]
|
||||||
|
platform = espressif32@6.8.1
|
||||||
|
board = esp32-s3-devkitc-1
|
||||||
|
framework = arduino
|
||||||
|
|
||||||
|
; Libraries
|
||||||
|
lib_deps =
|
||||||
|
lovyan03/LovyanGFX@^1.1.8
|
||||||
|
|
||||||
|
monitor_speed = 115200
|
||||||
|
|
||||||
|
; Critical settings for the N4R8 module (from working example)
|
||||||
|
board_upload.flash_size = 4MB
|
||||||
|
board_build.arduino.memory_type = qio_opi
|
||||||
|
board_build.f_flash = 80000000L
|
||||||
|
board_build.flash_mode = qio
|
||||||
|
|
||||||
|
; Use Huge APP partition (3MB No OTA/1MB SPIFFS)
|
||||||
|
board_build.partitions = huge_app.csv
|
||||||
|
|
||||||
|
; Required build flags for S3 display stability
|
||||||
|
build_flags =
|
||||||
|
-DARDUINO_USB_MODE=1
|
||||||
|
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
-DBOARD_HAS_PSRAM
|
||||||
|
-mfix-esp32-psram-cache-issue
|
||||||
145
src/lv_conf.h
Normal file
145
src/lv_conf.h
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
/**
|
||||||
|
* LVGL Configuration for Bitcoin Dashboard
|
||||||
|
* Target: Elecrow 7-inch HMI Display (800x480)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LV_CONF_H
|
||||||
|
#define LV_CONF_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define LV_COLOR_DEPTH 16
|
||||||
|
#define LV_COLOR_16_SWAP 0
|
||||||
|
|
||||||
|
#define LV_HOR_RES_MAX 800
|
||||||
|
#define LV_VER_RES_MAX 480
|
||||||
|
|
||||||
|
#define LV_DPI_DEF 100
|
||||||
|
|
||||||
|
#define LV_DISP_DEF_REFR_PERIOD 16
|
||||||
|
|
||||||
|
#define LV_TICK_CUSTOM 1
|
||||||
|
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h"
|
||||||
|
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis())
|
||||||
|
|
||||||
|
#define LV_MEM_CUSTOM 1
|
||||||
|
#define LV_MEM_CUSTOM_INCLUDE "Arduino.h"
|
||||||
|
#define LV_MEM_CUSTOM_ALLOC malloc
|
||||||
|
#define LV_MEM_CUSTOM_FREE free
|
||||||
|
|
||||||
|
#define LV_MEM_SIZE (64 * 1024U)
|
||||||
|
#define LV_MEM_ADR 0
|
||||||
|
|
||||||
|
#define LV_DRAW_CPU_ARM_ALIGN 4
|
||||||
|
|
||||||
|
#define LV_USE_DRAW_MASKS 1
|
||||||
|
#define LV_USE_DRAW_SW 1
|
||||||
|
#define LV_DRAW_SW_DRAW_UNIT_CNT 2
|
||||||
|
#define LV_USE_DRAW_SW_COMPLEX_GRADIENTS 1
|
||||||
|
#define LV_USE_DRAW_SW_SHADOW 1
|
||||||
|
#define LV_USE_DRAW_SW_BLUR 1
|
||||||
|
#define LV_USE_DRAW_SW_ARGB_TO_RGB565 1
|
||||||
|
|
||||||
|
#define LV_USE_ASSERT_NULL 1
|
||||||
|
#define LV_USE_ASSERT_MALLOC 1
|
||||||
|
|
||||||
|
#define LV_USE_MSG 1
|
||||||
|
#define LV_USE_FS_STDIO 0
|
||||||
|
#define LV_USE_FS_FATFS 0
|
||||||
|
#define LV_USE_FS_LITTLEFS 0
|
||||||
|
#define LV_USE_LODEPNG 0
|
||||||
|
#define LV_USE_LIBPNG 0
|
||||||
|
#define LV_USE_BMP 0
|
||||||
|
#define LV_USE_RLE 0
|
||||||
|
#define LV_USE_QRCODE 0
|
||||||
|
#define LV_USE_BARCODE 0
|
||||||
|
#define LV_USE_TJPGD 0
|
||||||
|
#define LV_USE_GIF 0
|
||||||
|
|
||||||
|
#define LV_USE_FLEX 1
|
||||||
|
#define LV_USE_GRID 1
|
||||||
|
|
||||||
|
#define LV_USE_SNAPSHOT 1
|
||||||
|
#define LV_USE_SYSMON 0
|
||||||
|
#define LV_USE_PERF_MONITOR 0
|
||||||
|
#define LV_USE_MEM_MONITOR 0
|
||||||
|
|
||||||
|
#define LV_THEME_DEFAULT_DARK 0
|
||||||
|
#define LV_THEME_DEFAULT_GROW 1
|
||||||
|
|
||||||
|
#define LV_USE_THEME_DEFAULT 1
|
||||||
|
#define LV_USE_THEME_BASIC 1
|
||||||
|
#define LV_USE_THEME_MONO 1
|
||||||
|
|
||||||
|
#define LV_USE_ARC 1
|
||||||
|
#define LV_USE_BAR 1
|
||||||
|
#define LV_USE_BTN 1
|
||||||
|
#define LV_USE_BTNMATRIX 1
|
||||||
|
#define LV_USE_CALENDAR 1
|
||||||
|
#define LV_USE_CANVAS 1
|
||||||
|
#define LV_USE_CHART 1
|
||||||
|
#define LV_USE_CHECKBOX 1
|
||||||
|
#define LV_USE_DROPDOWN 1
|
||||||
|
#define LV_USE_IMG 1
|
||||||
|
#define LV_USE_IMGBTN 1
|
||||||
|
#define LV_USE_KEYBOARD 1
|
||||||
|
#define LV_USE_LABEL 1
|
||||||
|
#define LV_LABEL_TEXT_SELECTION 1
|
||||||
|
#define LV_LABEL_LONG_TXT_HINT 1
|
||||||
|
#define LV_USE_LED 1
|
||||||
|
#define LV_USE_LINE 1
|
||||||
|
#define LV_USE_LIST 1
|
||||||
|
#define LV_USE_MENU 1
|
||||||
|
#define LV_USE_METER 1
|
||||||
|
#define LV_USE_MSGBOX 1
|
||||||
|
#define LV_USE_ROLLER 1
|
||||||
|
#define LV_USE_SCALE 1
|
||||||
|
#define LV_USE_SLIDER 1
|
||||||
|
#define LV_USE_SPAN 1
|
||||||
|
#define LV_USE_SPINBOX 1
|
||||||
|
#define LV_USE_SPINNER 1
|
||||||
|
#define LV_USE_SWITCH 1
|
||||||
|
#define LV_USE_TABVIEW 1
|
||||||
|
#define LV_USE_TABLE 1
|
||||||
|
#define LV_USE_TEXTAREA 1
|
||||||
|
#define LV_USE_TILEVIEW 1
|
||||||
|
#define LV_USE_WIN 1
|
||||||
|
|
||||||
|
#define LV_FONT_MONTSERRAT_12 1
|
||||||
|
#define LV_FONT_MONTSERRAT_14 1
|
||||||
|
#define LV_FONT_MONTSERRAT_16 1
|
||||||
|
#define LV_FONT_MONTSERRAT_18 1
|
||||||
|
#define LV_FONT_MONTSERRAT_20 1
|
||||||
|
#define LV_FONT_MONTSERRAT_22 1
|
||||||
|
#define LV_FONT_MONTSERRAT_24 1
|
||||||
|
#define LV_FONT_MONTSERRAT_26 1
|
||||||
|
#define LV_FONT_MONTSERRAT_28 1
|
||||||
|
#define LV_FONT_MONTSERRAT_30 1
|
||||||
|
#define LV_FONT_MONTSERRAT_32 1
|
||||||
|
#define LV_FONT_MONTSERRAT_34 1
|
||||||
|
#define LV_FONT_MONTSERRAT_36 1
|
||||||
|
|
||||||
|
#define LV_FONT_FMT_TXT_LARGE 1
|
||||||
|
#define LV_USE_FONT_COMPRESSED 1
|
||||||
|
#define LV_FONT_DEFAULT &lv_font_montserrat_14
|
||||||
|
|
||||||
|
#define LV_TXT_ENC_UTF8 1
|
||||||
|
#define LV_TXT_BREAK_CHARS " ,.;:-_)]}"
|
||||||
|
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
||||||
|
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||||
|
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||||
|
#define LV_TXT_COLOR_CMD "#"
|
||||||
|
|
||||||
|
#define LV_USE_INDEV_SCROLLBAR 1
|
||||||
|
#define LV_USE_INDEV_BUTTON 1
|
||||||
|
#define LV_USE_INDEV_KEYPAD 1
|
||||||
|
#define LV_USE_INDEV_ENCODER 1
|
||||||
|
|
||||||
|
#define LV_USE_GROUP 1
|
||||||
|
|
||||||
|
#define LV_USE_ANIM 1
|
||||||
|
#define LV_ANIM_HOLD_COUNT 1
|
||||||
|
|
||||||
|
#define LV_GRADIENT_MAX_STOPS 2
|
||||||
|
|
||||||
|
#endif // LV_CONF_H
|
||||||
2251
src/main.cpp
Normal file
2251
src/main.cpp
Normal file
File diff suppressed because it is too large
Load diff
132
src/mqtt_module.cpp
Normal file
132
src/mqtt_module.cpp
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
/**
|
||||||
|
* MQTT Module Implementation
|
||||||
|
* Handles connection to MQTT broker and price updates
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mqtt_module.h"
|
||||||
|
|
||||||
|
MQTTModule::MQTTModule()
|
||||||
|
: _port(1883), _lastReconnectAttempt(0), _initialized(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MQTTModule::begin(const char* server, int port, const char* user, const char* pass) {
|
||||||
|
_server = String(server);
|
||||||
|
_port = port;
|
||||||
|
_user = String(user);
|
||||||
|
_pass = String(pass);
|
||||||
|
|
||||||
|
_wifiClient.setInsecure();
|
||||||
|
_mqttClient.setClient(_wifiClient);
|
||||||
|
_mqttClient.setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
_mqttClient.setCallback([this](char* t, byte* p, unsigned int l) {
|
||||||
|
this->_callback(t, p, l);
|
||||||
|
});
|
||||||
|
|
||||||
|
_mqttClient.setServer(_server.c_str(), _port);
|
||||||
|
_initialized = true;
|
||||||
|
|
||||||
|
Serial.printf("[MQTT] Configured for %s:%d\n", _server.c_str(), _port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MQTTModule::setTopic(const char* topic) {
|
||||||
|
_topic = String(topic);
|
||||||
|
Serial.printf("[MQTT] Topic set to: %s\n", _topic.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MQTTModule::_callback(char* topic, byte* payload, unsigned int length) {
|
||||||
|
char buffer[MQTT_MAX_PACKET_SIZE];
|
||||||
|
if (length >= MQTT_MAX_PACKET_SIZE) {
|
||||||
|
length = MQTT_MAX_PACKET_SIZE - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buffer, payload, length);
|
||||||
|
buffer[length] = '\0';
|
||||||
|
|
||||||
|
Serial.printf("[MQTT] Received: %s\n", buffer);
|
||||||
|
_parsePriceData(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MQTTModule::_parsePriceData(const char* json) {
|
||||||
|
JsonDocument doc;
|
||||||
|
DeserializationError error = deserializeJson(doc, json);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
Serial.printf("[MQTT] JSON parse error: %s\n", error.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool updated = false;
|
||||||
|
|
||||||
|
if (doc.containsKey("btc")) {
|
||||||
|
btcPrice = doc["btc"].as<double>();
|
||||||
|
Serial.printf("[MQTT] BTC: $%.2f\n", btcPrice);
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc.containsKey("gold")) {
|
||||||
|
goldPrice = doc["gold"].as<double>();
|
||||||
|
Serial.printf("[MQTT] Gold: $%.2f\n", goldPrice);
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc.containsKey("silver")) {
|
||||||
|
silverPrice = doc["silver"].as<double>();
|
||||||
|
Serial.printf("[MQTT] Silver: $%.2f\n", silverPrice);
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updated) {
|
||||||
|
needsRefresh = true;
|
||||||
|
Serial.println("[MQTT] Triggering screen refresh");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MQTTModule::update() {
|
||||||
|
if (!_initialized) return;
|
||||||
|
|
||||||
|
if (!_mqttClient.connected()) {
|
||||||
|
unsigned long now = millis();
|
||||||
|
if (now - _lastReconnectAttempt > 5000) {
|
||||||
|
_lastReconnectAttempt = now;
|
||||||
|
reconnect();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_mqttClient.loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MQTTModule::isConnected() {
|
||||||
|
return _mqttClient.connected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MQTTModule::reconnect() {
|
||||||
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
|
Serial.println("[MQTT] WiFi not connected, skipping reconnect");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("[MQTT] Connecting...");
|
||||||
|
|
||||||
|
String clientId = "esp32-financial-" + String((uint32_t)ESP.getEfuseMac(), HEX);
|
||||||
|
|
||||||
|
if (_mqttClient.connect(clientId.c_str(), _user.c_str(), _pass.c_str())) {
|
||||||
|
Serial.println(" connected!");
|
||||||
|
|
||||||
|
if (_topic.length() > 0) {
|
||||||
|
if (_mqttClient.subscribe(_topic.c_str())) {
|
||||||
|
Serial.printf("[MQTT] Subscribed to: %s\n", _topic.c_str());
|
||||||
|
} else {
|
||||||
|
Serial.println("[MQTT] Subscribe failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.printf(" failed (rc=%d)\n", _mqttClient.state());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MQTTModule::disconnect() {
|
||||||
|
if (_mqttClient.connected()) {
|
||||||
|
_mqttClient.disconnect();
|
||||||
|
Serial.println("[MQTT] Disconnected");
|
||||||
|
}
|
||||||
|
}
|
||||||
46
src/mqtt_module.h
Normal file
46
src/mqtt_module.h
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* MQTT Module for Financial Dashboard
|
||||||
|
* Handles connection to MQTT broker and price updates
|
||||||
|
* Additive to existing firmware - uses needsRefresh flag
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MQTT_MODULE_H
|
||||||
|
#define MQTT_MODULE_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <PubSubClient.h>
|
||||||
|
#include <WiFiClientSecure.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
#define MQTT_MAX_PACKET_SIZE 2048
|
||||||
|
|
||||||
|
extern bool needsRefresh;
|
||||||
|
extern double btcPrice, goldPrice, silverPrice;
|
||||||
|
|
||||||
|
class MQTTModule {
|
||||||
|
public:
|
||||||
|
MQTTModule();
|
||||||
|
void begin(const char* server, int port, const char* user, const char* pass);
|
||||||
|
void setTopic(const char* topic);
|
||||||
|
void update();
|
||||||
|
bool isConnected();
|
||||||
|
void reconnect();
|
||||||
|
void disconnect();
|
||||||
|
|
||||||
|
private:
|
||||||
|
WiFiClientSecure _wifiClient;
|
||||||
|
PubSubClient _mqttClient;
|
||||||
|
String _server;
|
||||||
|
int _port;
|
||||||
|
String _user;
|
||||||
|
String _pass;
|
||||||
|
String _topic;
|
||||||
|
unsigned long _lastReconnectAttempt;
|
||||||
|
bool _initialized;
|
||||||
|
|
||||||
|
void _callback(char* topic, byte* payload, unsigned int length);
|
||||||
|
void _parsePriceData(const char* json);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Reference in a new issue