webapp_example

Example of the component espp/mcp266 v1.3.1
# MCP266 Web Console Example

Turns an ESP32-S3 into a **WebUSB / Web Serial front-end** for a Basicmicro
MCP266 motor controller: the hosted
[MCP266 console web app](https://esp-cpp.github.io/espp/apps/mcp266_console.html)
connects over native USB and can

- **configure** each axis' position loop (clamp + fallback P gain) and CiA 402
  software limits, and clear faults / e-stop,
- **command** profile-position moves (target, velocity, accel, decel), and
- **view** live per-axis status — position, velocity, DS402 state, target-reached
  — plus device telemetry (battery voltage, temperature).

Unlike the [CAN bridge](../../canopen/can_bridge_example) (which forwards raw CAN
and runs CANopen in the browser), this example runs the `espp::Mcp266` driver
**on the device** and exposes a small high-level protocol (see
`main/mcp266_protocol.hpp`, dispatcher **module id 6**), so the web app needs no
CANopen/DS402 knowledge. Both the vendor (WebUSB) and CDC (Web Serial) interfaces
carry the same protocol; the system console/logs stay on the built-in
USB-Serial-JTAG.

## Wiring & configuration

The ESP32-S3 is the CANopen **master** of the MCP266 node. Connect the TWAI
TX/RX GPIOs to a 3.3 V CAN transceiver (e.g. SN65HVD230) on a 120 Ω-terminated
bus, at the baudrate configured on the MCP266 in Basicmicro Motion Studio.

Defaults (change in `main/mcp266_webapp_example.cpp`):

| Setting | Value |
|---------|-------|
| TWAI TX | GPIO 17 |
| TWAI RX | GPIO 16 |
| CAN baudrate | 1000000 |
| MCP266 node id | 10 |

## Protocol (module 6)

Framed with `stream_frame` and routed by `espp::Dispatcher`. Requests use type
high-nibble 6; replies/events use high-nibble E (reply flag set).

| Type | Dir | Meaning |
|------|-----|---------|
| `0x60` START | H→D | NMT-start the node + clear faults |
| `0x61` RESET_FAULTS | H→D | clear latched CiA 402 faults (both axes) |
| `0x62` RESET_ESTOP | H→D | attempt an e-stop reset |
| `0x63` CONFIGURE_POSITION_LOOP | H→D | `[axis u8][min i32][max i32][fallback_p i32]` |
| `0x64` SET_POSITION_LIMITS | H→D | CiA 402 software limits: `[axis u8][min i32][max i32]` |
| `0x65` MOVE_TO_POSITION | H→D | `[axis u8][target i32][vel u32][accel u32][decel u32]` |
| `0x66` DRIVE_SPEED | H→D | `[axis u8][qpps i32]` (inert on tested firmware) |
| `0x67` DRIVE_DUTY | H→D | `[axis u8][duty i16]` (inert on tested firmware) |
| `0x68` GET_STATUS | H→D | request one STATUS snapshot |
| `0x69` SET_STATUS_STREAM | H→D | `[enable u8][period_ms u16]` |
| `0x6A` GET_DEVICE_INFO | H→D | request DEVICE_INFO |
| `0xE0` STATUS | D→H | per-axis `[pos i32][vel i32][statusword u16]` ×2, then `[battery_dV u16][temp_dC u16][flags u8]` |
| `0xE1` OK | D→H | `[request_type u8]` |
| `0xE2` ERROR | D→H | `[request_type u8][code u32][utf8 message]` |
| `0xE3` DEVICE_INFO | D→H | `[device_type u32][utf8 name]` |

`axis` is `0` = M1, `1` = M2.

## Build & flash

```
idf.py set-target esp32s3
idf.py build flash monitor
```

Then open the MCP266 console web app and Connect (WebUSB or Web Serial). Click
**Start node**, tick **Live status**, then configure a loop and command a move.

To create a project from this example, run:

idf.py create-project-from-example "espp/mcp266=1.3.1:webapp_example"

or download archive (~11.14 KB)