B9X Basic

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.

How to use this reference

Start with Chapters 1–6 to learn the language. Use Chapters 7–16 as the function reference. Chapter 17 shows complete patterns, and the appendices collect limits and quick-reference tables.

Conventions

NotationMeaning
nameA numeric variable or identifier.
name$A string variable or string-returning function.
expressionA numeric expression.
string-expressionA string literal, string variable, string function, or concatenation.
[ optional ]Optional syntax in this manual only; do not type the brackets.
Additional statements or arguments.

Contents

  • 1. Language fundamentals
  • 2. Values, variables, and arrays
  • 3. Expressions and operators
  • 4. Statements and control flow
  • 5. Subroutines and user functions
  • 6. Core string functions
  • 7. Formatting and time
  • 8. Mathematics
  • 9. GPIO, timing, ADC, and temperature
  • 10. Display, motion, WAV, and local TTS
  • 11. OpenAI text, transcription, and TTS
  • 12. Infrared remote control
  • 13. WS2812 LEDs
  • 14. MQTT
  • 15. Additional supplied functions
  • 16. Protected key variables
  • 17. Complete programming patterns
  • Appendix A. Language limits
  • Appendix B. Quick reference

1. Language fundamentals

Program structure

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.

' A minimal B9X Basic program
let greeting$ = "Hello from B9X";
counter = 3;
print greeting$;
print counter;

Lexical rules

ItemRule
Numeric identifierStarts with A–Z, a–z, or underscore; remaining characters may also include digits.
String identifierUses the same identifier rules and ends with $.
Stored name length31 characters maximum.
Numeric literalDecimal integer, decimal fraction, or scientific notation, such as 12, 3.5, or 1.2e-3.
String literalText enclosed in double quotes.
Statement terminatorA semicolon ends assignments, DIM, PRINT, CALL, and RETURN.
NamesNames are case-sensitive. Use the exact function spelling shown in this reference.

Comments

The lexer accepts three comment forms.

' apostrophe comment to end of line
// C++-style comment to end of line
/* block comment
   across lines */

Truth values

B9X Basic has no separate Boolean type. Zero is false; any nonzero numeric value is true. Comparisons and logical operations produce numeric 0 or 1.

2. Values, variables, and arrays

Numeric values

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.

x = 12.5;
scientific = 1.2e3;
negative = -7;
print x + scientific;

String values

A string variable is identified by a trailing $. Its usable value is limited to 512 characters. String assignment requires LET.

let first$ = "B9X";
let message$ = first$ + " Basic";
print message$;

Assignment

count = 1;
let count = count + 1;
let label$ = "ready";

Numeric arrays

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.

dim samples[9];
for i = 0 to 9 do
    samples[i] = i ** 2;
next
print samples[4];

Scope and lifetime

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.

3. Expressions and operators

Operator precedence

The table is ordered from highest precedence to lowest. Parentheses override the normal order.

PrecedenceOperatorsMeaningAssociativity
1( )Grouping and function calls
2+ – NOT !Unary sign and logical negationRight
3**ExponentiationRight
4* /Multiplication and divisionLeft
5+ –Addition/subtraction; + also concatenates stringsLeft
6< <= > >=Relational comparisonLeft
7== !=Equality and inequalityLeft
8AND &&Logical ANDLeft
9OR ||Logical ORLeft

Arithmetic expressions

result = 2 + 3 * 4;        ' 14
power = 2 ** 3 ** 2;       ' 512: exponentiation groups right
average = (a + b) / 2;

Comparison and logical expressions

if temperature >= 25 and enabled == 1 then
    print "warm and enabled";
endif

different = value != previous;
inactive = not enabled;

String expressions

The + operator concatenates string expressions. String functions can be nested and concatenated.

let full$ = left$("B9X Basic", 3) + " " + str$(42);
print full$;

4. Statements and control flow

PRINT

PRINT writes one numeric or string expression to the B9X Basic output.

print 2 + 2;
print "ready";
print fmt$(12.5, "0.00");

