https://github.com/HW-Lab-Hardware-Design-Agency/WebScreen-Software
WebScreen Firmware
https://github.com/HW-Lab-Hardware-Design-Agency/WebScreen-Software
arduino crowdsupply elk esp32 lvgl lvgl-esp32 lvgl9 mqtt openhardware opensource oshwa webscreen
Last synced: 4 months ago
JSON representation
WebScreen Firmware
- Host: GitHub
- URL: https://github.com/HW-Lab-Hardware-Design-Agency/WebScreen-Software
- Owner: HW-Lab-Hardware-Design-Agency
- License: mit
- Created: 2024-05-12T11:46:09.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2026-01-28T22:16:01.000Z (5 months ago)
- Last Synced: 2026-01-29T13:26:33.300Z (5 months ago)
- Topics: arduino, crowdsupply, elk, esp32, lvgl, lvgl-esp32, lvgl9, mqtt, openhardware, opensource, oshwa, webscreen
- Language: C
- Homepage: https://webscreen.cc/
- Size: 161 MB
- Stars: 35
- Watchers: 1
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: docs/CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://opensource.org/licenses/MIT)  [](https://webscreen.cc) [](https://deepwiki.com/HW-Lab-Hardware-Design-Agency/WebScreen-Software) [](https://www.crowdsupply.com/hw-media-lab/webscreen)
# WebScreen Software

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.
## Core Features
### Runtime Environment
- **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
### Hardware Integration
- **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
### Networking & Connectivity
- **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
### Development Features
- **Modular Architecture**: Separated concerns across hardware, network, and runtime modules
- **Serial Commands**: Interactive development console with comprehensive command system
- **Configuration System**: JSON-based configuration with comprehensive validation
- **Error Handling**: Robust error reporting and recovery mechanisms
- **Debug Support**: Serial logging and development utilities
## Quick Start
### Prerequisites
- **Hardware**: WebScreen PCB
- **Storage**: microSD card (formatted as FAT32)
- **Cable**: USB-C for serial communication and power
- **Software** (for compilation): Arduino IDE 2.0+
### Installation
#### Option 1: Web Flasher (Recommended for beginners)
For users who don't want to set up Arduino IDE and compile from source:
1. **Visit the Web Flasher**
Navigate to: https://flash.webscreen.cc/
2. **Connect WebScreen**
Connect your WebScreen device via USB-C cable
3. **Flash Firmware**
Select the latest firmware version and click "Flash"
4. **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.
#### Option 2: Arduino IDE (For developers)
1. **Install ESP32 Support**
```
File → Preferences → Additional Board Manager URLs
Add: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
```
2. **Install ESP32 Boards**
```
Tools → Board Manager → Search "ESP32" → Install v2.0.3+
```
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
```
4. **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
- **Enabled fonts**: Montserrat 14, 20, 28, 34, 40, 44, 48
- **Image formats**: PNG, GIF, SJPG (BMP disabled)
- **Widgets**: Label, Image, Arc, Line, Button, Chart, Meter, Span
- **Layouts**: Flexbox and Grid enabled
- Complex drawing features enabled (shadows, gradients, etc.)
5. **Open WebScreen Sketch**
```
File → Open → WebScreen-Software/webscreen/webscreen.ino
```
6. **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

#### Option 3: Direct Compilation
For advanced users who want to modify the source code, you can compile directly from the Arduino IDE following the steps above.
### Hardware Setup
#### Upload Mode (if USB not detected)
1. Power off device
2. Hold **BOOT** button (behind RST button)
3. Connect USB-C cable
4. Hold **BOOT**, press **RESET**, release **BOOT**
5. Upload firmware
6. Press **RESET** to run
#### Power Button
- **Single Press**: Toggle screen on/off
- **Long Press**: System functions (if implemented)
- **Pin**: GPIO 33 (INPUT_PULLUP)
## Configuration
WebScreen uses a JSON configuration file stored on the SD card as `/webscreen.json`. This file controls WiFi settings, display colors, MQTT configuration, and which JavaScript app to run.
### Configuration Format
**IMPORTANT:** The current firmware uses the following format with nested "settings" structure:
```json
{
"settings": {
"wifi": {
"ssid": "your_wifi_network",
"pass": "your_wifi_password"
},
"mqtt": {
"enabled": false
}
},
"screen": {
"background": "#2980b9",
"foreground": "#00fff1"
},
"display": {
"brightness": 200
},
"script": "app.js"
}
```
### Configuration Fields
| Section | Field | Description | Default |
|---------|-------|-------------|---------|
| **settings.wifi** | `ssid` | WiFi network name | `""` |
| | `pass` | WiFi password | `""` |
| **settings.mqtt** | `enabled` | Enable MQTT functionality | `false` |
| **screen** | `background` | Background color (hex format) | `"#000000"` |
| | `foreground` | Text/foreground color (hex) | `"#FFFFFF"` |
| **display** | `brightness` | Display brightness (0-255) | `200` |
| **Root** | `script` | JavaScript file to execute | `"app.js"` |
### Example Configurations
#### Basic WiFi Setup
```json
{
"settings": {
"wifi": {
"ssid": "MyNetwork",
"pass": "MyPassword"
}
},
"script": "app.js"
}
```
#### Custom Colors
```json
{
"settings": {
"wifi": {
"ssid": "MyNetwork",
"pass": "MyPassword"
}
},
"screen": {
"background": "#1a1a2e",
"foreground": "#eee"
},
"script": "weather.js"
}
```
#### With MQTT Enabled
```json
{
"settings": {
"wifi": {
"ssid": "MyNetwork",
"pass": "MyPassword"
},
"mqtt": {
"enabled": true
}
},
"script": "mqtt_dashboard.js"
}
```
#### Minimal Configuration (WiFi Only)
```json
{
"settings": {
"wifi": {
"ssid": "MyNetwork",
"pass": "MyPassword"
}
}
}
```
**Note:** WebScreen will start in fallback mode (displaying the notification screen) if:
- No `/webscreen.json` configuration file is found on the SD card
- The JavaScript file specified in the `script` field doesn't exist on the SD card
- The SD card cannot be mounted
**Important:** If WiFi configuration is missing or WiFi connection fails, WebScreen will still execute the JavaScript application (if the script file exists). This allows offline applications to run without network connectivity.
## Architecture & Building
### System Architecture
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 ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
```
### Build Process
#### Arduino IDE Build
```
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
```
#### LVGL Configuration
WebScreen includes a custom `lv_conf.h` file optimized for ESP32-S3 with AMOLED display:
**Display Settings:**
- **Color Format**: 16-bit RGB565 with byte swapping for SPI compatibility
- **Resolution**: 536x240 pixels
- **DPI**: 130 for optimal widget sizing
- **Refresh Rate**: 30ms for stable display output
**Available Fonts (Montserrat):**
| Size | Usage |
|------|-------|
| 14 | Default, small text |
| 20 | Body text |
| 28 | Subheadings |
| 34 | Medium headings |
| 40 | Large headings |
| 44 | Extra large |
| 48 | Display text |
**Note:** Other font sizes (8, 10, 12, 16, 18, 22, 24, etc.) are NOT available.
**Enabled Widgets:**
- **Core**: Label, Image, Arc, Line, Button, Button Matrix, Canvas
- **Extra**: Chart, Meter, Message Box, Span (rich text)
- **Layouts**: Flexbox and Grid
**Supported Image Formats:**
- PNG ✅, GIF ✅, SJPG ✅, BMP ❌
**Performance Optimizations:**
- Image caching disabled to save RAM
- Gradient caching disabled to reduce memory usage
- Shadow caching disabled for predictable memory consumption
- Memory management uses ESP32 heap allocator
#### Debug Build
To enable debug mode, uncomment this line in `webscreen/webscreen_config.h`:
```cpp
#define WEBSCREEN_DEBUG 1
```
This enables verbose logging and memory debugging features.
### Runtime Modes
| 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 |
### Development & Debugging
#### Serial Monitor Output
```
[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)
```
#### Serial Commands
WebScreen includes a comprehensive serial command system for interactive development. Commands work in both fallback and dynamic JavaScript modes:
**Core Commands:**
```
/help - Show all available commands
/stats - Display system statistics (memory, storage, WiFi)
/info - Show device information and version
/write - Interactive JavaScript editor
/load - Switch to different JS application
/brightness <0-255> - Set display brightness (no args to query current)
/reboot - Restart the device
```
**Network & Monitoring:**
```
/wget [file] - Download file from URL to SD card
/ping - Test network connectivity
/monitor [cpu|mem|net] - Live system monitoring (press any key to stop)
```
**Configuration Management:**
```
/config get - Get configuration value
/config set - Set configuration value
/backup [save|restore] - Backup or restore configuration
```
**File Operations:**
```
/ls [path] - List files/directories
/cat - Display file contents
/rm - Delete file
```
**Example Development Workflow:**
```
WebScreen> /write hello.js
Enter JavaScript code. End with a line containing only 'END':
---
+ create_label_with_text('Hello WebScreen!');
+ END
[OK] Script saved: /hello.js (45 bytes)
WebScreen> /load hello.js
[OK] Script queued for loading: /hello.js
[OK] Restarting to load new script...
```
For detailed command reference, see [docs/SerialCommands.md](docs/SerialCommands.md).
#### Debug Commands
```cpp
// Memory usage report
memory_print_report();
// Display statistics
display_print_status();
// System health check
webscreen_error_print_report();
// Network status
wifi_manager_print_status();
```
#### Performance Monitoring
```cpp
// 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);
```
## JavaScript API
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()` (all support custom ports like `http://host:port/path`), `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()`
- **Display:** `set_brightness()`, `get_brightness()`
- **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](docs/API.md).
## Secure HTTPS Connections
To call secure APIs (e.g., using `http_get()`), load a full chain certificate stored on the SD card using:
```js
http_set_ca_cert_from_sd("/timeapi.pem");
```
### Creating a Full Chain Certificate
1. **Obtain Certificates:**
Collect your server certificate and the intermediate certificate(s). Optionally, include the root certificate.
2. **Concatenate Certificates:**
Use a text editor or command-line tool:
```bash
cat server.crt intermediate.crt root.crt > fullchain.pem
```
Ensure each certificate block starts with `-----BEGIN CERTIFICATE-----` and ends with `-----END CERTIFICATE-----`.
3. **Deploy:**
Copy the resulting `fullchain.pem` file to the SD card.
4. **Usage:**
Your JavaScript app should load it with `http_set_ca_cert_from_sd()` to enable secure HTTPS requests.
## Contributing & Support
### For Developers
WebScreen is designed to be contributor-friendly with comprehensive documentation and testing frameworks.
#### Getting Started
1. **Read the Docs**: Check out [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) for detailed guidelines
2. **Set Up Environment**: Follow the development setup instructions
3. **Pick an Issue**: Look for "good first issue" labels on GitHub
4. **Submit PR**: Follow our contribution workflow
#### Key Areas for Contribution
- **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
### Getting Help
| Type | Resource | Description |
|------|----------|-------------|
| 🐛 **Bug Reports** | [GitHub Issues](https://github.com/HW-Lab-Hardware-Design-Agency/WebScreen-Software/issues) | Report bugs and request features |
| 💬 **Discussions** | [GitHub Discussions](https://github.com/HW-Lab-Hardware-Design-Agency/WebScreen-Software/discussions) | Ask questions and share ideas |
| 📖 **Documentation** | [docs/](docs/) | API reference and guides |
| 🌐 **Website** | [WebScreen.cc](https://webscreen.cc) | Official project website |
| 🛒 **Hardware** | [CrowdSupply](https://www.crowdsupply.com/hw-media-lab/webscreen) | Purchase WebScreen hardware |
### Support the Project
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
## License
This project is open source. See the [LICENSE](LICENSE) file for details.