NikiBasic e' dedicato a mio figlio Nikita.
Versione del linguaggio: NikiBasic Core 1.0.0. Stato: stabile, congelato e
verificato il 20 agosto 2026 su PC, ESP32 e tramite build PIC32. Le correzioni
compatibili mantengono la versione del linguaggio; il firmware di prodotto puo'
avere una propria versione distinta.
Questo manuale descrive il linguaggio comune e segnala i comandi forniti dalle
estensioni. Un comando legato a filesystem, rete, orologio o hardware puo' non
essere disponibile su tutte le piattaforme. HELP elenca sempre i comandi
effettivamente presenti nella build in uso.
Per mostrare un testo:
PRINT "CIAO"
Risultato:
CIAO
Per eseguire calcoli:
PRINT 2+3
PRINT 10/2
Il comando HELP mostra l'elenco dei comandi disponibili.
Sull'ESP32 del computer di stazione, DEVINFO identifica chiaramente il sistema.
La release corrente mostra:
Software: NikiBasic
Platform: ESP32
NikiBasic version: 1.0.0
Firmware version: 1.0.9-nikibasic-identity
Mostra inoltre Device ID, stato Wi-Fi/MQTT e supporto attivo: SD oppure
FAT FLASH.
Un comando senza numero viene eseguito subito:
PRINT "PROVA"
Una riga che comincia con un numero viene invece conservata come parte di un
programma:
10 PRINT "CIAO"
20 PRINT "QUESTO E' IL MIO PRIMO PROGRAMMA"
30 END
I numeri stabiliscono l'ordine delle righe. E' utile lasciare uno spazio tra i
numeri, per esempio 10, 20, 30, cosi' sara' possibile aggiungere in seguito una
riga 15 senza riscrivere tutto.
I comandi principali per lavorare con un programma sono:
| Comando | Cosa fa |
|---|---|
LIST |
Mostra il programma conservato in memoria. |
RUN |
Avvia il programma. |
NEW |
Cancella il programma corrente e ricomincia da zero. |
END |
Termina normalmente l'esecuzione. |
REM testo |
Inserisce una nota leggibile che non viene eseguita. |
PAUSE millisecondi |
Sospende il programma lasciandolo interrompibile. |
Esempio di commento:
10 REM QUESTO PROGRAMMA SALUTA L'UTENTE
20 PRINT "BUONGIORNO"
30 END
E' possibile mettere piu' istruzioni sulla stessa riga separandole con ::
10 A=5:PRINT A
Per rendere i programmi facili da leggere, e' comunque preferibile usare una
riga per ogni operazione.
Per sostituire una riga, riscrivere lo stesso numero con il nuovo contenuto:
10 PRINT "PRIMA VERSIONE"
10 PRINT "VERSIONE CORRETTA"
LIST mostrera' soltanto la seconda versione. Per eliminare una riga, inviare
soltanto il suo numero:
10
Questa operazione modifica il programma in memoria, ma non aggiorna
automaticamente il file dal quale era stato caricato. Per rendere permanente la
modifica occorre eseguire nuovamente SAVE.
Un metodo semplice riduce il rischio di perdere modifiche o eseguire un
programma diverso da quello atteso:
NEW prima di iniziare un programma nuovo;LIST;RUN;SAVE soltanto quando il risultato e' quello desiderato.
RUN controlla e compila l'intero programma prima di eseguirlo. Se trova una
riga non valida, non lascia una compilazione parziale: la console rimane
utilizzabile e la riga puo' essere corretta.
Una variabile e' un contenitore con un nome. Serve a conservare un valore per
usarlo in seguito.
Le lettere da A a Z possono contenere direttamente numeri:
A=12
PRINT A
Per nomi piu' descrittivi si usa LET:
LET PREZZO=25
PRINT PREZZO
Il testo va racchiuso tra virgolette. I nomi delle variabili che contengono
testo terminano con $:
LET NOME$="MASSIMO"
PRINT "CIAO ",NOME$
Regole pratiche:
LET prima di usarla;$;$ soltanto per le variabili di testo;
Il comando VARS mostra le variabili e i valori presenti. Il comando FREE
mostra quanta memoria BASIC e' ancora disponibile.
I registri A-Z sono comodi per calcoli brevi e contatori. Le variabili con
nome rendono invece piu' chiaro un programma lungo:
A=18
LET TEMPER=18
Entrambe conservano un numero, ma TEMPER spiega meglio lo scopo del valore.
NikiBasic distingue le variabili numeriche da quelle stringa mediante $:
LET STATO=1
LET STATO$="ATTIVO"
Sono due variabili diverse. Per evitare errori, scegliere nomi brevi ma
significativi e non riutilizzare lo stesso nome per scopi non collegati.
Durante lo sviluppo usare:
VARS
FREE
VARS aiuta a trovare valori inattesi dopo un ciclo o un INPUT. FREE
riporta l'uso delle aree BASIC, comprese righe, programma compilato e variabili.
Se lo spazio si riduce troppo, accorciare il programma o eliminare dati e
variabili non necessari; non ignorare gli errori di memoria.
INPUT ferma il programma e aspetta che l'utente scriva una risposta e prema
Invio. La variabile deve essere stata preparata prima con LET.
10 LET NOME$
20 INPUT "COME TI CHIAMI";NOME$
30 PRINT "CIAO ",NOME$
40 END
Per chiedere un numero:
10 LET ETA=0
20 INPUT "QUANTI ANNI HAI";ETA
30 PRINT "HAI ",ETA," ANNI"
40 END
Si possono leggere piu' risposte insieme:
10 LET BASE=0
20 LET ALTEZZA=0
30 INPUT "BASE E ALTEZZA";BASE,ALTEZZA
40 PRINT "AREA = ",BASE*ALTEZZA
50 END
In questo caso l'utente separa i due numeri con una virgola, per esempio
5,8.
La richiesta puo' leggere registri o variabili gia' dichiarate. Se viene
richiesto un numero, inserire un valore numerico; se la destinazione termina con
$, il testo viene conservato come stringa. Un dato del tipo sbagliato produce
un errore esplicito invece di modificare una variabile in modo ambiguo.
Quando un programma resta in attesa su INPUT, BREAK deve poterlo riportare
alla console. Questo e' utile soprattutto durante le prove remote.
| Simbolo | Significato | Esempio |
|---|---|---|
+ |
Addizione | PRINT 4+2 |
- |
Sottrazione | PRINT 4-2 |
* |
Moltiplicazione | PRINT 4*2 |
/ |
Divisione | PRINT 4/2 |
= |
Uguale o assegnazione | A=5 |
< |
Minore | A<10 |
> |
Maggiore | A>10 |
<= |
Minore o uguale | A<=10 |
>= |
Maggiore o uguale | A>=10 |
<> |
Diverso | A<>10 |
AND |
Entrambe le condizioni sono vere | A>0 AND A<10 |
OR |
Almeno una condizione e' vera | A=1 OR A=2 |
XOR |
Una sola delle due condizioni e' vera | A=1 XOR B=1 |
NikiBasic rispetta le normali priorita' matematiche. Le espressioni tra
parentesi vengono calcolate per prime; seguono moltiplicazioni e divisioni;
infine vengono eseguite addizioni e sottrazioni.
PRINT 2+3*4
Il risultato e' 14, perche' viene calcolato prima 3*4 e poi viene aggiunto
2. Non si ottiene 20, che sarebbe invece il risultato eseguendo le
operazioni semplicemente da sinistra verso destra, come avviene in alcuni
interpreti BASIC tradizionali piu' semplici.
Le parentesi permettono di cambiare esplicitamente l'ordine:
PRINT (2+3)*4
In questo caso il risultato e' 20, perche' viene calcolato prima 2+3.
Le parentesi possono essere nidificate, cioe' inserite una dentro l'altra:
PRINT 2*(3+(4*5))
NikiBasic calcola prima la parentesi piu' interna e procede verso l'esterno:
4*5 restituisce 20;3+20 restituisce 23;2*23 restituisce 46.
Il risultato finale e' quindi 46. Quando un'espressione e' complessa, usare
le parentesi rende il calcolo piu' chiaro e facile da controllare.
Lasciare uno spazio prima e dopo AND, OR e XOR.
I confronti vengono usati soprattutto dentro IF e WHILE. E' buona pratica
scrivere condizioni esplicite:
IF TEMPER>=20 AND TEMPER<=30 THEN PRINT "INTERVALLO NORMALE"
Non unire gli operatori alfabetici ai nomi: A OR B e' valido, mentre AORB
e' una parola diversa e viene rifiutata. Questa regola evita che un nome venga
interpretato accidentalmente come piu' token.
Divisione per zero, radice di un numero negativo, logaritmo fuori dominio e
overflow numerico generano un errore. Dopo l'errore la console deve restare
disponibile: correggere valori o formula e ripetere il comando.
IF permette al programma di scegliere cosa fare.
10 LET ETA=0
20 INPUT "ETA";ETA
30 IF ETA>=18 THEN PRINT "MAGGIORENNE" ELSE PRINT "MINORENNE"
40 END
Per decisioni composte da piu' righe si usano ELSE e ENDIF:
10 A=7
20 IF A>5 THEN
30 PRINT "A E' MAGGIORE DI 5"
40 ELSE
50 PRINT "A NON E' MAGGIORE DI 5"
60 ENDIF
70 END
La forma monoriga e' adatta a un'azione breve. La forma multilinea e'
preferibile quando ciascun ramo contiene piu' istruzioni. Ogni IF multilinea
deve avere il proprio ENDIF; l'indentazione non cambia l'esecuzione ma rende
visibili gli abbinamenti:
10 A=7
20 IF A>0 THEN
30 IF A<10 THEN
40 PRINT "A HA UNA CIFRA"
50 ENDIF
60 ELSE
70 PRINT "A NON E' POSITIVO"
80 ENDIF
90 END
Nelle righe inviate alla console gli spazi iniziali sono facoltativi. Sono
mostrati nell'esempio soltanto per rendere leggibile la struttura.
FOR ripete un gruppo di righe per un numero stabilito di volte. NEXT chiude
il ciclo.
10 FOR I=1 TO 5
20 PRINT I
30 NEXT I
40 END
Con STEP si sceglie l'incremento:
10 FOR I=10 TO 0 STEP -2
20 PRINT I
30 NEXT I
40 END
Il passo deve essere coerente con la direzione del ciclo. Usare un passo
positivo per salire e negativo per scendere. La variabile indicata da NEXT
deve corrispondere a quella del relativo FOR.
WHILE continua finche' una condizione e' vera. WEND chiude il ciclo.
10 A=1
20 WHILE A<=5
30 PRINT A
40 A=A+1
50 WEND
60 END
BREAK interrompe il ciclo. CNTN passa direttamente al giro successivo.
Durante un programma e' possibile interrompere l'esecuzione dalla console con
BREAK. Sulla console seriale ESP32 la sequenza prevista e' composta da tre
ritorni carrello consecutivi; app Android e Terminale Universale espongono un
pulsante BREAK.
CNTN salta il resto dell'iterazione corrente e torna a valutare la condizione
del WHILE. BREAK esce dal ciclo piu' vicino. Un esempio che stampa soltanto
i valori dispari e si ferma prima di 8:
10 A=0
20 WHILE A<10
30 A=A+1
40 IF A=8 THEN BREAK
50 IF A=2 OR A=4 OR A=6 THEN CNTN
60 PRINT A
70 WEND
80 END
Assicurarsi che almeno una riga del ciclo possa rendere falsa la condizione;
altrimenti il ciclo continua finche' non arriva BREAK.
GOTO continua l'esecuzione da un'altra riga:
10 PRINT "INIZIO"
20 GOTO 40
30 PRINT "QUESTA RIGA VIENE SALTATA"
40 PRINT "FINE"
GOSUB richiama una parte riutilizzabile del programma. RETURN torna alla
riga successiva alla chiamata:
10 PRINT "PRIMA"
20 GOSUB 100
30 PRINT "DOPO"
40 END
100 PRINT "SONO NEL SOTTOPROGRAMMA"
110 RETURN
Un sottoprogramma deve terminare con RETURN, non con un salto casuale nel
programma principale. END impedisce che l'esecuzione normale cada dentro le
righe del sottoprogramma poste in fondo:
10 GOSUB 100
20 PRINT "FINE PROGRAMMA"
30 END
100 PRINT "OPERAZIONE COMUNE"
110 RETURN
Usare GOTO per cambiare realmente fase del programma; per operazioni
riutilizzabili preferire GOSUB, perche' conserva automaticamente il punto di
ritorno.
DATA conserva una serie di valori. READ li legge uno dopo l'altro e
RESTORE ricomincia dal primo valore.
10 DATA 12,25,8
20 READ A
30 READ B
40 READ C
50 PRINT A,B,C
60 RESTORE
70 READ A
80 PRINT A
90 END
Non chiedere con READ piu' valori di quelli inseriti con DATA.
DATA e' utile per tabelle fisse, messaggi o sequenze di calibrazione che fanno
parte del programma. RESTORE riporta il puntatore al primo elemento, quindi la
stessa tabella puo' essere riletta:
10 DATA 3,6,9
20 FOR I=1 TO 3
30 READ A
40 PRINT A
50 NEXT I
60 RESTORE
70 READ A
80 PRINT "PRIMO=",A
90 END
Il tipo della destinazione deve essere compatibile con il valore letto.
Una funzione esegue un'operazione e restituisce un risultato.
| Funzione | Risultato | Esempio |
|---|---|---|
ABS(x) |
Valore senza segno | ABS(-5) restituisce 5 |
SQR(x) |
Radice quadrata | SQR(25) restituisce 5 |
INT(x) |
Numero intero inferiore | INT(3.8) restituisce 3 |
RND(x) |
Numero casuale tra 0 e 1 | PRINT RND(1) |
SIN(x) |
Seno | PRINT SIN(1) |
COS(x) |
Coseno | PRINT COS(1) |
TAN(x) |
Tangente | PRINT TAN(1) |
ATAN(x) |
Arcotangente | PRINT ATAN(1) |
LOG(x) |
Logaritmo naturale | PRINT LOG(10) |
EXP(x) |
Esponenziale | PRINT EXP(1) |
SGN(x) |
-1, 0 oppure 1 secondo il segno |
PRINT SGN(-8) |
VAL(s$) |
Converte testo in numero | VAL("12") restituisce 12 |
LEN(s$) |
Conta i caratteri | LEN("CIAO") restituisce 4 |
ASC(s$) |
Codice del primo carattere | PRINT ASC("A") |
| Funzione | Risultato | Esempio |
|---|---|---|
STR(n) |
Converte un numero in testo | STR(12) |
CHR(n) |
Carattere corrispondente al codice indicato | CHR(65) restituisce A |
LEFT(s$,n) |
Primi n caratteri |
LEFT("NIKIBASIC",4) restituisce NIKI |
RIGHT(s$,n) |
Ultimi n caratteri |
RIGHT("NIKIBASIC",5) restituisce BASIC |
MID(s$,inizio,n) |
Parte centrale del testo | MID("NIKIBASIC",5,5) restituisce BASIC |
INSTR(s$,testo$) |
Posizione del testo cercato, oppure 0 | INSTR("NIKIBASIC","BASIC") restituisce 5 |
Le funzioni possono comparire dentro espressioni piu' grandi:
PRINT ABS(-4)+SQR(25)
PRINT LEFT("NIKIBASIC",4),RIGHT("NIKIBASIC",5)
Con funzioni annidate usare parentesi chiare e provare prima le singole parti.
Gli indici e le lunghezze delle funzioni di testo devono riferirsi a posizioni
valide; un errore viene segnalato senza scrivere oltre i buffer disponibili.
POKE scrive un byte nella memoria virtuale NikiBasic e PEEK lo legge:
POKE 0,65
PRINT PEEK(0)
Il risultato e' 65. Indirizzo e valore devono essere numeri finiti e interi;
il byte deve essere compreso tra 0 e 255 e l'indirizzo deve appartenere alla
memoria disponibile sulla piattaforma. Valori negativi, frazionari o fuori
intervallo vengono rifiutati.
Questi comandi sono strumenti a basso livello. Non usarli come sostituti delle
variabili normali e non assumere che lo stesso indirizzo abbia un significato
hardware identico su PC, ESP32 e PIC32.
I comandi di questa sezione appartengono all'estensione filesystem. Sono
disponibili nella build PC e nelle composizioni embedded che includono un
filesystem.
I comandi per lavorare con file e cartelle sono:
| Comando | Cosa fa |
|---|---|
SAVE "nome.bas" |
Salva il programma corrente. |
LOAD "nome.bas" |
Carica un programma salvato. |
DIR |
Mostra file e cartelle disponibili. |
CAT "nome.bas" |
Mostra il contenuto di un file di testo. |
DEL "nome.bas" |
Elimina un file. |
RENAME "vecchio","nuovo" |
Rinomina un file o una cartella. |
MKDIR "nome" |
Crea una cartella. |
DELDIR "nome" |
Elimina una cartella vuota. |
CD "nome" |
Entra in una cartella. |
CD.. |
Torna alla cartella precedente. |
CD/ |
Torna alla cartella principale. |
Esempio:
SAVE "saluto.bas"
NEW
LOAD "saluto.bas"
LIST
RUN
Attenzione: DEL e DELDIR eliminano dati. Controllare sempre il nome prima
di confermare il comando.
Sugli ESP32 verificati il supporto viene scelto automaticamente:
AUTOEXEC.BAS viene caricato dal supporto attivo all'avvio;una cancellazione completa della memoria fisica la elimina.
La scritta FILESYSTEM: FAT FLASH sul modello senza lettore SD indica il
funzionamento previsto, non un guasto.
I nomi relativi partono dalla cartella corrente. Dopo:
CD "audio"
CAT "note.txt" cerca il file dentro audio. CD.. sale di un livello e
CD/ torna alla radice. Se un file sembra assente, eseguire DIR e controllare
prima la cartella corrente.
AUTOEXEC.BAS viene eseguito automaticamente all'avvio sulle composizioni che
lo prevedono. Prima di sostituirlo:
RUN;AUTOEXEC.BAS;
Un programma automatico non dovrebbe contenere cicli infiniti privi di attese o
punti di interruzione. Inserire PAUSE quando il lavoro non richiede esecuzione
continua alla massima velocita'.
TIME? e' un comando di estensione: e' disponibile soltanto nelle build che
includono il servizio RTC o l'orario di piattaforma.
Il comando TIME? mostra la data e l'ora correnti:
TIME?
Se l'orologio non e' ancora disponibile o sincronizzato, NikiBasic mostra un
messaggio esplicativo invece di fornire una data non valida.
Il computer di stazione combina il Core con estensioni di piattaforma. Fra i
comandi disponibili possono comparire:
| Gruppo | Comandi principali | Scopo |
|---|---|---|
| Identita' | DEVINFO |
Versioni, Device ID, rete, MQTT e memoria attiva. |
| Rete | WIFI |
Configurazione e stato del collegamento Wi-Fi. |
| Morse | CW, CWSPEED |
Trasmissione Morse su GPIO12. |
| Audio | PLAY, AUDIOIN |
WAV e ingresso analogico verso il flusso di rete. |
| File e ora | DIR, CD, CAT, LOAD, SAVE, DEL, MKDIR, DELDIR, RENAME, TIME? |
Supporto attivo e orologio SNTP. |
La disponibilita' esatta dipende dalla composizione caricata: controllare
HELP, non presumere che ogni build ESP32 includa tutti i gruppi.
I comandi MQTT, INTERVAL, SEND, SON, SOFF, HWNAME, DEFLOC,
DEFGPS, DEFSENS, DEFNSENS, DEFCLI e DEFMON appartengono alla
composizione datalogger separata e non al computer di stazione.
Wi-Fi e MQTT ritentano automaticamente la connessione dopo una perdita di rete.
La configurazione persistente non deve essere reinserita a ogni disconnessione.
DEVINFO e' il primo comando da usare per diagnosticare un dispositivo locale
o remoto.
La console seriale usa 9600 baud, 8N1, nessun controllo di flusso, DTR e RTS
disattivati. Il Device ID evita di comandare per errore un'altra centralina
quando si utilizza la console MQTT o l'app Android.
| Messaggio | Cosa significa | Come correggere |
|---|---|---|
Syntax Error |
La riga non e' scritta in una forma riconosciuta. | Controllare comando, parentesi, virgole e virgolette. |
Division By Zero Error |
Il programma ha tentato una divisione per zero. | Controllare il valore dopo /. |
Type Mismatch Error |
E' stato usato testo dove serviva un numero, o viceversa. | Controllare le variabili con $ e il dato inserito. |
Inexistent Line Error |
GOTO o GOSUB indica una riga inesistente. |
Correggere il numero di destinazione. |
Out Of DATA Error |
Non restano abbastanza valori da leggere. | Aggiungere valori a DATA oppure usare meno READ. |
Variable Name is Too Long Error |
Il nome della variabile supera il limite. | Accorciare il nome a 8 caratteri. |
Variable Name Not Allowed Error |
La variabile non e' stata preparata o il nome non e' valido. | Aggiungere prima LET e controllare il nome. |
IF Whitout ENDIF Error |
Manca la chiusura di una decisione su piu' righe. | Aggiungere ENDIF. |
RETURN o errore di chiamata |
Non esiste un GOSUB al quale tornare. |
Controllare la posizione di GOSUB e RETURN. |
NEXT o errore di ciclo |
Non esiste il relativo FOR. |
Controllare le coppie FOR e NEXT. |
Quando compare un errore, usare LIST, leggere la riga indicata e confrontarla
con gli esempi di questo manuale.
Quando un programma non si comporta come previsto:
LIST e controllare la riga indicata;VARS per osservare i valori correnti;PRINT;RUN dall'inizio;
Su ESP32 aggiungere DEVINFO e DIR per distinguere un problema del programma
da rete, MQTT o cartella corrente. Non cancellare o riformattare il supporto per
risolvere un semplice errore di sintassi.
Il programma seguente chiede un nome e tre misure, calcola la media e mostra un
messaggio diverso secondo il risultato.
10 LET NOME$
20 LET SOMMA=0
30 INPUT "NOME";NOME$
40 FOR I=1 TO 3
50 INPUT "MISURA";A
60 SOMMA=SOMMA+A
70 NEXT I
80 LET MEDIA=SOMMA/3
90 PRINT "UTENTE: ",NOME$
100 PRINT "MEDIA: ",MEDIA
110 IF MEDIA>=10 THEN PRINT "VALORE ALTO" ELSE PRINT "VALORE BASSO"
120 END
Per provarlo:
LIST per controllarle;RUN;SAVE "media.bas" se si desidera conservarlo.LET prima di usarle con INPUT.A-Z ai calcoli brevi.AND, OR e XOR con spazi.IF/ENDIF, FOR/NEXT, WHILE/WEND.DIR prima di usare DEL o DELDIR.AUTOEXEC.BAS manualmente prima di renderlo automatico.DEVINFO, VARS e FREE come strumenti ordinari, non soltanto dopo unguasto.
| Operazione | Comando |
|---|---|
| Scrivere un messaggio | PRINT "CIAO" |
| Vedere il programma | LIST |
| Avviare il programma | RUN |
| Cancellare il programma corrente | NEW |
| Chiedere un dato | INPUT "DOMANDA";VARIABILE |
| Ripetere un numero stabilito di volte | FOR ... TO ... e NEXT |
| Ripetere finche' una condizione e' vera | WHILE ... e WEND |
| Prendere una decisione | IF ... THEN ... ELSE ... |
| Salvare | SAVE "nome.bas" |
| Aprire | LOAD "nome.bas" |
| Vedere i comandi disponibili | HELP |
| Mostrare data e ora | TIME? |
| Identificare l'ESP32 di stazione | DEVINFO |
| Attendere senza bloccare BREAK | PAUSE millisecondi |
| Terminare un programma | END |