IF / THEN / ELSE / ENDIF

if distance < 20 then
    print "near";
else
    print "far";
endif

ELSE is optional. Blocks can contain any supported statements, including nested IF, WHILE, and FOR blocks.

WHILE / DO / WEND

count = 0;
while count < 5 do
    print count;
    count = count + 1;
wend

FOR / TO / STEP / NEXT

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.

for i = 1 to 5 do
    print i;
next

for j = 10 to 0 step -2
    print j;
next

Blocks

Braces form an explicit statement block and may be empty. Normal IF/WHILE/FOR examples do not require braces.

{
    x = 1;
    print x;
}

Unavailable classic BASIC statements

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.

5. Subroutines and user functions

SUB

A SUB is a named, argument-free procedure. Invoke it with CALL. RETURN; exits early; reaching END SUB also returns.

sub blink()
    setHigh(2);
    wait(100);
    setLow(2);
end sub

call blink();

Numeric FUNCTION

function clamp(value, low, high)
    if value < low then
        return low;
    endif
    if value > high then
        return high;
    endif
    return value;
end function

print clamp(120, 0, 100);

String FUNCTION

A string-returning function name ends in $. Parameters may be numeric or string parameters ending in $. Return a string expression.

function greeting$(name$)
    return "Hello, " + name$;
end function

let text$ = greeting$("B9X");
print text$;

Function-call rules

  • A user FUNCTION may accept up to 8 parameters.
  • Parameter types are determined by whether the parameter name ends in $.
  • A missing numeric return falls back to 0; a missing string return falls back to an empty string.
  • Place a FUNCTION definition before code that calls it.

6. Core string functions

LEN

len(text$)

Returns the number of characters in a string.

Example:

print len("B9X");        ' 3

Returns: Numeric character count.

LEFT$

left$(text$, count)

Returns up to count characters from the left side of text$.

Notes: Negative counts act as zero; counts longer than the source are capped.

Example:

let a$ = left$("B9X Basic", 3);   ' "B9X"

Returns: A string.

right$(text$, count)

Returns up to count characters from the right side of text$.

Notes: Negative counts act as zero; counts longer than the source are capped.

Example:

let a$ = right$("B9X Basic", 5);  ' "Basic"

Returns: A string.

MID$

mid$(text$, start, count)

Extracts count characters beginning at the 1-based start position.

Notes: Positions are 1-based and the result is clipped at the string boundary.

Example:

let a$ = mid$("B9X Basic", 5, 5);  ' "Basic"

Returns: A string.

CHR$

chr$(code)

Creates a one-character string from a numeric byte value.

Notes: Values above 255 are masked to 8 bits; negative values become 0.

Example:

let newline$ = chr$(10);

Returns: A one-character string.

ASC

asc(text$)

Returns the byte value of the first character.

Example:

print asc("A");             ' 65

Returns: A numeric byte code; an empty string yields 0.

STR$

str$(number)

Converts a number to compact text using %g-style formatting.

Example:

let n$ = str$(12.5);       ' "12.5"

Returns: A string.

VAL

val(text$)

Parses a leading decimal floating-point number from text.

Example:

print val("12.5 volts");     ' 12.5

Returns: The parsed number; 0 if parsing cannot begin.

INSTR

instr(text$, find$)
instr(start, text$, find$)

Searches text$ for find$. The two-argument form starts at the beginning; the three-argument form starts at a 1-based position.

Notes: An empty search string returns 1 in the two-argument form or the requested start position in the three-argument form.

Example:

print instr("B9X Basic", "Basic");      ' 5
print instr(6, "banana", "a");          ' 6

Returns: The 1-based match position, or 0 when not found.

7. Formatting and time

FMT$

fmt$(number, format$)

Formats a number using familiar numeric-format characters.

Example:

print fmt$(1234.5, "#,##0.00");  ' 1,234.50
print fmt$(0.256, "0.0%");       ' 25.6%

Returns: The formatted string.

