{"id":1282,"date":"2026-05-07T20:35:41","date_gmt":"2026-05-07T20:35:41","guid":{"rendered":"https:\/\/b9xelectronics.com\/?page_id=1282"},"modified":"2026-08-06T05:51:32","modified_gmt":"2026-08-06T05:51:32","slug":"workbench-c","status":"publish","type":"page","link":"https:\/\/b9xelectronics.com\/?page_id=1282","title":{"rendered":"B9X Basic"},"content":{"rendered":"\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/b9xelectronics.com\/wp-content\/uploads\/2026\/08\/B9X_Basic_Developer_Module_Getting_Started_Guide.pdf\" type=\"application\/pdf\" style=\"width:100%;height:600px\" aria-label=\"Embed of B9X_Basic_Developer_Module_Getting_Started_Guide.\"><\/object><a id=\"wp-block-file--media-3a361f4a-116b-4981-8ecf-e3bae81d18db\" href=\"https:\/\/b9xelectronics.com\/wp-content\/uploads\/2026\/08\/B9X_Basic_Developer_Module_Getting_Started_Guide.pdf\">B9X_Basic_Developer_Module_Getting_Started_Guide<\/a><a href=\"https:\/\/b9xelectronics.com\/wp-content\/uploads\/2026\/08\/B9X_Basic_Developer_Module_Getting_Started_Guide.pdf\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-3a361f4a-116b-4981-8ecf-e3bae81d18db\">Download<\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<!-- Paste this complete file into one WordPress Custom HTML block. -->\n<style>\n.b9x-basic-reference {\n  --b9x-maroon: #6b1f2a;\n  --b9x-maroon-dark: #47131b;\n  --b9x-cream: #faf7f5;\n  --b9x-ink: #282326;\n  --b9x-muted: #6d6568;\n  --b9x-border: #e4d9d5;\n  max-width: 1180px;\n  margin: 0 auto;\n  color: var(--b9x-ink);\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Arial, sans-serif;\n  font-size: 17px;\n  line-height: 1.68;\n}\n.b9x-basic-reference * { box-sizing: border-box; }\n.b9x-basic-reference .b9x-hero {\n  padding: 58px clamp(24px, 6vw, 76px);\n  border-radius: 6px;\n  background: linear-gradient(135deg, var(--b9x-maroon-dark), var(--b9x-maroon));\n  color: #fff;\n  box-shadow: 0 14px 34px rgba(71,19,27,.18);\n  margin-bottom: 34px;\n}\n.b9x-basic-reference .b9x-kicker {\n  margin: 0 0 8px;\n  text-transform: uppercase;\n  letter-spacing: .14em;\n  font-size: .78rem;\n  font-weight: 700;\n  color: #f1dfe2;\n}\n.b9x-basic-reference .b9x-hero h1 {\n  margin: 0 0 12px;\n  color: #fff;\n  font-size: clamp(2.25rem, 6vw, 4.5rem);\n  line-height: 1.05;\n  letter-spacing: -.035em;\n}\n.b9x-basic-reference .b9x-lead {\n  max-width: 760px;\n  margin: 0;\n  color: #fff;\n  font-size: 1.16rem;\n}\n.b9x-basic-reference .b9x-layout {\n  display: grid;\n  grid-template-columns: minmax(210px, 260px) minmax(0, 1fr);\n  gap: 44px;\n  align-items: start;\n}\n.b9x-basic-reference .b9x-toc {\n  position: sticky;\n  top: 24px;\n  padding: 20px;\n  border: 1px solid var(--b9x-border);\n  border-top: 4px solid var(--b9x-maroon);\n  background: #fff;\n}\n.b9x-basic-reference .b9x-toc h2 {\n  margin: 0 0 12px;\n  color: var(--b9x-maroon-dark);\n  font-size: 1rem;\n}\n.b9x-basic-reference .b9x-toc ol {\n  margin: 0;\n  padding-left: 1.2rem;\n  font-size: .86rem;\n  line-height: 1.42;\n}\n.b9x-basic-reference .b9x-toc li { margin: 0 0 7px; }\n.b9x-basic-reference .b9x-toc a { color: #51484b; text-decoration: none; }\n.b9x-basic-reference .b9x-toc a:hover { color: var(--b9x-maroon); text-decoration: underline; }\n.b9x-basic-reference .b9x-content { min-width: 0; }\n.b9x-basic-reference .b9x-content h2 {\n  margin: 2.25em 0 .55em;\n  padding-bottom: .28em;\n  color: var(--b9x-maroon);\n  border-bottom: 2px solid #eadfe0;\n  font-size: 1.8rem;\n  line-height: 1.2;\n}\n.b9x-basic-reference .b9x-content h3 {\n  margin: 1.75em 0 .45em;\n  color: var(--b9x-maroon-dark);\n  font-size: 1.35rem;\n  line-height: 1.25;\n}\n.b9x-basic-reference .b9x-content h4 {\n  margin: 1.5em 0 .35em;\n  color: #3f3337;\n  font-size: 1.08rem;\n  text-transform: uppercase;\n  letter-spacing: .025em;\n}\n.b9x-basic-reference p { margin: 0 0 1em; }\n.b9x-basic-reference ul, .b9x-basic-reference ol { margin: 0 0 1.15em; padding-left: 1.35em; }\n.b9x-basic-reference .b9x-code {\n  overflow-x: auto;\n  margin: .6em 0 1.2em;\n  padding: 17px 19px;\n  border-left: 4px solid var(--b9x-maroon);\n  border-radius: 0 4px 4px 0;\n  background: #f4f1f1;\n  color: #241f21;\n  font: .91rem\/1.52 Consolas, \"Courier New\", monospace;\n  white-space: pre;\n}\n.b9x-basic-reference .b9x-note {\n  margin: 1.2em 0;\n  padding: 15px 18px;\n  border: 1px solid #e7d8d8;\n  border-left: 5px solid var(--b9x-maroon);\n  background: var(--b9x-cream);\n}\n.b9x-basic-reference .b9x-note strong { color: var(--b9x-maroon-dark); }\n.b9x-basic-reference .b9x-label { margin-bottom: .65em; }\n.b9x-basic-reference .b9x-label strong { color: var(--b9x-maroon-dark); }\n.b9x-basic-reference .b9x-table-wrap { overflow-x: auto; margin: 1em 0 1.5em; }\n.b9x-basic-reference table { width: 100%; border-collapse: collapse; font-size: .93rem; }\n.b9x-basic-reference th {\n  padding: 11px 13px;\n  border: 1px solid #d8c8c9;\n  background: var(--b9x-maroon);\n  color: #fff;\n  text-align: left;\n}\n.b9x-basic-reference td { padding: 10px 13px; border: 1px solid var(--b9x-border); vertical-align: top; }\n.b9x-basic-reference tbody tr:nth-child(even) { background: #fbf8f7; }\n.b9x-basic-reference a { color: var(--b9x-maroon); }\n@media (max-width: 860px) {\n  .b9x-basic-reference { font-size: 16px; }\n  .b9x-basic-reference .b9x-layout { grid-template-columns: 1fr; }\n  .b9x-basic-reference .b9x-toc { position: static; }\n  .b9x-basic-reference .b9x-hero { padding: 38px 24px; }\n}\n@media print {\n  .b9x-basic-reference .b9x-toc { position: static; }\n  .b9x-basic-reference .b9x-layout { display: block; }\n  .b9x-basic-reference .b9x-hero { box-shadow: none; }\n}\n<\/style>\n<article class=\"b9x-basic-reference\">\n  <header class=\"b9x-hero\">\n    <p class=\"b9x-kicker\">B9X Electronics Documentation<\/p>\n    <h1>B9X Basic Language Reference<\/h1>\n    <p class=\"b9x-lead\">A complete guide to the B9X Basic language, including variables, expressions, operators, statements, control flow, functions, and practical examples.<\/p>\n  <\/header>\n  <div class=\"b9x-layout\">\n    <nav class=\"b9x-toc\" aria-label=\"Reference contents\">\n      <h2>On this page<\/h2>\n      <ol><li><a href=\"#how-to-use-this-reference\">How to use this reference<\/a><\/li>\n<li><a href=\"#1-language-fundamentals\">1. Language fundamentals<\/a><\/li>\n<li><a href=\"#2-values-variables-and-arrays\">2. Values, variables, and arrays<\/a><\/li>\n<li><a href=\"#3-expressions-and-operators\">3. Expressions and operators<\/a><\/li>\n<li><a href=\"#4-statements-and-control-flow\">4. Statements and control flow<\/a><\/li>\n<li><a href=\"#5-subroutines-and-user-functions\">5. Subroutines and user functions<\/a><\/li>\n<li><a href=\"#6-core-string-functions\">6. Core string functions<\/a><\/li>\n<li><a href=\"#7-formatting-and-time\">7. Formatting and time<\/a><\/li>\n<li><a href=\"#8-mathematics\">8. Mathematics<\/a><\/li>\n<li><a href=\"#9-gpio-timing-adc-and-temperature\">9. GPIO, timing, ADC, and temperature<\/a><\/li>\n<li><a href=\"#10-display-motion-wav-and-local-tts\">10. Display, motion, WAV, and local TTS<\/a><\/li>\n<li><a href=\"#11-openai-text-transcription-and-tts\">11. OpenAI text, transcription, and TTS<\/a><\/li>\n<li><a href=\"#12-infrared-remote-control\">12. Infrared remote control<\/a><\/li>\n<li><a href=\"#13-ws2812-addressable-leds\">13. WS2812 addressable LEDs<\/a><\/li>\n<li><a href=\"#14-mqtt\">14. MQTT<\/a><\/li>\n<li><a href=\"#15-additional-supplied-functions\">15. Additional supplied functions<\/a><\/li>\n<li><a href=\"#16-protected-key-variables\">16. Protected key variables<\/a><\/li>\n<li><a href=\"#17-complete-programming-patterns\">17. Complete programming patterns<\/a><\/li>\n<li><a href=\"#appendix-a-language-limits\">Appendix A. Language limits<\/a><\/li>\n<li><a href=\"#appendix-b-quick-reference\">Appendix B. Quick reference<\/a><\/li>\n<li><a href=\"#about-this-reference\">About this reference<\/a><\/li><\/ol>\n    <\/nav>\n    <main class=\"b9x-content\">\n<h2 id=\"how-to-use-this-reference\">How to use this reference<\/h2>\n<p>Start with Chapters 1\u20136 to learn the language. Use Chapters 7\u201316 as the function reference. Chapter 17 shows complete patterns, and the appendices collect limits and quick-reference tables.<\/p>\n<aside class=\"b9x-note\"><strong>Important<\/strong> <strong>B9X Basic<\/strong> is its own language. Syntax or functions from Visual Basic, QBASIC, or another BASIC dialect are not automatically available.<\/aside>\n<h3 id=\"conventions\">Conventions<\/h3>\n<div class=\"b9x-table-wrap\"><table>\n<thead><tr><th>Notation<\/th><th>Meaning<\/th><\/tr><\/thead>\n<tbody>\n<tr><td>name<\/td><td>A numeric variable or identifier.<\/td><\/tr>\n<tr><td>name$<\/td><td>A string variable or string-returning function.<\/td><\/tr>\n<tr><td>expression<\/td><td>A numeric expression.<\/td><\/tr>\n<tr><td>string-expression<\/td><td>A string literal, string variable, string function, or concatenation.<\/td><\/tr>\n<tr><td>[ optional ]<\/td><td>Optional syntax in this manual only; do not type the brackets.<\/td><\/tr>\n<tr><td>&#8230;<\/td><td>Additional statements or arguments.<\/td><\/tr>\n<\/tbody><\/table><\/div>\n<h3 id=\"contents\">Contents<\/h3>\n<ul>\n<li>1. Language fundamentals<\/li>\n<li>2. Values, variables, and arrays<\/li>\n<li>3. Expressions and operators<\/li>\n<li>4. Statements and control flow<\/li>\n<li>5. Subroutines and user functions<\/li>\n<li>6. Core string functions<\/li>\n<li>7. Formatting and time<\/li>\n<li>8. Mathematics<\/li>\n<li>9. GPIO, timing, ADC, and temperature<\/li>\n<li>10. Display, motion, WAV, and local TTS<\/li>\n<li>11. OpenAI text, transcription, and TTS<\/li>\n<li>12. Infrared remote control<\/li>\n<li>13. WS2812 LEDs<\/li>\n<li>14. MQTT<\/li>\n<li>15. Additional supplied functions<\/li>\n<li>16. Protected key variables<\/li>\n<li>17. Complete programming patterns<\/li>\n<li>Appendix A. Language limits<\/li>\n<li>Appendix B. Quick reference<\/li>\n<\/ul>\n<h2 id=\"1-language-fundamentals\">1. Language fundamentals<\/h2>\n<h3 id=\"program-structure\">Program structure<\/h3>\n<p>A program is a sequence of executable statements plus optional SUB and FUNCTION definitions. Most simple statements end with a semicolon. Block delimiters such as THEN, ELSE, ENDIF, DO, WEND, NEXT, END SUB, and END FUNCTION do not use semicolons.<\/p>\n<pre class=\"b9x-code\"><code>&#x27; A minimal B9X Basic program\nlet greeting$ = &quot;Hello from B9X&quot;;\ncounter = 3;\nprint greeting$;\nprint counter;<\/code><\/pre>\n<h3 id=\"lexical-rules\">Lexical rules<\/h3>\n<div class=\"b9x-table-wrap\"><table>\n<thead><tr><th>Item<\/th><th>Rule<\/th><\/tr><\/thead>\n<tbody>\n<tr><td>Numeric identifier<\/td><td>Starts with A\u2013Z, a\u2013z, or underscore; remaining characters may also include digits.<\/td><\/tr>\n<tr><td>String identifier<\/td><td>Uses the same identifier rules and ends with $.<\/td><\/tr>\n<tr><td>Stored name length<\/td><td>31 characters maximum.<\/td><\/tr>\n<tr><td>Numeric literal<\/td><td>Decimal integer, decimal fraction, or scientific notation, such as 12, 3.5, or 1.2e-3.<\/td><\/tr>\n<tr><td>String literal<\/td><td>Text enclosed in double quotes.<\/td><\/tr>\n<tr><td>Statement terminator<\/td><td>A semicolon ends assignments, DIM, PRINT, CALL, and RETURN.<\/td><\/tr>\n<tr><td>Names<\/td><td>Names are case-sensitive. Use the exact function spelling shown in this reference.<\/td><\/tr>\n<\/tbody><\/table><\/div>\n<h3 id=\"comments\">Comments<\/h3>\n<p>The lexer accepts three comment forms.<\/p>\n<pre class=\"b9x-code\"><code>&#x27; apostrophe comment to end of line\n\/\/ C++-style comment to end of line\n\/* block comment\n   across lines *\/<\/code><\/pre>\n<h3 id=\"truth-values\">Truth values<\/h3>\n<p><strong>B9X Basic<\/strong> has no separate Boolean type. Zero is false; any nonzero numeric value is true. Comparisons and logical operations produce numeric 0 or 1.<\/p>\n<h2 id=\"2-values-variables-and-arrays\">2. Values, variables, and arrays<\/h2>\n<h3 id=\"numeric-values\">Numeric values<\/h3>\n<p>All ordinary numeric variables and numeric function values use double-precision floating-point numbers. Integer-oriented functions discard any fractional portion when they require a whole number.<\/p>\n<pre class=\"b9x-code\"><code>x = 12.5;\nscientific = 1.2e3;\nnegative = -7;\nprint x + scientific;<\/code><\/pre>\n<h3 id=\"string-values\">String values<\/h3>\n<p>A string variable is identified by a trailing $. Its usable value is limited to 512 characters. String assignment requires LET.<\/p>\n<pre class=\"b9x-code\"><code>let first$ = &quot;B9X&quot;;\nlet message$ = first$ + &quot; Basic&quot;;\nprint message$;<\/code><\/pre>\n<aside class=\"b9x-note\"><strong>Syntax difference<\/strong> Numeric assignment may omit LET; string assignment must be written as LET name$ = string-expression; in this grammar.<\/aside>\n<h3 id=\"assignment\">Assignment<\/h3>\n<pre class=\"b9x-code\"><code>count = 1;\nlet count = count + 1;\nlet label$ = &quot;ready&quot;;<\/code><\/pre>\n<h3 id=\"numeric-arrays\">Numeric arrays<\/h3>\n<p>DIM creates a one-dimensional numeric array. The declared bound is inclusive: DIM sample[10]; creates indices 0 through 10. Array indices are numeric expressions converted to integers. String arrays are not implemented.<\/p>\n<pre class=\"b9x-code\"><code>dim samples[9];\nfor i = 0 to 9 do\n    samples[i] = i ** 2;\nnext\nprint samples[4];<\/code><\/pre>\n<aside class=\"b9x-note\"><strong>Bounds<\/strong> The largest legal declared bound is 1023. Access outside the allocated range causes a program error.<\/aside>\n<h3 id=\"scope-and-lifetime\">Scope and lifetime<\/h3>\n<p>Variables created outside a function are global. FUNCTION parameters temporarily use their own values and are restored when the call returns. A function can read or modify other global variables. SUB has no parameters.<\/p>\n<h2 id=\"3-expressions-and-operators\">3. Expressions and operators<\/h2>\n<h3 id=\"operator-precedence\">Operator precedence<\/h3>\n<p>The table is ordered from highest precedence to lowest. Parentheses override the normal order.<\/p>\n<div class=\"b9x-table-wrap\"><table>\n<thead><tr><th>Precedence<\/th><th>Operators<\/th><th>Meaning<\/th><th>Associativity<\/th><\/tr><\/thead>\n<tbody>\n<tr><td>1<\/td><td>( )<\/td><td>Grouping and function calls<\/td><td>\u2014<\/td><\/tr>\n<tr><td>2<\/td><td>+  &#8211;  NOT  !<\/td><td>Unary sign and logical negation<\/td><td>Right<\/td><\/tr>\n<tr><td>3<\/td><td>**<\/td><td>Exponentiation<\/td><td>Right<\/td><\/tr>\n<tr><td>4<\/td><td>*  \/<\/td><td>Multiplication and division<\/td><td>Left<\/td><\/tr>\n<tr><td>5<\/td><td>+  &#8211;<\/td><td>Addition\/subtraction; + also concatenates strings<\/td><td>Left<\/td><\/tr>\n<tr><td>6<\/td><td>&lt;  &lt;=  &gt;  &gt;=<\/td><td>Relational comparison<\/td><td>Left<\/td><\/tr>\n<tr><td>7<\/td><td>==  !=<\/td><td>Equality and inequality<\/td><td>Left<\/td><\/tr>\n<tr><td>8<\/td><td>AND  &amp;&amp;<\/td><td>Logical AND<\/td><td>Left<\/td><\/tr>\n<tr><td>9<\/td><td>OR  ||<\/td><td>Logical OR<\/td><td>Left<\/td><\/tr>\n<\/tbody><\/table><\/div>\n<h3 id=\"arithmetic-expressions\">Arithmetic expressions<\/h3>\n<pre class=\"b9x-code\"><code>result = 2 + 3 * 4;        &#x27; 14\npower = 2 ** 3 ** 2;       &#x27; 512: exponentiation groups right\naverage = (a + b) \/ 2;<\/code><\/pre>\n<h3 id=\"comparison-and-logical-expressions\">Comparison and logical expressions<\/h3>\n<pre class=\"b9x-code\"><code>if temperature &gt;= 25 and enabled == 1 then\n    print &quot;warm and enabled&quot;;\nendif\n\ndifferent = value != previous;\ninactive = not enabled;<\/code><\/pre>\n<aside class=\"b9x-note\"><strong>Equality<\/strong> Use == to compare. A single = performs assignment and is not the equality operator.<\/aside>\n<h3 id=\"string-expressions\">String expressions<\/h3>\n<p>The + operator concatenates string expressions. String functions can be nested and concatenated.<\/p>\n<pre class=\"b9x-code\"><code>let full$ = left$(&quot;B9X Basic&quot;, 3) + &quot; &quot; + str$(42);\nprint full$;<\/code><\/pre>\n<h2 id=\"4-statements-and-control-flow\">4. Statements and control flow<\/h2>\n<h3 id=\"print\">PRINT<\/h3>\n<p>PRINT writes one numeric or string expression to the <strong>B9X Basic<\/strong> output.<\/p>\n<pre class=\"b9x-code\"><code>print 2 + 2;\nprint &quot;ready&quot;;\nprint fmt$(12.5, &quot;0.00&quot;);<\/code><\/pre>\n<h3 id=\"if-then-else-endif\">IF \/ THEN \/ ELSE \/ ENDIF<\/h3>\n<pre class=\"b9x-code\"><code>if distance &lt; 20 then\n    print &quot;near&quot;;\nelse\n    print &quot;far&quot;;\nendif<\/code><\/pre>\n<p>ELSE is optional. Blocks can contain any supported statements, including nested IF, WHILE, and FOR blocks.<\/p>\n<h3 id=\"while-do-wend\">WHILE \/ DO \/ WEND<\/h3>\n<pre class=\"b9x-code\"><code>count = 0;\nwhile count &lt; 5 do\n    print count;\n    count = count + 1;\nwend<\/code><\/pre>\n<h3 id=\"for-to-step-next\">FOR \/ TO \/ STEP \/ NEXT<\/h3>\n<p>FOR initializes its numeric control variable, tests it against the inclusive limit, executes the body, and adds the step. STEP defaults to 1. Positive and negative steps are supported. DO may be included or omitted after the loop header.<\/p>\n<pre class=\"b9x-code\"><code>for i = 1 to 5 do\n    print i;\nnext\n\nfor j = 10 to 0 step -2\n    print j;\nnext<\/code><\/pre>\n<aside class=\"b9x-note\"><strong>Avoid STEP 0<\/strong> A zero step cannot advance the control variable and can create an endless loop.<\/aside>\n<h3 id=\"blocks\">Blocks<\/h3>\n<p>Braces form an explicit statement block and may be empty. Normal IF\/WHILE\/FOR examples do not require braces.<\/p>\n<pre class=\"b9x-code\"><code>{\n    x = 1;\n    print x;\n}<\/code><\/pre>\n<h3 id=\"unavailable-classic-basic-statements\">Unavailable classic BASIC statements<\/h3>\n<p>The attached grammar does not define GOTO, GOSUB, INPUT, DATA\/READ, SELECT CASE, BREAK, CONTINUE, or line-numbered program flow. Use structured blocks, SUB, and FUNCTION instead.<\/p>\n<h2 id=\"5-subroutines-and-user-functions\">5. Subroutines and user functions<\/h2>\n<h3 id=\"sub\">SUB<\/h3>\n<p>A SUB is a named, argument-free procedure. Invoke it with CALL. RETURN; exits early; reaching END SUB also returns.<\/p>\n<pre class=\"b9x-code\"><code>sub blink()\n    setHigh(2);\n    wait(100);\n    setLow(2);\nend sub\n\ncall blink();<\/code><\/pre>\n<h3 id=\"numeric-function\">Numeric FUNCTION<\/h3>\n<pre class=\"b9x-code\"><code>function clamp(value, low, high)\n    if value &lt; low then\n        return low;\n    endif\n    if value &gt; high then\n        return high;\n    endif\n    return value;\nend function\n\nprint clamp(120, 0, 100);<\/code><\/pre>\n<h3 id=\"string-function\">String FUNCTION<\/h3>\n<p>A string-returning function name ends in $. Parameters may be numeric or string parameters ending in $. Return a string expression.<\/p>\n<pre class=\"b9x-code\"><code>function greeting$(name$)\n    return &quot;Hello, &quot; + name$;\nend function\n\nlet text$ = greeting$(&quot;B9X&quot;);\nprint text$;<\/code><\/pre>\n<h3 id=\"function-call-rules\">Function-call rules<\/h3>\n<ul>\n<li>A user FUNCTION may accept up to 8 parameters.<\/li>\n<li>Parameter types are determined by whether the parameter name ends in $.<\/li>\n<li>A missing numeric return falls back to 0; a missing string return falls back to an empty string.<\/li>\n<li>Place a FUNCTION definition before code that calls it.<\/li>\n<\/ul>\n<h2 id=\"6-core-string-functions\">6. Core string functions<\/h2>\n<h4 id=\"len\">LEN<\/h4>\n<pre class=\"b9x-code\"><code>len(text$)<\/code><\/pre>\n<p>Returns the number of characters in a string.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print len(&quot;B9X&quot;);        &#x27; 3<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Numeric character count.<\/p>\n<h4 id=\"left\">LEFT$<\/h4>\n<pre class=\"b9x-code\"><code>left$(text$, count)<\/code><\/pre>\n<p>Returns up to count characters from the left side of text$.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> Negative counts act as zero; counts longer than the source are capped.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>let a$ = left$(&quot;B9X Basic&quot;, 3);   &#x27; &quot;B9X&quot;<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A string.<\/p>\n<h4 id=\"right\">RIGHT$<\/h4>\n<pre class=\"b9x-code\"><code>right$(text$, count)<\/code><\/pre>\n<p>Returns up to count characters from the right side of text$.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> Negative counts act as zero; counts longer than the source are capped.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>let a$ = right$(&quot;B9X Basic&quot;, 5);  &#x27; &quot;Basic&quot;<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A string.<\/p>\n<h4 id=\"mid\">MID$<\/h4>\n<pre class=\"b9x-code\"><code>mid$(text$, start, count)<\/code><\/pre>\n<p>Extracts count characters beginning at the 1-based start position.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> Positions are 1-based and the result is clipped at the string boundary.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>let a$ = mid$(&quot;B9X Basic&quot;, 5, 5);  &#x27; &quot;Basic&quot;<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A string.<\/p>\n<h4 id=\"chr\">CHR$<\/h4>\n<pre class=\"b9x-code\"><code>chr$(code)<\/code><\/pre>\n<p>Creates a one-character string from a numeric byte value.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> Values above 255 are masked to 8 bits; negative values become 0.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>let newline$ = chr$(10);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A one-character string.<\/p>\n<h4 id=\"asc\">ASC<\/h4>\n<pre class=\"b9x-code\"><code>asc(text$)<\/code><\/pre>\n<p>Returns the byte value of the first character.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print asc(&quot;A&quot;);             &#x27; 65<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A numeric byte code; an empty string yields 0.<\/p>\n<h4 id=\"str\">STR$<\/h4>\n<pre class=\"b9x-code\"><code>str$(number)<\/code><\/pre>\n<p>Converts a number to compact text using %g-style formatting.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>let n$ = str$(12.5);       &#x27; &quot;12.5&quot;<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A string.<\/p>\n<h4 id=\"val\">VAL<\/h4>\n<pre class=\"b9x-code\"><code>val(text$)<\/code><\/pre>\n<p>Parses a leading decimal floating-point number from text.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print val(&quot;12.5 volts&quot;);     &#x27; 12.5<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The parsed number; 0 if parsing cannot begin.<\/p>\n<h4 id=\"instr\">INSTR<\/h4>\n<pre class=\"b9x-code\"><code>instr(text$, find$)\ninstr(start, text$, find$)<\/code><\/pre>\n<p>Searches text$ for find$. The two-argument form starts at the beginning; the three-argument form starts at a 1-based position.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> An empty search string returns 1 in the two-argument form or the requested start position in the three-argument form.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print instr(&quot;B9X Basic&quot;, &quot;Basic&quot;);      &#x27; 5\nprint instr(6, &quot;banana&quot;, &quot;a&quot;);          &#x27; 6<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The 1-based match position, or 0 when not found.<\/p>\n<h2 id=\"7-formatting-and-time\">7. Formatting and time<\/h2>\n<h4 id=\"fmt\">FMT$<\/h4>\n<pre class=\"b9x-code\"><code>fmt$(number, format$)<\/code><\/pre>\n<p>Formats a number using familiar numeric-format characters.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print fmt$(1234.5, &quot;#,##0.00&quot;);  &#x27; 1,234.50\nprint fmt$(0.256, &quot;0.0%&quot;);       &#x27; 25.6%<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The formatted string.<\/p>\n<h3 id=\"fmt-format-tokens\">FMT$ format tokens<\/h3>\n<div class=\"b9x-table-wrap\"><table>\n<thead><tr><th>Token<\/th><th>Meaning<\/th><\/tr><\/thead>\n<tbody>\n<tr><td>0<\/td><td>Required digit; displays zero when no digit is present.<\/td><\/tr>\n<tr><td>#<\/td><td>Optional digit.<\/td><\/tr>\n<tr><td>.<\/td><td>Decimal separator.<\/td><\/tr>\n<tr><td>,<\/td><td>Thousands grouping.<\/td><\/tr>\n<tr><td>%<\/td><td>Multiplies by 100 and appends a percent sign.<\/td><\/tr>\n<tr><td>+ at start<\/td><td>Forces a sign for positive values.<\/td><\/tr>\n<tr><td>E or e<\/td><td>Scientific notation.<\/td><\/tr>\n<tr><td>positive;negative;zero<\/td><td>Selects separate format sections.<\/td><\/tr>\n<tr><td>&quot;text&quot;<\/td><td>Quoted literal text.<\/td><\/tr>\n<tr><td>\\character<\/td><td>Escapes the next format character.<\/td><\/tr>\n<\/tbody><\/table><\/div>\n<h4 id=\"hour\">HOUR<\/h4>\n<pre class=\"b9x-code\"><code>hour()<\/code><\/pre>\n<p>Returns the local clock hour, 0\u201323. The value uses the date and time configured for the <strong>B9X Basic<\/strong> system.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print hour();<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A number.<\/p>\n<h4 id=\"minute\">MINUTE<\/h4>\n<pre class=\"b9x-code\"><code>minute()<\/code><\/pre>\n<p>Returns the local minute, 0\u201359. The value uses the date and time configured for the <strong>B9X Basic<\/strong> system.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print minute();<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A number.<\/p>\n<h4 id=\"second\">SECOND<\/h4>\n<pre class=\"b9x-code\"><code>second()<\/code><\/pre>\n<p>Returns the local second, 0\u201359. The value uses the date and time configured for the <strong>B9X Basic<\/strong> system.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print second();<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A number.<\/p>\n<h4 id=\"month\">MONTH<\/h4>\n<pre class=\"b9x-code\"><code>month()<\/code><\/pre>\n<p>Returns the local month, 1\u201312. The value uses the date and time configured for the <strong>B9X Basic<\/strong> system.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print month();<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A number.<\/p>\n<h4 id=\"day\">DAY<\/h4>\n<pre class=\"b9x-code\"><code>day()<\/code><\/pre>\n<p>Returns the local day of month. The value uses the date and time configured for the <strong>B9X Basic<\/strong> system.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print day();<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A number.<\/p>\n<h4 id=\"year\">YEAR<\/h4>\n<pre class=\"b9x-code\"><code>year()<\/code><\/pre>\n<p>Returns the four-digit local year. The value uses the date and time configured for the <strong>B9X Basic<\/strong> system.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print year();<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A number.<\/p>\n<h2 id=\"8-mathematics\">8. Mathematics<\/h2>\n<h4 id=\"abs\">ABS<\/h4>\n<pre class=\"b9x-code\"><code>abs(x)<\/code><\/pre>\n<p>Absolute value.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print abs(-3.5);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 3.5.<\/p>\n<h4 id=\"min\">MIN<\/h4>\n<pre class=\"b9x-code\"><code>min(a, b)<\/code><\/pre>\n<p>Smaller argument.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print min(4, 9);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 4.<\/p>\n<h4 id=\"max\">MAX<\/h4>\n<pre class=\"b9x-code\"><code>max(a, b)<\/code><\/pre>\n<p>Larger argument.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print max(4, 9);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 9.<\/p>\n<h4 id=\"round\">ROUND<\/h4>\n<pre class=\"b9x-code\"><code>round(x)<\/code><\/pre>\n<p>Nearest integral value using the C math library\u2019s rounding rule.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print round(2.6);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 3.<\/p>\n<h4 id=\"sqrt\">SQRT<\/h4>\n<pre class=\"b9x-code\"><code>sqrt(x)<\/code><\/pre>\n<p>Square root.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> Inputs outside the mathematical domain produce the C math library\u2019s non-finite result.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print sqrt(81);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 9.<\/p>\n<h4 id=\"exp\">EXP<\/h4>\n<pre class=\"b9x-code\"><code>exp(x)<\/code><\/pre>\n<p>e raised to x.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print exp(1);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Approximately 2.71828.<\/p>\n<h4 id=\"log\">LOG<\/h4>\n<pre class=\"b9x-code\"><code>log(x)<\/code><\/pre>\n<p>Natural logarithm.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> Inputs outside the mathematical domain produce the C math library\u2019s non-finite result.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print log(exp(1));<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Approximately 1.<\/p>\n<h4 id=\"log10\">LOG10<\/h4>\n<pre class=\"b9x-code\"><code>log10(x)<\/code><\/pre>\n<p>Base-10 logarithm.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> Inputs outside the mathematical domain produce the C math library\u2019s non-finite result.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print log10(1000);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 3.<\/p>\n<h4 id=\"sin\">SIN<\/h4>\n<pre class=\"b9x-code\"><code>sin(radians)<\/code><\/pre>\n<p>Sine.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print sin(0);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 0.<\/p>\n<h4 id=\"cos\">COS<\/h4>\n<pre class=\"b9x-code\"><code>cos(radians)<\/code><\/pre>\n<p>Cosine.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print cos(0);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1.<\/p>\n<h4 id=\"tan\">TAN<\/h4>\n<pre class=\"b9x-code\"><code>tan(radians)<\/code><\/pre>\n<p>Tangent.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print tan(0);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 0.<\/p>\n<h4 id=\"asin\">ASIN<\/h4>\n<pre class=\"b9x-code\"><code>asin(x)<\/code><\/pre>\n<p>Inverse sine in radians.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> Inputs outside the mathematical domain produce the C math library\u2019s non-finite result.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print asin(1);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Approximately 1.5708.<\/p>\n<h4 id=\"acos\">ACOS<\/h4>\n<pre class=\"b9x-code\"><code>acos(x)<\/code><\/pre>\n<p>Inverse cosine in radians.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> Inputs outside the mathematical domain produce the C math library\u2019s non-finite result.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print acos(1);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 0.<\/p>\n<h4 id=\"atan\">ATAN<\/h4>\n<pre class=\"b9x-code\"><code>atan(x)<\/code><\/pre>\n<p>Inverse tangent in radians.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print atan(1);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Approximately 0.7854.<\/p>\n<h4 id=\"sinh\">SINH<\/h4>\n<pre class=\"b9x-code\"><code>sinh(x)<\/code><\/pre>\n<p>Hyperbolic sine.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print sinh(0);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 0.<\/p>\n<h4 id=\"cosh\">COSH<\/h4>\n<pre class=\"b9x-code\"><code>cosh(x)<\/code><\/pre>\n<p>Hyperbolic cosine.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print cosh(0);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1.<\/p>\n<h4 id=\"rnd\">RND<\/h4>\n<pre class=\"b9x-code\"><code>rnd(minimum, maximum)<\/code><\/pre>\n<p>Random integer in the inclusive range.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> maximum must be greater than or equal to minimum.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>roll = rnd(1, 6);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> An integer-valued number.<\/p>\n<h4 id=\"modulo\">MODULO<\/h4>\n<pre class=\"b9x-code\"><code>modulo(a, b)<\/code><\/pre>\n<p>C integer remainder after both arguments are truncated to integers.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> The divisor must not be zero.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print modulo(17, 5);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 2.<\/p>\n<h2 id=\"9-gpio-timing-adc-and-temperature\">9. GPIO, timing, ADC, and temperature<\/h2>\n<h4 id=\"wait\">WAIT<\/h4>\n<pre class=\"b9x-code\"><code>wait(milliseconds)<\/code><\/pre>\n<p>Pauses the current <strong>B9X Basic<\/strong> program for the requested number of milliseconds.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> Other background services can continue while the program is waiting.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>wait(250);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The supplied millisecond value.<\/p>\n<h4 id=\"getticks\">GETTICKS<\/h4>\n<pre class=\"b9x-code\"><code>getTicks(mode)<\/code><\/pre>\n<p>Reads elapsed operating time. Mode 0 returns seconds, 1 milliseconds, and 2 microseconds.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>start = getTicks(1);\nwait(50);\nprint getTicks(1) - start;<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Elapsed time as a number; an unsupported mode returns 0.<\/p>\n<h4 id=\"makeinput\">MAKEINPUT<\/h4>\n<pre class=\"b9x-code\"><code>makeInput(gpio)<\/code><\/pre>\n<p>Configures a positive GPIO number as an input with an internal pulldown.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> GPIO 0 and negative values are not changed.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>makeInput(4);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The GPIO argument.<\/p>\n<h4 id=\"getinput\">GETINPUT<\/h4>\n<pre class=\"b9x-code\"><code>getInput(gpio)<\/code><\/pre>\n<p>Reads a positive GPIO input.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>if getInput(4) == 1 then\n    print &quot;high&quot;;\nendif<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 0 or 1; for a nonpositive argument the argument itself is returned.<\/p>\n<h4 id=\"makeoutput\">MAKEOUTPUT<\/h4>\n<pre class=\"b9x-code\"><code>makeOutput(gpio)<\/code><\/pre>\n<p>Configures a positive GPIO number as an output.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>makeOutput(2);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The GPIO argument.<\/p>\n<h4 id=\"sethigh\">SETHIGH<\/h4>\n<pre class=\"b9x-code\"><code>setHigh(gpio)<\/code><\/pre>\n<p>Sets a positive GPIO output to logic 1.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>setHigh(2);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The GPIO argument.<\/p>\n<h4 id=\"setlow\">SETLOW<\/h4>\n<pre class=\"b9x-code\"><code>setLow(gpio)<\/code><\/pre>\n<p>Sets a positive GPIO output to logic 0.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>setLow(2);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The GPIO argument.<\/p>\n<h4 id=\"initadc\">INITADC<\/h4>\n<pre class=\"b9x-code\"><code>initADC()<\/code><\/pre>\n<p>Prepares analog-to-digital conversion for use.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>initADC();<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1.<\/p>\n<h4 id=\"readadcraw\">READADCRAW<\/h4>\n<pre class=\"b9x-code\"><code>readADCRaw(channel)<\/code><\/pre>\n<p>Reads a raw ADC conversion from the ADC channel number.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>raw = readADCRaw(3);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Raw ADC count.<\/p>\n<h4 id=\"readadcmv\">READADCMV<\/h4>\n<pre class=\"b9x-code\"><code>readADCMV(channel)<\/code><\/pre>\n<p>Reads a calibrated ADC result in millivolts.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>millivolts = readADCMV(3);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Millivolts.<\/p>\n<h4 id=\"deinitadc\">DEINITADC<\/h4>\n<pre class=\"b9x-code\"><code>deinitADC()<\/code><\/pre>\n<p>Releases the analog-to-digital converter when it is no longer needed.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>deinitADC();<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1.<\/p>\n<h4 id=\"readtemperature\">READTEMPERATURE<\/h4>\n<pre class=\"b9x-code\"><code>readTemperature(gpio)<\/code><\/pre>\n<p>Reads a DS18B20 temperature sensor connected to the specified GPIO.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>temperature = readTemperature(18);\nprint fmt$(temperature, &quot;0.0&quot;);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Temperature in degrees Celsius.<\/p>\n<h2 id=\"10-display-motion-wav-and-local-tts\">10. Display, motion, WAV, and local TTS<\/h2>\n<h4 id=\"displayinit\">DISPLAYINIT<\/h4>\n<pre class=\"b9x-code\"><code>displayInit(sda_gpio, scl_gpio)<\/code><\/pre>\n<p>Prepares a 128\u00d764 SSD1306 OLED display at I\u00b2C address 0x3C.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>displayInit(8, 9);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1.<\/p>\n<h4 id=\"displaytext\">DISPLAYTEXT<\/h4>\n<pre class=\"b9x-code\"><code>displayText(text$)<\/code><\/pre>\n<p>Displays text on the OLED.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> A line is displayed when ~ is reached. End every line, including the final line, with ~.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>displayText(&quot;B9X~Basic~ready~&quot;);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1.<\/p>\n<h4 id=\"motioninit\">MOTIONINIT<\/h4>\n<pre class=\"b9x-code\"><code>motionInit(port, tx_gpio)<\/code><\/pre>\n<p>Prepares the supported motion-distance sensor using the selected port and transmit GPIO.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>motionInit(1, 17);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1.<\/p>\n<h4 id=\"motiongetdistance\">MOTIONGETDISTANCE<\/h4>\n<pre class=\"b9x-code\"><code>motionGetDistance()<\/code><\/pre>\n<p>Reads the latest measured distance.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>distance = motionGetDistance();<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The reported distance.<\/p>\n<h4 id=\"playinit\">PLAYINIT<\/h4>\n<pre class=\"b9x-code\"><code>playInit(bclk_gpio, ws_gpio, data_gpio)<\/code><\/pre>\n<p>Prepares WAV audio playback on the selected pins.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>playInit(5, 4, 6);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The initialization result.<\/p>\n<h4 id=\"play\">PLAY<\/h4>\n<pre class=\"b9x-code\"><code>play(filename$)<\/code><\/pre>\n<p>Starts playback of a WAV file.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> Use an uncompressed 44.1-kHz, 16-bit stereo PCM WAV file.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>play(&quot;\/spiffs\/alert.wav&quot;);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The playback result.<\/p>\n<h4 id=\"isplaying\">ISPLAYING<\/h4>\n<pre class=\"b9x-code\"><code>isPlaying()<\/code><\/pre>\n<p>Tests whether WAV playback is active.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>while isPlaying() != 0 do\n    wait(20);\nwend<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Nonzero while busy; 0 when idle.<\/p>\n<h4 id=\"ttsinit\">TTSINIT<\/h4>\n<pre class=\"b9x-code\"><code>ttsInit(port, busy_gpio, tx_gpio, rx_gpio)<\/code><\/pre>\n<p>Prepares a local SYN6988 speech module.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>ttsInit(1, 7, 17, 18);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The initialization result.<\/p>\n<h4 id=\"ttsisbusy\">TTSISBUSY<\/h4>\n<pre class=\"b9x-code\"><code>ttsIsBusy()<\/code><\/pre>\n<p>Tests whether the local SYN6988 module is speaking.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>while ttsIsBusy() != 0 do\n    wait(20);\nwend<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Nonzero while busy; 0 when idle.<\/p>\n<h4 id=\"ttsspeak\">TTSSPEAK<\/h4>\n<pre class=\"b9x-code\"><code>ttsSpeak(text$)<\/code><\/pre>\n<p>Sends text to the local SYN6988 speech module.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>ttsSpeak(&quot;System ready.&quot;);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1 after submission.<\/p>\n<h2 id=\"11-openai-text-transcription-and-tts\">11. OpenAI text, transcription, and TTS<\/h2>\n<aside class=\"b9x-note\"><strong>Nonblocking design<\/strong> The x-suffixed functions submit work and return immediately. Submit a request once, then poll for its result with WAIT calls. Do not resubmit on every loop iteration.<\/aside>\n<h4 id=\"oaixinit\">OAIXINIT<\/h4>\n<pre class=\"b9x-code\"><code>oaixInit(api_key$)<\/code><\/pre>\n<p>Prepares OpenAI text questions using the supplied API key.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>ok = oaixInit(b9x_key1$);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1 on success or 0 on failure.<\/p>\n<h4 id=\"oaixaskquestion\">OAIXASKQUESTION<\/h4>\n<pre class=\"b9x-code\"><code>oaixAskQuestion(request_id, question$)<\/code><\/pre>\n<p>Queues a text question. request_id is an application-defined numeric tag passed into the worker request.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>queued = oaixAskQuestion(1, &quot;Name one moon of Mars.&quot;);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1 if queued; 0 if the queue is unavailable or full.<\/p>\n<h4 id=\"oaixgetanswer\">OAIXGETANSWER$<\/h4>\n<pre class=\"b9x-code\"><code>oaixGetAnswer$()<\/code><\/pre>\n<p>Polls for the next completed text answer.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>let answer$ = &quot;&quot;;\nwhile len(answer$) == 0 do\n    let answer$ = oaixGetAnswer$();\n    wait(50);\nwend\nprint answer$;<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> The answer string, or an empty string when no answer is ready.<\/p>\n<h4 id=\"vrxinit\">VRXINIT<\/h4>\n<pre class=\"b9x-code\"><code>vrxInit(bclk_gpio, ws_gpio, data_gpio, record_seconds, api_key$)<\/code><\/pre>\n<p>Initializes INMP441\/I\u00b2S recording and OpenAI transcription.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>ok = vrxInit(5, 4, 6, 5, b9x_key1$);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1 on success or 0 on failure.<\/p>\n<h4 id=\"vrxtranscribe\">VRXTRANSCRIBE<\/h4>\n<pre class=\"b9x-code\"><code>vrxTranscribe(request_id)<\/code><\/pre>\n<p>Queues one record-and-transcribe operation.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>queued = vrxTranscribe(100);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1 if queued; 0 if it could not be queued.<\/p>\n<h4 id=\"vrxgettranscript\">VRXGETTRANSCRIPT$<\/h4>\n<pre class=\"b9x-code\"><code>vrxGetTranscript$()<\/code><\/pre>\n<p>Polls for the next completed transcript.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>let transcript$ = &quot;&quot;;\nwhile len(transcript$) == 0 do\n    let transcript$ = vrxGetTranscript$();\n    wait(50);\nwend\nprint transcript$;<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Transcript text, or an empty string while no result is ready.<\/p>\n<h4 id=\"ttsxinit\">TTSXINIT<\/h4>\n<pre class=\"b9x-code\"><code>ttsxInit(bclk_gpio, ws_gpio, data_gpio, api_key$, voice$, instructions$)<\/code><\/pre>\n<p>Prepares OpenAI text-to-speech and audio output.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>ttsxInit(5, 4, 6, b9x_key1$, &quot;marin&quot;, &quot;Speak clearly.&quot;);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1 when ready.<\/p>\n<h4 id=\"ttsxspeak\">TTSXSPEAK<\/h4>\n<pre class=\"b9x-code\"><code>ttsxSpeak(text$)<\/code><\/pre>\n<p>Queues text for OpenAI speech synthesis and playback.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> Each submitted message can contain up to 255 characters.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>if ttsxSpeak(&quot;Hello from B9X.&quot;) == 0 then\n    print &quot;TTS queue busy&quot;;\nendif<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1 if accepted; 0 if busy or unavailable.<\/p>\n<h3 id=\"reliable-question-to-speech-pattern\">Reliable question-to-speech pattern<\/h3>\n<pre class=\"b9x-code\"><code>oaixInit(b9x_key1$);\nttsxInit(5, 4, 6, b9x_key1$, &quot;marin&quot;, &quot;Speak naturally.&quot;);\n\noaixAskQuestion(1, &quot;What is the capital of Michigan?&quot;);\nlet answer$ = &quot;&quot;;\nwhile len(answer$) == 0 do\n    let answer$ = oaixGetAnswer$();\n    wait(50);\nwend\n\n&#x27; Queue the completed answer exactly once.\naccepted = ttsxSpeak(answer$);\nprint answer$;<\/code><\/pre>\n<aside class=\"b9x-note\"><strong>API keys<\/strong> A 401 response means the supplied string is not a valid OpenAI API key. A voice name such as marin belongs in the voice argument, not in api_key$. Temporary connection failures should be retried after a delay.<\/aside>\n<h2 id=\"12-infrared-remote-control\">12. Infrared remote control<\/h2>\n<h4 id=\"irinit\">IRINIT<\/h4>\n<pre class=\"b9x-code\"><code>irInit(gpio)<\/code><\/pre>\n<p>Starts nonblocking infrared reception on the data pin of a demodulated 38-kHz receiver.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>irInit(15);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1 when reception starts.<\/p>\n<h4 id=\"irgetcode\">IRGETCODE<\/h4>\n<pre class=\"b9x-code\"><code>irGetCode()<\/code><\/pre>\n<p>Polls immediately for a decoded IR event and returns its command when confidence is greater than 90.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>code = irGetCode();\nif code &gt;= 0 then\n    print code;\nendif<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Command number, or -1 when no sufficiently confident event is available.<\/p>\n<p>The infrared receiver supports common remote-control formats, including Sony\/SIRC used by Sony Bravia remotes. IRGETCODE returns the decoded command number.<\/p>\n<h2 id=\"13-ws2812-addressable-leds\">13. WS2812 addressable LEDs<\/h2>\n<h4 id=\"ws2812init\">WS2812INIT<\/h4>\n<pre class=\"b9x-code\"><code>ws2812Init(gpio, led_count)<\/code><\/pre>\n<p>Creates a WS2812 strip instance.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>strip = ws2812Init(48, 8);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A positive handle on success; 0 on failure.<\/p>\n<h4 id=\"ws2812fill\">WS2812FILL<\/h4>\n<pre class=\"b9x-code\"><code>ws2812Fill(handle, red, green, blue)<\/code><\/pre>\n<p>Sets every pixel to one RGB color.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>ws2812Fill(strip, 0, 0, 32);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 0 on success; otherwise an error code.<\/p>\n<h4 id=\"ws2812setpixel\">WS2812SETPIXEL<\/h4>\n<pre class=\"b9x-code\"><code>ws2812SetPixel(handle, index, red, green, blue)<\/code><\/pre>\n<p>Sets one zero-based pixel.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>ws2812SetPixel(strip, 0, 32, 0, 0);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 0 on success; otherwise an error code.<\/p>\n<h4 id=\"ws2812show\">WS2812SHOW<\/h4>\n<pre class=\"b9x-code\"><code>ws2812Show(handle)<\/code><\/pre>\n<p>Updates the strip with all color changes made so far.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>ws2812Show(strip);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 0 on success; otherwise an error code.<\/p>\n<h4 id=\"ws2812clear\">WS2812CLEAR<\/h4>\n<pre class=\"b9x-code\"><code>ws2812Clear(handle)<\/code><\/pre>\n<p>Turns off every pixel on the strip.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>ws2812Clear(strip);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 0 on success; otherwise an error code.<\/p>\n<h4 id=\"ws2812isbusy\">WS2812ISBUSY<\/h4>\n<pre class=\"b9x-code\"><code>ws2812IsBusy(handle)<\/code><\/pre>\n<p>Tests whether a strip transmission is active.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>while ws2812IsBusy(strip) != 0 do\n    wait(1);\nwend<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> Nonzero while busy; 0 when idle.<\/p>\n<h2 id=\"14-mqtt\">14. MQTT<\/h2>\n<h4 id=\"initmqttclient\">INITMQTTCLIENT<\/h4>\n<pre class=\"b9x-code\"><code>initMQTTClient(uri$, username$, password$)<\/code><\/pre>\n<p>Starts an MQTT connection with the supplied server address and credentials.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>initMQTTClient(&quot;mqtt:\/\/broker.local&quot;, &quot;user&quot;, &quot;password&quot;);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> 1 when startup succeeds; otherwise an error value.<\/p>\n<h4 id=\"mqttclientsubscribe\">MQTTCLIENTSUBSCRIBE<\/h4>\n<pre class=\"b9x-code\"><code>mqttClientSubscribe(topic$)<\/code><\/pre>\n<p>Subscribes to a topic at QoS 0.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>id = mqttClientSubscribe(&quot;b9x\/input&quot;);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A message identifier, or a negative error value.<\/p>\n<h4 id=\"mqttclientunsubscribe\">MQTTCLIENTUNSUBSCRIBE<\/h4>\n<pre class=\"b9x-code\"><code>mqttClientUnsubscribe(topic$)<\/code><\/pre>\n<p>Removes a topic subscription.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>id = mqttClientUnsubscribe(&quot;b9x\/input&quot;);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A message identifier, or a negative error value.<\/p>\n<h4 id=\"mqttclientpublish\">MQTTCLIENTPUBLISH<\/h4>\n<pre class=\"b9x-code\"><code>mqttClientPublish(topic$, payload$)<\/code><\/pre>\n<p>Publishes a payload at QoS 1 with retain disabled.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>id = mqttClientPublish(&quot;b9x\/status&quot;, &quot;ready&quot;);<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> A message identifier, or a negative error value.<\/p>\n<h4 id=\"mqttclientgetmessage\">MQTTCLIENTGETMESSAGE$<\/h4>\n<pre class=\"b9x-code\"><code>mqttClientGetMessage$()<\/code><\/pre>\n<p>Polls for one MQTT event.<\/p>\n<p class=\"b9x-label\"><strong>Notes:<\/strong> TYPE can be DATA, CONNECT, DISCONNECT, SUBSCRIBED, UNSUBSCRIBED, PUBLISHED, or ERROR.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>let event$ = mqttClientGetMessage$();\nif len(event$) &gt; 0 then\n    print event$;\nendif<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> An empty string if none is ready; otherwise [TYPE][id][topic][data].<\/p>\n<h2 id=\"15-additional-supplied-functions\">15. Additional supplied functions<\/h2>\n<p>These simple functions are included for testing mixed numeric and string arguments.<\/p>\n<h4 id=\"user1\">USER1<\/h4>\n<pre class=\"b9x-code\"><code>user1(x)<\/code><\/pre>\n<p>Doubles its numeric argument.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print user1(10);       &#x27; 20<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> x \u00d7 2.<\/p>\n<h4 id=\"user2\">USER2<\/h4>\n<pre class=\"b9x-code\"><code>user2(a, b)<\/code><\/pre>\n<p>Adds two numeric arguments.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print user2(10, 20);   &#x27; 30<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> a + b.<\/p>\n<h4 id=\"usermix\">USERMIX<\/h4>\n<pre class=\"b9x-code\"><code>usermix(text$, number)<\/code><\/pre>\n<p>Combines a string-length calculation with a number.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>print usermix(&quot;ABC&quot;, 10);  &#x27; 13<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> number plus the character count of text$.<\/p>\n<h4 id=\"usermix\">USERMIX$<\/h4>\n<pre class=\"b9x-code\"><code>usermix$(text$, number)<\/code><\/pre>\n<p>Combines text and a number into one string.<\/p>\n<p class=\"b9x-label\"><strong>Example:<\/strong> <\/p>\n<pre class=\"b9x-code\"><code>let result$ = usermix$(&quot;ABC&quot;, 10);  &#x27; &quot;ABC 10&quot;<\/code><\/pre>\n<p class=\"b9x-label\"><strong>Returns:<\/strong> text$, a space, and the number.<\/p>\n<h2 id=\"16-protected-key-variables\">16. Protected key variables<\/h2>\n<p><strong>B9X Basic<\/strong> provides five predefined string values for passwords, API keys, and similar settings:<\/p>\n<pre class=\"b9x-code\"><code>b9x_key1$\nb9x_key2$\nb9x_key3$\nb9x_key4$\nb9x_key5$<\/code><\/pre>\n<p>Each can hold up to 512 characters and can be passed directly to functions such as oaixInit, vrxInit, and ttsxInit. Values can be set or replaced through the <strong>B9X Basic<\/strong> setup menu without displaying the existing value.<\/p>\n<aside class=\"b9x-note\"><strong>Good practice<\/strong> Use a protected key variable instead of placing passwords or API keys directly in a BASIC program that may be shared.<\/aside>\n<h2 id=\"17-complete-programming-patterns\">17. Complete programming patterns<\/h2>\n<h3 id=\"nonblocking-state-machine\">Nonblocking state machine<\/h3>\n<p>Use a state variable so an asynchronous request is submitted once and polled later.<\/p>\n<pre class=\"b9x-code\"><code>state = 0;\nlet answer$ = &quot;&quot;;\n\nwhile 1 do\n    if state == 0 then\n        if oaixAskQuestion(1, &quot;Give one short fact.&quot;) == 1 then\n            state = 1;\n        endif\n    endif\n\n    if state == 1 then\n        let answer$ = oaixGetAnswer$();\n        if len(answer$) &gt; 0 then\n            print answer$;\n            state = 2;\n        endif\n    endif\n\n    if state == 2 then\n        &#x27; Do not queue again unless a new event resets state.\n    endif\n\n    wait(50);\nwend<\/code><\/pre>\n<h3 id=\"gpio-event-with-debounce\">GPIO event with debounce<\/h3>\n<pre class=\"b9x-code\"><code>makeInput(4);\nlast = getInput(4);\n\nwhile 1 do\n    current = getInput(4);\n    if current != last then\n        wait(20);\n        current = getInput(4);\n        if current != last then\n            print current;\n            last = current;\n        endif\n    endif\n    wait(5);\nwend<\/code><\/pre>\n<h3 id=\"ir-controlled-leds\">IR-controlled LEDs<\/h3>\n<pre class=\"b9x-code\"><code>irInit(15);\nstrip = ws2812Init(48, 8);\n\nwhile 1 do\n    code = irGetCode();\n    if code == 21 then\n        ws2812Fill(strip, 32, 0, 0);\n        ws2812Show(strip);\n    endif\n    if code == 22 then\n        ws2812Clear(strip);\n    endif\n    wait(10);\nwend<\/code><\/pre>\n<h3 id=\"common-mistakes\">Common mistakes<\/h3>\n<div class=\"b9x-table-wrap\"><table>\n<thead><tr><th>Symptom<\/th><th>Likely cause<\/th><th>Correction<\/th><\/tr><\/thead>\n<tbody>\n<tr><td>Parse error after a simple statement<\/td><td>Missing semicolon.<\/td><td>Add ; after assignment, DIM, PRINT, CALL, or RETURN.<\/td><\/tr>\n<tr><td>Comparison behaves incorrectly<\/td><td>Used = instead of ==.<\/td><td>Use == for equality.<\/td><\/tr>\n<tr><td>String assignment parse error<\/td><td>LET omitted.<\/td><td>Write LET name$ = expression;.<\/td><\/tr>\n<tr><td>Repeated speech or requests<\/td><td>Queue function called every loop pass.<\/td><td>Submit once and move to a polling state.<\/td><\/tr>\n<tr><td>Empty async result<\/td><td>Work is not complete yet.<\/td><td>Poll with a delay; empty string means no queued result.<\/td><\/tr>\n<tr><td>OpenAI HTTP 401<\/td><td>Invalid key or voice name passed as key.<\/td><td>Pass a real API key in api_key$ and the voice separately.<\/td><\/tr>\n<tr><td>Audio resource busy<\/td><td>Two audio features were started at the same time.<\/td><td>Finish or stop one audio operation before starting another.<\/td><\/tr>\n<tr><td>Array error<\/td><td>Index outside 0..declared bound.<\/td><td>Validate indices before access.<\/td><\/tr>\n<\/tbody><\/table><\/div>\n<h2 id=\"appendix-a-language-limits\">Appendix A. Language limits<\/h2>\n<div class=\"b9x-table-wrap\"><table>\n<thead><tr><th>Language item<\/th><th>Maximum<\/th><\/tr><\/thead>\n<tbody>\n<tr><td>String value<\/td><td>512 characters<\/td><\/tr>\n<tr><td>Identifier<\/td><td>31 characters<\/td><\/tr>\n<tr><td>Numeric arrays<\/td><td>64<\/td><\/tr>\n<tr><td>Elements in each numeric array<\/td><td>1024; indices 0 through 1023<\/td><\/tr>\n<tr><td>User FUNCTION definitions<\/td><td>64<\/td><\/tr>\n<tr><td>Parameters in a user FUNCTION<\/td><td>8<\/td><\/tr>\n<tr><td>OpenAI TTS message<\/td><td>255 characters per submission<\/td><\/tr>\n<\/tbody><\/table><\/div>\n<p>These limits are important when planning larger <strong>B9X Basic<\/strong> programs.<\/p>\n<h2 id=\"appendix-b-quick-reference\">Appendix B. Quick reference<\/h2>\n<h3 id=\"statement-forms\">Statement forms<\/h3>\n<pre class=\"b9x-code\"><code>name = expression;\nlet name = expression;\nlet name$ = string-expression;\ndim array[upper_bound];\narray[index] = expression;\nprint expression;\nprint string-expression;\n\nif expression then ... [else ...] endif\nwhile expression do ... wend\nfor name = start to limit [step step] [do] ... next\n\nsub name() ... [return;] ... end sub\ncall name();\nfunction name(parameters) ... return expression; ... end function\nfunction name$(parameters) ... return string-expression; ... end function<\/code><\/pre>\n<h3 id=\"function-index\">Function index<\/h3>\n<div class=\"b9x-table-wrap\"><table>\n<thead><tr><th>Category<\/th><th>Functions<\/th><\/tr><\/thead>\n<tbody>\n<tr><td>Strings<\/td><td>len, left$, right$, mid$, chr$, asc, str$, val, instr, fmt$<\/td><\/tr>\n<tr><td>Date\/time<\/td><td>hour, minute, second, month, day, year, getTicks<\/td><\/tr>\n<tr><td>Math<\/td><td>abs, min, max, round, sqrt, exp, log, log10, sin, cos, tan, asin, acos, atan, sinh, cosh, rnd, modulo<\/td><\/tr>\n<tr><td>GPIO\/sensors<\/td><td>makeInput, getInput, makeOutput, setHigh, setLow, initADC, readADCRaw, readADCMV, deinitADC, readTemperature<\/td><\/tr>\n<tr><td>Task timing<\/td><td>wait<\/td><\/tr>\n<tr><td>Display\/motion\/audio<\/td><td>displayInit, displayText, motionInit, motionGetDistance, playInit, play, isPlaying<\/td><\/tr>\n<tr><td>Local TTS<\/td><td>ttsInit, ttsIsBusy, ttsSpeak<\/td><\/tr>\n<tr><td>OpenAI<\/td><td>oaixInit, oaixAskQuestion, oaixGetAnswer$, vrxInit, vrxTranscribe, vrxGetTranscript$, ttsxInit, ttsxSpeak<\/td><\/tr>\n<tr><td>Infrared<\/td><td>irInit, irGetCode<\/td><\/tr>\n<tr><td>WS2812<\/td><td>ws2812Init, ws2812Fill, ws2812SetPixel, ws2812Show, ws2812Clear, ws2812IsBusy<\/td><\/tr>\n<tr><td>MQTT<\/td><td>initMQTTClient, mqttClientSubscribe, mqttClientUnsubscribe, mqttClientPublish, mqttClientGetMessage$<\/td><\/tr>\n<tr><td>Additional supplied functions<\/td><td>user1, user2, usermix, usermix$<\/td><\/tr>\n<\/tbody><\/table><\/div>\n<h2 id=\"about-this-reference\">About this reference<\/h2>\n<p>This manual documents the <strong>B9X Basic<\/strong> language, its statements, and its available functions. For product information, updates, and support, visit b9xelectronics.com.<\/p>\n    <\/main>\n  <\/div>\n<\/article>\n\n\n\n<p class=\"wp-block-paragraph\">The information provided here by B9X Electronics (&#8216;we,&#8217; &#8216;us,&#8217; or &#8216;our&#8217;), in this document,<br>is for general informational purposes only. All information in this document<br>is provided in good faith, however, we make no representation or warranty of any kind,<br>express or implied, regarding the accuracy, adequacy, validity, reliability, availability,<br>or completeness of any information in this document. Under no circumstance shall we have any liability<br>to you for any loss or damage of any kind incurred as a result of the use of this document<br>or reliance on any information provided in this document.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>B9X Electronics Documentation B9X Basic Language Reference A complete guide to the B9X Basic language, including variables, expressions, operators, statements, control flow, functions, and practical examples. On this page How to use this reference 1. Language fundamentals 2. Values, variables, and arrays 3. Expressions and operators 4. Statements and control flow 5. Subroutines and user [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1282","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/b9xelectronics.com\/index.php?rest_route=\/wp\/v2\/pages\/1282","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/b9xelectronics.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/b9xelectronics.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/b9xelectronics.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/b9xelectronics.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1282"}],"version-history":[{"count":35,"href":"https:\/\/b9xelectronics.com\/index.php?rest_route=\/wp\/v2\/pages\/1282\/revisions"}],"predecessor-version":[{"id":1460,"href":"https:\/\/b9xelectronics.com\/index.php?rest_route=\/wp\/v2\/pages\/1282\/revisions\/1460"}],"wp:attachment":[{"href":"https:\/\/b9xelectronics.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1282"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}