Tutorial 07 — System Prompts for Embedded Development: Getting Reliable Behaviour Fro
Tutorial 07 — System Prompts for Embedded Development: Getting Reliable Behaviour From Any AI Tool
AI and PicBasic Pro Tutorial Series — Post 7
Content produced with AI assistance and reviewed by the forum administrator.
The Problem This Tutorial Solves
You ask an AI to add a single subroutine to your existing code. It returns the subroutine — plus a restructured main loop, renamed variables, reformatted comments, and three functions you did not ask for. Your working code is gone. The new version does not compile. You have lost more time than the task would have taken manually.
This is not unusual. AI tools are trained to be helpful, and their definition of helpful often includes improving, expanding, and tidying things that were not in scope. For general software development this is sometimes useful. For embedded development it is consistently destructive.
The fix is a system prompt — a set of instructions that runs before every conversation and overrides the AI's default behaviour. A well-written system prompt for embedded work tells the AI to do exactly what was asked, nothing more, ask before assuming, and never touch code it was not told to touch.
This tutorial covers what a system prompt is, where it lives in the major AI tools, and provides a set of generic starting prompts that embedded developers can adapt for their own use.
What is a System Prompt?
A system prompt is a permanent instruction that applies to every conversation before you type anything. It is not part of the conversation — it sits above it. The AI reads it at the start of every session and its instructions take priority over default behaviour.
Different tools call this different things and put it in different places:
- Claude (claude.ai) — Settings > Profile > "What would you like Claude to know about you?" — applies to all conversations. Additional instructions can be added per-workspace under the workspace instruction.
- ChatGPT (chat.openai.com) — Settings > Personalisation > Custom Instructions — two fields: what the AI should know about you, and how it should respond.
- Copilot / GitHub Copilot — Custom instructions via a .github/copilot-instructions.md file in the repository, or via the Copilot settings panel in supported IDEs.
- Warp (terminal AI) — Warp AI preferences and custom prompt settings in the Warp settings panel.
- API-based tools — the system parameter in the API call, which accepts a plain text instruction applied before every message.
The principle is the same regardless of tool. You write the instruction once and it applies everywhere within that tool. You do not repeat it in every conversation.
What Embedded Developers Need From a System Prompt
The failure modes of AI tools on embedded development tasks are well-documented. The system prompt needs to address each one directly:
Scope creep — the AI adds functionality that was not requested. Fix: require the AI to do exactly what was asked and nothing else.
Silent modification — the AI restructures, renames, or reformats code that was not in scope. Fix: require explicit instruction before touching anything outside the stated task.
Deletion without permission — the AI removes code it considers redundant or replaces working sections with its own version. Fix: prohibit deletion or replacement of existing code without explicit confirmation.
Assumption instead of clarification — the AI fills in missing information with assumptions rather than asking. For embedded work this produces plausible-looking code with wrong register values or incorrect timing. Fix: require the AI to ask before proceeding when information is missing or ambiguous.
Confidence without basis — the AI presents uncertain information as fact. Fix: require the AI to flag uncertainty explicitly rather than approximating silently.
Incomplete output — the AI produces skeleton code or placeholder comments without telling you that is what it is doing. Fix: require complete, compilable output or an explicit statement that a skeleton is being produced.
The Generic Embedded Development System Prompt
The following prompt addresses all of the above failure modes. It is written to be tool-agnostic — it works in Claude, ChatGPT, Copilot, Warp, and any other AI tool that accepts a system-level instruction.
This is a starting point. Read every section, understand what it does, and adapt it before use. Do not paste it unchanged — the device and compiler placeholders must be replaced with your specific details.
Code:
; ============================================================
; EMBEDDED DEVELOPMENT SYSTEM PROMPT — GENERIC STARTING POINT
; Adapt before use — replace all placeholders
; ============================================================
I am an embedded systems developer working in [YOUR LANGUAGE/COMPILER]
targeting [YOUR DEVICE FAMILY]. I have [YOUR EXPERIENCE LEVEL] experience
with this platform.
SCOPE — MOST IMPORTANT
Do exactly what I ask. Nothing more.
Do not add features, functions, or improvements I did not request.
Do not restructure, reformat, or rename anything outside the stated task.
Do not expand the scope of the task without asking me first.
If completing the task requires changing something outside the stated scope,
tell me what needs to change and why — then wait for my confirmation.
EXISTING CODE IS WORKING UNLESS I SAY OTHERWISE
Treat all code I provide as working unless I explicitly tell you it has
a problem. Do not correct, improve, or rewrite sections I did not ask
you to change. Do not delete anything. Do not replace working code with
your own version unless asked.
If you believe existing code contains an error I have not mentioned,
tell me once, clearly, and wait. Do not fix it silently.
BEFORE YOU WRITE ANY CODE — ASK FIRST IF:
- The target device is not specified or is ambiguous
- The clock speed or oscillator configuration is not stated
- The required register or peripheral behaviour is not clear
- The task description could reasonably be interpreted in more than one way
- Information needed to write correct code is missing
Do not assume. Do not approximate. Ask the specific question, wait for
the answer, then proceed.
UNCERTAINTY
If you are not certain about a syntax rule, register name, bit value,
or timing calculation — say so explicitly before presenting any code.
State what you are uncertain about and where to verify it.
Do not present uncertain information as fact.
CODE QUALITY
Every code response must be complete and ready to compile.
No skeleton code, no placeholder comments, no TODO sections — unless
I explicitly ask for an outline.
If the task cannot be completed without information you do not have,
ask for that information rather than producing incomplete output.
CHANGES TO EXISTING CODE
When modifying code I have provided:
- Show me the original unchanged first, clearly marked
- Then show the modified version, clearly marked
- Mark every individual change with a comment: ; CHANGED: reason
- Do not silently restructure anything outside the changed lines
CALCULATIONS
Show all timing and frequency calculations explicitly:
formula, values substituted, result.
Mark approximate results as approximate and state the margin.
Do not present a calculated result without showing the working.
FORMAT
Code in code blocks. Explanations in plain prose.
Lead with the answer. No lengthy preamble.
If you cannot do what I asked, say so in one sentence and explain why.
How to Adapt It
Replace the placeholders
The first section contains three placeholders you must fill in:
- [YOUR LANGUAGE/COMPILER] — for example: PicBasic Pro 3 by melabs, or MPLAB XC8, or assembly
- [YOUR DEVICE FAMILY] — for example: PIC16F mid-range, or PIC18F enhanced, or a specific part number
- [YOUR EXPERIENCE LEVEL] — this is worth including. "I have 20 years experience with PIC hardware" produces different output to "I am learning embedded development". The AI calibrates its explanations accordingly.
Add device-specific requirements
If you work exclusively with one device family, add a section that states it. For PBP3 specifically, consider adding:
Code:
; ============================================================
; PBP3-SPECIFIC ADDITIONS — ADD BELOW THE GENERIC PROMPT
; ============================================================
PICBASIC PRO 3 SPECIFIC
All code is for PicBasic Pro 3 (PBP3) by melabs.
DEFINE OSC must always appear before any timing-dependent code.
CONFIG bits must match the target device datasheet exactly.
Do not mix 16F and 18F CONFIG syntax.
If using inline assembly, all variables used in ASM blocks must be
declared BANK0 SYSTEM unless the code explicitly manages banking.
Show all Timer period calculations using the formula:
Period = (PR2 + 1) x 4 x Tosc x Prescaler
NOTE: The PBP3-specific section above is an example. The Timer formula shown is for Timer2 on mid-range devices. Verify it against your device datasheet before using it as a reference.
The Clarification Requirement — The Most Valuable Instruction
The single most valuable instruction in the prompt is the ask-first requirement. By default AI tools assume rather than ask. For general software development this speeds things up. For embedded development it produces code with wrong register values, incorrect clock assumptions, and timing errors that only surface on hardware.
The instruction works because it changes the AI's default response to ambiguity. Instead of filling a gap with a plausible assumption, it surfaces the gap and waits. You provide the specific information — clock speed, device variant, peripheral configuration — and the AI proceeds with correct values rather than approximated ones.
In practice the clarification request looks like this. You ask the AI to write a Timer2 ISR. Without the clarification instruction it assumes a clock speed, calculates a PR2 value, and produces code. With the clarification instruction it responds:
"Before I write this I need to confirm: what is the target device, what clock speed is it running at, and what tick rate do you want for the ISR?"
You answer those questions and the AI produces code with correct values rather than plausible guesses.
Where to Put It in Each Tool
Claude
Settings (bottom left) > Profile > paste into the "What would you like Claude to know about you?" field. This applies to all conversations. For device-specific additions, use the workspace instruction in your PBP3 workspace (Tutorial 02 covers this).
ChatGPT
Settings (bottom left) > Personalisation > Custom Instructions. There are two fields. Put your identity and background in the first field ("What should ChatGPT know about you?"). Put the behavioural instructions — scope, existing code, clarification requirement, code quality — in the second field ("How should ChatGPT respond?").
GitHub Copilot
Create a file at .github/copilot-instructions.md in your repository root. Paste the prompt content as plain markdown. Copilot reads this file and applies the instructions to all suggestions and chat responses within that repository.
Warp
Warp AI settings vary by version. Look for AI preferences or custom prompt settings in the Warp settings panel. The prompt content is the same — only the location changes.
Any API-based tool
Pass the prompt content as the system parameter in your API call. The format is tool-dependent but the content is identical.
Testing Your System Prompt
After setting up the prompt, test it with a deliberately ambiguous request before using it on real work. Something like:
"Write me a Timer ISR for my PIC project."
A correctly configured AI should respond by asking for the device, the clock speed, and the required tick rate before writing anything. If it proceeds without asking, the clarification requirement is not working and the prompt needs adjustment.
Also test scope control:
"Add a 50ms startup delay to this code." (paste a complete PBP3 program)
The AI should add the delay and return the modified code with only that change annotated. If it restructures other sections, renames variables, or adds anything unrequested, the scope instruction needs strengthening.
What This Prompt Does Not Cover
This prompt addresses behaviour. It does not address knowledge. An AI following these instructions perfectly will still produce incorrect register values, wrong DEFINE syntax, or invalid CONFIG bits if it does not have the right reference material. That is the problem addressed in Tutorials 02 and 05 — providing the compiler manual, device datasheet, and working examples as workspace documents.
The system prompt and the workspace documents work together. The prompt controls how the AI behaves. The documents give it the knowledge to behave correctly.
Community Contributions
If you develop additions to this prompt that work reliably for specific devices, peripherals, or use cases — please share them in a reply. Particularly useful additions would be:
- Device-family-specific instruction blocks that prevent known AI failure modes
- Peripheral-specific clarification triggers — instructions that force the AI to ask for the right information before writing timer, UART, or ISR code
- Additions that work well with specific tools where the generic prompt underperforms
Part of the AI and PicBasic Pro Tutorial Series.
This tutorial was produced with AI
The system prompt provided is a starting point. Test it, adapt it, and do not use placeholder values in production. All AI-generated code must be reviewed and hardware tested before use.