FMT$ format tokens

TokenMeaning
0Required digit; displays zero when no digit is present.
#Optional digit.
.Decimal separator.
,Thousands grouping.
%Multiplies by 100 and appends a percent sign.
+ at startForces a sign for positive values.
E or eScientific notation.
positive;negative;zeroSelects separate format sections.
"text"Quoted literal text.
\characterEscapes the next format character.

HOUR

hour()

Returns the local clock hour, 0–23. The value uses the date and time configured for the B9X Basic system.

Example:

print hour();

Returns: A number.

MINUTE

minute()

Returns the local minute, 0–59. The value uses the date and time configured for the B9X Basic system.

Example:

print minute();

Returns: A number.

SECOND

second()

Returns the local second, 0–59. The value uses the date and time configured for the B9X Basic system.

Example:

print second();

Returns: A number.

MONTH

month()

Returns the local month, 1–12. The value uses the date and time configured for the B9X Basic system.

Example:

print month();

Returns: A number.

DAY

day()

Returns the local day of month. The value uses the date and time configured for the B9X Basic system.

Example:

print day();

Returns: A number.

YEAR

year()

Returns the four-digit local year. The value uses the date and time configured for the B9X Basic system.

Example:

print year();

Returns: A number.

8. Mathematics

ABS

abs(x)

Absolute value.

Example:

print abs(-3.5);

Returns: 3.5.

MIN

min(a, b)

Smaller argument.

Example:

print min(4, 9);

Returns: 4.

MAX

max(a, b)

Larger argument.

Example:

print max(4, 9);

Returns: 9.

ROUND

round(x)

Nearest integral value using the C math library’s rounding rule.

Example:

print round(2.6);

Returns: 3.

SQRT

sqrt(x)

Square root.

Notes: Inputs outside the mathematical domain produce the C math library’s non-finite result.

Example:

print sqrt(81);

Returns: 9.

EXP

exp(x)

e raised to x.

Example:

print exp(1);

Returns: Approximately 2.71828.

LOG

log(x)

Natural logarithm.

Notes: Inputs outside the mathematical domain produce the C math library’s non-finite result.

Example:

print log(exp(1));

Returns: Approximately 1.

LOG10

log10(x)

Base-10 logarithm.

Notes: Inputs outside the mathematical domain produce the C math library’s non-finite result.

Example:

print log10(1000);

Returns: 3.

SIN

sin(radians)

Sine.

Example:

print sin(0);

Returns: 0.

COS

cos(radians)

Cosine.

Example:

print cos(0);

Returns: 1.

TAN

tan(radians)

Tangent.

Example:

print tan(0);

Returns: 0.

ASIN

asin(x)

Inverse sine in radians.

Notes: Inputs outside the mathematical domain produce the C math library’s non-finite result.

Example:

print asin(1);

Returns: Approximately 1.5708.

ACOS

acos(x)

Inverse cosine in radians.

Notes: Inputs outside the mathematical domain produce the C math library’s non-finite result.

Example:

print acos(1);

Returns: 0.

ATAN

atan(x)

Inverse tangent in radians.

Example:

print atan(1);

Returns: Approximately 0.7854.

SINH

sinh(x)

Hyperbolic sine.

Example:

print sinh(0);

Returns: 0.

COSH

cosh(x)

Hyperbolic cosine.

Example:

print cosh(0);

Returns: 1.

RND

rnd(minimum, maximum)

Random integer in the inclusive range.

Notes: maximum must be greater than or equal to minimum.

Example:

roll = rnd(1, 6);

Returns: An integer-valued number.

MODULO

modulo(a, b)

C integer remainder after both arguments are truncated to integers.

Notes: The divisor must not be zero.

Example:

print modulo(17, 5);

Returns: 2.

9. GPIO, timing, ADC, and temperature

WAIT

wait(milliseconds)

Pauses the current B9X Basic program for the requested number of milliseconds.

Notes: Other background services can continue while the program is waiting.

Example:

