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