{"id":44090742,"url":"https://github.com/HW-Lab-Hardware-Design-Agency/WebScreen-Software","last_synced_at":"2026-02-20T09:00:36.000Z","repository":{"id":260832189,"uuid":"799517411","full_name":"HW-Lab-Hardware-Design-Agency/WebScreen-Software","owner":"HW-Lab-Hardware-Design-Agency","description":"WebScreen Firmware","archived":false,"fork":false,"pushed_at":"2026-01-28T22:16:01.000Z","size":168770,"stargazers_count":35,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-29T13:26:33.300Z","etag":null,"topics":["arduino","crowdsupply","elk","esp32","lvgl","lvgl-esp32","lvgl9","mqtt","openhardware","opensource","oshwa","webscreen"],"latest_commit_sha":null,"homepage":"https://webscreen.cc/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HW-Lab-Hardware-Design-Agency.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-05-12T11:46:09.000Z","updated_at":"2026-01-28T22:13:36.000Z","dependencies_parsed_at":"2024-12-24T05:21:13.268Z","dependency_job_id":"ef017159-1ab4-4989-8940-7cc4b9b574c7","html_url":"https://github.com/HW-Lab-Hardware-Design-Agency/WebScreen-Software","commit_stats":null,"previous_names":["hw-lab-hardware-design-agency/webscreen-software"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/HW-Lab-Hardware-Design-Agency/WebScreen-Software","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HW-Lab-Hardware-Design-Agency%2FWebScreen-Software","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HW-Lab-Hardware-Design-Agency%2FWebScreen-Software/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HW-Lab-Hardware-Design-Agency%2FWebScreen-Software/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HW-Lab-Hardware-Design-Agency%2FWebScreen-Software/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HW-Lab-Hardware-Design-Agency","download_url":"https://codeload.github.com/HW-Lab-Hardware-Design-Agency/WebScreen-Software/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HW-Lab-Hardware-Design-Agency%2FWebScreen-Software/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29646517,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T08:48:14.886Z","status":"ssl_error","status_checked_at":"2026-02-20T08:45:26.777Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","crowdsupply","elk","esp32","lvgl","lvgl-esp32","lvgl9","mqtt","openhardware","opensource","oshwa","webscreen"],"created_at":"2026-02-08T11:00:29.809Z","updated_at":"2026-02-20T09:00:35.994Z","avatar_url":"https://github.com/HW-Lab-Hardware-Design-Agency.png","language":"C","funding_links":[],"categories":["📚 Resources"],"sub_categories":["WebScreen Serial IDE"],"readme":"[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) ![Issues](https://img.shields.io/github/issues/HW-Lab-Hardware-Design-Agency/WebScreen-Software) [![image](https://img.shields.io/badge/website-WebScreen.cc-D31027)](https://webscreen.cc) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/HW-Lab-Hardware-Design-Agency/WebScreen-Software) [![image](https://img.shields.io/badge/view_on-CrowdSupply-099)](https://www.crowdsupply.com/hw-media-lab/webscreen)\n\n# WebScreen Software\n\n![til](./docs/WebScreen_Notification.gif)\n\nWebScreen 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.\n\n## Core Features\n\n### Runtime Environment\n- **JavaScript Engine**: Elk JavaScript runtime with comprehensive API bindings\n- **Graphics Library**: LVGL integration with RM67162 AMOLED display support\n- **Storage Management**: Robust SD card handling with multiple filesystem drivers\n- **Fallback System**: Built-in notification app with scrolling text and GIF animation\n\n### Hardware Integration\n- **ESP32-S3 Platform**: Full PSRAM support and optimized memory allocation\n- **RM67162 Display**: 536x240 AMOLED with QSPI interface and brightness control\n- **Power Management**: Smart power button handling on GPIO 33\n- **Storage Interface**: SD_MMC card support with robust initialization\n\n### Networking \u0026 Connectivity  \n- **WiFi Management**: Connection handling with timeout and status monitoring\n- **Secure HTTPS**: Certificate chain validation with SD card certificate storage\n- **MQTT Integration**: Client support with publish/subscribe functionality\n- **BLE Support**: Bluetooth Low Energy stack integration\n\n### Development Features\n- **Modular Architecture**: Separated concerns across hardware, network, and runtime modules\n- **Serial Commands**: Interactive development console with comprehensive command system\n- **Configuration System**: JSON-based configuration with comprehensive validation\n- **Error Handling**: Robust error reporting and recovery mechanisms\n- **Debug Support**: Serial logging and development utilities\n\n## Quick Start\n\n### Prerequisites\n\n- **Hardware**: WebScreen PCB\n- **Storage**: microSD card (formatted as FAT32)\n- **Cable**: USB-C for serial communication and power\n- **Software** (for compilation): Arduino IDE 2.0+\n\n### Installation\n\n#### Option 1: Web Flasher (Recommended for beginners)\n\nFor users who don't want to set up Arduino IDE and compile from source:\n\n1. **Visit the Web Flasher**\n   Navigate to: https://flash.webscreen.cc/\n\n2. **Connect WebScreen**\n   Connect your WebScreen device via USB-C cable\n\n3. **Flash Firmware**\n   Select the latest firmware version and click \"Flash\"\n\n4. **Setup SD Card**\n   Create your `webscreen.json` configuration file and JavaScript app on SD card\n\nThis is the easiest way to get started with WebScreen without any development setup.\n\n#### Option 2: Arduino IDE (For developers)\n\n1. **Install ESP32 Support**\n   ```\n   File → Preferences → Additional Board Manager URLs\n   Add: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json\n   ```\n\n2. **Install ESP32 Boards**\n   ```\n   Tools → Board Manager → Search \"ESP32\" → Install v2.0.3+\n   ```\n\n3. **Install Required Libraries**\n   ```\n   Library Manager → Install:\n   - ArduinoJson (by Benoit Blanchon) - v6.x or later\n   - LVGL (by kisvegabor) - v8.3.X\n   - PubSubClient (by Nick O'Leary) - v2.8 or later\n   ```\n\n4. **Configure LVGL**\n   Copy the provided `lv_conf.h` file to your Arduino libraries folder:\n   ```\n   cp WebScreen-Software/lv_conf.h ~/Arduino/libraries/\n   ```\n\n   Key LVGL settings configured for WebScreen:\n   - Color depth: 16-bit (RGB565) with byte swap enabled\n   - Custom memory management using stdlib malloc/free\n   - Display refresh: 30ms for stability\n   - **Enabled fonts**: Montserrat 14, 20, 28, 34, 40, 44, 48\n   - **Image formats**: PNG, GIF, SJPG (BMP disabled)\n   - **Widgets**: Label, Image, Arc, Line, Button, Chart, Meter, Span\n   - **Layouts**: Flexbox and Grid enabled\n   - Complex drawing features enabled (shadows, gradients, etc.)\n\n5. **Open WebScreen Sketch**\n   ```\n   File → Open → WebScreen-Software/webscreen/webscreen.ino\n   ```\n\n6. **Board Configuration**\n   - **Board**: ESP32S3 Dev Module  \n   - **CPU Frequency**: 240MHz\n   - **Flash Size**: 16MB (or your board's flash size)\n   - **PSRAM**: OPI PSRAM  \n   - **USB CDC On Boot**: Enabled\n   - **Upload Speed**: 921600\n\n   ![Board Settings](docs/arduino_tools_settings.png)\n\n#### Option 3: Direct Compilation\n\nFor advanced users who want to modify the source code, you can compile directly from the Arduino IDE following the steps above.\n\n### Hardware Setup\n\n#### Upload Mode (if USB not detected)\n1. Power off device\n2. Hold **BOOT** button (behind RST button)  \n3. Connect USB-C cable\n4. Hold **BOOT**, press **RESET**, release **BOOT**\n5. Upload firmware\n6. Press **RESET** to run\n\n#### Power Button\n- **Single Press**: Toggle screen on/off\n- **Long Press**: System functions (if implemented)\n- **Pin**: GPIO 33 (INPUT_PULLUP)\n\n## Configuration\n\nWebScreen 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.\n\n### Configuration Format\n\n**IMPORTANT:** The current firmware uses the following format with nested \"settings\" structure:\n\n```json\n{\n  \"settings\": {\n    \"wifi\": {\n      \"ssid\": \"your_wifi_network\",\n      \"pass\": \"your_wifi_password\"\n    },\n    \"mqtt\": {\n      \"enabled\": false\n    }\n  },\n  \"screen\": {\n    \"background\": \"#2980b9\",\n    \"foreground\": \"#00fff1\"\n  },\n  \"display\": {\n    \"brightness\": 200\n  },\n  \"script\": \"app.js\"\n}\n```\n\n### Configuration Fields\n\n| Section | Field | Description | Default |\n|---------|-------|-------------|---------|\n| **settings.wifi** | `ssid` | WiFi network name | `\"\"` |\n| | `pass` | WiFi password | `\"\"` |\n| **settings.mqtt** | `enabled` | Enable MQTT functionality | `false` |\n| **screen** | `background` | Background color (hex format) | `\"#000000\"` |\n| | `foreground` | Text/foreground color (hex) | `\"#FFFFFF\"` |\n| **display** | `brightness` | Display brightness (0-255) | `200` |\n| **Root** | `script` | JavaScript file to execute | `\"app.js\"` |\n\n### Example Configurations\n\n#### Basic WiFi Setup\n```json\n{\n  \"settings\": {\n    \"wifi\": {\n      \"ssid\": \"MyNetwork\",\n      \"pass\": \"MyPassword\"\n    }\n  },\n  \"script\": \"app.js\"\n}\n```\n\n#### Custom Colors\n```json\n{\n  \"settings\": {\n    \"wifi\": {\n      \"ssid\": \"MyNetwork\",\n      \"pass\": \"MyPassword\"\n    }\n  },\n  \"screen\": {\n    \"background\": \"#1a1a2e\",\n    \"foreground\": \"#eee\"\n  },\n  \"script\": \"weather.js\"\n}\n```\n\n#### With MQTT Enabled\n```json\n{\n  \"settings\": {\n    \"wifi\": {\n      \"ssid\": \"MyNetwork\",\n      \"pass\": \"MyPassword\"\n    },\n    \"mqtt\": {\n      \"enabled\": true\n    }\n  },\n  \"script\": \"mqtt_dashboard.js\"\n}\n```\n\n#### Minimal Configuration (WiFi Only)\n```json\n{\n  \"settings\": {\n    \"wifi\": {\n      \"ssid\": \"MyNetwork\",\n      \"pass\": \"MyPassword\"\n    }\n  }\n}\n```\n\n**Note:** WebScreen will start in fallback mode (displaying the notification screen) if:\n- No `/webscreen.json` configuration file is found on the SD card\n- The JavaScript file specified in the `script` field doesn't exist on the SD card\n- The SD card cannot be mounted\n\n**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.\n\n## Architecture \u0026 Building\n\n### System Architecture\n\nWebScreen features a modular architecture with clear separation of concerns:\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                    Application Layer                        │\n│  ┌─────────────────┐    ┌─────────────────┐                │\n│  │  JavaScript     │    │   Fallback      │                │\n│  │   Runtime       │    │     App         │                │\n│  └─────────────────┘    └─────────────────┘                │\n├─────────────────────────────────────────────────────────────┤\n│                      Runtime Management                    │\n│  ┌─────────────────────────────────────────────────────────┐│\n│  │           webscreen_runtime.cpp/.h                     ││\n│  │  • LVGL initialization and management                   ││\n│  │  • Elk JavaScript engine integration                   ││\n│  │  • Task management and execution                       ││\n│  │  • Memory filesystem drivers                           ││\n│  └─────────────────────────────────────────────────────────┘│\n├─────────────────────────────────────────────────────────────┤\n│                    Core Application                        │\n│  ┌─────────────────────────────────────────────────────────┐│\n│  │             webscreen_main.cpp/.h                      ││\n│  │  • Configuration loading and management                ││\n│  │  • Application state management                        ││\n│  │  • Main setup and loop coordination                    ││\n│  └─────────────────────────────────────────────────────────┘│\n├─────────────────────────────────────────────────────────────┤\n│                  Hardware Abstraction                      │\n│  ┌─────────────────────────────────────────────────────────┐│\n│  │           webscreen_hardware.cpp/.h                    ││\n│  │  • SD card initialization with retry logic             ││\n│  │  • Power button handling                               ││\n│  │  • Display management                                  ││\n│  │  • Pin configuration and GPIO control                  ││\n│  └─────────────────────────────────────────────────────────┘│\n├─────────────────────────────────────────────────────────────┤\n│                     Network Layer                          │\n│  ┌─────────────────────────────────────────────────────────┐│\n│  │            webscreen_network.cpp/.h                    ││\n│  │  • WiFi connection with timeout handling               ││\n│  │  • HTTPS client with certificate validation            ││\n│  │  • MQTT client integration                             ││\n│  │  • BLE stack management                                ││\n│  └─────────────────────────────────────────────────────────┘│\n└─────────────────────────────────────────────────────────────┘\n```\n\n### Build Process\n\n#### Arduino IDE Build\n```\n1. Open Arduino IDE\n2. File → Open → webscreen/webscreen.ino  \n3. Select ESP32S3 Dev Module board\n4. Configure board settings (see installation guide)\n5. Click Upload button\n```\n\n#### LVGL Configuration\nWebScreen includes a custom `lv_conf.h` file optimized for ESP32-S3 with AMOLED display:\n\n**Display Settings:**\n- **Color Format**: 16-bit RGB565 with byte swapping for SPI compatibility\n- **Resolution**: 536x240 pixels\n- **DPI**: 130 for optimal widget sizing\n- **Refresh Rate**: 30ms for stable display output\n\n**Available Fonts (Montserrat):**\n| Size | Usage |\n|------|-------|\n| 14 | Default, small text |\n| 20 | Body text |\n| 28 | Subheadings |\n| 34 | Medium headings |\n| 40 | Large headings |\n| 44 | Extra large |\n| 48 | Display text |\n\n**Note:** Other font sizes (8, 10, 12, 16, 18, 22, 24, etc.) are NOT available.\n\n**Enabled Widgets:**\n- **Core**: Label, Image, Arc, Line, Button, Button Matrix, Canvas\n- **Extra**: Chart, Meter, Message Box, Span (rich text)\n- **Layouts**: Flexbox and Grid\n\n**Supported Image Formats:**\n- PNG ✅, GIF ✅, SJPG ✅, BMP ❌\n\n**Performance Optimizations:**\n- Image caching disabled to save RAM\n- Gradient caching disabled to reduce memory usage\n- Shadow caching disabled for predictable memory consumption\n- Memory management uses ESP32 heap allocator\n\n#### Debug Build\nTo enable debug mode, uncomment this line in `webscreen/webscreen_config.h`:\n```cpp\n#define WEBSCREEN_DEBUG 1\n```\nThis enables verbose logging and memory debugging features.\n\n### Runtime Modes\n\n| Mode | Trigger | Description |\n|------|---------|-------------|\n| **JavaScript** | Valid `script_file` found | Full JavaScript runtime with all APIs |\n| **Fallback** | No script or WiFi failure | Built-in notification app with GIF animation |\n| **Recovery** | System errors detected | Minimal mode with error reporting |\n| **Update** | Special SD card structure | Firmware update mode |\n\n### Development \u0026 Debugging\n\n#### Serial Monitor Output\n```\n[1234.567] INFO: [Main] WebScreen v2.0 initializing...\n[1234.678] INFO: [Memory] PSRAM: 8388608 bytes available\n[1234.789] INFO: [Display] RM67162 initialized (536x240)\n[1234.890] INFO: [WiFi] Connected to MyNetwork (192.168.1.100)\n[1234.991] INFO: [JavaScript] Loaded /apps/weather.js (2.4KB)\n```\n\n#### Serial Commands\n\nWebScreen includes a comprehensive serial command system for interactive development. Commands work in both fallback and dynamic JavaScript modes:\n\n**Core Commands:**\n```\n/help                    - Show all available commands\n/stats                   - Display system statistics (memory, storage, WiFi)\n/info                    - Show device information and version\n/write \u003cfilename\u003e        - Interactive JavaScript editor\n/load \u003cscript.js\u003e        - Switch to different JS application\n/brightness \u003c0-255\u003e      - Set display brightness (no args to query current)\n/reboot                  - Restart the device\n```\n\n**Network \u0026 Monitoring:**\n```\n/wget \u003curl\u003e [file]       - Download file from URL to SD card\n/ping \u003chost\u003e             - Test network connectivity\n/monitor [cpu|mem|net]   - Live system monitoring (press any key to stop)\n```\n\n**Configuration Management:**\n```\n/config get \u003ckey\u003e        - Get configuration value\n/config set \u003ckey\u003e \u003cval\u003e  - Set configuration value\n/backup [save|restore]   - Backup or restore configuration\n```\n\n**File Operations:**\n```\n/ls [path]               - List files/directories\n/cat \u003cfile\u003e              - Display file contents\n/rm \u003cfile\u003e               - Delete file\n```\n\n**Example Development Workflow:**\n```\nWebScreen\u003e /write hello.js\nEnter JavaScript code. End with a line containing only 'END':\n---\n+ create_label_with_text('Hello WebScreen!');\n+ END\n[OK] Script saved: /hello.js (45 bytes)\n\nWebScreen\u003e /load hello.js\n[OK] Script queued for loading: /hello.js\n[OK] Restarting to load new script...\n```\n\nFor detailed command reference, see [docs/SerialCommands.md](docs/SerialCommands.md).\n\n#### Debug Commands\n```cpp\n// Memory usage report\nmemory_print_report();\n\n// Display statistics  \ndisplay_print_status();\n\n// System health check\nwebscreen_error_print_report();\n\n// Network status\nwifi_manager_print_status();\n```\n\n#### Performance Monitoring\n```cpp\n// Enable performance profiling\ndisplay_set_performance_monitoring(true);\n\n// Monitor frame rate and memory usage\ndisplay_stats_t stats;\ndisplay_get_stats(\u0026stats);\nSerial.printf(\"FPS: %d, Memory: %d KB\\n\", stats.last_fps, stats.memory_used/1024);\n```\n\n## JavaScript API\n\nThe firmware exposes numerous functions to your JavaScript applications. Some highlights include:\n- **Basic:** `print()`, `delay()`\n- **Wi‑Fi:** `wifi_connect()`, `wifi_status()`, `wifi_get_ip()`\n- **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()`\n- **SD Card:** `sd_read_file()`, `sd_write_file()`, `sd_list_dir()`, `sd_delete_file()`\n- **BLE:** `ble_init()`, `ble_is_connected()`, `ble_write()`\n- **Display:** `set_brightness()`, `get_brightness()`\n- **UI Drawing:** `draw_label()`, `draw_rect()`, `show_image()`, `create_label()`, `label_set_text()`\n- **Image Handling:** `create_image()`, `create_image_from_ram()`, `rotate_obj()`, `move_obj()`, `animate_obj()`\n- **Styles \u0026 Layout:** `create_style()`, `obj_add_style()`, `style_set_*()`, `obj_align()`\n- **Advanced Widgets:** Meter, Message Box, Span, Window, TileView, Line\n- **MQTT:** `mqtt_init()`, `mqtt_connect()`, `mqtt_publish()`, `mqtt_subscribe()`, `mqtt_loop()`, `mqtt_on_message()`\n\nFor a full list and examples of usage, see the [JavaScript API Reference](docs/API.md).\n\n## Secure HTTPS Connections\n\nTo call secure APIs (e.g., using `http_get()`), load a full chain certificate stored on the SD card using:\n```js\nhttp_set_ca_cert_from_sd(\"/timeapi.pem\");\n```\n### Creating a Full Chain Certificate\n1. **Obtain Certificates:**  \n   Collect your server certificate and the intermediate certificate(s). Optionally, include the root certificate.\n2. **Concatenate Certificates:**  \n   Use a text editor or command-line tool:\n   ```bash\n   cat server.crt intermediate.crt root.crt \u003e fullchain.pem\n   ```\n   Ensure each certificate block starts with `-----BEGIN CERTIFICATE-----` and ends with `-----END CERTIFICATE-----`.\n3. **Deploy:**  \n   Copy the resulting `fullchain.pem` file to the SD card.\n4. **Usage:**  \n   Your JavaScript app should load it with `http_set_ca_cert_from_sd()` to enable secure HTTPS requests.\n\n## Contributing \u0026 Support\n\n### For Developers\n\nWebScreen is designed to be contributor-friendly with comprehensive documentation and testing frameworks.\n\n#### Getting Started\n1. **Read the Docs**: Check out [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) for detailed guidelines\n2. **Set Up Environment**: Follow the development setup instructions\n3. **Pick an Issue**: Look for \"good first issue\" labels on GitHub\n4. **Submit PR**: Follow our contribution workflow\n\n#### Key Areas for Contribution\n- **Performance**: Memory optimization, rendering improvements\n- **Hardware Support**: New display drivers, sensor integration  \n- **Network**: Protocol implementations, connectivity features\n- **Documentation**: API docs, tutorials, examples\n- **Testing**: Unit tests, integration tests, hardware testing\n\n### Getting Help\n\n| Type | Resource | Description |\n|------|----------|-------------|\n| 🐛 **Bug Reports** | [GitHub Issues](https://github.com/HW-Lab-Hardware-Design-Agency/WebScreen-Software/issues) | Report bugs and request features |\n| 💬 **Discussions** | [GitHub Discussions](https://github.com/HW-Lab-Hardware-Design-Agency/WebScreen-Software/discussions) | Ask questions and share ideas |\n| 📖 **Documentation** | [docs/](docs/) | API reference and guides |\n| 🌐 **Website** | [WebScreen.cc](https://webscreen.cc) | Official project website |\n| 🛒 **Hardware** | [CrowdSupply](https://www.crowdsupply.com/hw-media-lab/webscreen) | Purchase WebScreen hardware |\n\n### Support the Project\n\nIf WebScreen has been useful for your projects:\n\n- ⭐ **Star the repo** to show your support\n- 🍴 **Fork and contribute** to make it better  \n- 🐛 **Report issues** to help us improve\n- 📖 **Improve documentation** for other users\n- 💰 **Sponsor development** to fund new features\n\n## License\n\nThis project is open source. See the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHW-Lab-Hardware-Design-Agency%2FWebScreen-Software","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FHW-Lab-Hardware-Design-Agency%2FWebScreen-Software","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHW-Lab-Hardware-Design-Agency%2FWebScreen-Software/lists"}