wait(250);

Returns: The supplied millisecond value.

GETTICKS

getTicks(mode)

Reads elapsed operating time. Mode 0 returns seconds, 1 milliseconds, and 2 microseconds.

Example:

start = getTicks(1);
wait(50);
print getTicks(1) - start;

Returns: Elapsed time as a number; an unsupported mode returns 0.

MAKEINPUT

makeInput(gpio)

Configures a positive GPIO number as an input with an internal pulldown.

Notes: GPIO 0 and negative values are not changed.

Example:

makeInput(4);

Returns: The GPIO argument.

GETINPUT

getInput(gpio)

Reads a positive GPIO input.

Example:

if getInput(4) == 1 then
    print "high";
endif

Returns: 0 or 1; for a nonpositive argument the argument itself is returned.

MAKEOUTPUT

makeOutput(gpio)

Configures a positive GPIO number as an output.

Example:

makeOutput(2);

Returns: The GPIO argument.

SETHIGH

setHigh(gpio)

Sets a positive GPIO output to logic 1.

Example:

setHigh(2);

Returns: The GPIO argument.

SETLOW

setLow(gpio)

Sets a positive GPIO output to logic 0.

Example:

setLow(2);

Returns: The GPIO argument.

INITADC

initADC()

Prepares analog-to-digital conversion for use.

Example:

initADC();

Returns: 1.

READADCRAW

readADCRaw(channel)

Reads a raw ADC conversion from the ADC channel number.

Example:

raw = readADCRaw(3);

Returns: Raw ADC count.

READADCMV

readADCMV(channel)

Reads a calibrated ADC result in millivolts.

Example:

millivolts = readADCMV(3);

Returns: Millivolts.

DEINITADC

deinitADC()

Releases the analog-to-digital converter when it is no longer needed.

Example:

deinitADC();

Returns: 1.

READTEMPERATURE

readTemperature(gpio)

Reads a DS18B20 temperature sensor connected to the specified GPIO.

Example:

temperature = readTemperature(18);
print fmt$(temperature, "0.0");

Returns: Temperature in degrees Celsius.

10. Display, motion, WAV, and local TTS

DISPLAYINIT

displayInit(sda_gpio, scl_gpio)

Prepares a 128×64 SSD1306 OLED display at I²C address 0x3C.

Example:

displayInit(8, 9);

Returns: 1.

DISPLAYTEXT

displayText(text$)

Displays text on the OLED.

Notes: A line is displayed when ~ is reached. End every line, including the final line, with ~.

Example:

displayText("B9X~Basic~ready~");

Returns: 1.

MOTIONINIT

motionInit(port, tx_gpio)

Prepares the supported motion-distance sensor using the selected port and transmit GPIO.

Example:

motionInit(1, 17);

Returns: 1.

MOTIONGETDISTANCE

motionGetDistance()

Reads the latest measured distance.

Example:

distance = motionGetDistance();

Returns: The reported distance.

PLAYINIT

playInit(bclk_gpio, ws_gpio, data_gpio)

Prepares WAV audio playback on the selected pins.

Example:

playInit(5, 4, 6);

Returns: The initialization result.

PLAY

play(filename$)

Starts playback of a WAV file.

Notes: Use an uncompressed 44.1-kHz, 16-bit stereo PCM WAV file.

Example:

play("/spiffs/alert.wav");

Returns: The playback result.

ISPLAYING

isPlaying()

Tests whether WAV playback is active.

Example:

while isPlaying() != 0 do
    wait(20);
wend

Returns: Nonzero while busy; 0 when idle.

TTSINIT

ttsInit(port, busy_gpio, tx_gpio, rx_gpio)

Prepares a local SYN6988 speech module.

Example:

ttsInit(1, 7, 17, 18);

Returns: The initialization result.

TTSISBUSY

ttsIsBusy()

Tests whether the local SYN6988 module is speaking.

Example:

while ttsIsBusy() != 0 do
    wait(20);
wend

