Skip to content

Commit de8a11c

Browse files
authored
Merge pull request #8 from ainyan03/feature/stickcplusse-support
Add StickCPlusSE support and stabilize WiFi setup
2 parents 7daf764 + 9eb8c78 commit de8a11c

7 files changed

Lines changed: 502 additions & 178 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@
3030
*.exe
3131
*.out
3232
*.app
33+
34+
# PlatformIO build output and downloaded dependencies
35+
.pio/

README.md

Lines changed: 99 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,107 @@
1-
# T-Lite-Internal-FW (M5StickC-Plus + MLX90640 Thermal HAT)
1+
# M5Stick T-Lite Firmware
22

3-
### SKU:K126
3+
Firmware for the [M5Stack T-Lite (SKU K126)](https://docs.m5stack.com/en/app/T-Lite),
4+
a thermal camera built from an M5StickC Plus and an MLX90640 Thermal HAT.
45

56
![T-Lite](https://static-cdn.m5stack.com/resource/docs/products/app/T-Lite/img-1b8ebe07-4556-4641-a487-b6fe6bf8b0c6.jpg)
67

7-
## Related Link
8+
## Supported hardware
89

9-
- [Document & Datasheet](https://docs.m5stack.com/en/app/T-Lite)
10+
| Main unit | Thermal sensor |
11+
| --- | --- |
12+
| M5StickC Plus | MLX90640 Thermal HAT |
13+
| M5StickC Plus SE | MLX90640 Thermal HAT |
1014

11-
## License
15+
The same firmware image runs on both main units. T-Lite does not use the internal
16+
IMU, which is absent from the Plus SE.
17+
18+
## Features
19+
20+
- Thermal image display with multiple layouts and color palettes
21+
- Temperature range, refresh rate, noise filter, and emissivity settings
22+
- Wi-Fi setup from a phone using an access point and QR codes
23+
- Browser control, temperature data, and MJPEG streaming over the local network
24+
- Access by IP address or mDNS hostname
25+
- Battery level and charging status in the upper-right status row
26+
- Runtime heap, task stack, and Wi-Fi diagnostics at `/health`
27+
28+
## Wi-Fi setup
29+
30+
1. On T-Lite, open **Network > WiFi Setting > AP mode**.
31+
2. Scan the displayed Wi-Fi QR code with a phone. To connect manually, select
32+
`T-Lite_xxxx` and enter `12341234` as the password.
33+
3. After the phone joins the T-Lite network, scan the new QR code or open
34+
`http://192.168.4.1/wifi`.
35+
4. Select a nearby network from the SSID list, enter its password, and save.
36+
5. Reconnect the phone to the same local network as T-Lite.
37+
38+
If the SSID list is still being populated, wait for the page to refresh or select
39+
**Refresh networks**. When all phones leave the setup access point, T-Lite shows
40+
the Wi-Fi connection QR code again.
41+
42+
## Browser access
43+
44+
After Wi-Fi setup, the Network menu provides QR codes for local access.
45+
46+
| Method | Address |
47+
| --- | --- |
48+
| IP address | The address assigned by the local router |
49+
| mDNS | `http://t-lite-xxxx.local/` |
50+
51+
The home page links to browser control, text and JSON temperature data, system
52+
health, and the MJPEG stream. If the network or phone does not support mDNS, use
53+
the IP address instead.
54+
55+
The mDNS hostname changed from `T-Lite_xxxx.local` to `t-lite-xxxx.local`. Update
56+
saved bookmarks created with older firmware.
57+
58+
## Battery indicator
59+
60+
The battery icon shares the upper-right status row with the Wi-Fi and cloud icons.
61+
62+
| Appearance | Meaning |
63+
| --- | --- |
64+
| Green | Battery is charging |
65+
| White | Battery is not charging |
66+
| Gray | Charging state is unavailable |
67+
| Dash inside the icon | Battery level is unavailable |
1268

13-
- [MIT](LICENSE)
69+
The filled portion represents the estimated battery level and updates about once
70+
per second. A USB connection does not always mean that the battery is actively
71+
charging.
72+
73+
## Build
74+
75+
This project uses [PlatformIO](https://platformio.org/). The framework is pinned to
76+
Espressif32 6.12.0, which includes Arduino-ESP32 2.0.17.
77+
78+
Build the release firmware:
79+
80+
```sh
81+
pio run -e release
82+
```
83+
84+
Upload it to a connected device:
85+
86+
```sh
87+
pio run -e release -t upload
88+
```
89+
90+
For verbose runtime logging, use the `debug` environment:
91+
92+
```sh
93+
pio run -e debug
94+
```
95+
96+
The application image is generated at `.pio/build/release/firmware.bin`. It is an
97+
application-partition image for address `0x10000`; use the PlatformIO upload command
98+
above when writing a complete device.
99+
100+
## Links
101+
102+
- [T-Lite documentation and datasheet](https://docs.m5stack.com/en/app/T-Lite)
103+
- [M5StickC Plus SE specifications](https://docs.m5stack.com/en/core/StickC-Plus_SE)
104+
105+
## License
14106

107+
[MIT](LICENSE)

platformio.ini

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
[env]
1313
framework = arduino
14-
platform = espressif32@4.4.0
14+
; Arduino-ESP32 2.0.3 (platform 4.4.0) fails WPA2 SoftAP authentication on
15+
; StickCPlusSE. 2.0.17 has been verified with the same device and password.
16+
platform = espressif32@6.12.0
1517
board = m5stick-c
1618
board_build.partitions = huge_app.csv
1719
board_build.flash_mode = qio
@@ -27,7 +29,7 @@ lib_deps = bblanchon/ArduinoJson
2729
build_type = release
2830
build_flags = -DCORE_DEBUG_LEVEL=0 -O3
2931
extra_scripts = post:generate_user_custom.py
30-
custom_firmware_version = 0.0.11
32+
custom_firmware_version = 0.0.15
3133
custom_firmware_name = TLite-FW
3234
custom_firmware_suffix = .bin
3335
custom_firmware_dir = r:\

src/command_processor.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,21 @@ static inline void gpio_hi(int_fast8_t pin) { *get_gpio_hi_reg(pin) = 1 << (pin
6565
static inline void gpio_lo(int_fast8_t pin) { *get_gpio_lo_reg(pin) = 1 << (pin & 31); }
6666
/* clang-format on */
6767

68-
static int8_t _battery_state = 0;
69-
static int8_t _battery_level = 0;
68+
static int8_t _battery_state = m5::Power_Class::charge_unknown;
69+
static int8_t _battery_level = -1;
7070
static bool _battery_request = false;
7171

72+
static int8_t readBatteryLevel(void) {
73+
const int level = M5.Power.getBatteryLevel();
74+
return level < 0 ? -1 : (level > 100 ? 100 : level);
75+
}
76+
7277
void updateBattery(void) {
7378
if (M5.Power.getType() == m5::Power_Class::pmic_ip5306) {
7479
_battery_request = true;
7580
} else {
7681
_battery_state = M5.Power.isCharging();
77-
_battery_level = M5.Power.getBatteryLevel();
82+
_battery_level = readBatteryLevel();
7883
}
7984
}
8085

@@ -177,7 +182,7 @@ static void IRAM_ATTR mlxTask(void* main_handle) {
177182
if (_battery_request) {
178183
_battery_request = false;
179184
_battery_state = M5.Power.isCharging();
180-
_battery_level = M5.Power.getBatteryLevel();
185+
_battery_level = readBatteryLevel();
181186
}
182187
}
183188
vTaskDelete(nullptr);

src/common_header.h

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#include <stdint.h>
22
#include <stddef.h>
33
#include <M5GFX.h>
4+
#include <M5Unified.h>
45
#include <WiFi.h>
56

67
static constexpr const uint8_t firmware_ver_major = 0;
78
static constexpr const uint8_t firmware_ver_minor = 0;
8-
static constexpr const uint8_t firmware_ver_patch = 14;
9+
static constexpr const uint8_t firmware_ver_patch = 15;
910

1011
static constexpr uint8_t frame_width = 32;
1112
static constexpr uint8_t frame_height = 24;
@@ -831,14 +832,11 @@ struct config_param_t {
831832

832833
enum net_setup_mode_t {
833834
net_setup_mode_off,
834-
net_setup_mode_smartconfig,
835835
net_setup_mode_accesspoint,
836836
// net_wifi_mode_keep_connect,
837837
// net_wifi_mode_uploading,
838838
net_setup_mode_max,
839839
};
840-
// static constexpr const char* net_setup_mode_text[] = { "Off", "ESP TOUCH
841-
// APP", "AP mode", "Keep connection", "OnCloud only" };
842840

843841
enum alarm_mode_t {
844842
alarm_mode_off,
@@ -1066,7 +1064,6 @@ struct config_param_t {
10661064
{"WiFi Setting", "WiFi设置", "WiFi設定"},
10671065
(const localize_text_t[]){
10681066
{"Off", "关闭AP", "オフ"},
1069-
{"ESP TOUCH APP", "通过ESP TOUCH APP配置", "ESP TOUCHアプリ"},
10701067
{"AP mode", "连接本机AP热点", "アクセスポイントモード"},
10711068
},
10721069
net_setup_mode_t ::net_setup_mode_off,
@@ -1297,10 +1294,10 @@ struct draw_param_t : public config_param_t {
12971294
uint8_t update_count = 0;
12981295
uint8_t modify_count = 0;
12991296
uint32_t draw_count = 0;
1300-
int8_t battery_state;
1301-
int8_t battery_level;
1302-
uint8_t font_height = 8;
1303-
bool oncloud_conf_valid = false;
1297+
int8_t battery_state = m5::Power_Class::charge_unknown;
1298+
int8_t battery_level = -1;
1299+
uint8_t font_height = 8;
1300+
bool oncloud_conf_valid = false;
13041301
uint8_t macaddr[8];
13051302

13061303
enum cloud_status_t {
@@ -1318,10 +1315,11 @@ struct draw_param_t : public config_param_t {
13181315
std::string net_tmp_ssid; // APモードで設定のために一時的に利用するSSID
13191316
std::string
13201317
net_tmp_pwd; // APモードで設定のために一時的に利用するパスワード
1321-
std::string net_ap_url; // APモードアクセス用URL
1322-
std::string net_url_mdns; // mDNS名アクセス用URL
1323-
std::string net_url_ip; // mDNS名アクセス用URL
1324-
std::string net_hostname; // T-Lite_xxxx.local
1318+
std::string net_ap_wifi_qr; // Wi-Fi credentials for joining the setup AP
1319+
std::string net_ap_url; // APモードアクセス用URL
1320+
std::string net_url_mdns; // mDNS名アクセス用URL
1321+
std::string net_url_ip; // mDNS名アクセス用URL
1322+
std::string net_hostname; // DNS host label, without .local
13251323
std::string cloud_url;
13261324
IPAddress cloud_ip;
13271325

0 commit comments

Comments
 (0)