A modern, browser-based serial terminal for UART communication with microcontrollers, embedded devices, and IoT hardware. No installation required - just open in your browser and connect to your serial device.
"pineTERM" is an independent project. Any similarity to other software names is coincidental.
- Native Web Serial API - Direct hardware communication without native applications
- HEX and ASCII View Modes - On-the-fly switchable HEX and ASCII terminal views with synchronized scrolling
- Day/Night Themes - Switch between dark and light modes with persistent preferences
- Smart Input Handling - Auto-formatting HEX input with real-time validation
- JSON Command Sequences - Automated testing with programmable command batches
- Packet Timing Control - Intelligent frame detection based on inter-byte timing
- Log Export - Save terminal output as timestamped text files
- Responsive Design - Works on desktop and tablet browsers
- Dynamic input fields - add as many HEX and ASCII fields as you need, each with its own send button
- Custom baud rate support - set the baud rate you need, not need to be only standard
- Chrome 89+, Edge 89+, or Opera (desktop only)
- USB-to-Serial adapter or native serial port
- Target device (Arduino, ESP32, Raspberry Pi Pico, etc.)
Use it right now: https://wespeakenglish.github.io/pineTERM/
Simply open the link above in a supported browser, click "Connect to UART", and select your device. That's it!
If you prefer to run locally:
git clone https://github.com/wespeakenglish/pineTERM.git
cd pineTERM
# Open index.html in Chrome/Edge/Opera- Connect: Click "Connect to UART" → Select your serial port → Configure baud rate
- Send Data: Type HEX (48 65 6C 6C 6F) or ASCII (Hello) and click send
- Monitor: View responses in both HEX and ASCII tabs
- Export: Click "Export log" to save the session
pineTERM supports automated command sequences via JSON files for testing and batch operations.
[
{
"type": "ascii",
"data": "AT+GMR",
"times": 1,
"preDelay": 0,
"postDelay": 100
}
]| Field | Type | Default | Description |
|---|---|---|---|
type |
string | required | "ascii" for text commands, "hex" for raw bytes |
data |
string | required | Command payload. For hex: space-separated bytes (e.g., "FF FE 01 00") |
times |
integer | 1 |
Execution count: 0=skip, 1=once, N=repeat N times, -1=infinite loop |
preDelay |
integer | 0 |
Milliseconds to wait before sending this command |
postDelay |
integer | 100 |
Milliseconds to wait after sending (inter-command gap) |
[
{ "type": "ascii", "data": "AT\r\n", "times": 0 },
{ "type": "ascii", "data": "AT+GMR\r\n", "times": 1, "postDelay": 500 },
{ "type": "ascii", "data": "AT+CWMODE=1\r\n", "times": 1, "postDelay": 1000 },
{ "type": "ascii", "data": "AT+CWJAP=\"MyNetwork\",\"MyPassword\"\r\n", "times": 1, "preDelay": 200, "postDelay": 5000 },
{ "type": "hex", "data": "FF FE 01 00", "times": 3, "postDelay": 300 },
{ "type": "ascii", "data": "PING\r\n", "times": 5, "postDelay": 1000 },
{ "type": "hex", "data": "AA 55 0D 0A", "times": -1, "preDelay": 50, "postDelay": 50 }
]- Skip test command (times: 0)
- Get firmware version, wait 500ms
- Set station mode, wait 1s
- Connect to WiFi with 5s timeout for connection
- Send raw bytes 3 times with 300ms gaps
- Send PING 5 times with 1s intervals
- Infinite heartbeat loop (50ms delays)
- Click "Select JSON" in the Send Command panel
- Choose your .json file
- Click "Send JSON Commands" to execute
- Click "Stop" to halt execution
| Setting | Options | Default |
|---|---|---|
| Baud Rate | 9600 - 921600 | 9600 |
| Data Bits | 7, 8 | 8 |
| Stop Bits | 1, 2 | 1 |
| Parity | None, Even, Odd | None |
| Flow Control | None, Hardware | None |
Choose transmission termination:
- CR LF (\r\n) - Windows/DOS style
- LF (\n) - Unix/Linux style
- CR (\r) - Classic Mac style
- None - Raw data only
Enable "Separated less than X milliseconds treat like one package" to:
- Buffer rapid incoming bytes into single log entries
- Prevent frame fragmentation
- Default: 10 ms threshold
- User Permission Required: Browser prompts for serial port access each session
- No Data Transmission: All communication stays local between browser and device
- No Storage: Logs are not saved unless explicitly exported by user
- HTTPS Required: Web Serial API requires secure context (localhost or HTTPS)
| Browser | Support | Notes |
|---|---|---|
| Chrome 89+ | Full | Windows, macOS, Linux, ChromeOS |
| Edge 89+ | Full | Windows, macOS, Linux |
| Opera | Full | Windows, macOS, Linux |
| Firefox | With addon | Windows, macOS, Linux with addon |
| Safari | None | Not supported |
| Chrome Android | via RFCOMM | USB serial OTG not supported |
- Embedded Development - Debug Arduino, ESP8266/32, STM32 firmware
- IoT Prototyping - Test AT command sets on WiFi/BLE modules
- Hardware Testing - Automated regression testing with JSON sequences
- Reverse Engineering - Analyze proprietary serial protocols
- Education - Teach serial communication without complex tools
| Issue | Solution |
|---|---|
| "Web Serial API not supported" | Use Chrome/Edge/Opera desktop, check version 89+ |
| Device not appearing | Install USB-to-Serial drivers (CH340, CP2102, FTDI, etc.) |
| Garbled text | Verify baud rate matches device configuration |
| JSON commands fail | Validate JSON syntax, check console for errors |
Contributions welcome! Please:
- Fork the repository
- Create a feature branch (git checkout -b feature/amazing-feature)
- Commit changes (git commit -m 'Add amazing feature')
- Push to branch (git push origin feature/amazing-feature)
- Open a Pull Request
- Built with vanilla JavaScript- no frameworks, no dependencies
- Uses the Web Serial API standard
- Inspired by classic terminal emulators and modern web technologies
Made with 💙 for hardware hackers