Returns: Nonzero while busy; 0 when idle.

TTSSPEAK

ttsSpeak(text$)

Sends text to the local SYN6988 speech module.

Example:

ttsSpeak("System ready.");

Returns: 1 after submission.

11. OpenAI text, transcription, and TTS

OAIXINIT

oaixInit(api_key$)

Prepares OpenAI text questions using the supplied API key.

Example:

ok = oaixInit(b9x_key1$);

Returns: 1 on success or 0 on failure.

OAIXASKQUESTION

oaixAskQuestion(request_id, question$)

Queues a text question. request_id is an application-defined numeric tag passed into the worker request.

Example:

queued = oaixAskQuestion(1, "Name one moon of Mars.");

Returns: 1 if queued; 0 if the queue is unavailable or full.

OAIXGETANSWER$

oaixGetAnswer$()

Polls for the next completed text answer.

Example:

let answer$ = "";
while len(answer$) == 0 do
    let answer$ = oaixGetAnswer$();
    wait(50);
wend
print answer$;

Returns: The answer string, or an empty string when no answer is ready.

VRXINIT

vrxInit(bclk_gpio, ws_gpio, data_gpio, record_seconds, api_key$)

Initializes INMP441/I²S recording and OpenAI transcription.

Example:

ok = vrxInit(5, 4, 6, 5, b9x_key1$);

Returns: 1 on success or 0 on failure.

VRXTRANSCRIBE

vrxTranscribe(request_id)

Queues one record-and-transcribe operation.

Example:

queued = vrxTranscribe(100);

Returns: 1 if queued; 0 if it could not be queued.

VRXGETTRANSCRIPT$

vrxGetTranscript$()

Polls for the next completed transcript.

Example:

let transcript$ = "";
while len(transcript$) == 0 do
    let transcript$ = vrxGetTranscript$();
    wait(50);
wend
print transcript$;

Returns: Transcript text, or an empty string while no result is ready.

TTSXINIT

ttsxInit(bclk_gpio, ws_gpio, data_gpio, api_key$, voice$, instructions$)

Prepares OpenAI text-to-speech and audio output.

Example:

ttsxInit(5, 4, 6, b9x_key1$, "marin", "Speak clearly.");

Returns: 1 when ready.

TTSXSPEAK

ttsxSpeak(text$)

Queues text for OpenAI speech synthesis and playback.

Notes: Each submitted message can contain up to 255 characters.

Example:

if ttsxSpeak("Hello from B9X.") == 0 then
    print "TTS queue busy";
endif

Returns: 1 if accepted; 0 if busy or unavailable.

Reliable question-to-speech pattern

oaixInit(b9x_key1$);
ttsxInit(5, 4, 6, b9x_key1$, "marin", "Speak naturally.");

oaixAskQuestion(1, "What is the capital of Michigan?");
let answer$ = "";
while len(answer$) == 0 do
    let answer$ = oaixGetAnswer$();
    wait(50);
wend

' Queue the completed answer exactly once.
accepted = ttsxSpeak(answer$);
print answer$;

12. Infrared remote control

IRINIT

irInit(gpio)

Starts nonblocking infrared reception on the data pin of a demodulated 38-kHz receiver.

Example:

irInit(15);

Returns: 1 when reception starts.

IRGETCODE

irGetCode()

Polls immediately for a decoded IR event and returns its command when confidence is greater than 90.

Example:

code = irGetCode();
if code >= 0 then
    print code;
endif

Returns: Command number, or -1 when no sufficiently confident event is available.

The infrared receiver supports common remote-control formats, including Sony/SIRC used by Sony Bravia remotes. IRGETCODE returns the decoded command number.

13. WS2812 addressable LEDs

WS2812INIT

ws2812Init(gpio, led_count)

Creates a WS2812 strip instance.

Example:

strip = ws2812Init(48, 8);

Returns: A positive handle on success; 0 on failure.

WS2812FILL

ws2812Fill(handle, red, green, blue)

