[{"data":1,"prerenderedAt":284},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fgetting-started\u002Fpanel":3},{"id":4,"title":5,"body":6,"description":276,"extension":277,"meta":278,"navigation":279,"path":280,"seo":281,"stem":282,"__hash__":283},"content\u002Fdocs\u002Fgetting-started\u002Fpanel.md","The Panel",{"type":7,"value":8,"toc":269},"minimark",[9,13,28,31,36,134,141,144,148,155,159,195,199,218,222,225,254,257,265],[10,11,5],"h1",{"id":12},"the-panel",[14,15,16,17,22,23,27],"p",{},"The Panel is a built-in dashboard for poking at your board without writing code. Open the ",[18,19,21],"a",{"href":20},"\u002Fplayground","Playground",", connect a CONDUYT device, click ",[24,25,26],"strong",{},"Panel"," in the toolbar, and start adding widgets.",[14,29,30],{},"It's not a separate app — it shares the same serial port and the same connection state as the rest of the playground. Run a script to drive your board, then jump into the Panel to live-tweak a PWM channel without leaving the page.",[32,33,35],"h2",{"id":34},"widgets","Widgets",[37,38,39,55],"table",{},[40,41,42],"thead",{},[43,44,45,49,52],"tr",{},[46,47,48],"th",{},"Widget",[46,50,51],{},"Direction",[46,53,54],{},"Required pin capability",[56,57,58,73,84,96,109,122],"tbody",{},[43,59,60,64,67],{},[61,62,63],"td",{},"Digital switch",[61,65,66],{},"output",[61,68,69],{},[70,71,72],"code",{},"DIGITAL_OUT",[43,74,75,78,80],{},[61,76,77],{},"Push button (momentary)",[61,79,66],{},[61,81,82],{},[70,83,72],{},[43,85,86,89,91],{},[61,87,88],{},"PWM slider (0–255)",[61,90,66],{},[61,92,93],{},[70,94,95],{},"PWM_OUT",[43,97,98,101,104],{},[61,99,100],{},"LED indicator",[61,102,103],{},"input (polled @100ms)",[61,105,106],{},[70,107,108],{},"DIGITAL_IN",[43,110,111,114,117],{},[61,112,113],{},"Analog gauge",[61,115,116],{},"input (polled @200ms)",[61,118,119],{},[70,120,121],{},"ANALOG_IN",[43,123,124,127,130],{},[61,125,126],{},"Pin scope (oscilloscope)",[61,128,129],{},"input (polled @50ms)",[61,131,132],{},[70,133,121],{},[14,135,136,137,140],{},"Each widget binds to a pin via a dropdown. The dropdown is filtered to ",[24,138,139],{},"only the pins that actually advertise the required capability"," in the firmware's HELLO_RESP. You can't bind a PWM slider to a non-PWM pin or an analog gauge to a digital-only pin — the option simply doesn't appear.",[14,142,143],{},"This is the v0.3 capability-model paying off. Earlier firmware ships under-declared a lot of capabilities (the playground's old \"Permissive mode\" toggle worked around that). With v0.3 firmware flashed, the Panel's filtering matches the silicon's actual hardware.",[32,145,147],{"id":146},"permissive-mode","Permissive mode",[14,149,150,151,154],{},"If you flash a board the library doesn't have a profile for, or if the firmware's HELLO_RESP is incomplete, toggle ",[24,152,153],{},"Permissive"," in the Panel header. This bypasses the capability filter and shows every pin in every dropdown. Use it as an escape hatch — most of the time you should leave it off.",[32,156,158],{"id":157},"how-it-interacts-with-the-rest-of-the-playground","How it interacts with the rest of the playground",[160,161,162,173,183,189],"ul",{},[163,164,165,168,169,172],"li",{},[24,166,167],{},"The connection is shared."," Click ",[24,170,171],{},"Connect"," in the toolbar (or in the Panel — same button). Both the script runner and the Panel use the same serial port. You can't double-connect.",[163,174,175,178,179,182],{},[24,176,177],{},"The widget config persists"," to ",[70,180,181],{},"localStorage"," between sessions. Close the tab, come back, your dashboard is still there.",[163,184,185,188],{},[24,186,187],{},"Polling is live."," Input widgets (LED, gauge, scope) issue PIN_READ commands on a per-widget interval and update in place. Disconnecting stops polling cleanly.",[163,190,191,194],{},[24,192,193],{},"The runner and the Panel can coexist."," Running a script while the Panel is open works — both share the same serial transport. Be aware that they each track their own packet sequence numbers, so a long-running script that sends commands at the same time as the Panel's polling can in rare cases produce a stray timeout. Stop one or the other if you see this.",[32,196,198],{"id":197},"capability-backstop","Capability backstop",[14,200,201,202,205,206,209,210,213,214,217],{},"The firmware library validates incoming ",[70,203,204],{},"PIN_MODE","\u002F",[70,207,208],{},"PIN_READ"," against the same per-board profile that drives the Panel's widget filtering. If a host (somehow) sends a request the pin doesn't support, the firmware NAKs ",[70,211,212],{},"PIN_MODE_UNSUPPORTED"," rather than touching unsafe hardware. The most consequential example: on the Renesas RA4M1 (Uno R4), ",[70,215,216],{},"analogRead()"," on a non-ADC pin would block the firmware indefinitely waiting on a conversion that never completes. The Panel's filtering plus the firmware-side guard makes that bug unreachable.",[32,219,221],{"id":220},"custom-shields-and-unsupported-boards","Custom shields and unsupported boards",[14,223,224],{},"If you've wired a custom shield that changes a pin's role (e.g. an external interrupt on a normally-uninteresting GPIO), or if the board's profile is missing, you can override capabilities from your sketch:",[226,227,232],"pre",{"className":228,"code":229,"language":230,"meta":231,"style":231},"language-cpp shiki shiki-themes github-light github-dark","device.declarePinCaps(8, CONDUYT_PIN_CAP_DIGITAL_OUT | CONDUYT_PIN_CAP_PWM_OUT);\ndevice.declareI2cBus(1, \u002F*sda*\u002F 27, \u002F*scl*\u002F 26);\ndevice.declareSpiBus(0, \u002F*cs*\u002F 10, \u002F*copi*\u002F 11, \u002F*cipo*\u002F 12, \u002F*sck*\u002F 13);\n","cpp","",[70,233,234,242,248],{"__ignoreMap":231},[235,236,239],"span",{"class":237,"line":238},"line",1,[235,240,241],{},"device.declarePinCaps(8, CONDUYT_PIN_CAP_DIGITAL_OUT | CONDUYT_PIN_CAP_PWM_OUT);\n",[235,243,245],{"class":237,"line":244},2,[235,246,247],{},"device.declareI2cBus(1, \u002F*sda*\u002F 27, \u002F*scl*\u002F 26);\n",[235,249,251],{"class":237,"line":250},3,[235,252,253],{},"device.declareSpiBus(0, \u002F*cs*\u002F 10, \u002F*copi*\u002F 11, \u002F*cipo*\u002F 12, \u002F*sck*\u002F 13);\n",[14,255,256],{},"These overrides are merged into HELLO_RESP at handshake time, so the Panel's dropdowns and the firmware's guards both reflect them — no playground-side configuration needed.",[14,258,259,260,264],{},"See ",[18,261,263],{"href":262},"\u002Fdocs\u002Fconcepts\u002Fcapability-model","the capability model docs"," for the design rationale.",[266,267,268],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":231,"searchDepth":244,"depth":244,"links":270},[271,272,273,274,275],{"id":34,"depth":244,"text":35},{"id":146,"depth":244,"text":147},{"id":157,"depth":244,"text":158},{"id":197,"depth":244,"text":198},{"id":220,"depth":244,"text":221},"A Blynk-style dashboard built into the Playground. Switches, sliders, gauges — capability-aware, per-pin.","md",{},true,"\u002Fdocs\u002Fgetting-started\u002Fpanel",{"title":5,"description":276},"docs\u002Fgetting-started\u002Fpanel","sAKtJBEBL1R-JBbfzSuizaLvblPn346LtQSXkNT_A8g",1777412316044]