WebScreen is a hackable, open-source gadget for gamers, makers, and creators! Get the notifications you want, build custom JavaScript apps, and stay in the zoneβno distractions. Powered by ESP32-S3 with an AMOLED screen, fully open hardware and software.
- JavaScript Engine: Elk JavaScript runtime with comprehensive API bindings
- Graphics Library: LVGL integration with RM67162 AMOLED display support
- Storage Management: Robust SD card handling with multiple filesystem drivers
- Fallback System: Built-in notification app with scrolling text and GIF animation
- ESP32-S3 Platform: Full PSRAM support and optimized memory allocation
- RM67162 Display: 536x240 AMOLED with QSPI interface and brightness control
- Power Management: Smart power button handling on GPIO 33
- Storage Interface: SD_MMC card support with robust initialization
- WiFi Management: Connection handling with timeout and status monitoring
- Secure HTTPS: Certificate chain validation with SD card certificate storage
- MQTT Integration: Client support with publish/subscribe functionality
- BLE Support: Bluetooth Low Energy stack integration
- Modular Architecture: Separated concerns across hardware, network, and runtime modules
- Configuration System: JSON-based configuration with comprehensive validation
- Error Handling: Robust error reporting and recovery mechanisms
- Debug Support: Serial logging and development utilities
- Hardware: WebScreen PCB
- Storage: microSD card (formatted as FAT32)
- Cable: USB-C for serial communication and power
- Software (for compilation): Arduino IDE 2.0+
For users who don't want to set up Arduino IDE and compile from source:
-
Visit the Web Flasher Navigate to: https://flash.webscreen.cc/
-
Connect WebScreen Connect your WebScreen device via USB-C cable
-
Flash Firmware Select the latest firmware version and click "Flash"
-
Setup SD Card Create your
webscreen.json
configuration file and JavaScript app on SD card
This is the easiest way to get started with WebScreen without any development setup.
-
Install ESP32 Support
File β Preferences β Additional Board Manager URLs Add: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
-
Install ESP32 Boards
Tools β Board Manager β Search "ESP32" β Install v2.0.3+
-
Install Required Libraries
Library Manager β Install: - ArduinoJson (by Benoit Blanchon) - v6.x or later - LVGL (by kisvegabor) - v8.3.X - PubSubClient (by Nick O'Leary) - v2.8 or later
-
Configure LVGL Copy the provided
lv_conf.h
file to your Arduino libraries folder:cp WebScreen-Software/lv_conf.h ~/Arduino/libraries/
Key LVGL settings configured for WebScreen:
- Color depth: 16-bit (RGB565) with byte swap enabled
- Custom memory management using stdlib malloc/free
- Display refresh: 30ms for stability
- GIF support enabled
- Complex drawing features enabled (shadows, gradients, etc.)
- Montserrat 14pt font enabled
-
Open WebScreen Sketch
File β Open β WebScreen-Software/webscreen/webscreen.ino
-
Board Configuration
- Board: ESP32S3 Dev Module
- CPU Frequency: 240MHz
- Flash Size: 16MB (or your board's flash size)
- PSRAM: OPI PSRAM
- USB CDC On Boot: Enabled
- Upload Speed: 921600
For advanced users who want to modify the source code, you can compile directly from the Arduino IDE following the steps above.
- Power off device
- Hold BOOT button (behind RST button)
- Connect USB-C cable
- Hold BOOT, press RESET, release BOOT
- Upload firmware
- Press RESET to run
- Single Press: Toggle screen on/off
- Long Press: System functions (if implemented)
- Pin: GPIO 33 (INPUT_PULLUP)
WebScreen uses a JSON configuration system stored on the SD card as webscreen.json
. The configuration system supports both the current modular format and legacy formats for backward compatibility:
{
"wifi": {
"ssid": "your_wifi_network",
"password": "your_wifi_password",
"enabled": true,
"connection_timeout": 15000,
"auto_reconnect": true
},
"mqtt": {
"broker": "mqtt.example.com",
"port": 1883,
"username": "your_username",
"password": "your_password",
"client_id": "webscreen_001",
"enabled": false,
"keepalive": 60
},
"display": {
"brightness": 200,
"rotation": 1,
"background_color": "#2980b9",
"foreground_color": "#00fff1",
"auto_brightness": false,
"screen_timeout": 300000
},
"system": {
"device_name": "WebScreen-01",
"timezone": "UTC-8",
"log_level": 2,
"performance_mode": true,
"watchdog_timeout": 30000
},
"script_file": "/apps/weather_app.js",
"config_version": 2,
"last_modified": 1640995200
}
Section | Field | Description | Default |
---|---|---|---|
wifi | ssid |
WiFi network name | "" |
password |
WiFi password | "" |
|
enabled |
Enable WiFi connectivity | true |
|
connection_timeout |
Connection timeout (ms) | 15000 |
|
auto_reconnect |
Auto-reconnect on disconnect | true |
|
display | brightness |
Screen brightness (0-255) | 200 |
rotation |
Screen rotation (0-3) | 1 |
|
background_color |
Background color (hex) | "#000000" |
|
foreground_color |
Text color (hex) | "#FFFFFF" |
|
screen_timeout |
Auto-sleep timeout (ms, 0=never) | 0 |
|
system | log_level |
Logging level (0=debug, 4=fatal) | 2 |
performance_mode |
Enable performance optimizations | false |
|
watchdog_timeout |
Watchdog timeout (ms) | 30000 |
{
"wifi": {
"ssid": "MyNetwork",
"password": "MyPassword"
},
"script_file": "/app.js"
}
{
"display": {
"brightness": 255,
"auto_brightness": false
},
"system": {
"performance_mode": true,
"log_level": 3
}
}
{
"wifi": {
"enabled": false
},
"display": {
"brightness": 100,
"screen_timeout": 60000
},
"system": {
"performance_mode": false
}
}
WebScreen features a modular architecture with clear separation of concerns:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Application Layer β
β βββββββββββββββββββ βββββββββββββββββββ β
β β JavaScript β β Fallback β β
β β Runtime β β App β β
β βββββββββββββββββββ βββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Runtime Management β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β webscreen_runtime.cpp/.h ββ
β β β’ LVGL initialization and management ββ
β β β’ Elk JavaScript engine integration ββ
β β β’ Task management and execution ββ
β β β’ Memory filesystem drivers ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Core Application β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β webscreen_main.cpp/.h ββ
β β β’ Configuration loading and management ββ
β β β’ Application state management ββ
β β β’ Main setup and loop coordination ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Hardware Abstraction β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β webscreen_hardware.cpp/.h ββ
β β β’ SD card initialization with retry logic ββ
β β β’ Power button handling ββ
β β β’ Display management ββ
β β β’ Pin configuration and GPIO control ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Network Layer β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β webscreen_network.cpp/.h ββ
β β β’ WiFi connection with timeout handling ββ
β β β’ HTTPS client with certificate validation ββ
β β β’ MQTT client integration ββ
β β β’ BLE stack management ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. Open Arduino IDE
2. File β Open β webscreen/webscreen.ino
3. Select ESP32S3 Dev Module board
4. Configure board settings (see installation guide)
5. Click Upload button
WebScreen includes a custom lv_conf.h
file optimized for ESP32-S3 with AMOLED display:
Key Configuration Settings:
- Color Format: 16-bit RGB565 with byte swapping for SPI compatibility
- Memory Management: Custom malloc/free using ESP32 heap allocator
- Display Refresh: 30ms refresh rate for stable display output
- Graphics Features: Complex drawing enabled (gradients, shadows, anti-aliasing)
- File System: GIF animation support enabled
- Fonts: Montserrat 14pt as default UI font
Performance Optimizations:
- Image caching disabled to save RAM
- Gradient caching disabled to reduce memory usage
- Shadow caching disabled for predictable memory consumption
- DPI set to 130 for optimal widget sizing on AMOLED display
To enable debug mode, uncomment this line in webscreen/webscreen_config.h
:
#define WEBSCREEN_DEBUG 1
This enables verbose logging and memory debugging features.
Mode | Trigger | Description |
---|---|---|
JavaScript | Valid script_file found |
Full JavaScript runtime with all APIs |
Fallback | No script or WiFi failure | Built-in notification app with GIF animation |
Recovery | System errors detected | Minimal mode with error reporting |
Update | Special SD card structure | Firmware update mode |
[1234.567] INFO: [Main] WebScreen v2.0 initializing...
[1234.678] INFO: [Memory] PSRAM: 8388608 bytes available
[1234.789] INFO: [Display] RM67162 initialized (536x240)
[1234.890] INFO: [WiFi] Connected to MyNetwork (192.168.1.100)
[1234.991] INFO: [JavaScript] Loaded /apps/weather.js (2.4KB)
// Memory usage report
memory_print_report();
// Display statistics
display_print_status();
// System health check
webscreen_error_print_report();
// Network status
wifi_manager_print_status();
// Enable performance profiling
display_set_performance_monitoring(true);
// Monitor frame rate and memory usage
display_stats_t stats;
display_get_stats(&stats);
Serial.printf("FPS: %d, Memory: %d KB\n", stats.last_fps, stats.memory_used/1024);
The firmware exposes numerous functions to your JavaScript applications. Some highlights include:
- Basic:
print()
,delay()
- WiβFi:
wifi_connect()
,wifi_status()
,wifi_get_ip()
- HTTP:
http_get()
,http_post()
,http_delete()
,http_set_ca_cert_from_sd()
,parse_json_value()
- SD Card:
sd_read_file()
,sd_write_file()
,sd_list_dir()
,sd_delete_file()
- BLE:
ble_init()
,ble_is_connected()
,ble_write()
- UI Drawing:
draw_label()
,draw_rect()
,show_image()
,create_label()
,label_set_text()
- Image Handling:
create_image()
,create_image_from_ram()
,rotate_obj()
,move_obj()
,animate_obj()
- Styles & Layout:
create_style()
,obj_add_style()
,style_set_*()
,obj_align()
- Advanced Widgets: Meter, Message Box, Span, Window, TileView, Line
- MQTT:
mqtt_init()
,mqtt_connect()
,mqtt_publish()
,mqtt_subscribe()
,mqtt_loop()
,mqtt_on_message()
For a full list and examples of usage, see the JavaScript API Reference.
To call secure APIs (e.g., using http_get()
), load a full chain certificate stored on the SD card using:
http_set_ca_cert_from_sd("/timeapi.pem");
- Obtain Certificates:
Collect your server certificate and the intermediate certificate(s). Optionally, include the root certificate. - Concatenate Certificates:
Use a text editor or command-line tool:Ensure each certificate block starts withcat server.crt intermediate.crt root.crt > fullchain.pem
-----BEGIN CERTIFICATE-----
and ends with-----END CERTIFICATE-----
. - Deploy:
Copy the resultingfullchain.pem
file to the SD card. - Usage:
Your JavaScript app should load it withhttp_set_ca_cert_from_sd()
to enable secure HTTPS requests.
WebScreen is designed to be contributor-friendly with comprehensive documentation and testing frameworks.
- Read the Docs: Check out docs/CONTRIBUTING.md for detailed guidelines
- Set Up Environment: Follow the development setup instructions
- Pick an Issue: Look for "good first issue" labels on GitHub
- Submit PR: Follow our contribution workflow
- Performance: Memory optimization, rendering improvements
- Hardware Support: New display drivers, sensor integration
- Network: Protocol implementations, connectivity features
- Documentation: API docs, tutorials, examples
- Testing: Unit tests, integration tests, hardware testing
Type | Resource | Description |
---|---|---|
π Bug Reports | GitHub Issues | Report bugs and request features |
π¬ Discussions | GitHub Discussions | Ask questions and share ideas |
π Documentation | docs/ | API reference and guides |
π Website | WebScreen.cc | Official project website |
π Hardware | CrowdSupply | Purchase WebScreen hardware |
If WebScreen has been useful for your projects:
- β Star the repo to show your support
- π΄ Fork and contribute to make it better
- π Report issues to help us improve
- π Improve documentation for other users
- π° Sponsor development to fund new features
This project is open source. See the LICENSE file for details.