Sets every pixel to one RGB color.

Example:

ws2812Fill(strip, 0, 0, 32);

Returns: 0 on success; otherwise an error code.

WS2812SETPIXEL

ws2812SetPixel(handle, index, red, green, blue)

Sets one zero-based pixel.

Example:

ws2812SetPixel(strip, 0, 32, 0, 0);

Returns: 0 on success; otherwise an error code.

WS2812SHOW

ws2812Show(handle)

Updates the strip with all color changes made so far.

Example:

ws2812Show(strip);

Returns: 0 on success; otherwise an error code.

WS2812CLEAR

ws2812Clear(handle)

Turns off every pixel on the strip.

Example:

ws2812Clear(strip);

Returns: 0 on success; otherwise an error code.

WS2812ISBUSY

ws2812IsBusy(handle)

Tests whether a strip transmission is active.

Example:

while ws2812IsBusy(strip) != 0 do
    wait(1);
wend

Returns: Nonzero while busy; 0 when idle.

14. MQTT

INITMQTTCLIENT

initMQTTClient(uri$, username$, password$)

Starts an MQTT connection with the supplied server address and credentials.

Example:

initMQTTClient("mqtt://broker.local", "user", "password");

Returns: 1 when startup succeeds; otherwise an error value.

MQTTCLIENTSUBSCRIBE

mqttClientSubscribe(topic$)

Subscribes to a topic at QoS 0.

Example:

id = mqttClientSubscribe("b9x/input");

Returns: A message identifier, or a negative error value.

MQTTCLIENTUNSUBSCRIBE

mqttClientUnsubscribe(topic$)

Removes a topic subscription.

Example:

id = mqttClientUnsubscribe("b9x/input");

Returns: A message identifier, or a negative error value.

MQTTCLIENTPUBLISH

mqttClientPublish(topic$, payload$)

Publishes a payload at QoS 1 with retain disabled.

Example:

id = mqttClientPublish("b9x/status", "ready");

Returns: A message identifier, or a negative error value.

MQTTCLIENTGETMESSAGE$

mqttClientGetMessage$()

Polls for one MQTT event.

Notes: TYPE can be DATA, CONNECT, DISCONNECT, SUBSCRIBED, UNSUBSCRIBED, PUBLISHED, or ERROR.

Example:

let event$ = mqttClientGetMessage$();
if len(event$) > 0 then
    print event$;
endif

Returns: An empty string if none is ready; otherwise [TYPE][id][topic][data].

15. Additional supplied functions

These simple functions are included for testing mixed numeric and string arguments.

USER1

user1(x)

Doubles its numeric argument.

Example:

print user1(10);       ' 20

Returns: x × 2.

USER2

user2(a, b)

Adds two numeric arguments.

Example:

print user2(10, 20);   ' 30

Returns: a + b.

USERMIX

usermix(text$, number)

Combines a string-length calculation with a number.

Example:

print usermix("ABC", 10);  ' 13

Returns: number plus the character count of text$.

USERMIX$

usermix$(text$, number)

Combines text and a number into one string.

Example:

let result$ = usermix$("ABC", 10);  ' "ABC 10"

Returns: text$, a space, and the number.

16. Protected key variables

B9X Basic provides five predefined string values for passwords, API keys, and similar settings:

b9x_key1$
b9x_key2$
b9x_key3$
b9x_key4$
b9x_key5$

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 B9X Basic setup menu without displaying the existing value.

17. Complete programming patterns

Nonblocking state machine

Use a state variable so an asynchronous request is submitted once and polled later.

state = 0;
let answer$ = "";

while 1 do
    if state == 0 then
        if oaixAskQuestion(1, "Give one short fact.") == 1 then
            state = 1;
        endif
    endif

    if state == 1 then
        let answer$ = oaixGetAnswer$();
        if len(answer$) > 0 then
            print answer$;
            state = 2;
        endif
    endif

    if state == 2 then
        ' Do not queue again unless a new event resets state.
    endif

    wait(50);
wend

GPIO event with debounce

makeInput(4);
last = getInput(4);

while 1 do
    current = getInput(4);
    if current != last then
        wait(20);
        current = getInput(4);
        if current != last then
            print current;
            last = current;
        endif
    endif
    wait(5);
wend

IR-controlled LEDs

irInit(15);
strip = ws2812Init(48, 8);

while 1 do
    code = irGetCode();
    if code == 21 then
        ws2812Fill(strip, 32, 0, 0);
        ws2812Show(strip);
    endif
    if code == 22 then
        ws2812Clear(strip);
    endif
    wait(10);
wend

Common mistakes

SymptomLikely causeCorrection
Parse error after a simple statementMissing semicolon.Add ; after assignment, DIM, PRINT, CALL, or RETURN.
Comparison behaves incorrectlyUsed = instead of ==.Use == for equality.
String assignment parse errorLET omitted.Write LET name$ = expression;.
Repeated speech or requestsQueue function called every loop pass.Submit once and move to a polling state.
Empty async resultWork is not complete yet.Poll with a delay; empty string means no queued result.
OpenAI HTTP 401Invalid key or voice name passed as key.Pass a real API key in api_key$ and the voice separately.
Audio resource busyTwo audio features were started at the same time.Finish or stop one audio operation before starting another.
Array errorIndex outside 0..declared bound.Validate indices before access.

Appendix A. Language limits

Language itemMaximum
String value512 characters
Identifier31 characters
Numeric arrays64
Elements in each numeric array1024; indices 0 through 1023
User FUNCTION definitions64
Parameters in a user FUNCTION8
OpenAI TTS message255 characters per submission

These limits are important when planning larger B9X Basic programs.

Appendix B. Quick reference

Statement forms

name = expression;
let name = expression;
let name$ = string-expression;
dim array[upper_bound];
array[index] = expression;
print expression;
print string-expression;

if expression then ... [else ...] endif
while expression do ... wend
for name = start to limit [step step] [do] ... next

sub name() ... [return;] ... end sub
call name();
function name(parameters) ... return expression; ... end function
function name$(parameters) ... return string-expression; ... end function

Function index

CategoryFunctions
Stringslen, left$, right$, mid$, chr$, asc, str$, val, instr, fmt$
Date/timehour, minute, second, month, day, year, getTicks
Mathabs, min, max, round, sqrt, exp, log, log10, sin, cos, tan, asin, acos, atan, sinh, cosh, rnd, modulo
GPIO/sensorsmakeInput, getInput, makeOutput, setHigh, setLow, initADC, readADCRaw, readADCMV, deinitADC, readTemperature
Task timingwait
Display/motion/audiodisplayInit, displayText, motionInit, motionGetDistance, playInit, play, isPlaying
Local TTSttsInit, ttsIsBusy, ttsSpeak
OpenAIoaixInit, oaixAskQuestion, oaixGetAnswer$, vrxInit, vrxTranscribe, vrxGetTranscript$, ttsxInit, ttsxSpeak
InfraredirInit, irGetCode
WS2812ws2812Init, ws2812Fill, ws2812SetPixel, ws2812Show, ws2812Clear, ws2812IsBusy
MQTTinitMQTTClient, mqttClientSubscribe, mqttClientUnsubscribe, mqttClientPublish, mqttClientGetMessage$
Additional supplied functionsuser1, user2, usermix, usermix$

About this reference

This manual documents the B9X Basic language, its statements, and its available functions. For product information, updates, and support, visit b9xelectronics.com.

The information provided here by B9X Electronics (‘we,’ ‘us,’ or ‘our’), in this document,
is for general informational purposes only. All information in this document
is provided in good faith, however, we make no representation or warranty of any kind,
express or implied, regarding the accuracy, adequacy, validity, reliability, availability,
or completeness of any information in this document. Under no circumstance shall we have any liability
to you for any loss or damage of any kind incurred as a result of the use of this document
or reliance on any information provided in this document.