ANNEX32 WI-FI Basic

User Manual

Version beta 1.38 beta RC5

© ciccioCB 2019


 

 

COPYRIGHT

 

The Annex firmware, including the AnnexToolKit and this manual, are Copyright 2017-2019 by Francesco Ceccarella (ciccioCB).

 

The compiled object code (the .bin file) for the Annex firmware is free software: you can use or redistribute it as you please except for commercial purposes. It is not allowed to distribute or embed it into products that are sold or for any other activity making or intended to make a profit.

 

The compiled object code (the .exe file) for the AnnexToolKit utility is free software: you can use or redistribute it as you please except for commercial purposes. It is not allowed to distribute or embed it into products that are sold or for any other activity making or intended to make a profit.

 

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even

the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 

This manual is distributed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 France license (CC BY-NC-SA 3.0)

 

The above copyright notice and this permission notice shall be included in all copies or redistributions of the Software in any form.

License and credits

The base of the interpreter comes from the original project "MiniBasic" by Malcom Mclean.

Adafruit BNO055 Orientation Sensor library is written by KTOWN is Copyright © Adafruit Industries. It is released under MIT license.

TFT_eSPI display Library is Copyright ©  2017 Bodmer. It is released under FreeBSD license.

Adafruit PWM Servo Driver Library is Copyright © Adafruit. It is released under MIT license.

Arduino Library for Dallas Temperature ICs is Copyright © Miles Burton <miles@mnetcs.com>. It is released under LGPL license.

OneWire Library is Copyright 1999-2006 Dallas Semiconductor Corporation and Copyright © 2007, Jim Studt.

Adafruit DHT Humidity & Temperature Sensor Library is Copyright © Adafruit. It is released under MIT license.

ESP8266 and ESP32 Oled Driver for SSD1306 display is Copyright © 2016 by Daniel Eichhorn and Copyright © 2016 by Fabrice Weinberg

NeoPixelBus library is Copyright © Michael C. Miller.  It is released under LGPL license.

ESP AsyncTCP library is Copyright © 2016 Hristo Gochkov. It is released under LGPL license.

ESP AsyncWebServer library is Copyright © 2016 Hristo Gochkov. It is released under LGPL license.

IRremote library is Copyright © Sebastien Warin, Mark Szabo, Ken Shirriff, David Conran. It is released under LGPL license.

uRTCLib is is Copyright © 2015 Naguissa (naguissa.com@gmail.com). It is released under LGPL license.

BME280 library is written by Limor Fried/Ladyada for Adafruit Industries. It is released under BSD license,

APDS9960 library is written by Shawn Hymel for Sparkfun Electronics. It is released under Beerware license.

PID Library is written by Brett Beauregard (br3ttb@gmail.com). It  is released under MIT license.

MQTT library pubsubclient is Copyright (c) 2008-2015 Nicholas O'Leary. It is released under MIT license

The Javascript Editor  EditArea is  Copyright © 2008 Christophe Dolivet. It is released under LGPL license.

 

The M5Stack library is copyright © 2017 by M5Stack. It is released under MIT license.

The MPU9250 driver is part of the M5Stack Library.

Some GUI objects come from the library GUIslice Copyright © Calvin Hass that is released under MIT license.

 

 

 

Contributions

A very big thank you to Robin Baker (Electroguard) for his great involvement in the project by supporting all the tests on the real hardware (bought with his money), and all the advices that allowed me to add a lot of functionality, not to mention the Huge work he did while documenting the project on the website.


 

 

Content :

Introduction:                                                                                                                                                         16

Interpreter:                                                                                                                                                            18

Branch labels                                                                                                                                                        19

Variables:                                                                                                                                                              19

Arrays:                                                                                                                                                                   20

Scope of the variables:                                                                                                                                        21

Bases of the language                                                                                                                                         22

OPERATORS AND PRECEDENCE                                                                                                                   22

Basic internal keywords:                                                                                                                                    24

IF command :                                                                                                                                                   24

FOR loop                                                                                                                                                          25

WHILE WEND loop                                                                                                                                          26

DO LOOP loop                                                                                                                                                 27

SELECT CASE                                                                                                                                                27

GOTO                                                                                                                                                              28

GOSUB                                                                                                                                                            29

DATA                                                                                                                                                                29

END                                                                                                                                                                  30

EXIT                                                                                                                                                                 30

SUB                                                                                                                                                                  30

Logical / boolean Operations                                                                                                                             32

ERRORS HANDLING                                                                                                                                          33

ONERROR ABORT                                                                                                                                  34

ONERROR IGNORE                                                                                                                                34

ONERROR SKIP [nn]                                                                                                                                34

ONERROR CLEAR                                                                                                                                   34

ONERROR GOTO [label | OFF]                                                                                                               34

BAS.ERRLINE                                                                                                                                           34

BAS.ERRNUM                                                                                                                                          34

BAS.ERRMSG$                                                                                                                                        34

HOW the interpreter works with the HTML code and Objects :                                                                    35

HTML Objects                                                                                                                                                  39

TIMERS                                                                                                                                                                 44

EVENTS                                                                                                                                                                44

Button Event                                                                                                                                                     45

OnHtmlChange Event                                                                                                                                      45

OnHtmlReloadEvent                                                                                                                                        45

OnInfrared Event                                                                                                                                             46

OnSerial Event                                                                                                                                                 46

OnSerial2 Event                                                                                                                                               46

OnTouch Event                                                                                                                                                47

OnUDP Event                                                                                                                                                  47

OnWgetAsync Event                                                                                                                                       47

OnUrlMessage Event                                                                                                                                       48

OnEspNowMsg Event                                                                                                                                     51

OnEspNowError Event                                                                                                                                    52

OnMQTT Event                                                                                                                                               52

WiFI CONNECTIONS                                                                                                                                           52

RECOVERY MODE                                                                                                                                              54

DATE - TIME timekeeper                                                                                                                                    54

Unix Time functions                                                                                                                                            55

WIRING                                                                                                                                                                  56

DIGITAL I/O                                                                                                                                                          57

PIN INTERRUPTS                                                                                                                                                58

Analog inputs                                                                                                                                                       58

TOUCH inputs                                                                                                                                                      59

The function PIN.TOUCH(pin) can be used to read the touch value on the pins defined in the table below. 59

Hardware interfaces:                                                                                                                                           59

PWM                                                                                                                                                                59

PWM.SETUP pin, channel, default_value,  [,frequency] [,resolution]                                                       60

PWM.OUT channel, value                                                                                                                         60

SERVO                                                                                                                                                            61

I2S BUS                                                                                                                                                           62

SPEAKER OUTPUT                                                                                                                                       64

I2C BUS                                                                                                                                                           64

PCF8574 Module                                                                                                                                       65

ADS1115 Module                                                                                                                                       66

SPI BUS                                                                                                                                                           69

74HC595 Module                                                                                                                                       71

MCP23S17 Module                                                                                                                                    72

COUNTERS                                                                                                                                                    74

PID controllers                                                                                                                                                        74

SOUND PLAYER                                                                                                                                                  76

SPEECH SYNTHESIS with vintage C64 SAM speaker                                                                                       78

SPEECH SYNTHESIS using google translate                                                                                                      79

LCD DISPLAY USING I2C                                                                                                                                   79

OLED DISPLAY                                                                                                                                                    81

ST7920 LCD DISPLAY                                                                                                                                         83

RTC module                                                                                                                                                          85

PCA9685 (PWM / Servo) Module                                                                                                                        87

TM1637 display module                                                                                                                                      88

TM1638 display module                                                                                                                                      89

MAX7219 8-Digits 7-segment display                                                                                                                91

MAX7219 Dot Matrix Display                                                                                                                              92

NeoPixel WS2812B led strips                                                                                                                             95

NeoPixel based WS2812b Dot Matrix DIsplay                                                                                                  96

SDCARD ADAPTER                                                                                                                                          101

TFT DISPLAY                                                                                                                                                     102

TouchScreen                                                                                                                                                  105

GRAPHIC GUI for TFT                                                                                                                                      106

GUI Objects                                                                                                                                                   107

gui.TextLine                                                                                                                                              107

gui.Button                                                                                                                                                 107

gui.Image                                                                                                                                                  108

gui.ButtonImage                                                                                                                                       108

gui.CheckBox                                                                                                                                           109

gui.Slider                                                                                                                                                   109

gui.ProgressBar                                                                                                                                        110

gui.Ramp                                                                                                                                                  110

gui.Gauge                                                                                                                                                 110

gui.Box                                                                                                                                                     111

gui.Circle                                                                                                                                                  111

gui.Rect                                                                                                                                                    112

gui.Line                                                                                                                                                     112

GUI Functions                                                                                                                                                113

gui.GetValue                                                                                                                                             113

gui.Target                                                                                                                                                 113

GUI Commands                                                                                                                                             113

gui.INIT                                                                                                                                                     113

gui.REDRAW                                                                                                                                           113

gui.REFRESH                                                                                                                                          113

gui.AUTOREFRESH                                                                                                                               113

gui.SETVALUE                                                                                                                                        113

gui.SETTEXT                                                                                                                                           114

gui.SETIMAGE                                                                                                                                        114

gui.SETCOLOR                                                                                                                                       114

SETRANGE                                                                                                                                             114

SETEVENT                                                                                                                                              115

SETSTYLE                                                                                                                                               115

INFRARED INTERFACE                                                                                                                                   116

ULTRASONIC DISTANCE SENSOR HC-SR04                                                                                              120

DHT xx Temperature / Humidity Sensors                                                                                                       121

DS18B20 Temperature Sensors                                                                                                                       122

BNO055 Absolute Orientation Sensor                                                                                                            123

BME280 Combined humidity and pressure sensor                                                                                       125

APDS9960 Digital Proximity, Ambient Light, RGB and Gesture Sensor                                                    127

VL53L0X TOF (Time Of Flight) Distance Sensor                                                                                           130

The VL53L0X is a new generation Time-of-Flight (ToF) laser-ranging module providing accurate distance measurement whatever the target reflectances unlike conventional technologies. It can measure absolute distances up to 2m, setting a new benchmark in ranging performance levels, opening the door to various new applications.                                                                                                                                               130

MPU9250                                                                                                                                                             132

IMU FUSION FUNCTIONS                                                                                                                                133

ETHERNET Module W5500                                                                                                                              134

FTP                                                                                                                                                                      138

BAS.FTP$                                                                                                                                                      138

Server data requests  (GET and POST)                                                                                                          139

WGET$(server$, port, [,header])                                                                                                                   140

WPOST$(server$, body$, port [,header])                                                                                                      140

WGETASYNC[(]server$, port, [,header][)]                                                                                                    140

MQTT                                                                                                                                                                  141

Ret = MQTT.Setup(server$ [,port])                                                                                                         141

Ret = MQTT.Connect(login$, pass$ [id$])                                                                                               141

Ret = MQTT.Connect("", "", [id$])                                                                                                            141

Ret = MQTT.Disconnect()                                                                                                                       141

Ret = MQTT.Publish(topic$, message$)                                                                                                 141

Ret = MQTT.Subscribe(topic$ [,Qos])                                                                                                     141

Ret = MQTT.UnSubscribe(topic$)                                                                                                           141

Ret = MQTT.Connected()                                                                                                                        141

ESP-NOW                                                                                                                                                            142

CONVERSION FUNCTIONS                                                                                                                             152

CONVERT.DEGC_TO_F(degC)                                                                                                            153

CONVERT.F_TO_DEGC(degF)                                                                                                             153

CONVERT.TO_IEEE754(num)                                                                                                               153

CONVERT.FROM_IEEE754(iee754_bin)                                                                                              153

BAS CONSTANTS                                                                                                                                             153

BAS.VER                                                                                                                                                 154

BAS.VER$                                                                                                                                               154

BAS.ERRLINE                                                                                                                                         154

BAS.ERRNUM                                                                                                                                        154

BAS.ERRMSG$                                                                                                                                      154

BAS.FILENAME$                                                                                                                                    154

BAS.RTCMEM$                                                                                                                                      154

BAS.SSID$                                                                                                                                              154

BAS.PASSWORD$                                                                                                                                 154

BAS.LOAD                                                                                                                                               155

BAS.RESETREASON                                                                                                                             155

BAS.DEVICE                                                                                                                                           155

OPTION COMMANDS                                                                                                                                       155

OPTION.CPUFREQ 80|160|240                                                                                                             156

OPTION.MAC mac$                                                                                                                               156

OPTION.LOWRAM value                                                                                                                       156

FUNCTIONS:                                                                                                                                                      156

NUMERICAL FUNCTIONS                                                                                                                          156

ABS(number)                                                                                                                                           170

ACOS(number)                                                                                                                                        170

ADC(pin)                                                                                                                                                  170

APDS9960.SETUP (mode)                                                                                                                     170

APDS9960.READGESTURE                                                                                                                  170

APDS9960.AMBIENT                                                                                                                              170

APDS9960.RED                                                                                                                                      170

APDS9960.GREEN                                                                                                                                 170

APDS9960.BLUE                                                                                                                                     170

APDS9960.PROXIMITY                                                                                                                          170

APDS9960.GESTUREGAIN (gain)                                                                                                         170

APDS9960.GESTURELED (intensity)                                                                                                    170

ASC(string$)                                                                                                                                             170

ASIN(number)                                                                                                                                          170

ATAN(number)                                                                                                                                         170

ATAN2(x, y)                                                                                                                                             170

BAS.VER                                                                                                                                                 170

BAS.ERRLINE                                                                                                                                         159

BAS.ERRNUM                                                                                                                                        159

BME280.SETUP(address)                                                                                                                       170

BME280.ALT(qnh)                                                                                                                                   170

BME280.HUM                                                                                                                                          170

BME280.QFE                                                                                                                                           170

BME280.QNH(altitude)                                                                                                                            170

BME280.TEMP                                                                                                                                        170

BNO055.SETUP( address)                                                                                                                      170

BNO055.HEADING                                                                                                                                 170

BNO055.PITCH                                                                                                                                       170

BNO055.ROLL                                                                                                                                         170

BNO055.VECTOR ( param, axis)                                                                                                           170

BNO055.CALIB [(param)]                                                                                                                        170

CINT(number)                                                                                                                                          170

CONVERT.DEGC_TO_F(degC)                                                                                                            161

CONVERT.F_TO_DEGC(degF)                                                                                                             161

CONVERT.TO_IEEE754(num)                                                                                                               161

CONVERT.FROM_IEEE754(ieee754_bin)                                                                                            161

COS(number)                                                                                                                                          161

COUNTER.COUNT (cnt)                                                                                                                        170

COUNTER.PERIOD (cnt)                                                                                                                       170

DATEUNIX(date$)                                                                                                                                   170

DHT.TEMP                                                                                                                                              170

DHT.HUM                                                                                                                                                170

DHT.HEATINDEX                                                                                                                                   170

DISTANCE(pin_trig, pin_echo)                                                                                                                170

EMAIL from$, to$, subject$, message$                                                                                                  170

ESPNOW.ADD_PEER(MAC_add$)                                                                                                       163

ESPNOW.BEGIN                                                                                                                                    163

ESPNOW.DEL_PEER(MAC_add$)                                                                                                       163

ESPNOW.STOP                                                                                                                                      163

ESPNOW.WRITE( msg$)                                                                                                                       163

ESPNOW.WRITE( msg$,MAC_add$)                                                                                                    163

EXP(number)                                                                                                                                           163

FIX(number)                                                                                                                                             170

FILE.DELETE(filename$)                                                                                                                        170

FILE.EXISTS(filename$)                                                                                                                         170

FILE.SIZE(filename$)                                                                                                                              170

FLASHFREE                                                                                                                                            170

FUSION.ANGLE(axis)                                                                                                                             170

INSTR([start], string$, pattern$)                                                                                                               170

I2C.LEN                                                                                                                                                    170

I2C.READ                                                                                                                                                170

I2C.READREGBYTE (i2c_address, register)                                                                                         170

I2C.END                                                                                                                                                   170

INT(number)                                                                                                                                             170

LEN(string$)                                                                                                                                             170

LOG(number)                                                                                                                                           170

MILLIS                                                                                                                                                      170

MQTT.Setup(server$ [,port])                                                                                                                   166

MQTT.Connect(login$, pass$, [id$])                                                                                                        166

MQTT.Connect("", "", [id$])                                                                                                                      166

MQTT.Disconnect()                                                                                                                                 166

MQTT.Publish(topic$, message$)                                                                                                           166

MQTT.Subscribe(topic$ [,Qos])                                                                                                               166

MQTT.UnSubscribe(topic$)                                                                                                                     167

MQTT.Connected()                                                                                                                                  167

NEO.GETPIXEL(pos)                                                                                                                              167

NEO.RGB(R, G, B)                                                                                                                                 170

PI                                                                                                                                                              170

PID1.COMPUTE( current_value, target_value)                                                                                      167

PIN(pin_number)                                                                                                                                      167

PIN.TOUCH(pin_number)                                                                                                                       167

PING(host$)                                                                                                                                             167

POW(x, y)                                                                                                                                                170

RAMFREE                                                                                                                                               170

RND(number)                                                                                                                                          170

SERIAL.LEN                                                                                                                                            170

SERIAL2.LEN                                                                                                                                          170

SGN(number)                                                                                                                                          170

SIN(number)                                                                                                                                            170

SPI.BYTE(byte)                                                                                                                                       170

SQR(number)                                                                                                                                          170

TAN(number)                                                                                                                                           170

TFT.RGB(r,g,b)                                                                                                                                        170

TIMEUNIX(time$)                                                                                                                                    170

TM1638.BUTTONS                                                                                                                                 170

TOUCH.X                                                                                                                                                 170

TOUCH.Y                                                                                                                                                 170

VAL(string$)                                                                                                                                             170

WIFI.CHANNEL                                                                                                                                       169

WIFI.MODE                                                                                                                                             169

WIFI.NETWORKS  ( network$ )                                                                                                              169

WIFI.STATUS                                                                                                                                          170

WORD.COUNT( string$ [,delimiter$])                                                                                                     170

WORD.FIND( string$, find$ [,delimiter$])                                                                                                170

STRING FUNCTIONS                                                                                                                                  171

BAS.ERRMSG$                                                                                                                                      180

BAS.FILENAME$                                                                                                                                    180

BAS.FTP$( host$, login$, password$, file$, folder$)                                                                               171

BAS.PASSWORD$                                                                                                                                 171

BAS.RTCMEM$                                                                                                                                      171

BAS.SSID$                                                                                                                                              171

BAS.VER$                                                                                                                                               171

BIN$(number)                                                                                                                                          180

BUTTON$(name$, label [, id] )                                                                                                                180

CHECKBOX$( variable [,id])                                                                                                                   180

CHR$(number)                                                                                                                                        180

CSSID$(object_id, object_style)                                                                                                              180

DATE$[(format)]                                                                                                                                      180

ESPNOW.ERROR$                                                                                                                                172

ESPNOW.READ$                                                                                                                                   172

ESPNOW.REMOTE$                                                                                                                              172

FILE.DIR$[(path$)]                                                                                                                                   172

FILE.READ$(filename$,[line_num] | [start, length])                                                                                180

HEX$(number)                                                                                                                                         180

HtmlEventButton$                                                                                                                                    172

HtmlEventVar$                                                                                                                                         172

IMAGE$(path [,id])                                                                                                                                   173

IMAGEBUTTON$(path, label [,id])                                                                                                          180

IP$                                                                                                                                                            180

IR.GET$[ (param) ]                                                                                                                                  180

JSON$(string$, field$)                                                                                                                             180

LCASE$(string$)                                                                                                                                      180

LED$(variable [,id])                                                                                                                                  180

LEFT$(string$, num)                                                                                                                                180

LISTBOX$(variable$, "option1, option2, option3, ..." [, height]  [,id])                                                       180

MAC$[ (id) ]                                                                                                                                              174

METER$(variable, min, max [,id])                                                                                                           180

MID$(string$, start [,num])                                                                                                                       180

MQTT.Message$                                                                                                                                     174

MQTT.Topic$                                                                                                                                           175

OCT$(number)                                                                                                                                         175

PASSWORD$(variable [, id] )                                                                                                                  180

REPLACE$(expression$, find$, replacewith$)                                                                                        180

RIGHT$(string$, num)                                                                                                                             180

RTC.DATE$[(format)]                                                                                                                              180

RTC.TIME$                                                                                                                                              180

SERIAL.CHR$                                                                                                                                         180

SERIAL.INPUT$                                                                                                                                      180

SERIAL2.CHR$                                                                                                                                       180

SERIAL2.INPUT$                                                                                                                                    180

SLIDER$(variable, min, max [,step] [,id])                                                                                                180

SPACE$(number)                                                                                                                                    180

SPI.STRING$(data$, len)                                                                                                                        180

SPI.HEX$(datahex$, len)                                                                                                                         180

STR$ (number [,format$ [,toint]])                                                                                                             180

STRING$(num, char$)                                                                                                                            180

TEMPR$(pin_number [,ID])                                                                                                                     180

TEXTBOX$(variable [, id] )                                                                                                                      180

TRIM$(string$)                                                                                                                                         180

TIME$                                                                                                                                                       180

UCASE$(string$)                                                                                                                                     180

UDP.READ$                                                                                                                                            180

UDP.REMOTE$                                                                                                                                      180

UNIXDATE$(value [,format])                                                                                                                   180

UNIXTIME$(value)                                                                                                                                  180

URLMSGGET$ ([arg$])                                                                                                                           180

WGET$( http_server$, port [,header] )                                                                                                    180

WGETRESULT$                                                                                                                                      180

WORD$(string$, position [,delimiter$])                                                                                                    180

WORD.DELETE$(string$, position [delimiter$])                                                                                      180

WORD.EXTRACT$(string$, lead$, trail$)                                                                                               180

WORD.GETPARAM$( setting$, parameter$  [,separator$])                                                                  180

WPOST$(server$, body$, port [,header])                                                                                                181

COMMANDS:                                                                                                                                                     181

AUTOREFRESH interval                                                                                                                        208

BAS.LOAD filename$                                                                                                                              183

BAS.RTCMEM$ = val$                                                                                                                           182

CLS                                                                                                                                                          208

CSS style_code$                                                                                                                                     208

COMMAND cmd$                                                                                                                                   208

COUNTER.RESET cnt                                                                                                                           208

COUNTER.SETUP cnt, pin [,mode]                                                                                                       208

DATA const1 [,const2] ...                                                                                                                         208

DHT.SETUP pin, model                                                                                                                           208

EMAIL.SETUP server$, port, user_name$, password$ [, debug]                                                           183

EMAILASYNC from$, to$, subject$, message$                                                                                     208

FILE.SAVE filename$, content$                                                                                                              208

FUSION.INIT                                                                                                                                           208

FUSION.MADGWICK ax, ay, az, gx, gy, gz                                                                                           208

FUSION.MADGWICK ax, ay, az, gx, gy, gz, mx, my, mz                                                                     208

FUSION.MAHONY ax, ay, az, gx, gy, gz, mx, my, mz                                                                          208

FUSION.BETA =                                                                                                                                     208

FUSION.ZETA =                                                                                                                                      208

FUSION.KI =                                                                                                                                            208

FUSION.KP =                                                                                                                                          208

HTML code$                                                                                                                                            208

I2C.SETUP sda_pin, scl_pin [,freq [,stretch]]                                                                                          208

I2C.BEGIN address                                                                                                                                 208

I2C.END                                                                                                                                                   208

I2C.REQFROM address, length                                                                                                              208

I2C.READREGARRAY i2c_address, register, nb_of_bytes, Array()                                                     208

I2C.WRITE value                                                                                                                                     208

I2C.WRITEREGBYTE i2c_address,register, value                                                                                 208

I2C.WRITEREGARRAY i2c_address, register, nb_of_bytes, Array()                                                    208

INPUT.TIMEOUT timeout                                                                                                                       208

INPUT["prompt$";] variable                                                                                                                      208

INTERRUPT pin_no, {OFF | label}                                                                                                          208

IR.INIT pin_rx | OFF [, pin_tx]                                                                                                                  208

IR.SEND type, code$, bits                                                                                                                       208

JSCALL javaCode$                                                                                                                                 208

JSCRIPT script$                                                                                                                                      208

JSEXTERNAL file$                                                                                                                                  208

LCD.INIT address, cols, rows                                                                                                                  208

LCD.CLS                                                                                                                                                  208

LCD.PRINT x, y, text$                                                                                                                             208

LOCAL var1 [,var2], ...                                                                                                                             208

MAXDISPLAY.SETUP CS_pin                                                                                                               208

MAXDISPLAY.PRINT msg$ [,‘brightness]                                                                                              208

MAXSCROLL.SETUP nb_devices, CS_pin                                                                                           208

MAXSCROLL.PRINT msg$                                                                                                                    208

MAXSCROLL.NEXT msg$                                                                                                                     208

MAXSCROLL.TEXT msg$                                                                                                                      208

MAXSCROLL.SHOW pos [, brightness]                                                                                                 208

MAXSCROLL.SCROLL [brightness]                                                                                                       208

MAXSCROLL.OSCILLATE [brightness]                                                                                                 208

NEO.PIXEL led_pos, R, G, B [, disable]                                                                                                  208

NEO.PIXEL led_pos, COLOR [, disable]                                                                                                 208

NEO.SETUP pin [,nb_led]                                                                                                                       208

NEO.STRIP led_start_pos, led_end_pos, R, G, B [, disable]                                                                  208

NEO.STRIP led_start_pos, led_end_pos, COLOR [, disable]                                                                 208

NEOSCROLL.SETUP nb_devices, pin [,serpentine]                                                                              208

NEOSCROLL.PRINT msg$                                                                                                                    208

NEOSCROLL.NEXT msg$                                                                                                                     208

NEOSCROLL.COLORS col$                                                                                                                  208

NEOSCROLL. NEXTCOLORS col$                                                                                                       208

NEOSCROLL.SHOW pos [, brightness]                                                                                                 208

NEOSCROLL.TEXT msg$                                                                                                                      208

NEOSCROLL.SCROLL [‘brightness]                                                                                                      208

NEOSCROLL.OSCILLATE [‘brightness]                                                                                                 208

OLED.CLS                                                                                                                                               208

OLED.INIT orientation                                                                                                                              208

OLED.REFRESH fmt                                                                                                                              208

OLED.COLOR color                                                                                                                                208

OLED.PIXEL x, y                                                                                                                                     208

OLED.LINE x1, y1, x2, y2                                                                                                                       208

OLED.RECT x,y, width, height [,fill]                                                                                                        208

OLED.CIRCLE x, y, radius [, fill]                                                                                                             208

OLED.FONT font_num                                                                                                                            208

OLED.PRINT x, y, text$ [background]                                                                                                    208

OLED.IMAGE x, y, image$                                                                                                                     208

ONERROR ABORT or ONERROR IGNORE or ONERROR SKIP [nn] or ONERROR CLEAR or ONERROR GOTO label                                                                                                                         194

ONESPNOWERROR [label | OFF]                                                                                                        194

ONESPNOWMSG [label | OFF]                                                                                                             194

ONGESTURE [label | OFF]                                                                                                                     194

ONHTMLCHANGE [label | OFF]                                                                                                            208

ONHTMLRELOAD [label | OFF]                                                                                                             208

ONINFRARED label                                                                                                                                208

OnMQTT label                                                                                                                                         194

ONSERIAL [label | OFF]                                                                                                                          194

ONSERIAL2 [label | OFF]                                                                                                                        208

ONTOUCH [label | OFF]                                                                                                                         208

ONUDP [label | OFF]                                                                                                                               208

ONURLMESSAGE [label | OFF]                                                                                                             208

ONWGETASYNC [label | OFF]                                                                                                               208

OPTION.CPUFREQ 80|160                                                                                                                    208

OPTION.LOWRAM value                                                                                                                       208

PAUSE delay                                                                                                                                           208

PCA9685.SETUP addr                                                                                                                            208

PCA9685.SETFREQ freq                                                                                                                        208

PCA9685.PWM pin, value                                                                                                                       208

PID1.INIT Kp, Ki, Kd                                                                                                                                196

PID1.LIMITS min, max                                                                                                                            196

PID1.PERIOD msec                                                                                                                                196

PID1.PARAMS Kp, Ki, Kd                                                                                                                       196

PID1.SETMODE mode                                                                                                                           196

PIN(pin_number) = val                                                                                                                             196

PIN.MODE pin_number, mode [,PULLUP | PULLDOWN ]                                                                    208

PLAY.MP3 mp3$                                                                                                                                     208

PLAY.NETWORKS stream$                                                                                                                   208

PLAY.SETUP dest                                                                                                                                   208

PLAY.SPEAK message$ [, phonetic]                                                                                                      208

PLAY.STOP                                                                                                                                             208

PLAY.VOICE "message", "language" [, "filename"] [, action]                                                                  197

PLAY.VOLUME volume                                                                                                                          197

PLAY.WAV                                                                                                                                               208

PRINT expression[[,; ]expression] ...                                                                                                       208

PRINT2 expression [[,; ]expression] ...                                                                                                    208

PWM.SETUP pin, chan, default,  [,freq] [,resol]                                                                                      208

PWM.SETUP pin, OFF                                                                                                                            208

PWM.OUT chan, value                                                                                                                            208

READ var1 [,var2] ...                                                                                                                                208

REBOOT                                                                                                                                                  208

REFRESH                                                                                                                                                208

RESTORE                                                                                                                                               208

RTC.SETTIME Year, Month, Day, Hours, Minutes, Seconds                                                                208

SERIAL.BYTE ch1 [,ch2] . . .                                                                                                                   208

SERIAL2.BYTE ch1 [,ch2] . . .                                                                                                                 208

SERIAL.MODE baudrate                                                                                                                         208

SERIAL2.MODE baudrate, pin_tx, pin rx                                                                                                208

SERVO id, value                                                                                                                                      208

SERVO.SETUP id, pin_number | OFF                                                                                                   208

SETTIME Year, Month, Day, Hours, Minutes, Seconds                                                                         208

SLEEP value                                                                                                                                            208

SOCKET client, msg$                                                                                                                              208

SPI.SETUP speed [,data_mode [, bit_order]]                                                                                          208

ST7920.INIT CS_pin                                                                                                                                208

ST7920.CLS                                                                                                                                             208

ST7920.REFRESH fmt                                                                                                                           208

ST7920.COLOR color                                                                                                                             208

ST7920.PIXEL x, y                                                                                                                                  208

ST7920.LINE x1, y1, x2, y2                                                                                                                     208

ST7920.RECT x,y, width, height [,fill]                                                                                                      208

ST7920.CIRCLE x, y, radius [, fill]                                                                                                           208

ST7920.FONT font_num                                                                                                                         208

ST7920.PRINT x, y, text$ [background]                                                                                                 208

ST7920.IMAGE x, y, image$                                                                                                                   208

TM1637.PRINT msg$ [, brightness [, dotpoints]]                                                                                     208

TM1637.SETUP data_pin, clock_pin [, bit_delay]                                                                                   208

TM1638.PRINT msg$ [, brightness ]]                                                                                                      208

TM1638.SETUP data_pin, clock_pin, strobe_pin                                                                                    208

TM1638.LEDS val                                                                                                                                    208

TFT.BMP filename$, [x, y [, back_color] ]                                                                                               208

TFT.BRIGHTNESS val                                                                                                                            208

TFT.CIRCLE x, y, radius,color [, fill]                                                                                                        208

TFT.FILL color                                                                                                                                          208

TFT.IMAGE filename$, [x, y [, back_color] ]                                                                                           208

TFT.INIT orientation                                                                                                                                 208

TFT.JPG filename$, [x, y [, back_color] ]                                                                                               208

TFT.LINE x1, y1, x2, y2, col                                                                                                                    208

TFT.PRINT expression [[,; ]expression] ...                                                                                               208

TFT.RECT x, y, width, height, color [ [,fill] ,[round_radius] ]                                                                    208

TFT.TEXT.COL color [,backcolor]                                                                                                           208

TFT.TEXT.POS x, y                                                                                                                                208

TFT.TEXT.SIZE size                                                                                                                                208

TIMER0 interval, label                                                                                                                              208

TIMER1 interval, label                                                                                                                              208

TOUCH.CALIB                                                                                                                                        208

TRACE message                                                                                                                                     208

UDP.BEGIN port                                                                                                                                      208

UDP.REPLY msg$                                                                                                                                  208

UDP.STOP                                                                                                                                              208

UDP.WRITE ip, port, msg$                                                                                                                      208

URLMSGRETURN msg$ [,content_type$]                                                                                             208

WAIT                                                                                                                                                        208

WGETASYNC http_server$, port [,header]                                                                                             207

WIFI.AWAKE                                                                                                                                           208

WIFI.CONNECT SSID, password                                                                                                           208

WIFI.POWER pow                                                                                                                                   208

WIFI.SCAN                                                                                                                                              208

WIFI.SLEEP                                                                                                                                             208

WLOG [text$ | num]                                                                                                                                 208

WORD.DELPARAM setting$, parameter$, [,separator$]                                                                       208

WORD.SETPARAM  setting$, parameter$, value$ [,separator$]                                                           208

BASIC KEYWORDS                                                                                                                                           209

CASE                                                                                                                                                       211

DIM array(size) [, …]                                                                                                                                211

DO                                                                                                                                                            211

ELSE                                                                                                                                                        211

END [IF | SELECT | SUB]                                                                                                                       211

ENDIF                                                                                                                                                      211

EXIT {DO | SUB}                                                                                                                                     211

FOR                                                                                                                                                          211

GOSUB [label | lab$]                                                                                                                                211

GOTO label                                                                                                                                              211

IF                                                                                                                                                              211

LET var = expression                                                                                                                               211

LOOP                                                                                                                                                       211

NEXT                                                                                                                                                        211

OFF                                                                                                                                                          211

OUTPUT                                                                                                                                                  211

PULLUP                                                                                                                                                   211

REM                                                                                                                                                         211

RETURN                                                                                                                                                  211

SELECT                                                                                                                                                   211

SPECIAL                                                                                                                                                  211

STEP                                                                                                                                                        211

SUB                                                                                                                                                          211

THEN                                                                                                                                                       211

TO                                                                                                                                                            211

UNTIL                                                                                                                                                       211

WEND                                                                                                                                                      211

WHILE                                                                                                                                                      211

 

Introduction:

Annex32 WI-Fi RDS (Rapid Development Suite) is a version of the "basic" language developed to run on low cost ESP-32 WIFI devices.

Annex32 is specifically for the ESP32 range of devices, whose implemented features can vary greatly.

To offer some standardisation, Annex32 caters in particular to M5stack devices, which include a micro-SD card slot, TFT display, speaker, 3 user buttons plus a reset button, and a lipo battery, all self-contained in a plastic case offering expansion pin access and designed to accept ‘stackable’ expansion modules.

All drivers needed for the M5stack features are already included in the Annex32 firmware, and pre-configured for the M5stack so that features such as TFT display and SDcard work by default.

 

Similar functionality could be built using alternative TFT display and SD card reader etc, if preferred.

Please refer to the original M5Stack schematics for more details.

However, M5stack and its hardware features merely offer a convenient standard feature set, they are not mandatory - Annex32 works with any ESP32 devices, with or without hardware expansion modules.

Obviously appropriate hardware is needed for any required features - eg: an OLED display could be used, but scripts written for TFT displays will need modifying for the different display.

 

Annex32 can use the internal disk space or an external SD card.

The internal and the external (SDcard) space are mutually exclusive and cannot be accessed at the same time.

By default Annex32 will use the SD, if available, otherwise it will use the internal disk space (FATFS).

Both shares the same file system (FAT32), enabling the use of long file names and directories.

Depending on the module flash memory size (4, 8 or 16MB), the internal disk space can be from ~1MB to 13MB.

Using the ESP32 partition scheme it is possible to freely define this space, but modifying it will wipe out all existing files already stored.

 

Annex32 Wi-Fi RDS takes from the original concept of Annex WI-FI RDS for ESP8266 from which it shares essentially the IDE interface and the same command syntax as much as possible.

It should be straightforward switching to Annex32 if coming from Annex, and the same programs should run without (or with minimum) modifications.

Annex32 Wi-Fi RDS benefits from the powerful H/W architecture of the ESP32 using both cores and the RAM memory available. In addition, for modules equipped with PSRAM memory extension, Annex32 can make available to the users this additional RAM space (4MBytes).

 

Functionalities:

-       Includes an internal IDE so can be programmed directly using your web browser (even from your phone/tablet) without any additional utility.

-       Syntax highlighting with context sensitive Help

-       A programmable web server which includes a file server

-       Supports OTA (over the air) update.

-       Support async events (interrupts, timers, web access, UDP, ….)

-       Breakpoints, immediate execution of commands, display of variables, single step.

-       A basic interpreter with floating point variables (double precision) and string variables, multidimensional arrays (float and string), user defined subroutines.

-       Access to any available I/O pin for input/output, PWM and Servo.

-       Errors Handling .

-       Support TCP (HTTP) GET and POST for communications

-       Support for UDP for communications.

-       Support for sending Emails using SMTP SSL servers

-       Support for AJAX communications

-       Support for ESP-NOW communications

-       Support for MQTT communications

-       Support for FTP communications

-       Support for RJ45 wired ethernet using W5500 module

-       Accompanying utility suite includes Flasher, File Manager, HTML Converter, Backup/Restore to bin or zip, integrated Serial Port Monitor, OTA (over the air) update server and UDP Console.

-       IMU / AHRS Fusion algorithms 6 DOF and 9 DOF (Madgwick and Mahony)

-       Play MP3 or WAV sound files or streaming using a speaker or an external I2S DAC

-       Text to Speech using a speaker or an external I2S DAC

 

The following devices are supported directly with dedicated commands / functions :

-       DHT11, DHT21 or DHT22 Temperature / Humidity Sensors

-       DS18B20 Temperature sensor

-       LCD HD44780 with I2C interface module (1, 2 or 4 lines with 16 or 20 chars per line)

-       LCD Display based on chipset ST7920 with 128x64 pixels monochrome

-       OLED Display based on chipset SSD1306 or SH1106 with 128x64 pixels monochrome [1] 

-       TFT Display based on Chipset ILI9341 with 320x240 pixels and 16 bits colors

-       TM1637 4 digits 7-segments display

-       TM1638 8 digits 7-segments display including 8 leds and 8 buttons

-       MAX7219 8 digits 7-segments display

-       MAX7219 8x8 dot matrix display modules

-       Neopixel WS2812 led strips

-       Neopixel WS2812 8x8 dot matrix display

-       PCA9685 PWM/SERVO module

-       Infrared interface with many RC protocols (transmission and reception)

-       RTC module (DS1307 or DS3231)

-       HC-SR04 ultrasonic sensor for distance measurement

-       BNO055 Absolute Orientation Sensor

-       MPU9250 / MPU6500 IMU units

-       BME280 Combined humidity and pressure sensor

-       APDS9960 Digital Proximity, Ambient Light, RGB and Gesture Sensor

-       W5500 RJ45 wired Ethernet interface

-       VL63L0X TOF (Time Of Flight) Distance Sensor

-       Any compatible I2S DAC

Interpreter:

The basic interpreter works by reading a script file saved to the esp local disk filing system.

This is the default mode if no external SDcard(s) are connected to the ESP32.

In addition, Annex32 can use an external SDcard as file system permitting up to 16Gbytes of disk space.

During the startup, if an external SDcard is detected, it will be automatically connected and used as default file system. In this case the internal filing system will not be used.

Because the ESP32 contains a good quantity of RAM,  the user script is copied from the disk into a dedicated area in the RAM memory where it is executed, together with the list of the program lines, the branch labels and the list of the user defined subroutines..

This uses more RAM compared to other approaches, but allows faster program execution.

Another performance consideration is that the ESP32 must be capable of executing several activities in the background (web server, file server, ..) so needs sufficient free memory for running such tasks, and those parallel tasks will obviously have an impact on script performance..

So performance-wise, the interpreter is not particularly fast, but it should be fast enough for most tasks you may require. In particular is around 2 times faster than Annex for ESP8266, considering that many tasks can run in parallel without particular performance impact (such as playing music in the background).

 

Basic program lines :

A typical script line should comply with the following syntax :

[label:] command [argument1 [,argument2 …..]]

 

Script lines may contain several commands on the same line if separated by the colon character ":".

[label:] command1 [argument1 [,argument2 …..]]: command2 [argument1 [,argument2 …..]]

 

All program jumps (eg: GOTO, GOSUB) are referenced by their branch label names - line numbers are not referenced in scripts, they are merely available in the editor as a programming convenience if wished.

 

 

Branch labels

Branch labels should not be named the same as a command name, and must follow the same format as variables (see below).

A branch label definition must begin the line, and a colon (":") must terminate the label definition.

Any references to the defined label (GOTOs and GOSUBs etc) do not use a colon.

Example :

 

b = 10

a = 20 : c = 30

GOSUB LABEL1

END

LABEL1:  print "Label1"

RETURN

 

 

Variables:

The interpreter has 2 types of variables:

-          Floating Point (double precision)

-          String

Floating point variables can store numbers with decimal point; they can also store integer numbers with a precision equivalent to 32bits.

Strings contain sequences of characters (example "my program") and must be terminated by "$".

The strings are not limited in size, they are only limited by the amount of memory available.

NOTE: The string variables cannot contain the character with ASCII code 0 (zero) because it is used internally as an end of string delimiter.

 

The variables are defined as any name starting with an alpha character (a, b, ..z) followed by any alphanumeric character (a..z, 0..9); it can also include the "_" (underscore).

The case is don’t care, so  ‘’Num"  is equivalent to "nuM".

The name length is limited to 31 characters maximum, including the "$" for the strings.

There are no limits in terms of number of variables; the only limit is the RAM memory available.

Example:

 

NUM = 10.56

myString$ = "this is My String"

this_is_my_value$  = "ESP8266"

number = 8826621

 

Numeric variables and string variables are managed separately so the same name can be used; this means that A and A$ are different variables that can coexist at the same time (even if this could lead to confusion).

 

Constants:

The numeric constants can have the following format :

A = 5 : Z = 1.5

B = 1.23456E5   -> same as 123456

C = 1.23456E+5  -> same as 123456

D = 1.23456E-3  -> same as 0.00123456

 

The string constants are simply defined as a text between quotes:

A$ = "This is my string" : B$ = "another string"

 

The strings can include the character " (quote) simply typing it two times :

A$ = "this is ""MY"" string"

 

The | (vertical bar) can also be used as a string literal.

This permit to include the " (quote) easily inside a string constant :

A$ = |this is a "string" constant|

 

The hexadecimal constants can be defined simply prefixing it with &H :

E = &HABCD -> equivalent of decimal 43981  (hexadecimal constant)

F = &HA0   -> equivalent of decimal 160

 

The binary constants can be defined simply prefixing it with &B :

E = &B00000101  -> equivalent of decimal 5  (binary constant)

F = &B10000001   -> equivalent of decimal 129

 

The octal constants can be defined simply prefixing it with &O :

E = &O377  -> equivalent of decimal 255 (octal constant)

F = &O17   -> equivalent of decimal 15

 

Arrays:

Arrays are defined using the DIM command.

Their names follow the same rules as the regular variables and are followed by parenthesis (brackets) containing the index. The subscript always starts from 0.

The scope of the Arrays is always global (see next paragraph).

Example:

DIM A(100)              define a floating point array with 101 elements (index from 0 to 100)

DIM ABC$(50)          define a string array with 51 elements (index from 0 to 50)

A(15) = 1234.5678

ABC$(49) = "Hi friend!"

 

The arrays can have up to 5 subscripts (dimensions), examples:

DIM A(50,50)  -> create a floating point array with 51*51 elements (2601)

DIM J$(4, 4, 4)  -> create a string array with 5 * 5 * 5 elements (125)

 

 

NOTE:

The numerical Arrays are always initialised at 0 with the command DIM.

The string Arrays are always initialised as null string with the command DIM.

There are no limits to the number of arrays or their size, the only restriction is the RAM memory available.

 

The arrays can be re-dimensioned using the same command DIM.

In this case all the existing elements will maintain the previous value except the new elements that will be initialised at 0 or null string.

 

Example :

DIM A(5)      ' all the elements are initialised at 0

A(0) = 123

Print A(0)   ' print 123

Dim A(10)

Print A(0)  ' print the same value 123

Print A(10) ' print 0

 

In addition the elements of the arrays can be initialised with a given value during the command DIM.

Example :

DIM A(5) = 0, 1, 2, 3, 4, 5   ' set A(0)= 0, A(1)= 1, A(2)=2, ….

 

The same can be done with string arrays.

Example :

DIM A$(5) = "zero", "one", "two", "three", "four", "five"

 

Scope of the variables:

Variables and arrays defined in the main code are global, therefore any variable is accessible from any part of the code after it has been previously defined there.

Variables and arrays defined  inside “user defined” subroutine (SUB) are visible only inside that sub and inside all the code called by that subroutine; their content (and their memory space) is removed at the end of the SUB

The LOCAL command permits defining local variables inside of "user defined" subroutines; this permits to use the same name of an “already existing” variable locally without modifying the original.

As for all the variables defined inside SUB, they will disappear at the end of the subroutine.

 

Example:

A = 10

B = 20

C = 30

mysub "Hello"

PRINT A,B, C

END

 

SUB mysub(a$)

  LOCAL A,B

  A = 123

  B = 456

  C = 789

  D = 8888

  PRINT A$, D

END SUB

 

In this example, calling the user-defined subroutine "mysub" will not modify the content of the global variables A and B (defined locally) but will modify the content of the variable C (not defined locally) and the variable D will disappear at the end of the SUB.

 

Bases of the language

The keywords recognized by the interpreter can be defined into 3 classes:

     Operators

     Commands

     Functions

 

The Operators are symbols that tells the compiler to perform specific mathematical or logical manipulations.

Commands and Functions both execute an action, but functions also return a data value.

For example PRINTis a command and SIN() is a function whereas the ‘+’ in a = b + 5 is an operator.

The string functions are always followed by the "$" symbol if they return a string value.

In addition to commands and functions there are all the internal interpreter internal commands that are part of the language itself.

 

OPERATORS AND PRECEDENCE

The following operators are available. These are listed in the following tables by order of precedence. Operators on the same line are processed with a left to right precedence.

 

Arithmetic operators:

^

Power

* /  \  MOD

Multiplication, division, integer division and modulo (remainder of the division)

+ -

Addition and subtraction

 

Shift operators:

x << y    

x >> y

These operate in a special way. << means that the value returned will be the value of x shifted by y bits to the left while >> means the same only right shifted. They are integer functions and any bits shifted off are discarded and any bits introduced are set to zero.

For more information about the kinds of bitwise shifts, see Bitwise shifts.

 

Logical operators:

<>    <   >   <=

  =>    =

Not Equal, less than, greater than, less than or equal to,

greater than or equal to, equal

AND  OR  NOT XOR

Conjunction, disjunction, negation, Exclusive OR

 

String operators:

<>    <   >   <=

  >=    =

Not Equal, less than, greater than, less than or equal to,

greater than or equal to, equal

+   &

Add strings together

 

Bitwise operators:

AND OR  XOR NOT

Binary AND, binary OR, binary exclusive OR, binary negation

For more information about the bitwise operators, see Bitwise Operators

 

 

The operators AND, OR and XOR are integer bitwise operators. For example PRINT (3 AND 6) will output 2.

 

Expressions beginning with open parenthesis ‘(‘ are always considered numerical but the parser is able to determine if an expression is true or false even if the expression represents a string.

Each expression representing a comparison, returns a numerical value of 1 if the expression is true or 0 if false.

For example 10 = 10 represents a value of 1 whereas 10 = 5 represents a value of 0.

 

The same logic is applied for string expressions where "abc" = "abc" represents a value of 1 and "abc" = "def"  represents a value of 0.

This is very useful in the IF command and also in other expressions.

For example the following code :

 

 

A$ = "on"

If A$ = "on" then

   pin(4) = 1

Else

  pin(4) = 0

End if

 

 

Can be replaced by

pin(4) = (a$ = "on")

 

The strings can also be compared to determine the alphabetical order.

To see whether a string is greater than another, Annex uses the so-called “ASCII” order.

In other words, strings are compared letter-by-letter.

 

For example:

("Z" > "A")  is true

("Glow" > "Glee")  is true

("Bee" > "Be")  is true

("Bas" > "Bat")  is false

The algorithm to compare two strings is simple:

 

Compare the first character of both strings.

If the first character from the first string is greater (or less) than the other string, then the first string is greater (or less) than the second. We’re done.

Otherwise, if both strings’ first characters are the same, compare the second characters the same way.

Repeat until the end of either string.

If both strings end at the same length, then they are equal. Otherwise, the longer string is greater.

In the examples above, the comparison "Z" > "A" gets to a result at the first step while the strings"Glow" and "Glee" are compared character-by-character:

 

-       G is the same as G.

-       l is the same as l.

-       o is greater than e. Stop here. The first string is greater.

 

The comparison algorithm given above is roughly equivalent to the one used in dictionaries or phone books, but it’s not exactly the same.

For instance, case matters. A capital letter "A" is not equal to the lowercase "a". Which one is greater?

The lowercase "a". Why? Because the lowercase character has a greater index in the ASCII table.

 

Basic internal keywords:

 

IF command :

The IF can have the following syntax :

1)    IF expression THEN statement

2)    IF expression THEN statement1 ELSE statement 2

3)    IF expression THEN

Statements

            ELSE

Statements

            END IF

 

Example:

IF a > 100 THEN print "a"

 

IF b <a THEN print "b" ELSE print "a"

 

IF c > d THEN

   print "C"

   print "is greater"

ELSE

   print "D"

   print "is greater"

END IF  ' (can also be ENDIF without space between END and IF)

 

The AND , OR  keywords can be used between the expressions as long as they are in parenthesis.

Example:

IF (a=1) AND (b=2) THEN PRINT "ok"

 

Or

 

IF ((a=2) AND (b=3) AND (c = 3)) OR (d=4) THEN PRINT "ok"

 

 

The IF can be nested

Example:

 

IF a=2 THEN

  IF b = 2 THEN

    IF c = 3 THEN

      PRINT "ok"

    END IF

  END IF

END IF

 

The “THEN” keyword can eventually be removed, even if this is not recommended.

Example:

 

IF a > 100 print "a" else print "b"

 

FOR loop

The FOR loop can have the following syntax :

 

FOR variable=init_value to end_value [step value]

   Statements

NEXT variable

 

The ‘step’ value can be positive or negative

Example:

 

FOR i=1 to 5

  Print i

NEXT i

 

Will print 1, 2, 3, 4, 5

 

FOR i=1 to 3 step 0.5

  Print i

NEXT i

 

Will print 1, 1.5, 2, 2.5, 3

 

FOR i=3 to 1 step -0.5

  Print i

NEXT i

 

Will print 3, 2.5, 2, 1.5, 1

 

The command EXIT FOR can be used to exit from the loop at any time:

 

FOR i=1 to 50

  IF i=10 THEN EXIT FOR

  Print i

NEXT i

Print "end of loop"

 

Optionally, the variable in the NEXT statement can be omitted.

This means that this program is valid :

 

FOR i=1 to 5

  Print i

NEXT

WHILE WEND loop

The WHILE WEND loop can have the following syntax :

WHILE expression

   Statements

WEND

The loop is iterated as long as the expression is true

 

Example:

i = 0

WHILE i < 3

   Print i

   i = i + 1

WEND

 

Will print 0, 1, 2

 

DO LOOP loop

The DOLOOP can have one of the following 4 syntax :

 

DO WHILE expression

     Statements

LOOP

 

DO UNTIL expression

     Statements

LOOP

 

DO

     Statements

LOOP WHILE expression

 

DO

     Statements

LOOP UNTIL expression

 

The command EXIT DO can be used to exit from the loop at any time

 

Example

i = 0

DO

Print i

i = i + 0.5

LOOP UNTIL i >3

Will print 0, 0.5, 1, 1.5, 2, 2.5, 3

 

i = 0

DO

Print i

i = i + 0.5

IF i > 2 THEN EXIT DO

LOOP UNTIL i >3

Will print 0, 0.5, 1, 1.5, 2

 

SELECT CASE

The SELECTcan have the following syntax:

 

SELECT CASE expression

   CASE exp1 [: Statements]

       Statements

   CASE exp2 TO exp3 [: Statements]

       Statements

   CASE exp4 [,exp5], ... [: Statements]

       Statements

   CASE ELSE

       Statements

END SELECT

 

Example:

 

a = 4

SELECT CASE a

   CASE 1

     PRINT "case 1"

   CASE 2 : PRINT "case 2"

   CASE 3 : PRINT "case 3" : PRINT "can continue on same line"

   CASE 4 : PRINT "case 4"

     PRINT "can continue also on next line"

   CASE ELSE:

     PRINT "case else"

END SELECT

 

Multiple cases:

a = 4

SELECT CASE a

   CASE1       : PRINT "case 1"

   CASE 2, 3, 5 : PRINT "case 2 or 3 or 5"

   CASE4       : PRINT "case 4"

   CASE 6 TO 8  : PRINT "case 6 to 8"

   CASE 9 TO 20 : PRINT "case 9 to 20"

   CASE ELSE:

     PRINT "case else"

END SELECT

 

GOTO

The GOTOcan have the following syntax :

GOTO LABEL

 

Example

a = 5

   IF a > 5 THEN GOTO LABEL1

END

....

 

LABEL1:

PRINT "This is label1"

....

 

The goto must be considered as an obsolete command and is provided just for backward compatibility with old style Basic programs.

 

GOSUB

The GOSUBcan have the following syntax :

GOSUB [LABEL | LAB$]

The called function must terminate with the command RETURN

 

Example

a = 5

   IF a > 5 THEN GOSUB LABEL1

END

....

 

LABEL1:

PRINT "This is label1"

RETURN

 

DATA

The command DATA is used to store constant information in the program code, and is associated with the command READ. Each DATA-line can contain one or more constants separated by commas. Expressions containing variables  will be also evaluated here.

The goal of the DATA is to avoid repetitive variable assignation lines, in particular for arrays.

The DATA values will be read from left to right, beginning with the first line containing a DATA statement. Each time a READ instruction is executed the saved DATA position of the last READ is advanced to the next value. Strings must be written in quotes like string constants. The command RESTORE resets the pointer of the current DATA position, so the next READ will read from the first DATA found from the beginning of the program.

In case READ uses the wrong variable type the error message "Type mismatch" appears while referring the line number containing the READ statement that triggered the condition.

DATA lines may scattered throughout the whole program code, but for the sake of clarity they would be better kept together at the beginning of the program.

 

The DATA can have the following syntax :

DATA const1 [,const2] …..

The constants can be Numerical or String.

 

Example :

DATA 1, 55.88, "constant", 99

READ A, B, C$, D

PRINT A, B, C$, D

 

Example without DATA:

dim colors$(5)

colors$(1) = "Red"

colors$(2) = "Green"

colors$(3) = "Blue"

colors$(4) = "Yellow"

colors$(5) = "Magenta"

 

Same example but using  DATA:

DATA "Red", "Green", "Blue", "Yellow", "Magenta"

dim colors$(5)

For i=1 to 5

  Read colors$(i)

Next i

 

 

 

END

Define the end of the program. With this command the program stops.

It can also be :

END IF -> close the IF command

END SELECT -> closes the SELECT CASE command

END SUB -> closes the user defined SUB

 

EXIT

Permit to exit from a loop or a user defined SUB.

The syntax is :

EXIT DO  -> exit from a DO loop

EXIT FOR -> exit from a FOR loop

EXIT SUB -> exit from a user defined SUB.

SUB

Define a user-defined subroutine, which the script can use like a command or function.

User-defined subroutines are effectively additional commands, so cannot be used as branch labels.

Permit to create a user defined command with optional parameters.

The syntax is SUB subname[(arg1 [,arg2] …)]

The variables are passed by reference; this means that the arguments, if modified inside the subroutine, will modify the original variable. This can be useful to return values from the subroutine (acting like a function).

It is possible to pass arrays using the syntax array_name().

Using the LOCAL command will permit to define local variables (useful to avoid to modify existing global variables).

 

Example 1 : routine cube

 

SUB cube(x)

  PRINT X ^3

END SUB

 

cube 3 ' will print 27

 

 

Example 2: routine cube with returning argument

 

SUB cube(x,y)

  y = x ^3    ' the value is returned using the 2nd argument

END SUB

 

ret = 0

cube 5, ret

PRINT ret ' will print 125

 

 

Example 3: routine with local variables and returning argument

 

SUB left_trim(s$, ret$)

  LOCAL i

  i = 1

  DO UNTIL i = len(s$)

    IF mid$(s$, i, 1) <> " " THEN EXIT DO

    i = i + 1

  LOOP

  ret$ = mid$(s$, i)

END SUB

 

z$ = ""

FOR i = 1 to 3

  left_trim "  remove space from left ", z$

  PRINT  z$ + "--"

NEXT i

 

Will print

remove space from left          --

remove space from left          --

remove space from left          --

As you can see in this example, the variable i in the FOR loop is not modified by the LOCAL variable i in the subroutine.

 

Example 4: pass arrays

 

SUB pass_array(f(), c$())

  Dim myArray(10)

  myArray(0) = 456 

  Print f(0), c$(0), myArray(0)

  f(1) = 123

  c$(1) = "myText"

END SUB

 

Dim alpha(10)

Dim beta$(10)

alpha(0) = 456

beta$(0) = "testme"

Pass_array alpha(), beta$()

Print alpha(1), beta$(1)

 

In this example, the array alfa() is passed locally to the array f() and the array beta$() is passed locally to the array c$().

Modifying locally these arrays change the value of the original one as their content is passed by reference.

The array “myArray” will disappear at the end of the SUB

 

 

 

Logical / boolean Operations

As the numerical variables are stored internally as double precision floating number, it is possible to store numbers with a precision equivalent to 32 bits.

Several boolean operators are available to manipulate these numbers..

 

The first operator is the bit shift; it can be shift left << or shift right >>

This operator permit to shift the number of a specified number of positions to left or right.

 

Example

A = 1

Print A << 3 ' will print 8

 

A = 16

Print A >> 2 ' will print 4

 

The operators AND , OR , XOR are also available :

 

A = 24

A = 15

Print A AND B ' will print 8

 

A = 24

A = 15

Print A OR B ' will print 31

 

A = 24

A = 15

Print A XOR B ' will print 23

 

The unary operator NOT is also available. It inverts all the bits from 0 to 1:

A = 0

Print Hex$(NOT A) ' will print FFFFFFFF

 

For a 32 bits number, assuming 4 bytes ABCD where A is the MSB and D the LSB, the bytes can be extracted as follows :

 

VAR = &h12345678 ' this is a 32 bits variable

 

D = VAR AND &hFF

C = (VAR >>  8) AND &hFF

B = (VAR >> 16) AND &hFF

A = (VAR >> 24) AND &hFF

 

For more information, see Bitwise Operators

 

ERRORS HANDLING

Annex allows to control and manage errors happened during the execution of the code.

This is managed with the command ONERROR.

This command defines the action done when an error occurs and applies to all errors including syntax errors.

It can be used in different ways, as specified in the table below:

 

FUNCTIONS / COMMANDS

DESCRIPTION

ONERROR ABORT

Displays the error message and abort the program.

This is the normal behaviour and is the default when a program starts running.

ONERROR IGNORE

Any error will be simply ignored.

As this can make very difficult to debug a program it should be used wisely.

ONERROR SKIP [nn]

Ignore an error in a number of commands (specified by the number 'nn') executed following this command.

'nn' is optional, the default if not specified is one.

After the number of commands has completed (with an error or not) the behaviour will revert to ONERROR ABORT.

ONERROR CLEAR

Reset the eventual pending error

ONERROR GOTO [label | OFF]

Jumps to the error handling routine defined by the label.

It can be removed (hence reverting to ONERROR ABORT) replacing the label with OFF.

Using RETURN inside the error handling routine will continue the execution on the line following the error.

 

When an error occurs, the following constants are available :

 

CONSTANT

DESCRIPTION

BAS.ERRLINE

Returns the line number where the error happened. Value of 0 means no error.

It is reset to 0 with the command ONERROR CLEAR or  running the program or with the command ONERROR IGNORE or ONERROR SKIP.

BAS.ERRNUM

Returns a number where non zero means that there was an error.

It is reset to 0 with the command ONERROR CLEAR or  running the program or with the command ONERROR IGNORE or ONERROR SKIP.

BAS.ERRMSG$

Return a string representing the error message that would have normally been displayed on the console. It is reset to “No Error” running the program or with the command ONERROR CLEAR or ONERROR IGNORE or ONERROR SKIP.

 

Example of error handling using the command ONERROR GOTO :

 

ONERROR GOTO Error_Handler

Print "start"

Print 3/0  ' this generates a divide by zero error

Print space$(60000) ' this generates an out of memory error

End

 

Error_Handler:

Print "Error text "; BAS.ErrMsg$

Print "Error num  "; BAS.ErrNum

Print "Error line "; BAS.ErrLine

Return ' returns to the line following the error

 

 

HOW the interpreter works with the HTML code and Objects :

When a client connects to the module using its IP address, the module will redirect automatically to the url ‘/output?menu’, which sends an empty html page present on the module.

That page contains a bunch of javascript code permitting to interface the page with the module using javascript.

 

image

This page will automatically open a websocket connection with the module; the "squared led" indicates if the connection was successful (green) or not (red).

A mechanism of ping - pong has been implemented into the javascript in order to hold the connection alive all the time. If the connection is lost, the page will try to reconnect automatically without any manual action.

The button "reconnect" permit to force the reconnection if the automatic reconnection fails.

 

As soon as the connection is done with the module, the html page is ready to send and receive messages to / from the module.

Initially the page is empty but its content can be easily filled.

 

To send HTML code to the page, the command HTML is used.

The syntax is : HTML  HTML code.

For example the line

HTML "Hello, world <br>This is my first html content<br>"

 

Will give this result :

image

Continuing with the HTML command, the content can be improved :

HTML "Textbox: <input type='text'><br>"

 

image

 

Continuing again:

HTML "Button:  <button type='button'>Click Here</button>"

 

image

All the html code can be combined and sent with just one HTML command; this is much faster:

 

a$ = "Hello, world <br>This is my first html content<br>"

a$ = a$ + "Textbox: <input type='text'><br>"

a$ = a$ +  "Button:  <button type='button'>Click Here</button>"

HTML a$

 

 

To clear the content of the page, the command is:

CLS

image

 

Now we can try another example

CLS

a$ = "Now style me, please<br>"

a$ = a$ + "Button1:  <button id='but1' type='button'>ON</button> "

a$ = a$ + "Button2:  <button id='but2' type='button'>OFF</button>"

HTML a$

image

 

Now we will try to style the buttons using css.

This can be done using  command CSS CSSID$()

For example the line

CSS CSSID$("but1", "background-color: red;")

Will give this result :

image

 

Combining with the style for the other button:

 

a$ = a$ + cssid$("but1", "background-color: red;")

a$ = a$ + cssid$("but2", "background-color: green;")

CSS a$

 

image

 

A set of functions is included to simplify the creation of HTML pages as we will see later, so no need to worry if you are not familiar with writing HTML code.

 

Now we will mention an important ‘event’ that can be used to automatically fill the content of the page each time a client connects to the module : OnHtmlReload.

This ‘event’ defines a place where the program will jump to as soon as Websocket connection request is accepted.

Let’s clarify with an example :

OnHtmlReload Fill_Page    ‘will jump to Fill_Page when the page is reloaded

gosub Fill_Page  'load the page for the first time

Wait         ‘pause waiting for the event

Fill_Page:   ‘place where the page begins to be created

CLS

a$ = "Now style me, please<br>"

a$ = a$ + "Button1:  <button id='but1' type='button'>ON</button> "

a$ = a$ + "Button2:  <button id='but2' type='button'>OFF</button>"

HTML a$

a$ = cssid$("but1", "background-color: red;")

a$ = a$ + cssid$("but2", "background-color: green;")

HTML a$

RETURN

 

The result will be:

image

Now try to play with the button "Reconnect"; you’ll see that, at each time the page reconnects to the module, the HTML content is built and sent again. This ensures that each time a client connects to the module it will receive the correct content. At the same time, if other clients are already connected, the content of all the pages will be refreshed simultaneously. This insures a synchronized content between all the clients.

 

HTML Objects

As said previously, in order to simplify the creation of HTML pages, there are several functions permitting to generate the html code automatically.

Let’s start with the button.

A button is an object that is used to generate an action each time it is pressed on the web page.

The function is BUTTON$.

Let’s explain with an example:

 

CLS

HTML BUTTON$("Button1", jump1)

 

Wait         'pause waiting for the event

 

Jump1:

PRINT "Clicked on Button1"

Return

 

 

 

The result will be:

image

 

Try clicking on the button then checking the result in the terminal console; the message "Clicked on Button1" will be shown at each click.

image

 

To style the button, we need to modify the syntax of the BUTTON$ command slightly; in fact we need to add another parameter to give the button an ID:

 

CLS

HTML BUTTON$("Button1", jump1, "but1")   ' "but1" is the ID

 

Wait         'pause waiting for the event

 

Jump1:

PRINT "Clicked on Button1"

CSS cssid$("but1", "background-color: red;") 'the same ID is used here

Return

 

Clicking on the button now will change its color to red

image

 

Now we can now introduce the LED object. The LED object, is a circle that can be filled in red or green depending on the content of a variable. The function is LED$

As usual, let’s start with an example:

 

 

CLS

led = 1    ‘this is the variable associated with the LED. With 0 the led is red, with 1 the led is green

HTML LED$(led)

 

The result will be:

image

 

Let’s also add a button :

 

CLS

led = 0

a$ = BUTTON$("Button1", jump1, "but1")   ' "but1" is the ID

a$ = a$ + LED$(led)

HTML a$

 

Wait         'pause waiting for the event

 

Jump1:

PRINT "Clicked on Button1"

led = 1 - led ' invert the variable

REFRESH ' refresh (update) the variables between the code and the html

Return

 

 

The result will be:

image

 

Clicking on the button will toggle the led between red and green colors.

 

The command REFRESH permits to update (synchronize) the variables in the code with the corresponding objects variables on the web page. It should be run each time a variable is modified.

As a simpler alternative, the command AUTOREFRESH will regularly sync the variables.

The command must be run with the desired refresh timing.

Example

AutoRefresh 500   will refresh the variables each 500 milliseconds.

The interval should not be less than 300 milliseconds (otherwise the module will be too busy).

 

The example :

 

CLS

led = 0

a$ = BUTTON$("Button1", jump1, "but1")   ' "but1" is the ID

a$ = a$ + LED$(led)

HTML a$

AutoRefresh 300   'sync each 300 milliseconds

Wait         'pause waiting for the event

 

Jump1:

PRINT "Clicked on Button1"

led = 1 - led ' invert the variable

 

Return

 

The result will be the same as the previous example.

 

Now it’s time to introduce another object; the TEXTBOX with the corresponding function TEXTBOX$.

The TEXTBOX will display a ‘text box’ on the web page which is linked with a variable. When the variable is modified in the code, the TEXTBOX content will be updated on the web page and vice-versa.

This will lets us introduce another ‘event’ : the OnHtmlChange command.

This ‘event’ defines a branch for the program to jump to whenever a variable is modified inside the web page.

As usual, let’s start with an example:

 

 

CLS

text$ = "Change me, please"

HTML TEXTBOX$(text$)

OnHtmlChange Jump1  'will jump to Jump1 when a variable changes on the web page

Wait         'pause waiting for the event

 

Jump1:

Print text$ 'print the content of the variable inside the terminal console

Return

 

 

image

 

Try now to change the content of the textbox and press "Enter" on the keyboard.

Let’s see the result in the terminal console:

image

image

 

With the concepts already learned you’ll be able to use the other objects using the similar logic.

Refer to the pages below to understand the syntax of each object.

 

TIMERS

A timer is an "object" that permits to execute a particular action at regular intervals.

When the given time expires, the normal execution of the program is interrupted and control is passed to the "timer interrupt routine" until the execution of the return command.

Then the program continues from the point where it has been interrupted.

Let’s explain with an example :

 

timer0 1000, mytimer

wait

 

mytimer:

  wlog "mytimer " + time$

return

 

Annex WI-Fi Basic implements 2 timers, Timer0 and Timer1.

The Timer0 has a higher priority against Timer1.

EVENTS[2] 

Many of the actions are not executed directly by basic commands but can be executed as asynchronous events.

An  "event" is simply an action that can be executed when something happens.

For example, the pin change interrupts is an asynchronous events as it can happen at any time without user control.

In order to manage the events, a list of commands "ONxxxx" is provided. These commands define the place where the normal execution of the program will branch to when the event occurs.

So, when the "event" happens, the basic interrupts the normal execution of the code and "jumps" to the location defined by the corresponding command "ONxxx". As soon as the code associated with the "event" is terminated with the command "return", the basic continues from the previous interrupted location.

Button Event

This is a special event that happens every time aBUTTON$ object is clicked in the HTML pages.

When this happens, a special variable HtmlEventButton$ is created containing the name of the button that was clicked.

This is useful to determine the button within a group of buttons.

Let’s see an example:

 

CLS

HTML Button$("ON", buttonEvent) + " " + Button$("OFF", buttonEvent)

wait

 

buttonEvent:

print "You clicked on "; HtmlEventButton$

return

 

OnHtmlChange Event

This event is triggered when an object present in the HTML output page changes its value.

It is useful to make actions when something changes in the HTML Pages.

When this event happens, a special variable HtmlEventVar$ is created containing the name of the variable that changed its value.

This is useful to determine the object that generated the event.

Let’s see an example :

 

CLS

text$ = "Change me, please"

HTML TEXTBOX$(text$)

OnHtmlChange Jump1  'will jump to Jump1 when a variable changes on the web page

Wait         'pause waiting for the event

 

Jump1:

Print text$ 'print the content of the variable inside the terminal console

Return

 

OnHtmlReloadEvent

This event is triggered when a Websocket connection request is accepted.

This can be used to automatically fill the content of the WEB page each time a client connects to the module.

Let’s see an example :

 

CLS

OnHtmlReload Fill_Page   'will jump to Fill_Page when the page is reloaded

gosub Fill_Page  'load the page for the first time

Wait         'pause waiting for the event

Fill_Page:   'place where the page begins to be created

CLS

a$ = "Now style me, please<br>"

a$ = a$ + "Button1:  <button id='but1' type='button'>ON</button> "

a$ = a$ + "Button2:  <button id='but2' type='button'>OFF</button>"

HTML a$

a$ = cssid$("but1", "background-color: red;")

a$ = a$ + cssid$("but2", "background-color: green;")

HTML a$

Return

 

OnInfrared Event

This event is triggered when a code is received by the infrared receiver.

Refer to chapter INFRARED INTERFACE for more details.

 

OnSerial Event

This event is triggered when a message is received on the serial port.

Example:

 

print "Ram Available "; ramfree
onserial rec1
wait

rec1:
'print serial.input$
print serial.chr$;
return

 

 

 

OnSerial2 Event

This event is triggered when a message is received on the serial port #2.

Example

 

serial2.mode 9600, 2, 5 ' set serial port #2 to 9600 pin 2 TX, pin 5 RX
print2 "Ram Available "; ramfree
onserial2 rec2
wait

rec2:
print serial2.input$
return

 

 

OnTouch Event

This event is triggered when the TFT screen is touched.

Refer to the chapter TouchScreen for more details.

 

OnUDP Event

This event is triggered when a UDP message is received.

Example:

 

udp.begin 5001  'set the UDP commmunication using port 5001
onudp goudp
'Write several messages to the port
for i
= 0 to 100
  
udp.write "192.168.1.44", 5001, "Hello " + str$(i)
next i
wait

goudp:
v$
= udp.read$ 'receive the UDP data

print v$
return

 

 

OnWgetAsync Event

This event is triggered when a WgetAsync message is received.

This is associated with the command WGetAsync http_server$, port.

The goal of the WGetAsync command is to start a html get request without the module having to wait for the answer.

As the answer is async, this command will define the place where the program execution will continue when the message will be received.

Example:

 

ONWGETASYNC answer_done

WGETASYNC("www.fakeresponse.com/api/?sleep=5", 80)

For i = 0 to 10000

  ' a kind of sleep just to demonstrate that the code continue to run

  Print i

Next i

Wait

answer_done:

Print WGETRESULT$

Return

 

OnUrlMessage Event

This event is triggered as soon as a web client requests for a web page with the url composed with http://local_ip/msg?param=value. This kind of request is typically called an AJAX request as it permits to exchange in both directions between the client (the web browser) and the server (the ESP module).

In fact, in the url request, the client can send parameters in the form of couples of "param=value" separated by the character "&". For example, if the client wants to send 2 parameters, it can send the following request :

http://local_ip/msg?param1=value1&param2=value2.

As soon as this message is received by the ESP module, the event OnUrlMessage is triggered; this means that the program will continue from the location defined by the command OnUrlMessage.

As soon as the message is received, the parameters sent by the client can be got with the function UrlMsgGet$ and a message can be sent back to the client with the command UrlMsgReturn.

Let’s see an example :

 

onUrlMessage urlAjax

wait

 

urlAjax:

wlog "message received " + UrlMsgGet$("a") + " " + UrlMsgGet$("b")

UrlMsgReturn "Message sent back " + time$

print UrlMsgGet$("b"), ramfree

return

 

Now using another web browser window, let’s type the following url :

http://esp_local_ip/msg?a=10&b=20

As you can see in the following picture, the message is received by the ESP module

image

 

 

 

At the same time, the client receives the message sent back from the ESP module

image

 

If the program is stopped, the module will answer with the message "STOPPED"

image

Now, let’s see a more complete example :

cls

' this is the default value for pwm out

R = 512

G = 512

B = 512

'Setup the pwm channels

PWM.SETUP 12, 1, R, 10000, 10

PWM.SETUP 15, 1, G, 10000, 10

PWM.SETUP 13, 1, B, 10000, 10

'Set the default values

PWM.OUT 1, R

PWM.OUT 2, G

PWM.OUT 3, B

 

' these are the sliders

a$ = ""

a$ = a$ + |R <input type="range" id="dimmer_R" oninput="setPWM()" onclick="setPWM()" min="0" max="1023" value="| & str$(R) & |"/><br>|

a$ = a$ + |G <input type="range" id="dimmer_G" oninput="setPWM()" onclick="setPWM()" min="0" max="1023" value="| & str$(G) & |"/><br>|

a$ = a$ + |B <input type="range" id="dimmer_B" oninput="setPWM()" onclick="setPWM()" min="0" max="1023" value="| & str$(B) & |"/><br>|

a$ = a$ + |<input type='text' id="txbox" value='---'>|

html a$

'this is the javascript "AJAX" code

fun$ =    |function setPWM() {|

fun$ = fun$ & |r=_$("dimmer_R").value;|

fun$ = fun$ & |g=_$("dimmer_G").value;|

fun$ = fun$ & |b=_$("dimmer_B").value;|

fun$ = fun$ & |var xmlHttp = new XMLHttpRequest();|

fun$ = fun$ & |xmlHttp.open("GET", "msg?r=" + r +"&g=" + g +"&b=" + b, false);|

fun$ = fun$ & |xmlHttp.send(null);|

fun$ = fun$ & |r = xmlHttp.responseText;|

fun$ = fun$ & |_$("txbox").value = r;|

fun$ = fun$ & |return r;}|

 

' this is where the javascript code is inserted into the html

jscript fun$

 

'this is where the prog will jump on slider change

onUrlMessage message

wait

 

message:

print UrlMsgGet$()

 

PWM.OUT 1, val(UrlMsgGet$("r"))

PWM.OUT 2, val(UrlMsgGet$("g"))

PWM.OUT 3, val(UrlMsgGet$("b"))

UrlMsgReturn UrlMsgGet$()

return

 

Open the input page in another window and run the program

 

image

Using an external RGB led, you’ll be able to directly control its color.

You’ll see how the exchanges can be fast using AJAX exchanges. This program uses javascript embedded into the code. The javascript works with the function XMLHttpRequest.

A good reference for this function is here AJAX - Send a Request To a Server

OnEspNowMsg Event

This event is triggered when a ESP-NOW message is received.

Example:

 

espnow.begin  ' init the ESP-NOW

onEspNowMsg message ' set the place where jump in case of message reception

wait

 

message:

print "Message Received!"

return

 

OnEspNowError Event

This event is triggered when a ESP-NOW a transmission error occurs.

This happen, in particular, when the receiver device has not received the message.

 

espnow.begin  ' init the ESP-NOW

espnow.add_peer "60:01:94:51:D0:7D" ' set the MAC address of the receiver

onEspNowError status ' set the place where jump in case of TX error

espnow.write "TX message" ' send the message

wait

 

status:

print "TX error on "; espnow.error$  ' print the error

return

 

OnMQTT Event

This event is generated when a MQTT message is received

Example:

 

....

onmqtt mqtt_msg

 

wait

' receive messages from the server

mqtt_msg:

print "TOPIC  : "; mqtt.topic$

print "MESSAGE: "; mqtt.message$

return

 

 

WiFI CONNECTIONS

At startup, the module tries to connect to the router with the parameters provided in the page “Config”.

If the connection is unsuccessful, it will default to AP (Access Point) mode .

By default, if no parameters are specified into the “Config” page, the module will default to the IP address 192.168.4.1 in AP mode with the SSID composed of ESP(+ mac address).

If the connection is successful, the module will use the IP address defined in the “Config” page or, if not specified, the IP will be given automatically by the Router DHCP server.

As soon as the module is connected to the router, it will reconnect automatically in case of connection is lost.

 

There are several commands / functions available to manage the WIFI.

 

The first function is WIFI.STATUS which permits to get the status of the connection.

print WIFI.STATUS ’ print 3 if connected, 6 if disconnected

 

The first useful command is WIFI.CONNECT SSID, password

This command allows you to connect to any WIFI network overriding the parameters defined into the’ “Config” page. This function is async so the connection is done in background, while the program continues to run.

It is then possible to check the status of the connection using the function WIFI.STATUS

Example :

WIFI.CONNECT “HOMENET”, “MyPassword”

print "connecting"
While WIFI.STATUS <> 3
 
Print "."
 
pause 500
wend

 

It is eventually possible to control the output power of the module with the command WIFI.POWER pow

WIFI.POWER 5 ’ set the output power at 5 dBm.

 

The module can be also put in WiFi sleep mode. This mode permits to turn off the WiFi reducing the power requirements of the module; this is very useful for battery oriented applications or for applications where the WiFi is not required.

To put the module in “modem-sleep”, the command to execute is WIFI.SLEEP.

The module will stay in that mode until the execution of the command WIFI.AWAKE.

After this command, the module will reconnect automatically to the router (the command WIFI.CONNECT is not required).

Another function available is WIFI.CHANNEL that shows the current Radio Channel used by the WIFI.

 

It is also possible to scan for the WiFi networks accessible around the module.

This can be done using the command WIFI.SCAN and the function WIFI.NETWORKS(network$).

Example :
WIFI.SCAN
While WIFI.NETWORKS(A$) = -1
Wend
Print a$

The result will be :

Vodaphone, 00:50:56:C0:00:08, -50, 5

Orange, 00:50:56:C0:32:07, -70, 5

Xxxx,  00:50:56:C0:86:CA,-78, 12

These information represent, in the order :

SSID, BSSID(mac address), RSSI(signal intensity), Channel Radio

 

Another Wifi related command is OPTION.MAC mac$ that permit to modify the MAC address of the module.

This is very important for the ESP Now functionality.

Example :

OPTION.MAC "AA:BB:CC:DD:EE:FF"

 

In addition, the functions BAS.SSID$ and BAS.PASSWORD$ returns respectively the login and the password used for the STATION wifi connection.

 

RECOVERY MODE

In case of any IP or Autorun problem preventing the module from being accessed, it is possible to temporarily bypass the IP settings of the module and disable the Autorun file by connecting the serial TX and RX pins together (GPIO1 to GPIO3) during the startup phase (power up).

This could happen if, for example, a wrong IP address has been set.

Doing this action when restarting the module will put it in AP mode with the IP address at 192.168.4.1, just like a module that has not been configured.

A message “Recovery Mode” will be printed on the console, but none of the existing files on the module will be modified, including the internal configuration parameters.

In this mode it will be possible to gain access to the module for changing such correct wrong IP parameters using the configuration page.

When the TX/RX link is removed, the module can be rebooted to the configured settings at next restart.

DATE - TIME timekeeper

The ESP module normally synchronises its date and time from either of two NTP time servers ("pool.ntp.org" and "time.nist.gov"). Optionally an alternative (eg: intranet) time server can be defined using the [CONFIG] page.

Using these servers the ESP doesn’t require any date/time setting (except the configuration of the Time Zone and DST done using the [CONFIG] page).

 

The timezone is defined as a string like CET-1CEST,M3.5.0,M10.5.0/3 that describe how the local time must be managed in terms of time shift and DST (summer / winter time).

 

A complete list of timezone strings can be found here : https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv

 

An internal timekeeper has been included if no time server is available, eg no available internet access.

This timekeeper starts from 01/01/1970 00:00:00 and counts the seconds since the power on of the module.

If internet connection becomes available later, the internal timekeeper will sync its time with the NTP servers.

 

The time can be sync with the NTP time server at any moment using the command OPTION.NTPSYNC.

 

This time and date can be manually set using the command SETTIME.

The Syntax is :

SETTIME year, month, day, hours, minutes, seconds

 

Example

Set the date to 02 September 2017 at 13:58:12

 

SETTIME 17, 9, 2, 13, 58, 12

 

The time and date can also be manually synchronised to computer using the "Time Sync" button in the File Manager window of the computer utility ‘tool’ if it has websocket connection.

 

 

 

WARNING:

In both cases of manual setting, the time and date will be reset back to 1970 default at next restart of the module, so will require setting again.

 

For more information about the Time Zones and DST, please consult the following page :

Time Zone and DST

 

It is also possible to connect an RTC (DS1307 or DS3231) to the module.

See the chapter “RTC Module” for more details.

Unix Time functions

The following functions utilises the time following the “Unix Time Stamp” format :

DATEUNIX(date$), TIMEUNIX(time$), UNIXDATE$(value [,format]), UNIXTIME$(value)

 

The “Unix Time Stamp” is a way to track time as a running total of seconds.

This count starts at the Unix Epoch on January 1st, 1970 at UTC.

Therefore, the unix time is merely the number of seconds between a particular date and the Unix Epoch.

In synthesys :

-       DATEUNIX("01/01/18") returns the number of seconds from 01/01/1970 to the specified date 01/01/2018  (1514764800)

-       TIMEUNIX("12:30:55") returns the number of second since midnight (45055)

-       UNIXDATE$("1532773308") returns 28/07/18

-       UNIXTIME$(1532773308) returns 10:21:48

WIRING

image

 

This diagram shows pin mapping for the popular ESP32 DEV Board module.

(*) pins GPIO6 to GPIO11 are not available.

 

 

Annex 32, as it supports by default the M5stack wiring, assumes the following pins already allocated/dedicated

 

PIN

FUNCTION

DESCRIPTION

32

PWM BL TFT

Backlight TFT display

33

RST TFT

RST pin TFT

27

D/C TFT

D/C pin TFT

14

CS TFT

CS pin TFT

23

SPI MOSI

SPI MOSI pin (shared with SD and TFT)

19

SPI MISO

SPI MISO pin (shared with SD and TFT)

18

SPI SCK

SPI CLOCK pin (shared with SD and TFT)

4

CS SDCARD

CS pin SDCARD

0

CS TFT TOUCH

CS pin Touchscreen (from the TFT)

 

 

 

3

RX0

Serial Port RX pin

1

TX0

Serial Port TX pin

 

 

 

25

SPEAKER

Speaker or mono audio output

21

SDA I2C

I2C SDA pin

22

SCL I2C

I2C SCL pin

 

 

 

2

I2S DATA

Audio DAC I2S DATA pin

5

I2S BCLK

Audio DAC I2S BCLK pin

26

I2S LRCK

Audio DAC I2S LRCK pin

16

PSRAM

Optional PSRAM

17

PSRAM

Optional PSRAM

 

 

image

 

DIGITAL I/O

 

Pin numbers correspond directly to the ESP32 GPIO pin numbering.

The function of the pin (input / output) must be defined before using the function PIN.MODE as below :

 

To define the pin 5 as input :

PIN.MODE 15, INPUT

 

To define the pin 4 as input with a pullup:

PIN.MODE 4, INPUT, PULLUP

 

To define the pin 4 as input with a pulldown:

PIN.MODE 4, INPUT, PULLDOWN

 

To define the pin 2 as output

PIN.MODE 2, OUTPUT

 

Although pin numbers can be from 0 to 39, gpio pins 6 to 11 should not be used because they are connected to flash memory chips on most modules. Trying to use these pins as IOs will likely cause the program to crash.

 

Pins 34 to 39 are INPUT only and cannot be configured as PULLUP or PULLDOWN.

Pins 0 to 33 can be INPUT, OUTPUT INPUT, PULLUP or INPUT, PULLDOWN.

 

Pins may also serve other functions, like Serial, I2C, SPI.

These functions are normally activated by the corresponding library.

 

The value from a pîn can read as below :

A = PIN(5) read from GPIO5 pin

 

The pin value can be set as below

PIN(2)= 0 set 0 on the GPIO2 pin

 

The pin value (0 or 1) can also be easily toggled by subtracting it from 1 (because 1-0=1 and 1-1=0), eg:

PIN(2)= 1 - PIN(2) toggles the value of GPIO2 pin

 

PIN INTERRUPTS

The INTERRUPT command permits to trigger an event when the signal on an input pin changes.

The interrupt is triggered BOTH when the signal goes from LOW to HIGH and HIGH to LOW.

 

Example:

 

pin.mode 12, input   ' set pin 12 as input
interrupt 12, change_input  ' set interrrupt on pin 12

wait

change_input:
if pin(12) = 0 then return   ' if the pin is low, returns back
print "The pin changed to HIGH"
Return

 

Analog inputs

Annex32  has a 8 ADC pins with 12 bits resolution available to users.

The function ADC(pin) can be used to read voltage on the pins defined in the table below.

 

GPIO Pins Available as Analog Input

32

33

34

35

36

37

38

39

 

To read the voltage applied at the pin, the function ADC can be used as below :

 

print ADC(39)' read voltage from the pin 39

 

The voltage range is  0 ... 3.3V and the corresponding range returned by the function is 0 … 4095.

 

NOTE: When using the function ADC,the pin is automatically converted to Analog Input

TOUCH inputs

Annex32 supports an additional ESP32feature, the capacitive touch.

With this feature, it is possible to activate inputs with your fingers with just one wire attached to the pin.

The function PIN.TOUCH(pin) can be used to read the touch value on the pins defined in the table below.

 

GPIO Pins Available as Touch Input

0

2

4

12

13

14

15

27

32

33

 

The function PIN.TOUCH(pin) returns a value that drops as soon as the pin is touched.

Normal values are around 70 when not touched and lower than 20 when touched.

 

'Pin Touch example

'Place a wire on pin 13 and look how the value changes when touching it

while 1

  print pin.touch2(13)

  pause 100

wend

end

 

Hardware interfaces:

The ESP32 contains several H/W interfaces that can be controlled by Annex32 WI-Fi using specific commands and functions.

PWM

This functionality permits to control the output duty cycle of any pin, acting like an analog output.

There are 16 channels available where each channel can be connected to any output pin.

 

To use it, the function must first be configured using the command PWM.SETUP and then the value can be set using the command PWM.OUT.

 

The frequency and the resolution can be defined individually for each channel.

The resolution can be from 1 to 15 bits.

The maximal frequency is 80000000 / 2^resolution

 

This table resumes the maximal frequency available in function of the resolutions and the associated range:

 

RESOLUTION (BITS)

MAX FREQUENCY

VALUE RANGE

1

40000000

0 ... 1

2

20000000

0 ... 3

3

10000000

0 ... 7

4

5000000

0 .. 15

5

2500000

0 .. 31

6

1250000

 0 … 63

7

625000

0 … 127

8

312500

0 … 255

9

156250

0 … 511

10

78125

0 … 1023

11

39063

0 … 2047

12

19531

0 … 4095

13

9766

0 … 8191

14

4883

0 … 16383

15

2441

0 … 32767

 

All the output pins can be used for the PWM (the pins from GPIO0 to GPIO33).

As there are 16 channels, up to 16 individual output pins can be used.

If using the M5Stack, the channels 0 and 7 are already reserved and attached to the pin 25 and pin 32.

In this case the channels 0 and 7 must be avoided.

 

To setup an output pin as a PWM output the following command must be used :

PWM.SETUP pin, channel, default_value,  [,frequency] [,resolution]

 

For example, to define a PWM output at 5KHz with 12 bits of resolution on the pin GPIO5 the command is :

PWM.SETUP 5, 1, 2048, 5000, 12 ‘ pin 5, channel 1, output value at 2048 (50%), 5KHz, 12 bits

As the resolution is set at 12 bits, the range will be from 0 to 4095 (hence 2048 is the 50%).

 

To define a PWM output at 10KHz with 8 bits on the pin GPIO22, the command is :

PWM.SETUP 22, 2, 128  ‘ pin 22, channel 2, value 128( 50%) , freq 10 KHz (default), resolution 8 bits (default)

 

As soon as the command PWM.SETUP is done, the PWM output can simply be changed with the command :

 

PWM.OUT channel, value

 

For example, the command

PWM.OUT 1, 1000

Set the channel 1 (associated with the pin 5 in the previous command) at 1000.

 

And the command

PWM.OUT 2, 10

Set the channel 2 (associated with the pin 22 in the previous command) at 10

 

To disconnect the pin from the PWM output the command is :

PWM.SETUP pin, OFF.

 

For example the command

PWM.SETUP 5, OFF

Disconnect the pin 5 fro the PWM

 

NOTE for the M5stack:

The channel 0 is dedicated to the internal speaker (pin 25)

The channel 7 is dedicated to the TFT backlight (pin 32)

 

 

SERVO

This functionality exposes the ability to control RC (hobby) servo motors.

There are no special commands dedicated as the servo can simply be used by setting a PWM pin with a 50Hz frequency.

For example, the following command :

PWM.SETUP 17, 1, 150, 50, 12

Defines the pin 17 with the pwm channel 1 with a default value of 150 (frequency at 50 Hz and resolution at 12 bits).

 

The output can then be set with the command

PWM.OUT 1, 307‘ channel 1 set at 90°

 

 

A typical servo motor expects to be updated every 20 ms with a pulse between 1 ms and 2 ms, or in other words, between a 5 and 10% duty cycle on a 50 Hz waveform. With a 1.5 ms pulse, the servo motor will be at the natural 90 degree position. With a 1 ms pulse, the servo will be at the 0 degree position, and with a 2 ms pulse, the servo will be at 180 degrees. You can obtain the full range of motion by updating the servo with any value in between.

image

Using a 12 bits resolution (max value = 4095 for 20 msec pulse (1/50 Hz)), the theoretical values should be :

  0° -> 1 msec -> 1/20 * 4096 = 205

90° -> 1.5 msec -> 1.5/20 * 4096 = 307

180° -> 2 msec -> 2/20 * 4096 = 409

 

I2S BUS

I²S (Inter-IC Sound), is an electrical serial bus interface standard used for connecting digital audio devices together. It is used to communicate PCM audio data between integrated circuits in an electronic device.

The I²S bus separates clock and serial data signals, resulting in a lower jitter than is typical of communications systems that recover the clock from the data stream.

Despite the name, I²S is unrelated to the bidirectional I²C (I2C) bus.

 

The bus consists of three lines:

Bit clock line

-       Typically called "bit clock (BCLK)".  PIN GPIO5

Word clock line

-       Typically called "left-right clock (LRCLK)"  or “Word Select (WSEL)”. PIN GPIO26

Data line

-       Typically called "serial data (SD)". Can also be called (SDIN, SDOUT or DATA). PIN GPIO2

 

The typical use of the I2S is to connect an external DAC to provide a High Quality stereo sound output.

 

Using the PLAY.xxx commands, it will be possible to play MP3 and WAV files directly from the disk.

 

Any generic I2S DAC can be used.

Annex32 has been successfully tested with the PC5102A and the UDA1334A

 

imageUDA1334A I2S DAC

 

 

 

image

 

imagePCM5102A I2S DAC

image

 

 

SPEAKER OUTPUT

The M5stack contains an internal speaker connected, via an audio amplifier, to the pin GPIO25.

This permits the generation of audio signals using the internal 8 bits DAC.

Using the PLAY.xxx commands, it will be possible to play MP3 and WAV files directly from the disk.

 

It is possible to connect an earphone directly on the output between the pin GPIO25 and the ground but the best is to connect a little audio amplifier.

 

NOTE: it is recommended to put a capacitor ( ~100nF) between the GPIO25 and the audio amplifier in order to remove the DC component from the audio signal.

 

I2C BUS

The I²C bus allows the module to connect to I²C devices.

 

I²C uses only two bidirectional open-drain lines, Serial Data Line (SDA) and Serial Clock Line (SCL), pulled up with resistors (typically 4.7K to 10K).

 

The I²C has a 7 bit address space permitting, theoretically, to connect up to 126 I/O devices.

 

The maximal number of nodes is limited by the address space and also by the total bus capacitance of 400 pF, which restricts practical communication distances to a few meters. The relatively high impedance and low noise immunity requires a common ground potential, which again restricts practical use to communication within the same PC board or small system of boards.

 

The current implementation is master mode @ 100Khz by default.

 

The SDA and SCL pins can be freely defined using the command I2C.SETUP sda_pin, scl_pin.

For example, to define pins 21(SDA) and 22(SCL) the command is :

I2C.SETUP 21, 22

 

It is important to provide correct pullup resistor on these lines; values between 4.7K to 10K should be appropriate.

 

The commands available are :

I2C.BEGIN, I2C.END, I2C.REQFROM, I2C.SETUP, I2C.WRITE

The functions available are :

I2C.LEN, I2C.READ, I2C.END

 

There are also other advanced functions / commands to simplify exchanges with the i2c bus.

The advanced commands available are :

I2C.READREGARRAY, I2C.WRITEREGBYTE,I2C.WRITEREGARRAY

 

The advanced functions available are :

I2C.READREGBYTE

 

As all the devices can have a "not well" determined address, please find here a little i2c scanner program which returns the address of all the devices found connected to the bus

'I2C Address Scanner

'print in the console the address of the devices found

I2C.SETUP 21, 22  ' set I2C port on pins 21 and 22

 

for i = 0 to 120

  i2c.begin i

  if i2c.end = 0 then

     print "found "; i , hex$(i)

     pause 10

  end if

next i

 

end

 

 

PCF8574 Module

This is an example of connection of a module with PCF8574 bought on Ebay at less than 2€ 

 

image

This drawing shows how this module must be connected to the ESP32.

It provides 8 digital inputs or outputs.

image

This is an example of code that "drives" this module:

I2C.SETUP 21, 22  ' set I2C port on pins 21 and 22

device_address = 32  'set to module i2c address

'Write from 0 to 255 on the module

'Each pin will blink at different frequency

For i = 0 to 255

PCF8574_write i

Next i

 

'Read all the inputs

'The result is printed into the serial console

' put all the inputs at pullup state

PCF8574_write 255

 

r = 0

For i = 0 to 1000

  PCF8574_read r

  Print r

Next i

End

 

sub PCF8574_write(x)

  i2c.begin device_address

  i2c.write x

  i2c.end

end sub

 

sub PCF8574_read(x)

  i2c.begin device_address

  i2c.reqfrom device_address, 1

  x = i2c.read

  i2c.end

end sub

 
ADS1115 Module

This is another example of connection of a module with ADS1115 bought on Ebay at less than 2€.

This is a 16 Bit ADC 4 channel Module with Programmable Gain Amplifier.

imageimage

 

Because the module already contains two 10K I2C pullups, no external resistors are required

 

image

 

As this device is quite simple to interface, it can be directly driven using a “driver” written in basic.

' ADS1115 Driver for Annex

' datasheet http://www.ti.com/lit/ds/symlink/ads1115.pdf

' ADS1115 Registers

ADS1115_ADDRESS = &h48

ADS1115_CONV_REG = 0 : ADS1115_CONF_REG = 1

ADS1115_HI_T_REG = 2 : ADS1115_LO_T_REG = 3

 

dim BUFF_IN(2) ' buffer used for read/write to module

i2c.setup 21, 22 ' set I2C bus

 

' Set the ADS1115 with :

'    AINp = AIN0 and AINn = AIN1

'    FSR = ±4.096 V

'    16 SPS

ADS1115_setup 0, 1, 1

 

' scale in volt

scale = 4.096 / 32768

 

v = 0

for i = 0 to 100000

 ADS1115_read v  ' read from the module

 print v * scale

next i

 

end

 

'---------------------------------------------------------

' INPUT MULTIPLEX :

' AINp is the input positive

' AINn is the input negative

'0 : AINp = AIN0 and AINn = AIN1

'1 : AINp = AIN0 and AINn = AIN3

'2 : AINp = AIN1 and AINn = AIN3

'3 : AINp = AIN2 and AINn = AIN3

'4 : AINp = AIN0 and AINn = GND

'5 : AINp = AIN1 and AINn = GND

'6 : AINp = AIN2 and AINn = GND

'7 : AINp = AIN3 and AINn = GND

 

'GAIN

'0 : FSR = ±6.144 V

'1 : FSR = ±4.096 V

'2 : FSR = ±2.048 V

'3 : FSR = ±1.024 V

'4 : FSR = ±0.512 V

'5 : FSR = ±0.256 V

'6 : FSR = ±0.256 V

'7 : FSR = ±0.256 V

 

'DATA RATE

'0 : 8 SPS

'1 : 16 SPS

'2 : 32 SPS

'3 : 64 SPS

'4 : 128 SPS

'5 : 250 SPS

'6 : 475 SPS

'7 : 860 SPS

sub ADS1115_setup(inp_mux, gain, rate)

 local conf

 conf = (inp_mux << 12) or (gain << 9) or (rate << 5) or 3 ' + disable comp

 BUFF_IN(0) = (conf and &hff00) >> 8 : BUFF_IN(1) = conf and &hff

 i2c.WriteRegArray ADS1115_ADDRESS, ADS1115_CONF_REG, 2, BUFF_IN()

end sub

 

sub ADS1115_read(ret)

 i2c.ReadRegArray ADS1115_ADDRESS, ADS1115_CONV_REG, 2, BUFF_IN()

 ret = BUFF_IN(0) << 8 +  BUFF_IN(1)

 if ret > 32768 then ret = ret - 65536

end sub

 

[3] SPI BUS

The SPI bus allows the module to connect to SPI devices.

 

The Serial Peripheral Interface bus (SPI) is a synchronous serial communication interface used for short distance communication between devices.

SPI devices communicate in full duplex mode using a master-slave architecture where the ESP32 is the master. The ESP32 generates the frame for reading and writing.

Multiple slave devices are supported through selection with individual chip select (CS) lines.

The SPI bus utilise four logic signals:

 

SIGNAL

DESCRIPTION

I/O PIN

SCLK

Serial Clock (output from the ESP32)

GPIO18

MISO

Master Input Slave Output (data input to the ESP32)

GPIO19

MOSI

Master Output Slave Input (data output from the ESP32)

GPIO23

CS

Chip Select (often active low, output from the ESP32)

Any output pin, controlled automatically

 

CS pin

As many devices can be connected in parallel, sharing the same SCLK, MISO and MOSI signals, each device is controlled individually using an individual CS signal.

As Annex32 implement multitasking, in order to warrant that the CS signal is generated in phase with the data to be transferred, the CS pin is managed automatically.

The command SPI.SETCSPIN pin [, polarity] permit to define the pin associated with the device to be controlled. Additionally, it permit to define the polarity  as 0 = active low (default) and 1 = active high.

 

SPI Mode: Polarity and Clock Phase

The SPI interface defines no protocol for data exchange, limiting overhead and allowing for high speed data streaming. Clock polarity (CPOL) and clock phase (CPHA) can be specified as ‘0’ or ‘1’ to form four unique modes to provide flexibility in communication between master and slave as shown below :

 

image

If CPOL and CPHA are both ‘0’ (defined as Mode 0) data is sampled at the leading rising edge of the clock. Mode 0 is by far the most common mode for SPI bus slave communication.

If CPOL is ‘1’ and CPHA is ‘0’ (Mode 2), data is sampled at the leading falling edge of the clock. Likewise, CPOL = ‘0’ and CPHA = ‘1’ (Mode 1) results in data sampled at on the trailing falling edge and CPOL = ‘1’ with CPHA = ‘1’ (Mode 3) results in data sampled on the trailing rising edge.

The table below summarizes the available modes.

 

Mode

CPOL

CPHA

0

0

0

1

0

1

2

1

0

3

1

1

 

The data can also be sent MSB first or LSB first.

This is defined as bit order and is MSB first by default

 

Even if the chip is able to achieve 80Mhz, the maximum realistic SPI speed is 40Mhz.

 

The commands available are :

SPI.SETUP speed [,data_mode [, bit_order]]

SPI.CSPIN pin [, polarity]

[4] The functions available are :

ret = SPI.BYTE(byte)

a$ = SPI.STRING$(data$, len)

a$ = SPI.HEX$(datahex$, len)

As said previously,  because the ESP32 use multitasking, it is impossible to warrant the exclusive use of the SPI bus during the execution of the script (it could be used by the SD card or the TFT, for example).

For this reason, the CS pin it is managed internally by Annex directly by the SPI functions.

This is defined with the command SPI.CSPIN pin [, polarity]

The optional parameter  polarity  defines if the CS signal must be active low (0 = default) or active high (1).

This command will set automatically the pin as output.

 

Look at the examples below for more details:

74HC595 Module

This is an example of connection of a module with 74HC595 bought on Ebay at less than 2€ 

image

 

This drawing shows how this module must be connected to the ESP8266.

It provides 8 digital outputs.

image

This is an example of code that "drives" this module:

 

'Write from 0 to 255 on the module

'Each pin will blink at different frequency

 

spi.setup 100000  ' set the SPI port at 100KHz

SPI.CSPIN 15, 1 ' defines the pin 15 as CS active high

for i = 0 to 255

  r = spi.byte(i)

next i

 

end

 

 

MCP23S17 Module

This is an another example of connection of a module with MCP23S17 bought on Ebay at less than 2€.

This module provides 16 GPIO pins that can be used as digital inputs or outputs. 

imageimage

 

image

 

As this device is quite simple to interface, it can be directly driven using a “driver” written in basic.

This is an example using the SPI pins and the GPIO15 as CS signal

 

' MCP23S17 Driver for Annex

' datasheet http://ww1.microchip.com/downloads/en/DeviceDoc/20001952C.pdf

 

spi.setup 1000000

 

'MCP23S17 SPI address

MCP23S17_ADDR = &h40  ' assumes A2, A1, A0 to GND

'MCP23S17 internal registers

IODIRA   = 0  : IODIRB   = 1 : IPOLA   = 2  : IPOLB   = 3

GPINTENA = 4  : GPINTENB = 5 : DEFVALA = 6  : DEFVALB = 7

INTCONA  = 8  : INTCONB  = 9 : IOCONA  = 10 : IOCONB  = 11

GPPUA    = 12 : GPPUB   = 13 : INTFA   = 14 : INTFB   = 15

INTCAPA  = 16 : INTCAPB = 17 : GPIOA   = 18 : GPIOB   = 19

OLATA    = 20 : OLATB   = 21

 

MCP23S17_WRITE IOCONA, &h08 ' init MCP23S17 with bit HAEN

MCP23S17_WRITE IODIRA, &h00 ' all PORT A pins as output

MCP23S17_WRITE IODIRB, &hff ' all PORT B pins as input

MCP23S17_WRITE GPPUB , &hff ' all PORT B pins as pullup

 

v = 0

for i = 0 to 255

 for z = 0 to 255

   MCP23S17_WRITE GPIOA, z ' pulse all GPIOA pins

   MCP23S17_READ  GPIOB, v ' read  all GPIOB pins

   print v

 next z

next i

End

 

' function for read / write the MCP23S17

sub MCP23S17_WRITE(register, value)

 SPI.CSPIN 15

 a = SPI.byte(MCP23S17_ADDR)

 a = SPI.byte(register)

 a = SPI.byte(value)

end sub

 

sub MCP23S17_READ(register, value)

 local a

 SPI.CSPIN 15

 a = SPI.byte(MCP23S17_ADDR or 1)

 a = SPI.byte(register)

 value = SPI.byte(0)

end sub

 

COUNTERS[5] 

This functionality exposes two counters that permit to count pulses from any input pin.

Additionally, each counter can also return the time occurred between consecutive pulses (period); this is useful as this will permit to determine the frequency of low frequency signals simply taking its reciprocal 

(f = 1 / period).

These counters are not based on H/W but are managed using processor interrupts so the input frequency should be limited to around 10 Khz.

It is possible to define when the pulse is counted (on Rising Edge, on Falling Edge, on Change).

The “on Change” is particularly interesting when associated with low frequency measurement as it will permit to double the number of pulses.

Before using the counters, the input pin must be set as INPUT using the command PIN.MODE.

To start to use the counters, the following command is available:

COUNTER.SETUP cnt, pin [,mode]

where:

‘cnt’ defines which counter (1 or 2)

‘pin’ defines the input pin (can be any valid pin except GPIO16)

‘mode’ can be 1 (rising edge), 2 (falling edge) or 3 (change). If not specified, the mode change is enabled.

 

Example:

PIN.MODE 12,INPUT   ‘defines the pin GPIO12 as INPUT

COUNTER.SETUP 1, 12, 1  ‘ Counter 1 using pin GPIO12, count on Rising Edge

 

The pulses counted can be read using the function COUNTER.COUNT(cnt).

The period between 2 consecutive pulses can be read using the function COUNTER.PERIOD(cnt).

 

Example:

print COUNTER.COUNT(1)  ‘print the pulses counted from the counter 1

print COUNTER.PERIOD(1) ‘print the period from the counter 1

 

FInally the counters can be reset with the command COUNTER.RESET cnt

 

Example:

COUNTER.RESET 1  ‘ reset the counter 1

 

PID controller[6] [7] s

A proportional–integral–derivative controller (PID controller. or three-term controller) is a control loop feedback mechanism widely used in industrial control systems and a variety of other applications requiring continuously modulated control. (ref wikipedia)

A PID controller continuously calculates an error value e(t) as the difference between a desired setpoint (SP) and a measured process variable (PV) and applies a correction based on proportional, integral, and derivative terms (denoted P, I, and D respectively), hence the name.

In practical terms it automatically applies accurate and responsive correction to a control function.

An everyday example is the cruise control on a car, where ascending a hill would lower speed if only constant engine power is applied. The controller's PID algorithm restores the measured speed to the desired speed with minimal delay and overshoot, by increasing the power output of the engine.

Annex implements 4 PID controllers that can be used simultaneously for any application.

 

The commands are :

PIDx.INIT Kp, Ki, Kd

PIDx.SETMODE mode

PIDx.LIMITS min, max

PIDx.PERIOD msec

PIDx.PARAMS Kp, Ki, Kd

 

The main function is:

Pid_Out = PIDx.COMPUTE(CURR_VALUE, TARGET_VALUE)

 

PIDx can bePID1, PID2, PID3 or PID4.

 

The first step is to initialise the PID controller.

This can be done with the command PIDx.INIT Kp, Ki, Kd :

Example:

PID1.INIT 50, 80, 1 'initialise the controller with Kp = 50, Ki = 80 and Kd = 1

 

Optionally the output limits can be set using the command PIDx.LIMITS min, max.

If not defined the output is limited between 0 and 255

Example:

PID1.LIMITS 0, 1023 ' limits the output between 0 and 1023

 

Then the sampling period can be defined using the command PIDx.PERIOD msec

If not defined the period is set at 100 msec

Example:

PIDx.PERIOD 50 ' define the period at 50 msec

 

Finally the main function  output = PIDx.COMPUTE(input, setpoint)

Example:

Pid_Out = PID1.COMPUTE(CURR_VALUE, TARGET_VALUE)

 

This function must be called regularly in a loop; the best is to call it using a timer.

 

The command PIDx.SETMODE mode can be used to put the loop in manual with PIDx.SETMODE 0.

In this case the PID loop will be stopped and the output value will be frozen.

To restore the auto mode (default), the command is PIDx.SETMODE 1.

 

At any moment the PID parameters can be changed using the command PIDx.PARAMS Kp, Ki, Kd :

Example:

PID1.PARAMS 30, 80, 10 ' modify the PID parameters with Kp = 30, Ki = 80 and Kd = 10

 

The following example shows how to control the speed of a 3-wire 12V PC fan.

The PID utilise the counter to determine the fans speed controlling it using the PWM.

A little circuit is required to drive the positive side of the FAN.image

 

 

SOUND PLAYER

Annex provide the functionality to play WAV and MP3 sound directly from disk (SPIFFS or SD card).

The mp3 streaming from the web is also supported permitting to play Web Radios.

As the ESP-32 is equipped with a dual core CPU, this activity is done in parallel and does not impact the overall performance of Annex-32.

The sound output can be sent to the internal speaker (for the m5stack) or to an external I2S DAC.

Look at the previous chapters for more details on the sound output.

 

To play sounds, the command available is PLAY.xxx.

 

Before using this command, the sound output must be set as below :

PLAY.SETUP dest

If ‘dest’ is 0 is the output will be sent to the internal speaker (mono)

If ‘dest’ is 1 is the output will be sent to the external DAC (stereo)

NOTE : as soon as the output destination is chosen, a restart of the module is required to change (internal speaker  / external DAC)

 

If the command PLAY.SETUP is not specified, the sound is sent by default to the internal speaker.

 

To play mp3 files, the command is :

PLAY.MP3 mp3file$

Example

PLAY.MP3 "/mp3/MyMusic.mp3"

 

To play wav files, the command is:

PLAY.WAV wavfile$

Example

PLAY.WAV "/wav/MySound.wav"

 

The position (the time) of the sound played can be controlled using the command PLAY.SEEK using a value from 0 (beginning) to 100 (end).

Example

PLAY.SEEK 50 position the sound at the middle of its length (50%)

PLAY.SEEK 0  rewind the sound

 

The function PLAY.POS return the current position of the file from 0 (beginning) to 100 (end)

Example:

print PLAY.POS

 

It is also possible to play mp3 streaming web radios with the command

PLAY.NETWORKS[8]  streaming_url$

Example:

PLAY.NETWORKS"http://91.121.159.124:8000/eko-des-garrigues-128k.mp3"

 

The sound is played in the background, even if the program is stopped, until the end of the file (or forever for the web radios).

 

As the sound is played in the background, the functionPLAY.ISPLAYING returns the following values :

 

VALUE

DESCRIPTION

0

The sound is stopped

1

The mp3 file is playing

2

The wav file is playing

 

 

To stop playing, the command is :

PLAY.STOP

 

The volume can be changed with the command:

PLAY.VOLUME vol

‘vol’ is by default 100 and represents the full volume (100%).

In case of sound files recorded with low volume, it is also possible to specify a value greater than 100.

Take into account that the output audio will saturate if the value is too high.

 

Example

PLAY.VOLUME 50  ‘set the sound at 50% of normal volume.

 

SPEECH SYNTHESIS with vintage C64 SAM speaker

Annex integrates ESP8266SAM, a port of the reverse-engineered speech synthesizer Software Automatic Mouth (SAM)

Sam is a very small Text-To-Speech (TTS) program written in C, that runs on most popular platforms. It is an adaption to C of the speech software SAM (Software Automatic Mouth) for the Commodore C64 published in the year 1982 by Don't Ask Software (now SoftVoice, Inc.). It includes a Text-To-Phoneme converter called reciter and a Phoneme-To-Speech routine for the final output. It is so small that it work also on embedded computers.

The sound output and the volume follow the same rules defined in the previous chapter

 

To use it, the command is:

PLAY.SPEAK“message” [, phonetic]

Example

PLAY.SPEAK “The quick brown fox jumps over the lazy dog”

 

Using an optional parameter “phonetic” to 1, it is possible to use the synthesys in phonetic mode

 

This table lists the phonemes available:

 

VOWELS                            VOICED CONSONANTS

IY           f(ee)t                    R        red

IH           p(i)n                     L        allow

EH           beg                       W        away

AE           Sam                       W        whale

AA           pot                       Y        you

AH           b(u)dget                  M        Sam

AO           t(al)k                    N        man

OH           cone                      NX       so(ng)

UH           book                      B        bad

UX           l(oo)t                    D        dog

ER           bird                      G        again

AX           gall(o)n                  J        judge

IX           dig(i)t                   Z        zoo

                                       ZH       plea(s)ure

DIPHTHONGS                             V        seven

EY           m(a)de                    DH       (th)en

AY           h(igh)

OY           boy

AW           h(ow)                     UNVOICED CONSONANTS

OW           slow                      S         Sam

UW           crew                      Sh        fish

                                       F         fish

                                       TH        thin

SPECIAL PHONEMES                       P         poke

UL           sett(le) (=AXL)           T         talk

UM           astron(omy) (=AXM)        K         cake

UN           functi(on) (=AXN)         CH        speech

Q            kitt-en (glottal stop)    /H        a(h)ead

 

 

The complete documentation of the original SAM can be found here :

http://www.retrobits.net/atari/sam.shtml

 

SPEECH SYNTHESIS using google translate

Annex32 implements a feature permitting to speech texts using the voice synthesis available in google translate.

Obviously this feature requires the module to be connected to the internet.

The command is PLAY.VOICE"message", "language" [, "filename"] [, action]

Example:

PLAY.VOICE"Hello World with Annex 32", "en" 'speech this text in english

 

The voice sound (in mp3 format) is first downloaded locally on the local disk then is played using the internal MP3 player.  By default the sound is saved as  /_voice.mp3 but the name can be changed using the optional parameter "filename".

This permits to “reuse” these “speech” in a later time simply playing them like regular mp3 files.

This is particularly interesting as the voice download process is not immediate (it takes a few seconds).

 

 

The last optional parameter (action) can be used to modify the default behaviour as defined below :

 

VALUE

DESCRIPTION

0 (default)

Stop a sound in progress and speech

1

Waits for the end of the sound in progress and then speech

2

Simply save the sound as file on the disk

 

The message should be limited at less than 200 characters.

The language should be any valid google language code:

PLAY.VOICE"Hello World with Annex 32", "en" 'standard English British

PLAY.VOICE"Hello World with Annex 32", "en-US" ' US (American) English

PLAY.VOICE"Benvenuti in Annex 32", "it" ' Italian

PLAY.VOICE"Bonjour avec Annex 32", "fr" ' French

PLAY.VOICE"Bonjour avec Annex 32", "fr-CA" ' French Canadian

 

The complete list of google “language codes” can be found here :

https://cloud.google.com/text-to-speech/docs/voices

LCD DISPLAY USING I2C

An LCD display can be connected to the module using I2C interface.

These displays are very cheap and available on Ebay at less than 4€.

This picture shows an LCD with 4 lines at 20 characters per line.

image

In general these displays are based on the chip HD44780 and work with a parallel interface.

Because the number of pins available on the ESP module is very limited, there is an additional module (usually supplied with the display) which allows connection using the 2-wire I2C bus.

 

This picture shows the module (generally soldered in the back of the display) enabling the I2C connection.

image

These modules are based on the chip PCF8574 and have the following relationship between the display pins and the bits of the PCF8574:

 

PCF8574 BIT

LCD SIGNAL

 

PCF8574 BIT

LCD SIGNAL

BIT 0

RS

 

BIT 4

D4

BIT 1

RW

 

BIT 5

D5

BIT 2

E

 

BIT 6

D6

BIT 3

BACKLIGHT

 

BIT 7

D7

 

However, this mapping is managed directly into the ESP module so you don’t need to worry about it.

The only important information is the I2C address of the display which may change depending on the card.

The connection is very simple, just 2 pins for the I2C  and the power supply are required.

image

An important point is that the display must be powered with 5V because it will not work at 3.3 V.

 

In order to use the LCD, there are 2 steps :

-       Initialise the I2C bus

-       Init the display

This can be done with the following commands :

 

I2C.SETUP 21, 22  ' set I2C port on pins 21 and 22

LCD.INIT 63, 20, 4  ‘ init an LCD at address 63 (3F in hex) with 20 characters per line and 4 lines

 

After these 2 lines, there are 2 additional commands available :

LCD.CLS  ‘ clear the screen of the LCD

LCD.PRINT x, y, text$  ‘ print a text on the LCD at the position (x, y)

 

Example:

I2C.SETUP 21, 22  ' set I2C port on pins 21 and 22

'init an LCD at address 63 (3F in hex) with 20 characters per line and 4 lines

LCD.INIT 63, 20, 4

LCD.CLS  ' clear the screen of the LCD

'print a message on the LCD at the first char of the first line

LCD.PRINT 1, 1, "HELLO WORLD"

 

OLED DISPLAY

An OLED display can be connected to the module using I2C interface.

These displays are very cheap and available on Ebay at less than 3€.

This picture shows an OLED with 128 x 64 pixels monochrome but the size is only 0.96".

 

image

 

This display is based on the chipset SSD1306

 

It is also possible to use a display based on the chipset SH1106[9] .

The connection is very simple, just 2 pins for the I2C  and the power supply are required.

image

 

In order to use the OLED, there are 2 steps :

-       Initialise the I2C bus

-       Init the display

This can be done with the following commands :

 

I2C.SETUP 21, 22  ' set I2C port on pins 21 and 22

OLED.INIT orientation 'init with a given orientation (0 = normal, 1 = upside-down)

 

After these 2 lines, there are several commands available :

OLED.CLS, OLED.COLOR, OLED.FONT, OLED.PIXEL, OLED.LINE, OLED.RECT, OLED.CIRCLE, OLED.PRINT, OLED.IMAGE, OLED.REFRESH

 

The current implementation of the OLED is based on a double buffering; this permits to draw in background on the screen while the current image is still shown. This technique permits to avoid flickering while drawing objects on the screen. The command OLED.REFRESH fmt  allows to choose between an automatic refresh (OLED.REFRESH 1) or a manual refresh (OLED.REFRESH 0). By default the refresh is automatic.

 

When an automatic refresh is set, the image is immediately updated after each drawing command, whereas with the manual refresh, the image is refreshed only when an OLED.REFRESH command is executed.

 

The OLED.COLOR col defines the color to be used by the different drawing commands. As the display is monochrome, only the color 0 (black) and 1(white) can be defined; an additional color 2 (reverse) permits to draw objects in reverse to the existing color already present on the screen; useful to draw and clear the same object. By default the color is 1 (white).

 

The OLED.IMAGE x, y, image$ permits to draw an image on the screen from a file. The file format must be XBM, a kind of ‘C’ source code. This format is not really popular but it is supported by the free tool Gimp.

The command OLED.FONT font_num permits to define the font to be used by the command OLED.PRINT.

There are 3 fonts available, ARIAL MT10,  ARIAL MT16,  ARIAL MT24.

 

Example:

I2C.SETUP 21, 22  ' set I2C port on pins 21 and 22

OLED.INIT 1 ' init the OLED upside-down

OLED.CLS ' clear the screen

OLED.FONT 2

OLED.COLOR 1

OLED.PRINT 10,10, "HELLO WORLD"

 

ST7920 LCD DISPLAY

An ST7920 LCD display can be connected to the module using SPI interface.

These displays are very cheap and available on Ebay at less than 5€.

This picture shows an ST7920 with 128 x 64 pixel monochrome.

 

Some cheap boards will have PSB connected to VDD (5v) This forces the parallel interface to be used. Before you connect your display check that pin 2 (VDD ,5v) and pin 15  (PSB) are not connected.  If they are you may need to cut a jumper. Otherwise you will short out your power supply, and the display will not work.

imageimage

 

This display is provided with a parallel interface BUT it can be used with a SPI interface, so only 3 pins are required.

image

In order to use the display, it must be initialised.

This can be done with the following command:

ST7920.INIT CS_pin

As per the wiring above, the command is

ST7920.INIT 15

 

After these 2 lines, there are several commands available :

ST7920.CLS, ST7920.COLOR, ST7920.FONT, ST7920.PIXEL, ST7920.LINE, ST7920.RECT, ST7920.CIRCLE, ST7920.PRINT, ST7920.IMAGE, ST7920.REFRESH

 

The current implementation of the ST7920 is based on a double buffering; this permits to draw in background on the screen while the current image is still shown. This technique permits to avoid flickering while drawing objects on the screen. The command ST7920.REFRESH fmt allows to choose between an automatic refresh (ST7920.REFRESH 1) or a manual refresh (ST7920.REFRESH 0). By default the refresh is automatic.

 

When an automatic refresh is set, the image is immediately updated after each drawing command whereas, with the manual refresh, the image is refreshed only when an ST7920.REFRESH command is executed.

 

The ST7920.COLOR col defines the color to be used by the different drawing commands. As the display is monochrome, only the color 0 (black) and 1(white) can be defined; an additional color 2 (reverse) permit to draw object that reverse the existing color already present on the screen; useful to draw and clear the same object. By default the color is 1 (white).

 

The ST7920.IMAGE x, y, image$ permit to draw an image on the screen from a file. The file format must be XBM, a kind of ‘C’ source code. This format is not really popular but it is supported by the free tool Gimp.

The command ST7920.FONT font_num permits to define the font to be used by the command ST7920.PRINT.

There are 3 fonts available, ARIAL MT10,  ARIAL MT16,  ARIAL MT24.

 

Example:

ST7920.INIT 15 ' init the ST7920 with the CS at the pin 15

ST7920.CLS ' clear the screen

ST7920.FONT 2

ST7920.COLOR 1

ST7920.PRINT 10,10, "HELLO WORLD"

 

RTC module

A module based on chipset DS1307 or DS3231 can be connected to the module using the I2C interface.

These modules are very cheap and available on Ebay at less than 2€ (check if battery is included).

This picture shows a DS3231 module which is very compact and already contains two 4.7K I2C pullups :

               image                                image

The connection is very simple, just 2 pins for the I2C  and the power supply are required.

image

 

Available Instructions:

RTC.DATE$[(format)]

RTC.TIME$

RTC.SETTIME Year, Month, Day, Hours, Minutes, Seconds

 

The use of the RTC module is very simple.

First the I2C must be initialised with the command I2C.SETUP.

Then the date and the time can be read with the string functions RTC.TIME$ and RTC.DATE$.

 

This time and date can be manually set using the command RTC.SETTIME.

The Syntax is :

RTC.SETTIME Year, Month, Day, Hours, Minutes, Seconds

 

Example

Set the date to 02 September 2017 at 13:58:12

 

RTC.SETTIME 17, 9, 2, 13, 58, 12

 

Example

I2C.SETUP 21, 22  ' set I2C port on pins 21 and 22

Print "The date is " + RTC.DATE$

Print "The time is " + RTC.TIME$

 

PCA9685 (PWM / Servo) Module

A PWM / Servo module based on chipset PCA9685  can be connected to the module using the I2C interface.

These modules are very cheap and available on Ebay at less than 2€.

This picture shows a PCA9685 module that makes available up to 16 PWM / Servo outputs.

The PCA9685 is an I²C-bus controlled 16-channel controller optimized for Red/Green/Blue/Amber (RGBA) color backlighting applications. It operates at a programmable frequency from a typical of 24 Hz to 1526 Hz. All outputs share the same PWM frequency.

The duty cycle for each output is adjustable from 0 % to 100 % with 12-bit resolution (4096 steps).

It can also be used to control servo actuators, simply specifying the PWM frequency at 50 Hz.

imageimage

This module must be connected using I2C and, because it already contains two 10K I2C pullups, no external resistors are required.

image

Available Instructions:

PCA9685.SETUP address

PCA9685.SETFREQ freq

PCA9685.PWM pin, value

 

In order to use the module, it must be first set with the command PCA9685.SETUP address

Then the PWM frequency can be set with the command PCA9685.SETFREQ freq

FInally, the outputs can be driven with the command PCA9685.PWM pin, value

 

This is an example that drives 2 servos connected on outputs 0 and 1.

PCA9685.SETUP &H40, 55

PCA9685.SETFREQ 50

PCA9685.PWM 0, 150

PCA9685.PWM 1, 100

 

DX = 1

DY = 1

MINX = 100 : MAXX = 500

MINY = 150 : MAXY = 300

X = MINX : Y = MINY

 

WHILE 1

  PCA9685.PWM 0, Y

  PCA9685.PWM 1, X

  PAUSE 30

  PRINT Y, DY, MAXY

  X = X + DX

  Y = Y + DY

  IF (X < MINX) OR (X > MAXX) THEN DX = - DX

  IF (Y < MINY) OR (Y > MAXY) THEN DY = - DY

WEND

END

TM1637 display module

A display module based on the chipset TM1637 with 4 7-segments display can be connected to the module.

These modules are very cheap and available on Ebay at around 1€.

This picture shows a module with 4 displays at 0.36”.

 

image       image

The connection is very simple, just 2 pins and the power supply are required.

 

Even if the protocol is very similar to the I2C, it is quite different, so the I2C pins used for other I2C devices cannot be shared as this will conflict.

image

 

Available Instructions are:

TM1637.PRINT msg$ [, brightness [, dotpoints]]

TM1637.SETUP data_pin, clock_pin [, bit_delay]

 

To use it, is very simple.

First initialise the display with the command TM1637.SETUP data_pin, clock_pin [, bit_delay]

With the wiring above, the command must be :

TM1637.SETUP 15, 16

Note that some modules may already include i2c pullup resistors on board (so simply try first without).

It is important to highlight that some display modules may have a capacitor on the input pins.

In that case it will be required an extra parameter (bit_delay) at the end of the setup command.

This value can be experimentally found but a value of 100 should be appropriate for all the modules.

Example :  TM1637.SETUP 4, 5, 100

The display can be used with the command TM1637.PRINT msg$ [, brightness [, dotpoints]]

Where

msg$ is a text string that can contain up to 4 chars,

brightness defines the luminosity of the display from 0 (OFF) to 7 (MAX); if omitted the value is 7

dotpoints defines if the 2 dot points must be OFF (if 0) or ON (if 255); if omitted, the points are OFF

All ASCII characters can be used but will be shown within the limitation of the 7 segments of the display.

 

Example

TM1637.SETUP 15, 16, 100

For i = 0 to 9999

  TM1637.PRINT str$(i), 4, 255

Next i

 

 

TM1638 display module

A display module based on the chipset TM1638 with 8 7-segments display can be connected to the module.

These modules provides  8 LEDs, 8 Digits and 8 Keypad Interface.

These modules are very cheap and available on Ebay at around 2€.

This picture shows a module with 8 digits at 0.36”, 8 leds and 8 buttons

 

image

The connection requires 3 pins plus the power supply.

image

 

 

Available Instructions are:

TM1638.BUTTONS

TM1638.PRINT msg$ [, brightness ]

TM1638.SETUP data_pin, clock_pin, strobe_pin

TM1638.LEDS val

 

To use it, is very simple.

First initialise the display with the command TM1638.SETUP data_pin, clock_pin, strobe_pin

With the wiring above, the command must be :

TM1638.SETUP 4, 5, 15

The display can then be used with the command TM1638.PRINT msg$ [, brightness ]

Where

msg$ is a text string that can contain up to 8 chars ,

brightness defines the luminosity of the display from 0 (OFF) to 15 (MAX); if omitted the value is 15

All ASCII characters can be used but will be shown within the limitation of the 7 segments of the display.

 

Example

TM1638.SETUP 21, 22, 15

For i = 0 to 9999

  TM1638.PRINT str$(i)

Next i

 

As the module contains also 8 leds, it is possible to control them using the command TM1638.LEDS val.

val is a 8 bit number where each bit is associated to a led.

Example

TM1638.SETUP 21, 22, 15

For i = 0 to 255

  TM1638.LEDS i

Next i

 

It is also possible to get the status of the buttons with the function TM1638.BUTTONS

Example

TM1638.SETUP 21, 22, 15

For i = 0 to 5000

  Print TM1638.BUTTONS

Next i

 

MAX7219 8-Digits 7-segment display

A display module based on the chipset MAX7219 with 8 7-segments display can be connected to the module.

These modules provides  8 Digits 7-segments display including dot points.

These modules are very cheap and available on Ebay at around 2€.

This picture shows a module with 8 digits at 0.36”.

image

image

The wiring is done using the SPI bus plus a dedicated CS pin.

image

Available Instructions are:

MAXDISPLAY.SETUP CS_pin

MAXDISPLAY.PRINT msg$ [,brightness]

 

To use it, is very simple.

First initialise the display with the command MAXDISPLAY.SETUP CS_pin

With the wiring above, the command must be :

MAXDISPLAY.SETUP 15

The display can then be used with the command MAXDISPLAY.PRINT msg$ [,brightness]

Where

msg$ is a text string that can contains up to 8 chars ,

brightness defines the luminosity of the display from 0 (OFF) to 15 (MAX); if omitted the value is 15

All ASCII characters can be used but will be shown within the limitation of the 7 segments of the display.

 

Example

MAXDISPLAY.SETUP 15

For i = 0 to 9999

  MAXDISPLAY.PRINT str$(i)

Next i

 

MAX7219 Dot Matrix Display

It is also possible to connect dot matrix modules based on the chipset MAX7219.

These modules contains 4 8x8 dot matrix displays each one with a dedicated MAX7219 chip.

These modules can be chained in order to compose a larger display.

The picture shows a module available on Ebay at around 5€.

image

image

 

The wiring is done using the SPI bus plus a dedicated CS pin.

image

 

Available Instructions are:

MAXSCROLL.SETUP nb_devices, CS_pin

MAXSCROLL.PRINT msg$

MAXSCROLL.NEXT msg$

MAXSCROLL.TEXT msg$

MAXSCROLL.SHOW position [, brightness]

MAXSCROLL.SCROLL [brightness]

MAXSCROLL.OSCILLATE [brightness]

 

To use it, the first command required is the setup of the display.

This can be done with the command MAXSCROLL.SETUP nb_devices, CS_pin.

The first argument defines the number of 8x8 displays connected; using the module shown above, the number is 4. 

The 2nd argument defines the pin used for the CS signal; using the schematic shown above the pin is 15 (GPIO15). In our case the command must be :

 MAXSCROLL.SETUP 4, 15

 

The text can then be set on the display with 3 different commands :

1.    MAXSCROLL.PRINT msg$

2.    MAXSCROLL.NEXT msg$

3.    MAXSCROLL.TEXT msg$

The first will set the text that will be shown at the beginning, the 2nd will set the text that will be shown when the first one will be scrolled out of the display and the 3rd will permit to modify immediately the text shown.

 

For example, 

MAXSCROLL.PRINT "Hello"

MAXSCROLL.NEXT "Friend"

 

Will permit to show “Hello” at the beginning; then as soon as “Hello” is scrolled out of the screen, the text “Friend” will be shown and it will scroll on the display forever until the next execution of the command MAXSCROLL.NEXT msg$

 

The command MAXSCROLL.TEXT msg$ will permit to modify the text during the scrolling sequence, useful for “dynamic” messages (i.e time/date information).

 

The command MAXSCROLL.SHOW position [, brightness] will permit to move the text in a given position.

The position 1 if the rightmost line of the display and increasing this value will move the text more on the left.

Optionally is is possible to define the brightness of the display.

 

The last set of commands is composed of

1.    MAXSCROLL.SCROLL [brightness]

2.    MAXSCROLL.OSCILLATE [brightness]

 

The first will permit to scroll the text from the right to the left and, when the text will be completely scrolled out, it will restart again with the same text or, if defined, with the text set with the command MAXSCROLL.NEXT.

 

The 2nd will permit to scroll the text from the right to the left and, when the text will be completely scrolled out, it will be scrolled back in the opposite direction until it will reach the initial position, then the process will restart again.

 

These 2 commands have an optional parameter permitting to define the luminosity of the display in a range from 0 (min) to 15 (max); the default value is 0.

 

As the message requires a continuous scrolling, these commands must be called on a timed interval (using a timer).

 

Let show with an example using the SCROLL command

'Set 4 8x8 displays with GPIO15 as CS pin

MAXSCROLL.SETUP 4, 15

'Set the first message as the current time

MAXSCROLL.PRINT TIME$

'Set the second message as the current date

MAXSCROLL.NEXT DATE$

'Set the refresh rate of the display (50 msec) - lower values -> scroll faster

TIMER0 50, SCROLLME

WAIT

 

SCROLLME:

 'Scroll the display with an intensity of 5

 MAXSCROLL.SCROLL 5

RETURN

 

This is another example using the OSCILLATE command:

'Set 4 8x8 displays with GPIO15 as CS pin

MAXSCROLL.SETUP 4, 15

'Set the message

MAXSCROLL.PRINT "Hello World"

'Set the refresh rate of the display (50 msec) - lower values -> scroll faster

TIMER0 50, SCROLLME

WAIT

 

SCROLLME:

 'Oscillate the display with an intensity of 5

 MAXSCROLL.OSCILLATE 5

RETURN

 

NeoPixel WS2812B led strips

It is possible to connect NeoPixel led strips based on WS2812B Leds.

These strips are generally available in a linear form but also as a circular array.

imageimage[10] 

 

The wiring is very simple as only one output pin is required for the ESP32.

 

The strips must be supplied at 5V with a dedicated power-supply.

As each led could require up-to 60mA, the power supply must be sized in consequence.

 

The strip is considered as a sequence of leds where each one has a position and can have a different color.

From a logical point of view, even the circular array is seen as a linear strip with a start and end position.

Then the following commands are available :

 

NEO.SETUP pin, [nb_led]

NEO.STRIP led_start_pos, led_end_pos, R, G, B [, disable]

NEO.STRIP led_start_pos, led_end_pos, COLOR [, disable]

NEO.PIXEL led_pos, R, G, B [, disable]

NEO.PIXEL led_pos, COLOR [, disable]

NEO.RGB(R, G, B)

NEO.GETPIXEL(pos)

 

The first command, NEO.SETUP pin, [nb_led], defines the pin to be used as output and the size (in pîxels) of the led strip.

For example  NEO.SETUP 2, 60  defines a strip containing 60 leds (or a ring with 60 leds) connected on the pin GPIO02.

This creates a local memory buffer of the strip line permitting the manipulation of the colors in the background.

 

Then, the leds of the strips can be addressed taking into account that the first led has the position 0 and the last has the position (nb_led - 1).

For example, using the declaration  NEO.SETUP 2, 60, the last led has the position 59.

 

The leds can then be addressed individually using the command NEO.PIXEL or as a block using the commandNEO.STRIP.

 

For example, NEO.PIXEL 10, 255, 0, 0  set the led at the position 10 with the color RED and the command NEO.STRIP 20, 30, 0, 0, 255  set the leds at the position 20 through 30 with the color BLUE

 

The colors can be specified as a sequence of 3 numbers from 0 to 255 representing the intensity for the Red, Green and Blue components or as a single number where the 3 colors are merged together as a whole.

 

The function NEO.RGB(R, G, B) permits to generate this merged color.

 

For example, these 3 commands produce the same effect :

 NEO.STRIP 0, 10, 0, 255, 0

 NEO.STRIP 0, 10, NEO.RGB(0, 255, 0)

 NEO.STRIP 0, 10, 65280

 

The optional argument [, disable] if set to 1, permit to write in memory without refreshing the strip. This is useful to manipulate several leds refreshing the complete line only when required.

 

For example, with the following program, all the leds will be refresh one by one at 100ms interval :

NEO.SETUP 60

FOR z = 0 TO 59

  NEO.PIXEL z, 128

  PAUSE 100

NEXT z

 

But, with the following program, all the leds will be updated in a single shot at the end (after 6 seconds) :

NEO.SETUP 60

FOR z = 0 TO 59

  NEO.PIXEL z, 128, 1

  PAUSE 100

NEXT z

NEO.PIXEL 59, 128

NeoPixel based WS2812b Dot Matrix DIsplay

It is also possible to connect Dot Matrix modules based on WS2812B Leds.

These modules contains 64 WS2812B leds organised in 8x8 matrix.

Several modules can be chained in order to compose a large display.

imageimage

The wiring is very simple as only one output pin is required for the ESP32.

The modules must be supplied at 5V with a dedicated power-supply.

image

It must be taken into account that these 8x8 modules can require a lot of current, in particular if all the leds are at max intensity.

As each led could require up-to 60mA, the power supply must be sized accordingly.

From a practical point of view, the displays will probably never show all the pixels at the same time, so we can consider at least 2 amps per display (so 20 amps for 10 displays).

 

Available Instructions are:

NEOSCROLL.SETUP nb_devices, pin [, serpentine]

NEOSCROLL.PRINT msg$

NEOSCROLL.NEXT msg$

NEOSCROLL.COLORS col$

NEOSCROLL.NEXTCOLORS col$

NEOSCROLL.SHOW pos [, brightness]

NEOSCROLL.TEXT msg$

NEOSCROLL.SCROLL [brightness]

NEOSCROLL.OSCILLATE [brightness]

NEOSCROLL.CLS [refresh]

 

To use it, the first command required is the setup of the display.

This can be done with the command NEOSCROLL.SETUP nb_devices, pin [, serpentine].

The first argument defines the number of 8x8 modules connected; using the schematic shown above, the number is 4. 

The 2nd argument defines the pin used for the input signal; using the schematic shown above the pin is 2 (GPIO2).

The 3rd argument defines if the display itself is arranged in a linear way or as a serpentine.

If it is 0 (default) the normal layout is selected, if is 1, the serpentine layout is chosen.

image

In our case the command must be :

 NEOSCROLL.SETUP 4, 2

 

The text can then be set on the display with 3 different commands :

4.    NEOSCROLL.PRINT msg$

5.    NEOSCROLL.NEXT msg$

6.    NEOSCROLL.TEXT msg$

The first will set the text that will be shown at the beginning, the 2nd will set the text that will be shown when the first one will be scrolled out of the display and the 3rd will permit to modify immediately the text shown.

 

For example, 

NEOSCROLL.PRINT "Hello"

NEOSCROLL.NEXT "Friend"

 

Will permit to show “Hello” at the beginning; then as soon as “Hello” is scrolled out of the screen, the text “Friend” will be shown and it will scroll on the display forever until the next execution of the command NEOSCROLL.NEXT msg$

 

The command NEOSCROLL.TEXT msg$ will permit to modify the text during the scrolling sequence, useful for “dynamic” messages (i.e time/date information).

 

As the display permit to show colors, 2 more commands are available:

1.  NEOSCROLL.COLORS col$

2.  NEOSCROLL.NEXTCOLORS col$

The first defines the colors of the text set with the commandNEOSCROLL.PRINT whilst the 2nd defines the colors of the text set with the command NEOSCROLL.NEXT.

These command NEOSCROLL.COLORS defines the color of each character of the text set with the command NEOSCROLL.PRINT .

 

The logic is based on a one-to-one correspondence between the text string and the color string.

The color is based on this table :

 

COLOR

CODE

Blue

B

Green

G

Cyan

C

Red

R

Magenta

M

Yellow

Y

Black

K

White

W

White

Any other char

 

For example, the commands

NEOSCROLL.PRINT "Hello"

NEOSCROLL.COLOR "RGBCM"

Will show the string “Hello” where the first character is Red, the 2nd Green, the 3rd Blue, ….

 

With the same logic, the commands

NEOSCROLL.NEXT "Friend"

NEOSCROLL.NEXTCOLOR "YWRGBM"

Will show the string “Friend” where the first character is Yellow, the 2nd White, the 3rd Red, ….

 

The command NEOSCROLL.SHOW position [, brightness] will permit to move the text in a given position.

The position 1 if the rightmost line of the display and increasing this value will move the text more on the left.

Optionally is is possible to define the brightness of the display.

 

The last set of commands is composed of

3.    NEOSCROLL.SCROLL [brightness]

4.    NEOSCROLL.OSCILLATE [brightness]

 

The first will permit to scroll the text from the right to the left and, when the text will be completely scrolled out, it will restart again with the same text or, if defined, with the text set with the command NEOSCROLL.NEXT.

 

The 2nd will permit to scroll the text from the right to the left and, when the text will be completely scrolled out, it will be scrolled back in the opposite direction until it will reach the initial position, then the process will restart again.

 

These 2 commands have an optional parameter permitting to define the luminosity of the display in a range from 0 (off) to 255 (max); the default value is 5.

Take into account that these displays are very bright so a luminosity of 5 is already enough.

 

As the message requires a continuous scrolling, these commands must be called on a timed interval (using a timer).

 

Let show with an example using the SCROLL command

'Set 4 WS2812B displays with GPIO2 as input

NeoScroll.Setup 4, 2

'Set the first message as the current time

NeoScroll.print  "TRY Annex WiFi BASIC"

NeoScroll.colors "CMYRGCRGBYWRGBCMYRGB"

 

'Set the next message

NeoScroll.next       "Hello World!"

NeoScroll.nextcolors "BYWRGBCMYRGB"

 

'Set the refresh rate of the display (30 msec) - lower values -> scroll faster

timer0 30, scrollme

wait

 

Scrollme:

  'Scroll the display with an intensity of 5

 NeoScroll.scroll 5

return

 

This is another example using the OSCILLATE command:

'Set 4 WS2812B displays with GPIO2 as input

NeoScroll.Setup 4, 2

'Set the first message as the current time

NeoScroll.print  "000"

NeoScroll.colors "RBG"

 

'Set the refresh rate of the display (50 msec) - lower values -> scroll faster

timer0 50, scrollme

 

'Set the counter at 0

v = 0

'Set the incrementing rate

timer1 100, increment  

 

wait

 

Scrollme:

  'Scroll the display with an intensity of 5

  NeoScroll.oscillate 5

return

 

increment:

  v = (v + 1) mod 1000 'increment and limits the value at 999

  NeoScroll.text str$(v, "%03f")

return

 

 

SDCARD ADAPTER

An SDCARD can be connected using a module wired as below:

 

image

 

 

The following SD CARD modules have been successfully tested with Annex32:

 

Module for MicroSD with active buffer on board.

As this module sports a voltage regulator that converts 5V to 3.3V, it is required to bypass it using the connection as shown in the picture below:

 

image

image

 

 

 

Module for full size SD-CARD with passive adapters:

image

TFT DISPLAY

A TFT Display based on chipset ILI9341 can be connected to the module using the SPI interface.

These displays are available on Ebay at different sizes from 2.2” to 3.2” and are very cheap.

The resolution of the display is 320 x 240 pixel with 65K colors.

They can also include a touchscreen controller to receive positional feedback via the SPI interface.

The model shown below is a 2.8” and contains an interface for the Touch Screen.

As the interface is SPI, the display requires at least 5 pins when connected as a display only and 6 when the touch screen is enabled.

Additionally these displays include also an SDCARD reader that can be used to connect an SDCARD to the module.

 

The image below shows an 2.8” display provided with touch screen interface:

image

image

These displays have a little jumper zone (J1) that must be solder-bridged if powering the module from 3.3V else it will be configured to work at 5v.

 

 

Wiring with touch and SDCARD

 

image[11] 

                             

 

image[12] [13] 

 

 

 

 

 

In order to use the TFT, the first step is to initialise the Display

This can be done with the following commands :

TFT.INIT orientation

 

The display can then be cleared with the command

TFT.FILL 0

 

The display is now ready to receive drawing commands.

The list of commands available is :

TFT.CIRCLE, TFT.LINE, TFT.PRINT, TFT.RECT, TFT.TEXT.COL, TFT.TEXT.POS, TFT.TEXT.SIZE, TFT.BMP, TFT.JPG, TFT.IMAGE, TFT.BRIGHTNESS

 

The list of the functions available is:

TFT.RGB, TFT.COLOR

 

The color is defined as a number between 0 and 65535; this corresponds to the color format named 565 where 5 bits are dedicated to Red, 6 to green and 5 to blue.

The function TFT.RGB permit to specify the R,G,B components as numbers from 0 to 255.

For example the function TFT.RGB(255,0,0) defines the color RED and TFT.RGB(0,255,0) defines the color green.

 

It is also possible to define a color giving directly its name.

The function is TFT.COLOR(colorname)

Colorname can be :[14] [15] [16] 

 

BLACK

NAVY

DARKGREEN

DARKCYAN

MAROON

PURPLE

OLIVE

LIGHTGREY

DARKGREY

BLUE

GREEN

CYAN

RED

MAGENTA

YELLOW

WHITE

ORANGE

PINK

 

 

 

The backlight of the display is controlled using a PWM output on the pin GPIO32.

The command TFT.BRIGHTNESS value (from 0 to 255) can be used to control the luminosity.

 

Look at the documentation for the details of each command.

 

Example :

Tft.init 1

tft.fill 0

for r = 0 to 30000 step 0.02

 d=r/6

 s=sin(r)*sin(5*r+d)*140+160

 c=cos(r)*sin(5*r+d)*100+120

 tft.circle s,c,10,rnd(65535),1

next r

 

It is also possible to save (dump) the content of the screen into a file on the disk (SPIFFS or SDCARD).

Note: this will not work on the M5stack as the SPI input pin is not wired on the display

The command is

TFT.SAVE “dumpfile.data”.

The file will be stored into a “raw” format and can be open using GIMP in raw mode; using the extension ”.data” will permit to be automatically recognised by GIMP.

TouchScreen

The touchscreen functionality permits to get the position of the point pressed on the screen.

It is associated with the event OnTouch and the functions TOUCH.X , TOUCH.Y and TOUCH.Z.

The touchscreen must be calibrated before to be used.

This can be done with the command  TOUCH.CALIB

The user will be asked to click on the 4 crosses for the calibration.

The calibration result will be stored permanently inside the module and will not be required to do anymore.

 

There are 2 commands to read the touchscreen :

TOUCH.READ -> read the touchscreen position calibrated

TOUCH.RAW -> read the touchscreen without calibration

 

There are 3 functions :

TOUCH.X -> returns the X position

TOUCH.Y -> returns the Y position

TOUCH.Z -> returns the touched status (if 1 means touched)

 

Example:

OnTouch touchme

wait

 

touchme:

  touch.read 'Read the calibrated position

  print "touched", touch.x, touch.y, touch.z

return

 

GRAPHIC GUI for TFT

[17] A full set of graphical objects has been included to Annex.

 

There are several objects that can be defined using a specific gui.xxxx function.

When defining the object, each function returns a handler that must be stored into a variable to gain access to this object later in the code.

 

All these graphical objects are strongly associated with the touchscreen that must be calibrated before with the command TOUCH.CALIB.

 

At the beginning, the command GUI.INIT Nb_objects, back_color is required to define how many objects will be declared and the initial background color.

Nb_objects defines the max number of objects present on the screen at the same time but the program can contain more objects.

 

The objects created using the functions defined below, will not be drawn directly on the screen but will be held in memory until the command GUI.REFRESH is executed.

This permits to update all the objects at the same time.

 

Here is a simple example that will create two GUI items, a textline and a button. When the button is clicked , or the left button on M5stack is pressed, the textline changes.

'simple GUI example

gui.init 20, 0   'reserve memory for 20 GUI objects. clears screen to black

 

txt = GUI.Textline(10,50,190,20, "Text Line Here", 2)  'x,y,w,h,text,fontsize

but = GUI.Button(20, 200, 100, 20, "BUTTON!",2 ) 'x,y,w,h,text,fontsize

 

gui.setevent but,1,buttonclick  'set button clicked event, jump to buttonclick

interrupt 39, buttonclick 'if using M5stack can't click screen- so use left button

gui.autorefresh 30, 1 'display gui items automatically each 30ms including touch

wait

 

buttonclick:

gui.settext txt,"Button Pressed" 'change text line.

return

 

 

 

For example, defining a textline with:

TXT1 = GUI.Textline(10, 10, 100, 20, "Hello World!")

The variable txt1 will contain a handler permitting to modify the properties of the textline; for example the following line :

GUI.SetText TXT1, "Text changed!"

Will change the text of the object previously defined.

 

If it is not required to hold the handler of the object into the code (for example if it never changes), it is possible to ignore the handler and define the object using a command syntax without parentheses:

GUI.Textline 10, 10, 100, 20, "Hello World!"

 

GUI Objects

gui.TextLine

Txt1 =GUI.Textline(x, y, width, height, “text” [,font])

Font is the size of the font.

image

gui.Button

But1 = GUI.Button(x, y, width, height, “text” [,font [,radius [,style [,group]]]])

Font is the size of the font.

Radius is the radius of the rounded part of the button (0 by default is not rounded).

Style is 0 for temporary (default) or 1 for toggle.

Group is a number that permit to associate interactive buttons together; this permits to deactivate a toggle button when selecting another in the group (like a group of radio buttons).

image

gui.Image

Img1 = GUI.Image(x, y, width, height, fname$[,background [,background_on [,style [,group]]]])

The width and the height are just used to define the touch area, because the size of the image will be defined by the image file content.

The file can be BMP or JPG format.

The BMP can be also with 32bits permitting to define a color background that can be eventually changed with the command gui.setcolor.

Using the gui.setcolor and defining 2 different colors, it is possible to use the image as a kind of “buttonImage” where the background color changes as a function of the button state.

image

gui.ButtonImage[18] 

A combination of a button with 2 images

Img2 = gui.buttonImage(x, y, width, height, image1$, image2$ [, style [, group]])

 

The width and the height are just used to define the touch area, because the size of the image will be defined by the image file content.

The files can be BMP or JPG format.

The BMP can be also with 32bits permitting to define a color background with the command gui.setcolor.

Style is 0 for temporary (default) or 1 for toggle.

Group is a number that permit to associate interactive buttons together; this permits to deactivate a toggle button when selecting another in the group (like a group of radio buttons).

imageimage

gui.CheckBox

Chk1 = gui.checkbox(x, y, width, height, value [, style [, group]])

Font is the size of the font.

Value is the initial value of the checkbox (0 or 1.)

Style is : 0 for squared checkbox, 1 for crossed checkbox, 2 for circular checkbox (radio button).

Group is a number that permit to associate interactive checkboxes together; this permits to deactivate a checkbox when selecting another in the group (like a group of radio buttons).

image

gui.Slider

Sld1 = gui.slider(x, y, width, height, value [,orientation])

The slider has by default a range from 0 to 100.

Value permit to define the default value.

Orientation can be 0 (default) for horizontal and 1 for vertical.

image

gui.ProgressBar

Prg1 = gui.progressbar(x, y, width, height, value)

The progressBar has by default a range from 0 to 100.

image

gui.Ramp

Rmp1 = gui.ramp(x, y, width, height, value)

The ramp has by default a range from 0 to 100.

image

gui.Gauge

Gau1 = gui.gauge(x, y, width, height, value)

The gauge has, by default a range from 0 to 100.

imageimage

gui.Box

Box1 = gui.box(x, y, width, height, color1 [,frame_color [,color2]])

The box has by default a unique color with a white frame around.

The optional parameter ‘frame_color” defines the color of the frame.

The optional parameter ‘color2’ allows the color of the box to be swapped between the 2 colors using the command gui.setvalue (example for a squared led).

By default color2 is black

image

 

gui.Circle

Cir1 = gui.circle(x, y, radius, color1 [,color2])

The circle has by default a unique color with a white frame around.

The optional parameter ‘frame_color” defines the color of the frame.

The optional parameter ‘color2’ allows the color of the circle to be swapped between the 2 colors using the command gui.setvalue (example for a circular led).

By default color2 is black.

image

gui.Rect

Rect1 = gui.rect(x, y, width, height, color)

This draws a simple rectangle.

image

gui.Line

Line1 = gui.line (x1, y1 x2, y2, color)

This draws a simple line.

image

GUI Functions

gui.GetValue

Value = gui.getvalue(obj)

 

Returns the current value from any object.

Works for button, Imagebutton, checkbox, slider, ….

 

gui.Target

Id = gui.target

Returns the ID of the object that generated the event.

Useful for having a common event handler routine for several objects.

GUI Commands

gui.INIT

Gui.init nb_elements [, back_color]

Initialise the graphical GUI interface.

Nb_elements define how many graphical elements will be defined.

This is just for memory reasons, if more objects are defined, they will be ignored.

Back_color defines the background color (by default is black).

gui.REDRAW

Gui.redraw

Redraw all the content of the GUI.

All the objects will be redrawn, even those that have not changed since the last refresh.

gui.REFRESH           

Gui.refresh [touch]

Refresh the content of the GUI.

If ‘touch’ is 1, the touchscreen will also be refreshed. This is useful if the module doesn’t have a touchscreen (like the m5stack).

 

gui.AUTOREFRESH

Gui.autorefresh interval [, touch]

Refresh the content of the GUI at regular intervals.

‘Interval’ defines the time interval in milliseconds.

If ‘touch’ is 1, the touchscreen will also be refreshed. This is useful if the module doesn’t have a touchscreen (like the m5stack).

 

gui.SETVALUE        

Gui.setvalue object, value

Set the value for any valid object.

 

gui.SETTEXT           

Gui.settext object, text$

Set the text for textline and for buttons.

 

gui.SETIMAGE         

Gui.setimage object, image1$ [,image2$]

Defines the image(s) for the IMAGE object and the ImageButton Object.

 

gui.SETCOLOR       

Gui.setcolor object, col1 [,col2 [,col3 [,col4]]]

Set the colors for all the objects.

This command is valid for all the objects, but the syntax is different for each object.

The detail is :

 

Object

Format

TextLine

gui.setcolor object, color_text [,color_back [,color_frame]]

Button

gui.setcolor object, color_text [,color_pressed [,color_released [,color_frame]]]

Checkbox

gui.setcolor object, color_set [, color_back [, color_frame]]

ProgressBar

gui.setcolor object, color_set [, color_back [, color_frame]]

Slider

gui.setcolor object, color_cursor [, color_back [, color_frame [, color_ticks]]]

Gauge

gui.setcolor object, color_needle [, color_back [, color_frame [, color_ticks]]]

Box

gui.setcolor object, color_set [, color_back [, color_frame [, color_released]]]

Circle

gui.setcolor object, color_set [, color_back [, color_frame [, color_released]]]

Rectangle

gui.setcolor object, color

Line

gui.setcolor object, color

Image

gui.setcolor object, color_back  ( this works only with bmp with transparency)

ButtonImage

gui.setcolor object, color_back1, color_back2

 

 

 

SETRANGE  

Gui.setrange object, value_mini, value_maxi

Define the range for the slider, the progressbar, the ramp and the gauge.

 

SETEVENT  [19] 

Gui.setevent object, event_type, label | OFF

Define an event for any object.

 

Event

Meaning

0 (NONE)

Disable the event

1 (CLICK)

Triggered when touching on the object

2 (LEAVE)

Triggered when leaving the touch from the object

3 (CHANGE)

Triggered when the value of the object change

 

Label is the place where it will jump. OFF disable the event.

The events can be defined for button, checkbox, slider, image and imagebutton.

 

ID = GUI.TARGET 

Returns the ID of the object that generated the event.

Useful for having a common event handler routine for several objects

 

SETSTYLE   

Set the style for all the objects.

This command is valid for all the objects, but the syntax is different for each object.

The detail is :

 

Object

Format

Slider

gui.setstyle object size_cursor [, number_of_ticks [, tick_length]]

Gauge

gui.setstyle object needle_length [, needle_width  [, number_of_ticks [, tick_length]]]

TextLine

gui.setstyle object, text_alignment [, text_margin]

 

Text_alignement can be :

 

VALUE

ALIGNMENT

0

Top left

1

Middle of top

2

Top right

3

Middle of left side

4

Center

5

Middle of the right side

6

Bottom left

7

Middle of bottom

8

Bottom right

 

 

Text_margin defines the margin in pixels.

 

INFRARED INTERFACE[20] [21] 

An infrared receiver can be connected to the module permitting to decode messages received from RC remote controller.

It is also possible to connect an IR led permitting to generate RC codes from the module.

 

This picture shows a kit containing an IR receiver, an IR LED and a controller available on ebay at around 1€.

image

 

 

The following drawing shows an example of connection using the pins GPIO12 and GPIO14:

 

image

image

Details of wiring for the VS1838B

 

 

There are several commands associated with the IR functions :

IR.INIT, IR.GET$, IR.SEND and ONINFRARED.

 

In order to use the Infrared functions, the first command to use is IR.INIT.

This command defines the pins to be used for the IR receiver and the IR transmitter.

As per the wiring given above, the command must be:

IR.INIT 14, 12

 

The command ONINFRARED defines the label where the program will jump when a code is received by the Infrared receiver. Then, using the function IR.GET$ it will be possible to retrieve the code of the message received:

 Example

IR.INIT 14, 12

ONINFRARED irReceived

Wait

 

irReceived:

PRINT IR.GET$

RETURN

 

The transmission can be done using the command IR.SEND:

The format is IR.SEND format, code$, bits

 

Example for a NEC code:

IR.SEND 3, "20DF40BF", 32

 

The following formats are supported for the reception and the transmission :

VALUE

FORMAT

-1

UNKNOWN

0

UNUSED

1

RC5

2

RC6

3

NEC

4

SONY

5

PANASONIC

6

JVC

7

SAMSUNG

 

This is an example working with the RC controller shown in the picture above.

It shows the status of the button 1 to 8 pressed on the web page and can control 8 leds wired to a PCF8574 using the I2C bus :

 

oninfrared irReceived

onHtmlReload mypage

l1 = 0: l2 = 0: l3=0: l4=0: l5=0: l6=0: l7=0: l8=0

ir.init 14

i2c.setup 4,5

l = 0

PCF8574_write l

 

gosub mypage

wait

 

irReceived:

print ir.get$, ir.get$(1), ir.get$(2), val("&h" + ir.get$(3)), ir.get$(4), ir.get$(5)

code_type = val(ir.get$(1))

address = val(ir.get$(2))

cmd = val("&h" + ir.get$(3))

' if NEC CODE

if code_type = 3 then

  ' if RC address is 0

  if address = 0 then

     if cmd = 22 then l = l xor 1

     if cmd = 25 then l = l xor 2

     if cmd = 13 then l = l xor 4

     if cmd = 12 then l = l xor 8

     if cmd = 24 then l = l xor 16

     if cmd = 94 then l = l xor 32

     if cmd =then l = l xor 64

     if cmd = 28 then l = l xor 128   

     PCF8574_write l

     setleds l

  end if

end if

return

 

mypage:

cls

a$ = ""

a$ = a$ + |<h1> TEST OF IR REMOTE CONTROLLER COUPLED<br>|

a$ = a$ + | WITH AN I2C PCF8574 AND 8 LEDS</h1>|

a$ = a$ + led$(l1) + led$(l2) + led$(l3) + led$(l4) + led$(l5) + led$(l6) + led$(l7) + led$(l8)

html a$

return

 

sub setleds(x)

  ' set the status for the leds

  l1 = (x and 1)

  l2 = (x and 2)

  l3 = (x and 4)

  l4 = (x and 8)

  l5 = (x and 16)

  l6 = (x and 32)

  l7 = (x and 64)

  l8 = (x and 128)    

  refresh

end sub

 

sub PCF8574_write(x)

  i2c.begin 32 'PCF8574

  i2c.write x

     i2c.end

end sub

 

ULTRASONIC DISTANCE SENSOR HC-SR04[22] 

An Ultrasonic distance sensor HC-SR04 can be connected to the module.

This sensor permits to measure the distance from a target positioned in front in a range going from a minimum of 3 cm to a maximum of 3 meters.

image

For the connection, it requires 2 pins plus the power supply. (5 Volts).

 

image

 

There is just one function, DISTANCE(pin_trig, pin_echo) that return the distance from the target in cm.

 

Example:

' Measure the distance from the target 2 times / second

print "DISTANCE MEASUREMENT"

for i = 0 to 1000

  print str$(DISTANCE(15,12), "%4f") + "cm"

  pause 500

next i

end

 

 

DHT xx Temperature / Humidity Sensors[23] 

A Temperature / Humidity sensor of the DHTxx family can be connected.

The picture below the ones that are actually supported.

image

 

These sensors requires a single wire connection like shown below:

 

image[24] 

 

To use them, is very simple.

First initialise the sensor with the command DHT.SETUP pin, model

The pin can be any available pin of the device and model can be 11, 21 or 22 (for DHT11, DHT21 or DHT22).

Assuming that we are using the DHT22 on the pin GPIO2,  the command must be :

 

DHT.SETUP 2, 22

 

Then 3 functions are available :

DHT.TEMP

DHT.HUM

DHT.HEATINDEX

 

The first returns the value of the temperature in °C

The 2nd returns the value of the Humidity in %

The 3rd returns the value of the heat index in °C

.

Example

DHT.SETUP 2 ,22

Print "The Temperature is "; DHT.TEMP ; "°C"

Print "The Humidity is "; DHT.HUM ; "%"

Print "The Heat Index is "; DHT.TEMP ; "°C"

 

 

 

 

DS18B20 Temperature Sensors

One or several  DS18B20 Temperature can be connected.

The picture below shows the ones that are actually supported.

image

These Dallas 1-wire sensors use a single wire connection as shown below, allowing multiple sensors to be connected in parallel on the same 1-wire bus from a single gpio pin.

 

image

 

There is just one function available :

TEMPR$(pin_number, [ID])

 

This function will return the temperature or the ID of the device depending on the parameter ‘ID’ specified.

In the schematic above, to read the 3 temperatures, the example code is :

Print "The Temperature 1 is ";TEMPR$(2, 1) ; "°C"

Print "The Temperature 2 is ";TEMPR$(2, 2) ; "°C"

Print "The Temperature 3 is ";TEMPR$(2, 3) ; "°C"

 

BNO055 Absolute Orientation Sensor

A BNO055 Absolute Orientation Sensor can be connected to the module using I2C interface.

This sensor contains 3 accelerometers, 3 gyros and 3 magnetometers BUT contains also an integrated 32 bits controller running Bosch Sensortec sensor fusion software.

This permits to unload the module from all the calculations related to the implementation of a Fusion algorithm.

 

image

This component is quite expensive ( ~10 €) compared to the classic MPU6050, MPU9250, ... but the quality of the internal fusion algo permits to use it without any effort.

Before connect it, the links S0 and S1 must be soldered with the ‘-’ position, as shown in the picture, to enable I2C.

 

The connection is very simple, just 2 pins for the I2C bus and the power supply are required.

The module is already provided with on-board pull-up resistors, so external pull-up resistors are not required.

 

 

 

image

Available instructions are :

BNO055.SETUP(address)
BNO055.HEADING
BNO055.PITCH
BNO055.ROLL
BNO055.VECTOR ( param )
BNO055.CALIB [(param)]

 

The use of the BNO055 module is very simple.

First the I2C must be initialised with the command I2C.SETUP.

Then the module must be initialised with the function BNO055.SETUP(address).

‘address’ must be &h28 if the pin ‘I2C’ is connected to GND or &h29 if connected to VCC.

This function returns 1 if the module has been initialised properly otherwise it returns 0.

After the initialisation, the euler angles can be simply read using the corresponding functions BNO055.HEADING, BNO055.PITCH and BNO055.ROLL

Another useful function is BNO055.CALIB [(param)] that returns the calibration status of the BNO055 internal sensors.

If used without any parameters, it returns 1 when all the internal sensors are calibrated otherwise it returns 0.

The BNO055 is put in auto calibration mode so it will calibrate by itself in the background.

Refer to the following link for more information : BNO055 Calibration

 

Example

I2C.SETUP 21, 22  ' set I2C port on pins 21 and 22
if bno055.setup(&h28) = 0 then
  print "BNO module not found"
  end
end if

for z = 1 to 1000
  print "Pitch:", bno055.pitch
  print "Roll:", bno055.roll

  print "Heading:", bno055.heading

  print "Calibrated:", bno055.calib

  pause 100
next z

end

 

BME280 Combined humidity and pressure sensor

A BME280 Sensor can be connected to the module using I2C interface.

This unit combines individual high linearity, high accuracy sensors for pressure, humidity and temperature.

A unit based on the chip BMP280 can also be used, except that this one doesn’t contains the humidity sensor.

 

imageimage

 

The connection is very simple, just 2 pins for the I2C bus and the power supply are required.

The module is already provided with on-board pull-up resistors, so external pull-up resistors are not required.

 

 

 

 

 

 

 

 

image

Available instructions are :

BME280.SETUP(address)
BME280.ALT(qnh)
BME280.HUM
BME280.QFE
BME280.QNH(altitude)
BME280.TEMP


The use of the BME280 module is very simple.

First the I2C must be initialised with the command I2C.SETUP.

Then the module must be initialised with the function BME280.SETUP(address).

‘address’ must be &h76 if the pin ‘SDO’ is connected to GND or &h77 if connected to VCC.

This functions returns 1 if the module has been initialised properly otherwise it returns 0.

After the initialisation, the temperature, pressure and humidity can be simply read using the corresponding functions BME280.TEMP, BME280.QFE and BME280.HUM.

The function BME280.ALT(qnh) returns the altitude information but requires, as parameter, the pressure at sea level.

At the opposite, the function BME280.QNH(altitude) returns the sea level pressure but requires, as parameter, the current altitude.

Example

I2C.SETUP 21, 22  ' set I2C port on pins 21 and 22

if bme280.setup(&h76) = 0 then print "BME280 not found" : end

for z = 1 to 1000
  print "Temperature", bme280.temp
  print "Humidity", bme280.hum
  print "Pressure", bme280.qfe
  qnh = bme280.qnh(150) ' assume the altitude at 150 meters
  print "Qnh     ", qnh
  print "Altitude", bme280.alt(1019) ' assume a sea level pressure at 1019 Hpa
  pause 100
next z

 

APDS9960 Digital Proximity, Ambient Light, RGB and Gesture Sensor

An APDS9960 Sensor can be connected to the module using I2C interface.

 

The APDS-9960 device features advanced Gesture detection, Proximity detection, Digital Ambient Light Sense (ALS) and Color Sense (RGBC).

Gesture detection utilizes four directional photodiodes to sense reflected IR energy (sourced by the integrated LED) to convert physical motion information (i.e. direction and distance) to a digital information.

image

 

The connection is very simple, just 2 pins for the I2C bus and the power supply are required.

The module is already provided with on-board pull-up resistors, so external pull-up resistors are not required.

 

 

 

image

Available functions are :

APDS9960.SETUP(mode)
APDS9960.READGESTURE
APDS9960.AMBIENT
APDS9960.RED
APDS9960.GREEN
APDS9960.BLUE
APDS9960.PROXIMITY
APDS9960.GESTUREGAIN
APDS9960.GESTURELED

 

There is also an associated ONGESTURE event.

The use of the APDS9960 module is quite simple.

 

First the I2C must be initialised with the command I2C.SETUP.

Then the module must be initialised with the function APDS9960.SETUP(mode).

mode” must be 1 for “GESTURE” mode.

As soon as a gesture is recognised, the event ONGESTURE is triggered, so it is then possible to get the recognised gesture with the function APDS9960.READGESTURE

 

Example

'APDS9960 GESTURE SENSOR DEMO
i2c.setup 21,22
'set the sensor in GESTURE mode
if apds9960.Setup(1) = 0 then print "APDS9960 not found" : end
'define the Gesture event
ongesture gesture
'Wait for the event
wait

gesture:
r = apds9960.ReadGesture
select case r
  case 1
    print "LEFT"
  case 2
    print "RIGHT"
  case 3
    print "UP"
  case 4
    print "DOWN"
  case 5
    print "NEAR"
  case 6
    print "FAR"
  case else
    print "none"
end select
return

 

The module can also be configured as Ambient & RGB light sensor.

In this case “mode” must be 2 for “Ambient Light and RGB Color” mode.

Example

'APDS9960 LIGHT SENSOR DEMO
i2c.setup 21,22
'set the sensor in Ambient light and RGB Color mode
if apds9960.Setup(2) = 0 then print "APDS9960 not found" : end

for z
= 1 to 10000
 
print "Light:", apds9960.ambient, apds9960.red, apds9960.green, apds9960.blue
 
pause 100
next z
end

 

The module can, finally, be configured also as a Proximity sensor.

In this case “mode” must be 3 for “Proximity” mode.

Example

'APDS9960 PROXIMITY SENSOR DEMO
i2c.setup 21,22
'set the sensor in Proximity mode
if apds9960.Setup(3) = 0 then print "APDS9960 not found" : end

for z
= 1 to 10000
 
print "Distance:", apds9960.proximity
 
pause 100
next z
end

 

VL53L0X TOF (Time Of Flight) Distance Sensor 

The VL53L0X is a new generation Time-of-Flight (ToF) laser-ranging module providing accurate distance measurement whatever the target reflectances unlike conventional technologies. It can measure absolute distances up to 2m, setting a new benchmark in ranging performance levels, opening the door to various new applications.

It must connected using I2C using the wiring as shown below :

image image

 

To start to use, it must be initialised using the VL53L0X.INIT function.  

The syntax is:

 

Ret = VL53L0X.INIT

 

It returns 1 if the initialisation was successful or 0 if not OK.

 

Then, the following commands are available :

 

VL53L0X.SETRANGE range

Set the distance range (sensitivity); by default the value is 0 for a max range of 600 mm

 

VL53L0X.SETRANGE

Range (mm)

0 ( default)

~ 600

1

~ 2000

 

VL53L0X.SETACCURACY accuracy

Set the accuracy of the readout modifying the time required for the measurement.

By default the value is 0 for a Measurement time of 33 msec.

 

VL53L0X.SETACCURACY

Measurement time (msec)

0 ( default)

33

1

 200

2

400

 

Finally it is possible to read the distance using the function

Dist = VL53L0X.DISTANCE

The value returned is the distance measured in millimeters.

If the measurement is not valid, for example if the distance is out of range, this function returns 8190.

This is a “blocking” function meaning that the program will stop the time required for the measurement, i.e. 400 ms when using the accuracy at 2.

 

For this reason the function VL53L0X.DISTANCE_N returns the same information but without blocking the execution of the code.

Obviously, the distance measured will be “refreshed” only at the rate defined with the function VL53L0X.SETACCURACY

 

Example:

' VL53L0X example program

print VL53L0X.init  ' will print 1 if the device has been found

VL53L0X.SetAccuracy 2 ' set the refresh rate at 400 msec (max accuracy)

VL53L0X.SetRange 1 ' set the range at 2000 mm ( 2 meters )

for z = 1 to 100000

  print VL53L0X.Distance ' get the distance 

next z

 

MPU9250 

The MPU-9250 is a 9-DOF System in Package (SiP) that combines two chips: the MPU-6500, which contains a 3-axis gyroscope as well as a 3-axis accelerometer, and the AK8963, which features a 3-axis magnetometer.

image

image

 

It must be connected using I2C wiring.

 

 

To start to use, it must be initialised using theMPU9250.SETUP function.

The syntax is:

 

Ret =MPU9250.SETUP(address)

‘Address’ can be &h68 or &h69 depending on the wiring of the MPU9250 (eventually the MPU6050).

This is function of the voltage applied on the pin AD0 :

 

LEVEL ON PIN AD0

ADDRESS (HEXADECIMAL)

GND or open

68

VCC

69

 

It returns 1 if the initialisation was successful or 0 if not OK.

 

The values can then be read using the function

Ret = MPU9250.VECTOR(array())

The function returns 1 if the action was successful; otherwise 0.

The variables are read in a one-shoot operation, as per the table below:

 

INDEX

PARAMETER

UNITS

0

Accelerometer X axis

m/sec2

1

Accelerometer Y axis

2

Accelerometer Z axis

3

Gyroscope X axis

deg / sec

4

Gyroscope Y axis

5

Gyroscope Z axis

6

Magnetometer X axis

micro tesla

7

Magnetometer Y axis

8

Magnetometer Z axis

 

Example:

Dim vect(10)

Ret =  MPU9250.VECTOR(vect())

Print "ax "; vect(0), "ay "; vect(1), "az "; vect(2)

Print "gx "; vect(3), "gy "; vect(4), "az "; vect(5)

Print "mx "; vect(6), "my "; vect(7), "mz "; vect(7)

 

 

It must be noted that, because of the different internal orientation of the MPU6500 part and the AK8963, the axis of the magnetometers are not aligned with the accelerometers and the gyros.

To correct, the following rules must be applied :

Real mx = my

Real my = mx

Real mz = -mz

IMU FUSION FUNCTIONS

Annex includes 2 fusion algorithm designed to provide pitch, roll and yaw orientation from data coming from IMUs like the MPU9250.

The 2 algorithms are Madgwick and Mahony.

 

The Madgwick is provided into 2 forms, with 6-DOF and 9-DOF.

The Mahony is only with 9-DOF.

 

To start, the algos must be initialised with the command

FUSION.INIT

 

Then the different algos can be called as below :

 

For the 6-DOF Madgwick:

FUSION.MADGWICK ax, ay, az, gx, gy, gz

 

For the 9-DOF Madgwick:

FUSION.MADGWICK ax, ay, az, gx, gy, gz, mx, my, mz

 

For the 9-DOF Mahony:

FUSION.MAHONY ax, ay, az, gx, gy, gz, mx, my, mz

 

The angles can be read using the function FUSION.ANGLE(axis) following the table below:

 

AXIS

RETURNED INFORMATION

UNIT

1

PITCH

°

2

ROLL

°

3

YAW

°

 

The 2 algos can be tuned using the following coefficients :

For Magdwick :

FUSION.BETA = 0.6   ‘ default value 0.6

FUSION.ZETA = 0.6   ‘ default value 0.6  - only for 6-DOF algo

 

For Mahony:

FUSION.Kp = 10  ‘ proportional feedback default value 10

FUSION.Ki = 0  ‘ integral feedback default value 0

 

Example with the MPU9250 and a Madgwick algo:

 

i2c.setup 21,22, 400000

print mpu9250.setup(&h68)

fusion.init

fusion.beta = 0.6

dim p(10)

for j=0 to 100000

   i = mpu9250.vector(p())

   fusion.Madgwick p(0), p(1), p(2), (p(3) * PI/180), (p(4)* Pi/180), (p(5) * Pi/180), p(7), p(6), -p(8)

   pitch = -fusion.angle(1)

   roll = fusion.angle(2)

   yaw = (-fusion.angle(3) + 360) mod 360

   print str$(pitch, "%3.1f"), str$(roll, "%3.1f"), str$(yaw, "%3.1f"), deltat

next j

End

 

 

 

ETHERNET Module W5500

 

It is possible to connect a W5500 Ethernet module using the SPI Bus.

An Ethernet module based on the chipset WIZnet W5500 can be connected to the module using SPI interface.

These modules are very cheap and available on Ebay at less than 5€.

 

This picture shows 2 modules based on this chipset which have been successfully tested with Annex32.

imageimage

imageimage

 

This schematic shows how to connect the W5500 module to the ESP32 module.

image

 

This module permit to connect the ESP32 to the network using a wired connection.

Annex32 implement the functionalities to send and receive TCP and UDP packets.

It can be used in ADDITION to the existing WI-FI functionalities, as it exposes all the functionalities permitting to communicate with other modules / web services.

However, Annex32 cannot be administered through this connection, it must continue to be done using Wi-Fi.

The actual implementation introduces a new keyword, ETHERNET, that is the prefix for all the commands / functions related to it.

For simplicity, all the commands / functions replicate the same existing Wi-Fi functionality.

For example Ethernet.wget$ is the equivalent of wget$, Ethernet.IP$ is the equivalent of IP$, etc.

 

 

a = ETHERNET.init( cs_pin [ ip, mask, gateway ] )     Initialise the interface, variable a holds the status result.

If ip, mask, gateway are not defined, the module will request a DHCP address from a DHCP server.

DHCP status returns  =0 if failed to receive a DHCP IP,  =1 if DHCP IP received successfully,  =2 if using a manually configured fixed IP address,  =-1 if ethernet module not found, =-2 if UTP cable is not connected

 

a$ = ETHERNET.IP$   returns the IP address of the module (same format as IP$)

 

 

a$ = ETHERNET.WGET$( url, [port] )  same as WGET$ but the syntax has been modified also for the WGET$

make a GET request on a remote server. The arguments http_server [, port ]

the format of the url is [protocol]://web_address:port/path

Example for the same website (all are valid):

print ethernet.wget$(“jsonplaceholder.typicode.com/posts”)  ‘ use by default the port 80

print ethernet.wget$(“http://jsonplaceholder.typicode.com/posts”)  ‘ use by default the port 80

print ethernet.wget$(“jsonplaceholder.typicode.com:80/posts”)  ‘ define the the port 80

print ethernet.wget$(“jsonplaceholder.typicode.com/posts”, 80)  ‘ define the the port 80

 

Another example

print ethernet.wget$("http://portquiz.net:8080/") ‘ define the port 8080

print ethernet.wget$("http://portquiz.net/", 8080) ‘ define the port 8080

 

a$ = ETHERNET.WPOST$( url, [ [, port | payload$] [,port] ] )

make a POST request on a remote server

the arguments http_server [ [, port | payload$] [,port] ]

the format of the url is [protocol]://web_address:port

 

These functions :

 

ETHERNET.UDP.BEGIN      ETHERNET.UDP.STOP        ETHERNET.UDP.WRITE      ETHERNET.UDP.REPLY            ETHERNET.UDP.READ$     ETHERNET.UDP.REMOTE$

 

Have the same function and format of the already existing ones but for the ethernet network

 

 

WEB SERVER:

 

ETHERNET.SERVER.BEGIN [port]  ‘ start the ethernet web server on the defined port (by default 80)

ETHERNET.SERVER.STOP  ‘ stop the ethernet web server

 

ETHERNET.SERVER.GETURL$ ‘ returns the url of the request done on the server

ETHERNET.SERVER.GETARG$ ‘ returns the arg from the request (same as

URLMSGGET$)

 

ETHERNET.SERVER.RETURN  ret$  [, content_type$]

‘ permit to return a content to the caller page

 

 

EVENTS:

ONETHERNETUDP  label

same event as ONUDP but for the ETHERNET

 

ONETHERNETURL label

Is triggered when a request is done with any url

The url can be read with the function ethernet.server.geturl$ and

The arguments can be read with the function ethernet.server.getarg$

FTP

The File Transfer Protocol (FTP) is a standard network protocol used for the transfer of computer files between a client and server on a computer network.

Annex implements a function permitting to send  files stored locally to the remote server.

 

The function is :

BAS.FTP$

The FTP port is defined by default at the standard value 21.

 

To send a file the command is

 

res$ =  BAS.FTP$(host$, login$, password$, file$, folder$)

Where :

     host$ is the address of the FTP server

     login$ is the login of the account on the FTP server

     password$ is the password of the account on the FTP server

     file$ is the file that will be sent

     folder$ is the folder where the file will be sent

 

Note :

     If the remote folder does not exist, it will be created automatically.

   in this case make sure you have the right to create the directories on the FTP server

 

If the transmission was successful, the function returns a message like this:

-       226 Transfer complete (153.536 KB/s).

 

In case of problems, the function returns a self explaining messages like this :

-       550 Can't change directory to "/newfolder".   

-       530 Permission denied

-       -2 File not found

-       …...

 

Example :

res$ =  BAS.FTP$("192.168.1.57", "myLogin", "myPass", "/test.bas", "/")

 

This is a useful example that permit to backup the module sending all the local files to the FTP server

 

' FTP function example revised

' cicciocb 2019

' send all the local files to the remote server

' in the folder /

' The directory structure will be also copied

 

'starts from the root

d$ = FILE.DIR$("/")

'Then lists all the files

While D$ <> ""

  print "I'm sending ", d$

  path$ = left$(d$, instr(-1, d$, "/")) ' extract the path

  print bas.ftp$( "192.168.1.57", "robin", "hood", d$, path$)

  d$ = FILE.DIR$

Wend

end

 

 

Server data requests  (GET and POST)

Annex includes the functionality to request/send data from/to the server using HTTP GET and POST requests.

The GET is the most common HTTP method, generally used to request (GET) data from a server but can also be used to send data to the server.

This is what your web browser does when typing a url in the address bar.

This method uses the url to include all the data to be transferred to the server and returns the answer from the server.

As support, there is a nice site https://jsonplaceholder.typicode.com/ that permits to exercise into issuing GET requests.

For example, http://jsonplaceholder.typicode.com/comments/1  is composed of :

 

 

http:// => protocol. By default uses the port 80.

jsonplaceholder.typicode.com => base url

/comments/1 => url used to transfer arguments (comments = 1)

 

Another way to transfer arguments is using them after a ? as below:

http://jsonplaceholder.typicode.com/comments?id=1 

In this case we transfer the request for comments with id=1

 

Another example : http://jsonplaceholder.typicode.com/comments?id=1&id=4

In this case we transfer the request for comments with id=1 and id=4.

To note that the arguments are composed of couples arg=value separated by &

 

The same requests can be done using an encrypted protocol, the https:// that uses the port 443 :

https://jsonplaceholder.typicode.com/comments?id=1&id=4  (to note the https://)

 

The POST method is less used than the GET but it is the most appropriate to send data to the server.

In contrast to the GET method where the data are transferred inside the url of the request, the POST method transfers the data in the body of the message.

 

Annex implements 3 methods to make HTTP requests :

-       WGET$(server$, port, [,header])

-       WPOST$(server$, body$, port [,header])

-       WGETASYNC[(]server$, port, [,header][)]

 

Basically WGET$ and WGETASYNC both do the same operation but WGET$ waits until the server answers whilst WGETASYNC continues the normal execution of the program and triggers (asynchronously) an event when the answer arrives .

 

Example with WGET$ :

' do an HTTP GET request

a$ = WGET$("jsonplaceholder.typicode.com/comments?id=1&id=4", 80)

' do an HTTPS GET request

a$ = WGET$("jsonplaceholder.typicode.com/comments?id=1&id=4", 443)

 

To note :

The leading HTTP:// or HTTPS:// must be removed

The protocol is specified using the port number; by default is HTTP but will be HTTPS if the port is 443.

 

Example with WPOST$ :

' do an HTTP POST request

a$ = WPOST$("ptsv2.com/t/annextest/post", "name=Annex&version=1.39", 80)

' check at https://ptsv2.com/t/annextest for the result

 

To note :

The leading HTTP:// or HTTPS:// must be removed

The protocol is specified using the port number; by default is HTTP but will be HTTPS if the port is 443.

 

Example with WGETASYNC:

ONWGETASYNC answer_done

' do an HTTPS GET request

WGETASYNC("jsonplaceholder.typicode.com/comments?id=1&id=4", 443)

Wait

answer_done:

Print WGETRESULT$

Return

 

To note :

The leading HTTP:// or HTTPS:// must be removed

The protocol is specified using the port number; by default is HTTP but will be HTTPS if the port is 443.

The brackets around WGETASYNC are optional.

 

Optionally it is possible to specify an extra parameter for WGET$, WPOST$ and WGETASYNC.

If this parameter is 1, the server header will be included in the answer.

This will be helpful for debugging.

Note: if you don’t know what is the header, just ignore this option.

MQTT

MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks. The design principles are to minimise network bandwidth and device resource requirements whilst also attempting to ensure reliability and some degree of assurance of delivery. These principles also turn out to make the protocol ideal of the emerging “machine-to-machine” (M2M) or “Internet of Things” world of connected devices, and for mobile applications where bandwidth and battery power are at a premium.

 

Annex implements the protocol with the following limitations :

-       It can only publish QoS 0 messages.

-       It can subscribe at QoS 0 or QoS 1.

-       The maximum message size is 256 characters

-       The keepalive interval is set to 15 seconds

-       The client uses MQTT 3.1.1

The following table describes the functions available.

All the numerical functions return 1 if successful or 0 if there is a  problem.

 

FUNCTIONS / COMMANDS

DESCRIPTION

Ret = MQTT.Setup(server$ [,port])

Setup the MQTT communications.

Server$ is the MQTT server address

Port is the MQTT port; if not defined defaults to 1883

Ret = MQTT.Connect(login$, pass$ [id$])

Connect to the server using the provided login and password.

Optionally id$ permit to define an arbitrary ID

Ret = MQTT.Connect("", "", [id$])

Connect to the server without identification

Optionally id$ permit to define an arbitrary ID

Ret = MQTT.Disconnect()

Disconnects from the MQTT server

Ret = MQTT.Publish(topic$, message$)

Publish a string message in the specified topic

Ret = MQTT.Subscribe(topic$ [,Qos])

Subscribes to messages published to the specified topic.

Qos can be 0 or 1; if not defined defaults to 0

Ret = MQTT.UnSubscribe(topic$)

Unsubscribes from the specified topic

Ret = MQTT.Connected()

Returns the current connection status.

Returns 1 if connected or 0 if disconnected

OnMQTT label

Define a label where the program will jump when an MQTT message is received

Ret$ = MQTT.Message$

Returns the MQTT message received

Ret$ = MQTT.Topic$

Returns the MQTT topic received

 

This is an example based on the free MQTT test server “test.mosquitto.org”.

The program subscribe and send message to the same “/AnnexTest” topic.

It should print the same messages it sent to the server.

 

' MQTT test program

' Using mosquitto test server

print mqtt.setup("test.mosquitto.org")

print mqtt.connect("", "") ' No login / pass required

print mqtt.subscribe("/AnnexTest") ' subscribe to the topic /AnnexTest

onmqtt mqtt_msg

 

for z = 1 to 10

  ' send messages to the topic /AnnexTest

  print mqtt.publish("/AnnexTest", "Annex"+str$(z))

  pause 100

next z

print ramfree

wait

' receive messages from the server

mqtt_msg:

print "TOPIC  : "; mqtt.topic$

print "MESSAGE: "; mqtt.message$

return

 

 

ESP-NOW

ESP-NOW is a fast, connectionless communication technology featuring short packet transmission.

ESP-NOW is ideal for smart lights, remote control devices, sensors and other applications.

 

This is a special protocol developed by Espressif that enables the ESP8266 / ESP32  modules to communicate between themselves easily without any specific network connection (i.e. no router).

 

The modules (peers) can inter-communicate even if they are not connected on a common network, the unique requirement is to share the same Wifi radio channel.

 

Practically, each peer of the ESP-NOW network can send a message to any other peers(s) directly and very fast without establishing a network link before. After sending, it will be able to know if the message has been received

In the same way, it can also receive a message from any other peer.

 

The ESP-NOW is very fast and simple to put in place but there are the following limitations :

-       The max number of peers is 20

-       The transmitted message size can be max 250 characters

-       For the ESP32 it does not work in STA mode (only in AP+STA mode) when used in combination with the ESP8266 (works OK between ESP32 only)

 

The ESP-NOW network does not use TCP/IP, so uses the peers MAC addresses to communicate instead of IP addresses.

 

As Annex is very versatile, a network module can use its wifi interface for ESP-NOW and for standard routed IP WiFi networking, so it can communicate with both types of network modules, allowing it to function as a kind of “Gateway” between ESP-NOW and routed WiFi.

Each module (peer) holds a list of ‘receivers” containing the MAC addresses of all the peers that will receive a message when using the command EspNow.Write(msg$)

 

Functions and commands available :

 

FUNCTIONS / COMMANDS

DESCRIPTION

Ret = EspNow.Begin

starts the ESP-NOW communications

Ret = EspNow.Stop

stops the ESP-NOW communications

Ret = EspNow.Add_Peer(MAC_add$)

add a peer (module) to the ‘receiver’ list

Ret = EspNow.Del_Peer

delete a peer (module) from the ‘receiver’ list

Ret = EspNow.Write(msg$)

write a message to the peers defined in the list

Ret = EspNow.Write(msg$, MAC_add$)

write a message to a specific peer defined by its MAC address

All these functions return a value; a non-zero value indicates that an error has occurred.

If the returned value is not required, the functions can be used as commands without reading into a variable.

Example :

Ret = EspNow.Write(msg$)                 used as function

EspNow.Write msg$               used as command (without brackets)

 

 

STRING FUNCTIONS

DESCRIPTION

Msg$ = EspNow.READ$

Read the message received

MAC_add$ = ESPNow.REMOTE$

Read the MAC address of the emitter of the message received

Err$ = ESPNow.ERROR$

Read the MAC address of the device(s) that didn’t received the message

 

 

 

EVENTS

DESCRIPTION

OnEspNowMsg label

tTrigger an event each time a message is received

OnEspNowError label 

tTrigger an event each time that a transmission error occurs.

This happen, in particular, when the receiver device has not received the message

 

 

These pictures shows some 3 typical ESP-NOW communication models:

image

 

image

 

image

 

 

Let’s see an example with 3 modules with 2 acting like sensors and the 3rd as receiver.

The sensor modules will send a message each second to the receiver.

The receiver will print these message in the console.

image

Code for the SENSOR1 module

'ESP-NOW sensor1 example

RECEIVER_MAC$ = "60:01:94:51:D0:7D" ' MAC address of the receiver

print "init " ; espnow.begin  ' should print 0 if all OK

espnow.add_peer RECEIVER_MAC$    ' set the address of the receiver

onEspNowError status ' set the place where jump in case of TX error

timer0 1000, sendMessage ' trigger a message at each second

wait

 

sendMessage:

espnow.write "Sensor 1 : " + str$(rnd(1000)) ' send the message

return

 

status:

print "TX error on "; espnow.error$  ' print the error

return

 

 

Code for the SENSOR2 module

'ESP-NOW sensor2 example

RECEIVER_MAC$ = "60:01:94:51:D0:7D" ' MAC address of the receiver

print "init " ; espnow.begin  ' should print 0 if all OK

espnow.add_peer RECEIVER_MAC$    ' set the address of the receiver

onEspNowError status ' set the place where jump in case of TX error

timer0 1000, sendMessage ' trigger a message at each second

wait

 

sendMessage:

espnow.write "Sensor 1 : " + str$(rnd(1000)) ' send the message

return

 

status:

print "TX error on "; espnow.error$  ' print the error

return

 

 

Code for the RECEIVER module

'ESP-NOW receiver example

print "init " ; espnow.begin  ' should print 0 if all OK

onEspNowMsg message ' set the place where jump in case of message reception

wait

 

message:

print "RX:"; espnow.read$; " from "; espnow.remote$ ' print the message

return

 

Let’s see another example always with 2 sensors and one receiver.

In this case the receiver will retransmit back to the sensor 1 the message received.

This means that the sensor 1 will receive the message coming from the sensor 2 and also its own message.

The sensor 1 and the receiver will print the messages received in the console

image

Code for the SENSOR1 module

'ESP-NOW sensor example

RECEIVER_MAC$ = "60:01:94:51:D0:7D"

print "init " ; espnow.begin  ' should print 0 if all OK

espnow.add_peer RECEIVER_MAC$    ' set the address of the receiver

onEspNowMsg message ' set the place where jump in case of message reception

onEspNowError status ' set the place where jump in case of TX error

timer0 1000, sendMessage ' trigger a message at each second

wait

 

sendMessage:

espnow.write "Sensor 1 : " + str$(rnd(1000)) ' send the message

return

 

message:

print "RX:"; espnow.read$; " from "; espnow.remote$ ' print message

return

 

status:

print "TX error on "; espnow.error$  ' print the error

return

 

 

Code for the SENSOR2 module

'ESP-NOW sensor2 example

RECEIVER_MAC$ = "60:01:94:51:D0:7D" ' MAC address of the receiver

print "init " ; espnow.begin  ' should print 0 if all OK

espnow.add_peer RECEIVER_MAC$    ' set the address of the receiver

onEspNowError status ' set the place where jump in case of TX error

timer0 1000, sendMessage ' trigger a message at each second

wait

 

sendMessage:

espnow.write "Sensor 1 : " + str$(rnd(1000)) ' send the message

return

 

status:

print "TX error on "; espnow.error$  ' print the error

return

 

 

Code for the RECEIVER module

'ESP-NOW receiver example #2

SENSOR1_MAC$ = "68:C6:3A:C3:06:DB"

print "init " ; espnow.begin  ' should print 0 if all OK

espnow.add_peer SENSOR1_MAC$    ' set the address of the sensor 1

onEspNowMsg message ' set the place where jump in case of message reception

wait

 

message:

msg$ = espnow.read$

rem$ = espnow.remote$

print "RX:"; msg$; " from "; rem$

ret = espnow.write( msg$ + " Transferred from " + rem$ ) ' transfer the message received

return

 

status:

print "TX error on "; espnow.error$ ' print the message

return

 

Let’s see now another example where a sensor will send a message to 2 receivers :

 image

Code for the SENSOR module

'ESP-NOW sensor example

RECEIVER1_MAC$ = "60:01:94:51:D0:7D"

RECEIVER2_MAC$ = "68:C6:3A:C3:06:DB"

print "init " ; espnow.begin  ' should print 0 if all OK

espnow.add_peer RECEIVER1_MAC$    ' set the address of the receiver 1

espnow.add_peer RECEIVER2_MAC$    ' set the address of the receiver 2

onEspNowError status ' set the place where jump in case of TX error

timer0 1000, sendMessage ' trigger a message at each second

wait

 

sendMessage:

espnow.write "Sensor : " + str$(rnd(1000)) ' send the message

return

 

status:

print "TX error on "; espnow.error$  'print the error

return

 

 

Code for the RECEIVER 1 module

'ESP-NOW receiver example

print "init " ; espnow.begin  ' should print 0 if all OK

onEspNowMsg message ' set the place where jump in case of message reception

wait

 

message:

print "RX:"; espnow.read$; " from "; espnow.remote$ ' print the message

return

 

 

Code for the RECEIVER 2 module

'ESP-NOW receiver example

print "init " ; espnow.begin  ' should print 0 if all OK

onEspNowMsg message ' set the place where jump in case of message reception

wait

 

message:

print "RX:"; espnow.read$; " from "; espnow.remote$ ' print the message

return

 

 

 

 

CONVERSION FUNCTIONS

A set of conversion function has been implemented.

These permit to convert from different units / formats in a simple way.

All these functions share the same suffix CONVERT. followed by the specific conversion name.

 

The functions implemented are :

 

FUNCTION

DESCRIPTION

CONVERT.DEGC_TO_F(degC)

Converts from °C to °F

CONVERT.F_TO_DEGC(degF)

Converts from °F to °C

CONVERT.TO_IEEE754(num)

Converts from float number to IEEE754 binary format

CONVERT.FROM_IEEE754(iee754_bin)

Converts from IEEE754 binary format to float number

 

BAS CONSTANTS

Several constants are available in the interpreter using the BAS.xxx format.

All these constants share the same suffix BAS. followed by the specific option.

Some of them (i.e. BAS.RTCMEM$) can also be also be written using it as destination..

 

CONSTANT

DESCRIPTION

BAS.VER

Returns the version of the Basic in numerical format

Example:

Print BAS.VER

1.37

BAS.VER$

Returns the version of the Basic in string format

Example:

Print BAS.VER$

Annex32 WI-Fi 1.37

BAS.ERRLINE

Returns the line number where the error happened. Value of 0 means no error.

It is reset to 0 with the command ONERROR CLEAR or  running the program or with the command ONERROR IGNORE or ONERROR SKIP.

BAS.ERRNUM

Returns a number where non zero means that there was an error.

It is reset to 0 with the command ONERROR CLEAR or  running the program or with the command ONERROR IGNORE or ONERROR SKIP.

BAS.ERRMSG$

Return a string representing the error message that would have normally been displayed on the console. It is reset to “No Error” running the program or with the command ONERROR CLEAR or ONERROR IGNORE or ONERROR SKIP.

BAS.FILENAME$

Returns the name of the current basic file

BAS.RTCMEM$

Returns the content of the CPU RTC internal memory.

This memory maintains the content between reset so it is useful in association with the SLEEP command when the module goes in low power mode.

This memory is limited at 512 bytes and can be set with the corresponding command  BAS.RCTMEM$ = “xxx”.

BAS.SSID$

Returns the login used for the STATION wifi connection.

BAS.PASSWORD$

Returns the password used for the STATION wifi connection.

 

BAS.LOAD

Loads another .bas program and run it immediately.

Returns 0 if successful or -1 if the file was not found

Example:

Print BAS.LOAD "/test.bas"

BAS.RESETREASON

Returns the reason of last reset.

The reason is defined in the table below

VALUE

REASON

0

Unknown

1

Power on reset

2

Unknown

3

Software reset digital core

4

Legacy watch dog reset digital core

5

Deep Sleep reset digital core

6

Reset by SLC module, reset digital core

7

Timer Group0 Watch dog reset digital core

8

Timer Group1 Watch dog reset digital core

9

RTC Watch dog Reset digital core

10

 Instrusion tested to reset CPU

11

Time Group reset CPU

12

Software reset CPU

13

RTC Watch dog Reset CPU

14

for APP CPU, reseted by PRO CPU

15

Reset when the vdd voltage is not stable

16

RTC Watch dog reset digital core and rtc module

BAS.DEVICE

Returns 1 if the device is an M5Stack otherwise 0

 

 

OPTION COMMANDS

It is possible to define some options in the interpreter using the OPTION.xxx commands.

All these commands share the same suffix OPTION. followed by the specific option.

 

The options available are :

 

COMMAND

DESCRIPTION

OPTION.CPUFREQ 80|160|240

Define CPU speed in Mhz of the module.

The value can be 80, 160 or 240. 

The default value is 240Mhz.

Setting the speed at 80Mhz, will divide by 3 the speed of the module but lower the power requirement of the module of around 5mA

OPTION.MAC mac$

Define an arbitrary MAC address for the module.

‘mac$’ must be a valid MAC address.

Example :

OPTION.MAC "AA:BB:CC:DD:EE:FF"

OPTION.LOWRAM value

Define the RAM available lower limit. If during the execution of the program this limit is reached, the program automatically stops with an OUT OF MEMORY error message. By default the value is defined at 10000.

As it introduces a little overhead, it can be disabled setting this option at 0 (however this is not recommended).

OPTION.NTPSYNC

Sync the local time with the remote NTP servers

 

FUNCTIONS:

The functions are divided into 2 groups :

-       Numerical functions (Double precision / integer)

-       String functions

The string functions always terminated by a ‘$’ (dollar) sign.

 

NUMERICAL FUNCTIONS

 

ABS(number)

Returns the absolute value of the argument 'number'

ACOS(number)

Returns the arccosine value of the argument 'number' in radians

ADC(pin)

Returns external voltage applied to then ADC pin defined as argument. The value goes from 0 to 4095.

Input voltage range is 0 ... 3.3V.

APDS9960.SETUP (mode)

Initialise a APDS9960 sensor connected using I2C to the module.

‘mode’ determine the sensing modality as per the table below :

 

MODE

SENSING MODALITY

1

Gesture Detection

2

Ambient Light and RGB Color Sensing

3

Proximity Sensing

 

Before using it, the I2C bus must be initialised with the command I2C.SETUP

This function returns 1 if the APDS9960 sensor has been found, otherwise returns 0

APDS9960.READGESTURE

Returns the last gesture detected by the APDS9960 sensor.

The APDS9960 sensor must be set in “Gesture Detection” mode before using this function ( APDS9960.SETUP(1) )

The returned value is :

VALUE

GESTURE

0

NONE

1

LEFT

2

RIGHT

3

UP

4

DOWN

5

NEAR

6

FAR

APDS9960.AMBIENT

Returns the ambient luminosity detected by the APDS9960 sensor.

The APDS9960 sensor must be set in “Ambient Light and RGB Color Sensing” mode before using this function ( APDS9960.SETUP(2) )

The range of the returned value is from 0 to 65535

APDS9960.RED

Returns the red light intensity detected by the APDS9960 sensor.

The APDS9960 sensor must be set in “Ambient Light and RGB Color Sensing” mode before using this function ( APDS9960.SETUP(2) )

The range of the returned value is from 0 to 65535

APDS9960.GREEN

Returns the green light intensity detected by the APDS9960 sensor.

The APDS9960 sensor must be set in “Ambient Light and RGB Color Sensing” mode before using this function ( APDS9960.SETUP(2) )

The range of the returned  value is from 0 to 65535

APDS9960.BLUE

Returns the blue light intensity detected by the APDS9960 sensor.

The APDS9960 sensor must be set in “Ambient Light and RGB Color Sensing” mode before using this function ( APDS9960.SETUP(2) )

The range of the returned value is from 0 to 65535

APDS9960.PROXIMITY

Returns a distance information detected by the APDS9960 sensor.

The APDS9960 sensor must be set in “Proximity Sensing” mode before using this function ( APDS9960.SETUP(3) )

The range of the returned value is from 0 to 255

APDS9960.GESTUREGAIN (gain)

Set the gain of the gesture sensing provided by the APDS9960 sensor.

‘gain’ can be one of the following values:

 

GAIN

MEANING

0

1x

1

2x

2

4x

3

8x

 

This function returns 1 if the function was successful, otherwise returns 0

APDS9960.GESTURELED (intensity)

Set the inensity of the LED used during the gesture sensing provided by the APDS9960 sensor.

‘intensity’ can be one of the following values:

 

INTENSITY

MEANING

0

100 mA

1

50 mA

2

25 mA

3

12.5 mA

 

This function returns 1 if the function was successful, otherwise returns 0

ASC(string$)

Returns the ASCII code of the first char in ‘string$’

ASIN(number)

Returns the arcsine value of the argument 'number' in radians

ATAN(number)

Returns the arctangent of the argument 'number' in radians

ATAN2(x, y)

Returns the angle whose tangent is the quotient of two specified numbers.

BAS.VER

Returns the version of the Basic in numerical format

Example:

Print BAS.VER

1.25

BAS.ERRLINE

Returns the line number where the error happened. Value of 0 means no error.

It is reset to 0 with the command ONERROR CLEAR or  running the program or with the command ONERROR IGNORE or ONERROR SKIP.

BAS.ERRNUM

Returns a number where non zero means that there was an error.

It is reset to 0 with the command ONERROR CLEAR or  running the program or with the command ONERROR IGNORE or ONERROR SKIP.

BME280.SETUP(address)

Initialise a BME280 sensor connected using I2C to the module.

‘address’ defines the I2C address of the sensor. The value can be &h76 or &h77.

Before using it, the I2C bus must be initialised with the command I2C.SETUP

Returns 1 if the BME280 sensor has been found, otherwise returns 0

BME280.ALT(qnh)

Returns the current altitude using the baro pressure from the sensor BME280.

The sea level pressure (in HectoPascal) must be given as argument.

The unit of the value returned is Meters (m)

BME280.HUM

Returns the Humidity parameter from the sensor BME280.

The unit of the value returned is ‘%’

If the value returned is always 0, the sensor is probably a BMP280.

BME280.QFE

Returns the Barometric Pressure parameter from the sensor BME280.

The unit of the value returned is HectoPascal ‘Hpa’

BME280.QNH(altitude)

Returns the sea level pressure using the baro pressure from the sensor BME280.

The current altitude (in meters) must be given as argument.

The unit of the value returned is HectoPascal ‘Hpa’

BME280.TEMP

Returns the Temperature parameter from the sensor BME280.

The unit of the value returned is ‘%’

BNO055.SETUP( address)

Initialise a BNO055 connected using I2C to the module.

‘address’ defines the I2C address of the sensor. The value can be &h28 or &h29.

Before using it, the I2C bus must be initialised with the command I2C.SETUP

Returns 1 if the BNO055 sensor has been found, otherwise returns 0

BNO055.HEADING

Returns the Heading angle information from the sensor BNO055.

The unit of the value returned is ‘degrees’

BNO055.PITCH

Returns the Pitch angle information from the sensor BNO055.

The unit of the value returned is ‘degrees’

BNO055.ROLL

Returns the Roll angle information from the sensor BNO055.

The unit of the value returned is ‘degrees’

BNO055.VECTOR ( param, axis)

Returns different type of information from the sensor BNO055.

Refer to the table below for the details of the information returned.

 

Example:

Print “Gyro infos x,y “, BNO055.VECTOR(3,1), BNO055.VECTOR(3,2)

 

PARAM

AXIS

PARAMETER

UNITS

1

1

Accelerometer X axis

m/sec2

2

Accelerometer Y axis

3

Accelerometer Z axis

2

1

Magnetometer X axis

micro tesla

2

Magnetometer Y axis

3

Magnetometer Z axis

3

1

Gyroscope X axis

deg / sec

2

Gyroscope Y axis

3

Gyroscope Z axis

4

1

Linear Accelerometer X axis

m/sec2

2

Linear Accelerometer Y axis

3

Linear Accelerometer Z axis

5

1

Gravity Data X axis

m/sec2

2

Gravity Data Y axis

3

Gravity Data Z axis

6 or any other value

1

Euler Angle Heading

deg

2

Euler Angle Roll

3

Euler Angle Pitch

BNO055.CALIB [(param)]

Returns the calibration status of the BNO055 sensor.

Used without any argument, it will return the global calibration status ( 1 = calibrated, 0 = not calibrated).

Refer to the table below when the function is called with an argument

 

PARAM

PARAMETER

1

System Status

2

Gyroscopes Status

3

Accelerometers Status

4

Magnetometers Status

none

Global Status (returns 1 if all are OK)

Example:

Print “Is Calibrated“, BNO055.CALIB

CINT(number)

Round numbers with fractional portions up or down to the next whole number or integer.

For example :

     15.46 will round to 15

     15.57 will round to 16

     -83.45 will round to -83

     -83.55 will round to -84

See also INT() and FIX().

CONVERT.DEGC_TO_F(degC)

Converts from °C to °F

CONVERT.F_TO_DEGC(degF)

Converts from °F to °C

CONVERT.TO_IEEE754(num)

Converts from float number to IEEE754 binary format

CONVERT.FROM_IEEE754(ieee754_bin)

Converts from IEEE754 binary format to float number

COS(number)

Returns the cosine of the argument 'number' in radians.

COUNTER.COUNT (cnt)

Returns the number of pulses recorded by the counter.

‘cnt’ identify the counter and can be 1 or 2

It is associated with the commands COUNTER.SETUP, COUNTER.RESET

COUNTER.PERIOD (cnt)

Returns the period of time between 2 successive pulses recorded by the counter.

The value returned is expressed in uS (micro seconds).

‘cnt’ identify the counter and can be 1 or 2

It is associated with the commands COUNTER.SETUP, COUNTER.RESET

DATEUNIX(date$)

Converts a date in format dd/mm/yy into UNIX FORMAT.

See also TIMEUNIX, and the complementary UNIXDATE$ and UNIXTIME$

DHT.TEMP

Returns the temperature of the DHT sensor set with "DHT.SETUP"

The syntax is temp = DHT.TEMP

Returns the temperature in °C

DHT.HUM

Returns the humidity of the DHT sensor set with "DHT.SETUP"

The syntax is hum = DHT.HUM

Returns the humidity in %

DHT.HEATINDEX

Returns the heat index of the DHT sensor set with "DHT.SETUP"

The syntax is heat = DHT.HEATINDEX

Returns the heatindex in °C

DISTANCE(pin_trig, pin_echo)

Using a HC-SR04 ultrasonic sensor, this function returns the distance in cm to a target. The range is approximately from 3 cm to 3 meters.

‘pin_trig’ and ‘pin_echo’ define the pins where the HC-SR04 module is connected.

EMAIL from$, to$, subject$, message$

Send an e-mail and returns the status of the sending.

The program will stop the execution until the message is sent or an error occurred.

The result will be 1 if OK or 0 is a problem happend.

‘from$’ is the email address of the sender (ex: from_me@yahoo.com)

‘to$’’ is the email address of the receiver  (ex: to_you@yahoo.com)

‘subject$’ is the subject of the message

‘message$’ is the content of the message

The sender and receiver must be a valid email addresses.

Example :

r = EMAIL ("from_me@yahoo.com", "to_you@gmail.com", "Important message " + date$,  "The memory available is " + str$(ramfree) )

ESPNOW.ADD_PEER(MAC_add$)

Add a peer (module)  to the ‘receiver’ list.

The peer is specified by its MAC address

Returns 0 if OK or another number in case of error

ESPNOW.BEGIN

Starts the ESP-NOW communications.

Returns 0 if OK or another number in case of error

ESPNOW.DEL_PEER(MAC_add$)

Delete a peer (module)  from the ‘receiver’ list.

The peer is specified by its MAC address (MAC_add$)

Returns 0 if OK or another number in case of error

ESPNOW.STOP

Stops the ESP-NOW communications.

Returns 0 if OK or another number in case of error

ESPNOW.WRITE( msg$)

write a message to the peers defined in the list

The message ‘msg$’ must be less than 250 characters.

Returns 0 if OK or another number in case of error

ESPNOW.WRITE( msg$,MAC_add$)

write a message to a specific peer defined by its MAC address (MAC_add$)

The message ‘msg$’ must be less than 250 characters.

Returns 0 if OK or another number in case of error

EXP(number)

Returns the exponential value of 'number'.

FIX(number)

Truncate a number to a whole number by eliminating the decimal point and all characters to the right of the decimal point.

For example :

     7.11 will return 7

     7.85 will return 7

      -2.11 will return -2

     -2.75 will return -2

The major difference between FIX and INT is that FIX provides a true integer function (ie, does not return the next lower number for negative numbers as INT() does).

See also INT() and CINT() .

FILE.DELETE(filename$)

Delete the file specified by ‘filename$’.

Returns 1 if the delete was successful, otherwise returns 0

FILE.EXISTS(filename$)

Returns 1 if the file ‘filename$’ exists, otherwise returns 0

FILE.SIZE(filename$)

Returns the size of the file (in bytes) if the file exist, otherwise returns -1

FLASHFREE

Returns the free disk memory available (number of bytes)

FUSION.ANGLE(axis)

Returns the angles (in degrees) calculated by the FUSION algorithm.

The returned value is :

AXIS

RETURNED INFORMATION

1

PITCH

2

ROLL

3

YAW

INSTR([start], string$, pattern$)

Returns the position at which 'pattern$’ is located into ‘string$’, starting from (optional) start.

‘start’ can also be a negative number. In this case the pattern will be searched from the end of the string.

The function returns 0 if pattern$ is not found

I2C.LEN

Returns the number of bytes available for retrieval with I2C.READ. This should be called on a master device after a call to I2C.REQFROM.

Example:

Len = I2C.LEN

I2C.READ

Reads a byte that was transmitted from a slave device to a master after a call to I2C.REQFROM.

Example:

b = I2C.READ

I2C.READREGBYTE (i2c_address, register)

Read a byte from a slave device using a given device register address.

‘i2c_address’ define the I2C slave address

‘register’ defines the device register

 

Example:

i2c_addr = &h60 : register = 33

value = I2C.ReadRegByte i2c_addr , register

Will read the value of the register address 33 on the device with i2c address &h60.

 

For clarification, this command is equivalent to the following program:

  i2c.begin i2c_addr

  I2c.write register

  i2c.end 

  i2c.reqfrom i2c_addr, 1

  value = i2c.read

  I2c.end

 

TBD : the syntax must be conformed to the other functions (using parenthesis)

I2C.END

Ends a transmission to a slave device that was begun by I2C.BEGIN and transmits the bytes that were queued by I2C.WRITE.

It  returns a value indicating the status of the transmission:

0:success

1:data too long to fit in transmit buffer

2:received NACK on transmit of address

3:received NACK on transmit of data

4:other error

 

Example:

stat = I2C.END

INT(number)

Truncate an expression to the next whole number less than or equal to the argument.

For example :

     7.11 will return 7

     7.85 will return 7

      -2.11 will return -3

     -2.75 will return -3

The FIX() function provides a true integer function.

See also FIX() and CINT() .

LEN(string$)

Returns the length of the string ‘string$’

LOG(number)

Returns the natural logarithm of the argument 'number'

MILLIS

Returns the number of milliseconds passed from the start-up of the module

MQTT.Setup(server$ [,port])

Setup the MQTT communications.

Server$ is the MQTT server address

Port is the MQTT port; if not defined defaults to 1883

Returns 1 if successful or 0 if there is a  problem.

MQTT.Connect(login$, pass$, [id$])

Connect to the server using the provided login and password.

Optionally ID$ permits to define an arbitrary ID

Returns 1 if successful or 0 if there is a  problem.

MQTT.Connect("", "", [id$])

Connect to the server without identification

Optionally ID$ permits to define an arbitrary ID

Returns 1 if successful or 0 if there is a  problem.

MQTT.Disconnect()

Disconnects from the MQTT server

Returns 1 if successful or 0 if there is a  problem.

MQTT.Publish(topic$, message$)

Publish a string message in the specified topic

Returns 1 if successful or 0 if there is a  problem.

MQTT.Subscribe(topic$ [,Qos])

Subscribes to messages published to the specified topic.

Qos can be 0 or 1; if not defined defaults to 0

Returns 1 if successful or 0 if there is a  problem.

MQTT.UnSubscribe(topic$)

Unsubscribes from the specified topic

Returns 1 if successful or 0 if there is a  problem.

MQTT.Connected()

Returns the current connection status.

Returns 1 if connected or 0 if disconnected

NEO.GETPIXEL(pos)

Gets, in a stripline, the merged color value of the led at position 'led_pos'

NEO.RGB(R, G, B)

Returns the 3 supplied R,G,B colours merged into a single 32bit RGB color value, useful for the NEO.PIXEL function and web page colors

PI

Returns the value 3.1415925….

PID1.COMPUTE( current_value, target_value)

Returns the computed value of the given PID controller.

The ‘target_value’ is desired output value while ‘current_value’ is the value coming from the sensor.

This function must be called regularly in a loop

As there are 4 PID controllers, the prefix can be PID1, PID2, PID3 or PID4.

[25] PIN(pin_number)

Returns the value of any external I/O pin.

The pin_number refers to GPIO and can be from 0 ... 5 or 12 ...15

The value returned is 0 if the pin is LOW and 1 if the pin is HIGH

PIN.TOUCH(pin_number)

Returns the touch value for the pin ‘pin_number’.

‘Pin_number’ can be 0, 2, 4, 12, 13, 14, 15, 27 32, 33.

The value returned is around 70 when not touched and around 15 when touched.

PING(host$)

The ping function can be used to test the ability of the ESP8266 to reach a specified destination computer. The ping command is usually used as a simple way verify that a computer can communicate over the network with another computer or network device.

‘host$’ is the remote address to ping. Can be also an IP address.

Returns 1 if the remote host is reachable, otherwise 0

Example:

Print PING("www.google.com")

Print PING("192.168.1.1")

Important:

This function doesn’t works in immediate mode.

POW(x, y)

Return the number x raised to the power of y

RAMFREE

Returns the free ram available (number of bytes)

RND(number)

Returns a random number in the range from 0 to ‘number'

SERIAL.LEN

Returns the number of chars available in the receive buffer of the serial port

SERIAL2.LEN

Returns the number of chars available in the receive buffer of the serial port #2

SGN(number)

Returns the sign of the argument 'number', +1 for positive numbers, 0 for 0, and -1 for negative numbers.

SIN(number)

Returns the sine of the argument 'number' in radians.

SPI.BYTE(byte)

Write and receive a byte on the SPI bus.

Send the content of ‘byte’ and returns the byte received

Example:

r = SPI.BYTE(&haa)

SQR(number)

Return the square root of the argument ‘number’

TAN(number)

Returns the tangent of the argument 'number' in radians.

TFT.RGB(r,g,b)

Returns a 16 bit number representing the RGB565 conversion of a color specified with 8 bit resolution.

‘r’  is the red component; must be in the range 0 to 255

‘g’  is the green component; must be in the range 0 to 255

‘b’  is the blue component; must be in the range 0 to 255

 

Example :

TFT.FILL TFT.RGB(0,255,0)  ‘ fill the screen with a full green color

TIMEUNIX(time$)

Converts a time in format hh:mm:ss into UNIX FORMAT.

See also DATEUNIX, and the complementary UNIXTIME$ and UNIXDATE$

TM1638.BUTTONS

Returns the state of the 8 buttons installed on the module TM1638.

It returns an 8-bits value where each bit is associated with a button

Example :

Print TM1638.BUTTONS  ‘print 1 if the button 1 is pressed

TOUCH.X

Returns the X position of the touched position on the TFT screen.

Useful in combination with the function TOUCH.Y and the command ONTOUCH

TOUCH.Y

Returns the X position of the touched position on the TFT screen.

Useful in combination with the function TOUCH.X and the command ONTOUCH

VAL(string$)

Returns the supplied string into a numeric value.

Example :

a$ = “12.34”

b = val(a$)

The same function can also be used to convert from HEX :

a$ = "&HFF01"

b = val(a$)

WIFI.CHANNEL

Returns the current radio channel used for the WIFI communication.

Can be a number from 1 to 13

WIFI.MODE

Return the current mode of the WIFI connection.

The returned value is:

 

VALUE

MEANING

0

The WIFI is in sleep mode

1

The WIFI is in STATION mode

2

The WIFI is in AP mode

WIFI.NETWORKS  ( network$ )

Returns the number of networks found after the command WIFI.SCAN.

The returned value is :

            -2 if the scan is not started

            -1 if the scan is not terminated

            or the number of networks found (can be 0 if none)

The variable ‘network$’ will contain the list of any networks found.

‘network$’ will contains a line for each network with the SSID, the BSSID and the RSSI separated by comma (,).

 

Example :

WIFI.SCAN

While WIFI.NETWORKS(A$) = -1

Wend

Print a$

 

The result will be :

Vodaphone, 00:50:56:C0:00:08, -50

Orange, 00:50:56:C0:32:07, -70

Xxxx,  00:50:56:C0:86:CA,-78

WIFI.STATUS

Returns the status of the WIFI connection.

The returned value is :

VALUE

MEANING

0

IDLE

1

NO SSID AVAILABLE

2

SCAN COMPLETED

3

CONNECTED

4

CONNECTION FAILED

5

CONNECTION LOST

6

DISCONNECTED

255

OFF

WORD.COUNT( string$ [,delimiter$])

This function returns the number of the words in the string.

The string delimiter is optional; when it is not used, the space character is the delimiter.

Example :

a$ = "abc def ghi ijk"

Print WORD.COUNT(a$)  ‘ will print 4

b$ = "the-!-quick-!-brown-!-fox-!-jumps-!-over"

Print WORD.COUNT(b$ "-!-") ‘ will print 6

See also WORD$, WORD.DELETE$ and WORD.FIND.

WORD.FIND( string$, find$ [,delimiter$])

This function returns the word position in the string.

The string delimiter is optional; when it is not used, the space character is the delimiter.

If the word is not found, the result is 0.

Example :

a$ = "abc def ghi ijk"

Print WORD.FIND(a$, "ghi")  ‘ will print 3

b$ = "the-!-quick-!-brown-!-fox-!-jumps-!-over"

Print WORD.FIND(b$, "fox", "-!-") ‘ will print 4

See also WORD$, WORD.DELETE$ and WORD.COUNT.

 

STRING FUNCTIONS

BAS.ERRMSG$

Return a string representing the error message that would have normally been displayed on the console. It is reset to “No Error” running the program or with the command ONERROR CLEAR or ONERROR IGNORE or ONERROR SKIP.

BAS.FILENAME$

Returns the name of the current basic file

BAS.FTP$( host$, login$, password$, file$, folder$)

Transfer a file stored locally on an FTP server.

Returns an explicit text message as the result of the operation.

host$ is the address of the FTP server

login$ is the login of the account on the FTP server

password$ is the password of the account on the FTP server

file$ is the file that will be sent

folder$ is the folder where the file will be sent

BAS.PASSWORD$

Returns the password used for the STATION wifi connection.

 

BAS.RTCMEM$

Returns the content of the CPU RTC internal memory.

This memory maintains the content between reset so it is useful in association with the SLEEP command when the module goes in low power mode.

This memory is limited at 512 bytes and can be set with the corresponding command  BAS.RCTMEM$ = “xxx”.

BAS.SSID$

Returns the login used for the STATION wifi connection.

BAS.VER$

Returns the version of the Basic in string format

Example:

Print BAS.VER$

Annex WI-Fi Basic 1.36 beta

BIN$(number)

Returns the Binary representation of the argument ‘number’.

The number is converted to integer before the conversion.

BUTTON$(name$, label [, id] )

Returns a string containing the html representation of a button.

‘name$’ represent the text shown in the button,

‘label’ is the GOSUB label where it will branch to when clicked,

‘id’ is an optional argument that can be used to define the ID of the object (useful to style it with CSS).

The function called when clicking on the button must always terminate with the RETURN command

Check the chapter about html objects for more details

CHECKBOX$( variable [,id])

Returns a string containing the html representation of a checkbox.

‘variable’ represent the variable associated with the checkbox; changing the value of the variable in the basic code will change also the value in the html and vice-versa (0 = unchecked, 1 = checked).

The variable must be Numerical.

‘id’ is an optional argument and can be used to define the ID of the object (useful to style it with CSS).

When the value is changed by the user, the event ‘onHtmlChange’ is triggered.

Check the chapter about html objects for more details

CHR$(number)

Returns a string containing the ASCII character with the code ‘number’

Example: z$ = CHR$(64)

now z$ contains the "@" character

number must be between 0-255

CSSID$(object_id, object_style)

Returns a string containing the css representation of style defined for a given object.

‘object_id’ represent the ID of the object to be styled.

‘object _style’ represent the property to be given to the object.

Check the chapter about html objects for more details

DATE$[(format)]

Returns the actual date with the format dd/mm/yy

The time takes into account the Time Zone parameter defined into the "Config" page.

If ‘format’ is specified, the format can be :

format = 1  => American format  M/D/Y

format = 2 => Canadian format Y/M/D

ESPNOW.ERROR$

Returns the MAC address of the device(s) that didn’t received the message

ESPNOW.READ$

Returns the message received from the ESP-NOW peer

ESPNOW.REMOTE$

Returns the MAC address of the emitter of the message received

FILE.DIR$[(path$)]

Will search for files and return the names of entries found.

 'path$' represent the directory name.

 'path$' can include wildcards characters as ‘*’, ‘.’ and ‘?’

The function will return the first entry found.

To retrieve subsequent entries use the function with no arguments. ie, DIR$.

The return of an empty string indicates that there are no more entries to retrieve.

Example, to get all the files present in the directory /html :

d$ = FILE.DIR$("/html")

While D$ <> ""

  Print d$

  d$ = FILE.DIR$

Wend

Valid wildcard expressions are :

d$ = FILE.DIR$(“/html/ex*.html”)  ‘ returns all the files starting with the “ex”

d$ = FILE.DIR$(“/html/list.*”)  ‘ returns all the files named list.xxx

FILE.READ$(filename$,[line_num] | [start, length])

Returns the content of the file ‘filename$’.

Specifying 'line_num', only the corresponding line is read from the file.

If start and length options are specified, the file is read from the ‘start’ position for ‘length’ characters, otherwise the complete file is read in one go.

HEX$(number)

Returns the Hexadecimal representation of the argument ‘number’

The number is converted to integer before the conversion.

HtmlEventButton$

returns the name of the button that generate the jump.

Useful to manage several buttons in the same function

HtmlEventVar$

Returns the name of the variable changed during the event onHtmlChange.

Useful to determine the object that changed its value

IMAGE$(path [,id])

Returns a string containing the html representation of an image.

‘Path’ represent the url of the image; it can be local or from internet.

‘id’ is an optional argument and can be used to define the ID of the object (useful to style it with CSS)

Check the chapter about html objects for more details

IMAGEBUTTON$(path, label [,id])

Returns a string containing the html representation of an image that can be clicked as a button.

‘Path’ represent the url of the image; it can be local or from internet.

‘label’ is the GOSUB label where it will branch to when clicked,

‘id’ is an optional argument and can be used to define the ID of the object (useful to style it with CSS)

The function called when clicking on the image must always terminate with the RETURN command

Check the chapter about html objects for more details

IP$

Returns the local IP address, the Subnet mask and the Gateway address separated by space.

Example:

Print IP$ ‘print the complete address separated by single space

192.168.1.45 255.255.255.0 192.168.1.1

Print WORD$(IP$,1) ‘ will print only the IP

192.168.1.45

IR.GET$[ (param) ]

Returns the code received by the IR receiver.

In function of the param value, the function returns :

 

PARAM

RETURNED VALUE

0 or missing

Hexadecimal code

1

Decode type

2

Address

3

Command

4

Bits

5

Repeat

 

Must be used in association with the command IR.INIT and ONINFRARED

Example

IR.GET$ ‘ will print the HEX code received

JSON$(string$, field$)

Will parse a json string for a named data element within it.

It the element is found, its value is returned in String format else the text "not found".

The key can have the following syntax :

"Key.subkey.innerkey….." .

 Array can also be included such as "weather[5].description"

LCASE$(string$)

Returns ‘string$’ converted to lowercase characters

LED$(variable [,id])

Returns a string containing the html representation of a led.

‘variable’ represent the variable associated with the led; changing the value of the variable in the basic code will change the led from red (0) to green ( any value not equal to 0).

The variable must be Numerical.

‘id’ is an optional argument and can be used to define the ID of the object (useful to style it with CSS)

Check the chapter about html objects for more details

LEFT$(string$, num)

Returns the leftmost ‘num’ characters of ‘string$’

LISTBOX$(variable$, "option1, option2, option3, ..." [, height]  [,id])

Returns a string containing the html representation of a listbox / combobox.

‘variable$’ represent the variable associated with the listbox;

changing the value of the variable in the basic code will change also the value in the html and vice-versa. The variable must be String.

‘option1’, ‘option2’, …. represent the content of the listbox.

‘height’ is an optional parameter and define the height of the listbox; if not defined, the object will be a combobox

‘id’ is an optional argument and can be used to define the ID of the object (useful to style it with CSS).

When the value is changed by the user, the event ‘onHtmlChange’ is triggered.

Check the chapter about html objects for more details

MAC$[ (id) ]

Returns the active MAC address. It consists of 6 hex bytes separated by colon.

It must be noted that the MAC address can be different if the module is connected in Station mode or in AP mode.

Example:

Print MAC$

62:01:94:5E:37:8D

 

Optionally it is possible to select the address to be shown using the argument ‘id’

Example :

Print MAC$(0)  ‘ print the Station mode address

60:01:94:5E:37:8D

Print MAC$(1) ‘ print the AP mode address

62:01:94:5E:37:8D

[26] METER$(variable, min, max [,id])

Returns a string containing the html representation of a meter.

‘variable’ represent the variable associated with the slider; changing the value of the variable in the basic code will change the value in the html.

The variable must be Numerical.

‘min’ and max represent the minimum and maximum value of the meter.

‘id’ is an optional argument and can be used to define the ID of the object (useful to style it with CSS)

Check the chapter about html objects for more details

MID$(string$, start [,num])

Returns a substring of ‘string$’ starting from ‘start’ with a length of ‘num’ characters. If ‘num’ is not defined, the result will continue until the end of the line

Start must be integer starting at 1

example:

z$="Hello World"

wlog mid$(z$,4,5) ‘will print "lo Wo"

MQTT.Message$

Returns the MQTT message received

MQTT.Topic$

Returns the MQTT topic received

OCT$(number)

Returns the Octal representation of the argument ‘number’

The number is converted to integer before the conversion.

PASSWORD$(variable [, id] )

Returns a string containing the html representation of a password textbox..

‘variable’ represent the variable associated with the textbox; changing the value of the variable in the basic code will change also the value in the html and vice-versa. The variable can be Numerical or String.

‘id’ is an optional argument and can be used to define the ID of the object (useful to style it with CSS)

Check the chapter about html objects for more details

REPLACE$(expression$, find$, replacewith$)

Returns a substring of ‘expression$’ where any instances of the text inside ‘find$’ is replaced with ‘replacewith$’

RIGHT$(string$, num)

Returns the rightmost ‘num’ characters of ‘string$’

RTC.DATE$[(format)]

Returns the RTC module date with the format dd/mm/yy

The module can be DS1307 or DS3231

If ‘format’ is specified, the format can be :

format = 1  => American format  M/D/Y

format = 2 => Canadian format Y/M/D

See also the RTC.SETTIME and RTC.TIME$

NOTE : If no RTC is connected, (or is not connected correctly) then will return "165/165/165"

RTC.TIME$

Returns the RTC module time with the format hh:mm:ss.

The module can be DS1307 or DS3231

See also the RTC.SETTIME and RTC.DATE$

NOTE : If no RTC is connected, (or is not connected correctly) then will return "45:165:165"

SERIAL.CHR$

Returns the first character present in the input buffer of the serial port

Useful in association with the command ONSERIAL

SERIAL.INPUT$

Returns all the characters present in the input buffer of the serial port.

Useful in association with the command ONSERIAL

SERIAL2.CHR$

Returns the first character present in the input buffer of the serial port #2

Useful in association with the command ONSERIAL

SERIAL2.INPUT$

Returns all the characters present in the input buffer of the serial port #2

Useful in association with the command ONSERIAL2

SLIDER$(variable, min, max [,step] [,id])
 

Returns a string containing the html representation of a slider.

‘variable’ represent the variable associated with the slider; changing the value of the variable in the basic code will change also the value in the html and vice-versa. The variable must be Numerical.

‘Min’ and max represent the minimum and maximum value of the slider.

The optional argument ‘step’ represent the minimal increment (by default the value is 1).

‘id’ is an optional argument and can be used to define the ID of the object (useful to style it with CSS).

When the value is changed by the user, the event ‘onHtmlChange’ is triggered.

Check the chapter about html objects for more details

SPACE$(number)

Returns a string consisting of the specified number of spaces.

SPI.STRING$(data$, len)

Write and receive a string on the SPI bus.

Write the content of ‘len’ characters of the string ‘data$’

Example:

a$ = SPI.STRING("hello", 5)

SPI.HEX$(datahex$, len)

Write and receive an HEX string on the SPI bus.

The string is a sequence of hex characters (2 for each byte)

Write the content of ‘len’ characters of the string ‘data$’

Example:

a$ = SPI.HEX("A0B1C2D3E4F5", 6) ‘ send 6 bytes (sequence of A0, B1, C2, D3, E4, F5) and receive the result in a$

STR$ (number [,format$ [,toint]])

Returns the argument ‘‘number’ converted to string format.

 

The optional ‘format$’ permit to define how the number is printed.

The format is based on ‘C’ printf command.

The last optional format ‘toint’, if =1,  permit to convert the number in integer format. This is useful to convert the number in integer format.

Example :

a = 12.34567890

Print STR$(a, "%2.4f")  ‘ will print 12.3456

Print STR$(a, "%3.5f")  ‘ will print  12.34567

 

a = 255

Print STR$(a, "%04x", 1)  ‘ will print 00FF  ‘HEX

Print STR$(a, "%04o", 1)  ‘ will print 0377  ‘OCT

 

The formats available are :

 

FORMAT

DESCRIPTION

TYPE

b

Binary

Integer

c

Char

Integer

d

Signed Integer

Integer

e

Exponential

Float

f

Floating Point

Float

g

Use shorter of the two formats

f or e

Float

o

Octal

Integer

p

Pointer (8 digits hex)

Integer

P

Pointer without 0x

Integer

u

Unsigned Integer

Integer

x

Hexadecimal (lower case letters)

Integer

X

Hexadecimal (upper case letters)

Integer

 

The format must observe the following rule :

 

%[integer_with][.][precision][format]

 

For example to specify a floating number composed of 4 digits before the decimal point and 3 digit after the point you must write : %4.3f

 

Example for several formats

 

Format

Number

Result

 

%2.1f

14.33

14.3

28.128

28.1

 

%4.3f

15

  15.000

4152.3751

4152.375

 

%1.4e

128

1.2800e+02

12852

1.2852e+02

%04f

12

0012

%4x

255

  ff

%04X

255

00FF

STRING$(num, char$)

Returns a string ‘num’ chars long composed of the char ‘char$’ - char$ can also be a string of chars, eg: "<BR>" or "&nbsp;"

TEMPR$(pin_number [,ID])

Returns information from the DS18B20 temperature sensor

 

The syntax is a$ = TEMPR$(pin_number [, ID])

 

The ‘pin number’ is any available pin of the device; it can change between calls permitting to use several pins at the same time.

The ID can be a number, a String or not specified:

- If is a number (say 'n'), the result will be the temperature (in °C) of the nth device connected on that pin

- If is a string, it must contains the Hex address of the device requested; this address can be recovered using the command without this argument

- If not specified, the result will be the address list of the devices connected on the pin (blocks of 8 bytes separated by ',')

Example using 2 DS18B20 are connected on the pin 12 :

Print TEMPR$(12,1) ‘ will print 20.5

Print TEMPR$(12,2) ‘ will print 22.3

 

Print TEMPR(12) ‘will print 28ff5bdb701604f0,28ff5bdb7016045

 

Print TEMPR(12,"28ff5bdb701604f0") ‘will print 20.5

TEXTBOX$(variable [, id] )

Returns a string containing the html representation of a textbox.

‘variable’ represent the variable associated with the textbox;

changing the value of the variable in the basic code will change also the value in the html and vice-versa. The variable can be Numerical or String.

‘id’ is an optional argument and can be used to define the ID of the object (useful to style it with CSS).

When the value is changed by the user, the event ‘onHtmlChange’ is triggered.

Check the chapter about html objects for more details

TRIM$(string$)

Returns ‘string$’ with the leading and trailing spaces removed

TIME$

Returns the actual time with the format hh:mm:ss.

The time takes into account the Time Zone parameter defined into the "Config" page.

UCASE$(string$)

Returns ‘string$’ converted to uppercase characters

UDP.READ$

Returns the UDP message received or an empty string if no message received.

Useful in association with the command ONUDP

UDP.REMOTE$

Returns the IP address and the port of the sender of the message received.  The format is IP:port  (example 192.168.1.88:5541).

Useful in association with the command ONUDP

UNIXDATE$(value [,format])

Returns a date with the format dd/mm/yy extract from ‘value’ given in UNIX format. The value can be Numerical or String.

This is useful to extract the date from the JSON string given by OpenWeatherApi

if ‘format’ is specified, the format can be :

format = 1  => American format  M/D/Y

format = 2 => Canadian format Y/M/D

See also the complementary DATEUNIX()

UNIXTIME$(value)

Returns a time with the format hh:mm:ss extract from ‘value’ given in UNIX format. The value can be Numerical or String.

This is useful to extract the time from the JSON string given by OpenWeatherApi

See also the complementary TIMEUNIX()

URLMSGGET$ ([arg$])

Get the message received from the URL AJAX GET request.

Returns the value of the url argument defined in arg$.

If arg$ is missing, all the arguments are returned (useful for debugging).

Useful in combination with ONURLMESSAGE and URLMSGRETURN

Example : if a remote client makes the following url request :

http://esp_local_ip/msg?red=10&green=20&blue=30

Print URLMSGGET$("red")     ‘ will return 10

Print URLMSGGET$("green")   ‘ will return 20

Print URLMSGGET$("blue")    ‘ will return 30

Print URLMSGGET$() ‘ will return  red=10&green=20&blue=30

More information here

WGET$( http_server$, port [,header] )

Returns the result of a GET server request.

‘http_server$’ is the server url request

‘port’ is the port number; if port=443, the connection will be done using SSL (secure).

‘Header’, if =1, will include the header in the answer (useful for debug)

The program will stop waiting for the answer.

Example :

print WGET$("www.fakeresponse.com/api/?sleep=5", 80)

In this case the program will stop 5 seconds waiting for the answer of the server.

See the command WGETASYNC to avoid this limitation.

WGETRESULT$

Return the message received asynchronously from the command WGETASYNC

WORD$(string$, position [,delimiter$])

This function returns the nth word in the string, where n=1 or greater.

The string delimiter is optional; when it is not used, the space character is the delimiter.

Example :

a$ = "abc def ghi ijk"

Print WORD$(a$, 3)  ‘ will print ghi

b$ = "the-!-quick-!-brown-!-fox"

Print WORD$(b$, 2, "-!-") ‘ will print quick

See also WORD.COUNT, WORD.FIND and WORD.DELETE$

WORD.DELETE$(string$, position [delimiter$])

This function returns a string where the nth word has been deleted.

The string delimiter is optional; when it is not used, the space character is the delimiter.

Example :

a$ = "abc def ghi ijk"

Print WORD.DELETE$(a$, 3)  ‘ will print abc def ijlk

b$ = "the-!-quick-!-brown-!-fox"

Print WORD.DELETE$(b$, 2, "-!-") ‘ will print the-!-brown-!-fox

See also WORD, WORD.COUNT and WORD.FIND.

WORD.EXTRACT$(string$, lead$, trail$)

Returns the substring included between lead$ and trail$.

Example

a$ = “https://www.google.com/test

Print WORD.EXTRACT$(a$, “https://”, “/test”) ‘ will print www.google.com

WORD.GETPARAM$( setting$, parameter$  [,separator$])

Get a parameter from a string containing a series of parameters stored as below:

param1=value1

param2=value2

…….

paramx=valuex

‘setting$’ defines the string containing the set of parameters

‘parameter$’ defines the parameters to be get.

‘separator$’ is an optional parameter specifying a different separator character.

Example, assuming that setting$ contains the parameters :

print WORD.GETPARAM$(setting$, "param2")‘will print value2

 

By default the separator is the character ‘=’.

Useful in combination with WORD.SETPARAM and FILE.READ$

WPOST$(server$, body$, port [,header])

Returns the result of a POST server request.

‘http_server$’ is the server url request

‘body$’ is the field that will be sent in the request

‘port’ is the port number; if port=443, the connection will be done using SSL (secure).

‘Header’, if =1, will include the header in the answer (useful for debug)

The program will stop waiting for the answer.

Example :

print  WPOST$("ptsv2.com/t/annextest/post", "name=Annex&version=1.39", 80)

 

 

COMMANDS:

 

AUTOREFRESH interval

Same function of the command REFRESH but with an automatic interval.

Define the variables refresh interval in milliseconds.

This should never be lower than 300ms due to performances reasons.

NOTE: It must be run after the command CLS at it is managed into the javascript.

BAS.LOAD filename$

Loads another .bas program and run it immediately.

Returns 0 if the successful or -1 if the file was not found

Example:

Print BAS.LOAD "/test.bas"

BAS.RTCMEM$ = val$

Set the content of the CPU RTC internal memory.

This memory maintains the content between reset so it is useful in association with the SLEEP command when the module goes in low power mode.

This memory is limited at 512 bytes and can be read with the corresponding command  val$ = BAS.RCTMEM$

CLS

Clear the html content of the page to all the clients connected by Websockets.

This command is equivalent to TRACE "cls"

 

Check the chapter about html objects for more details

See also the commands TRACE, HTML, JSCALL, JSCRIPT, JSEXTERNAL, CSS and WLOG

CSS style_code$

Send a CSS style code to the page to all the clients connected by Websockets.

This command is equivalent to TRACE "csshtml" + style_code$

 

Check the chapter about html objects for more details

See also the commands TRACE, HTML, JSCALL, JSCRIPT, JSEXTERNAL, CLS and WLOG

COMMAND cmd$

Permit to execute any basic command defined into ‘cmd$’.

It acts as a macro command like the immediate window

Example :

COMMAND ("print sin(PI/2)")  ‘will print 1

COUNTER.RESET cnt

Reset the counter to 0 (count and period).

‘cnt” defines the counter and can be 1 or 2

COUNTER.SETUP cnt, pin [,mode]

Setup a counter in association with a pin.

There are 2 counters that can count the number of pulses or the period between pulses.

‘cnt” defines the counter and can be 1 or 2

‘pin’ defines the pin and can be any valid pin number

‘mode’ defines the when the pulses are taken into account :

 

MODE

EDGE

1

On the RISING edge

2

On the FALLING edge

3

On CHANGE

 

 If not specified, the mode is 3 (on change)

DATA const1 [,const2] ...

Stores numerical and string constants to be accessed by READ.

String constant must be between double quotes "

Expressions can be used for the numerical constants (ex. PI * 2)

DHT.SETUP pin, model

Set the parameters for Temperature / Humidity sensor DHT11, DHT21 or DHT22

The syntax is DHT.SETUP pin, model

The pin number is any available pin of the device;

The model can be 11, 21 or 22 (for DHT11, DHT21 or DHT22)

See also the functions DHT.TEMP, DHT.HUM and DHT.HEATINDEX

EMAIL.SETUP server$, port, user_name$, password$ [, debug]
 

Setup the parameters for an SMTP server to be used to send e-mails.

This command must be executed before using the command EMAIL or EMAILASYNC.

An SMTP account like <mail.smtp2go.com> is required.

NEW : The command rely on a SSL connection so it should work with any SMTP service provider; the port should be 465

‘server$’ is the url of the service provider (ex. mail.smtp2go.com)

‘Port’ is the port required (ex. 465)

‘user_name$’ is the login name of the SMTP account

‘password$’ is the password of the SMTP account

All the parameters are required.

The last optional parameter ‘debug’ if set to 1, enable a debug mode useful to catch connection problems.

Example :

EMAIL.SETUP "mail.smtp2go.com", 465, "my_login", "my_pass"

EMAILASYNC from$, to$, subject$, message$

Send an e-mail in async mode; this means that the request is managed in the background and the program will continue to run without interruptions.

‘from$’ is the email address of the sender (ex: from_me@yahoo.com)

‘to$’’ is the email address of the receiver  (ex: to_you@yahoo.com)

‘subject$’ is the subject of the message

‘message$’ is the content of the message

The sender and receiver must be a valid email addresses.

Example :

EMAILASYNC ("from_me@yahoo.com", "to_you@gmail.com", "Important message " + date$,  "The memory available is " + str$(ramfree) )

FILE.SAVE filename$, content$

Save the content of ‘content$’ in the file ‘filename$[27] .

The file can be read back using the function FILE.READ$(filename$).

File size is only limited by available SPIFFS memory

FUSION.INIT

Initialise the FUSION IMU / AHRS algorithm

FUSION.MADGWICK ax, ay, az, gx, gy, gz

Execute the MADGWICK 6 DOF algo

The input parameters are the following :

 

PARAM

MEANING

UNITY

ax

Acceleration on x axis

g *

ay

Acceleration on y axis

g *

az

Acceleration on z axis

g *

gx

Gyro on x axis

°/sec

gy

Gyro on y axis

°/sec

gz

Gyro on z axis

°/sec

(*) the unit is not really important but must be consistent between the group

This algo utilise the variables FUSION.BETA and FUSION.ZETA

FUSION.MADGWICK ax, ay, az, gx, gy, gz, mx, my, mz

Execute the MADGWICK 9 DOF algo

The input parameters are the following :

 

PARAM

MEANING

UNITY

ax

Acceleration on x axis

g *

ay

Acceleration on y axis

g *

az

Acceleration on z axis

g *

gx

Gyro on x axis

°/sec

gy

Gyro on y axis

°/sec

gz

Gyro on z axis

°/sec

mx

Magnetometer on x axis

milligauss *

my

Magnetometer on y axis

milligauss *

mz

Magnetometer on z axis

milligauss *

(*) the unit is not really important but must be consistent between the group

This algo utilise the variable FUSION.BETA

FUSION.MAHONY ax, ay, az, gx, gy, gz, mx, my, mz

Execute the MAHONY 9 DOF algo

The input parameters are the following :

 

PARAM

MEANING

UNITY

ax

Acceleration on x axis

g *

ay

Acceleration on y axis

g *

az

Acceleration on z axis

g *

gx

Gyro on x axis

°/sec

gy

Gyro on y axis

°/sec

gz

Gyro on z axis

°/sec

mx

Magnetometer on x axis

milligauss *

my

Magnetometer on y axis

milligauss *

mz

Magnetometer on z axis

milligauss *

 

(*) the unit is not really important but must be consistent between the group

This algo utilise the variables FUSION.KP and FUSION.KI

FUSION.BETA =

Set the BETA parameter. This is used for the MADGWICK algo 6 DOF and 9 DOF.

FUSION.ZETA =

Set the ZETA parameter. This is used for the MADGWICK algo 6 DOF.

FUSION.KI =

Set the KI parameter. This is used for the MAHONY algo 9 DOF.

FUSION.KP =

Set the KP parameter. This is used for the MAHONY algo 9 DOF.

HTML code$

Send html content to the page of all the clients connected by Websockets.

This command is equivalent to TRACE "html" + code$

 

Check the chapter about html objects for more details

See also the commands TRACE, CLS, JSCALL, JSCRIPT, JSEXTERNAL, CSS and WLOG

I2C.SETUP sda_pin, scl_pin [,freq [,stretch]]

Initiate the Wire library and join the I2C bus as a master. The ‘sda_pin’ and ‘scl_pin’ define the pins to be used as SDA and SCL signals.

The frequency (up-to 700 Khz) and the stretch timeout can also be defined using the parameters ‘freq’ and ‘stretch’

Example:

I2C.SETUP 21, 22 ‘ define the pin 21 as SDA and the pin 22 as SCL

I2C.BEGIN address

Begin a transmission to the I2C slave device with the given address. Subsequently, queue bytes for transmission with the I2C.WRITE command and transmit them by calling I2C.END command.

‘address’ defines the the 7-bit address of the device to transmit to

Example:

I2C.BEGIN &h57 ‘ begins the transmission on the address hex 57

I2C.END

Ends a transmission to a slave device that was begun by I2C.BEGIN and transmits the bytes that were queued by I2C.WRITE.

Example:

I2C.END

 

It can also returns a value indicating the status of the transmission:

0:success

1:data too long to fit in transmit buffer

2:received NACK on transmit of address

3:received NACK on transmit of data

4:other error

 

Example:

stat = I2C.END

I2C.REQFROM address, length

Used by the master to request bytes from a slave device. The bytes may then be retrieved with the I2C.LEN and I2C.READ functions.

 

‘address’ defines the 7-bit address of the device to request bytes from

‘Length’ defines the number of bytes to request

Example:

I2C.REQFROM &h57, 8 ‘ requests for 8 bytes from the address hex 57

 

I2C.READREGARRAY i2c_address, register, nb_of_bytes, Array()

Read a series of bytes from a slave device using a given device register address.

The result is copied into an array given as argument.

Each received byte will be placed into an element of the array (starting from 0).

The array must be defined before the command with enough space to receive the bytes.

Example :

Dim MyArray(10) : i2c_addr = &h60 : register = 33 : length = 7

I2C.ReadRegArray i2c_addr , register, length , MyArray()

Will read 7 bytes from the register address 33 on the device with i2c address &h60.

The result will be placed into MyArray where MyArray(0) will contain the 1st received byte, MyArray(1) the 2nd, …..

 

For clarification, this command is equivalent to the following program:

 

  i2c.begin i2c_addr

  i2c.write register

  i2c.end 

  i2c.reqfrom i2c_addr, length

  for i = 0 to length - 1

    MyArray(i) = i2c.read

  next i

  i2c.end

I2C.WRITE value

Writes queues bytes for transmission from a master to slave device (in-between calls to I2C.BEGIN and I2C.END).

 

‘value’ represents a value to send as a single byte

Example:

I2X.WRITE &h55

I2C.WRITEREGBYTE i2c_address,register, value

Write a byte to a slave device using a given device register address.

‘i2c_address’ define the I2C slave address

‘register’ defines the device register

‘value’ defines the value to be written into the device

Example:

i2c_addr = &h60 : register = 33 : value = 55

I2C.WriteRegByte i2c_addr , register, value

Will write 55 in the register address 33 on the device with i2c address &h60.

 

For clarification, this command is equivalent to the following program:

 

  i2c.begin i2c_addr

  I2c.write register

  i2c.write value

  i2c.end 

I2C.WRITEREGARRAY i2c_address, register, nb_of_bytes, Array()
 

Write a series of bytes to a slave device using a given device register address.

The values to be written are taken from an array given as argument.

Each byte must be placed into an element of the array (starting from 0).

The array must be defined before the command and set with the desired byte sequence to be sent

Example :

Dim MyArray(10) : MyArray(0) = 12 : MyArray(1) = 34 : MyArray(2) = 56

i2c_addr = &h60 : register = 33 : length = 3

I2C.WriteRegArray i2c_addr , register, length , MyArray()

Will write 3 bytes to the register address 33 on the device with i2c address &h60.

The sequence 12, 34, 56 will be written to the device

 

For clarification, this command is equivalent to the following program:

 

  i2c.begin i2c_addr

  i2c.write register

  for i = 0 to length - 1

    i2c.write MyArray(i)

  next i

  i2c.end

INPUT.TIMEOUT timeout

Define the time (in milliseconds) that the INPUT command will wait for an input from the serial port (console). After this time the INPUT will return an empty value.

INPUT.TIMEOUT 0 remove the timeout

INPUT["prompt$";] variable
 

Allows input from the console to a variables.

The input command will prompt with a question mark (?).

If the "prompt string$" is specified it will be printed before the question mark.

During the input command the execution of the program will be stopped waiting for an input from the serial port. This can be an issue as the program can stuck.

The command INPUT.TIMEOUT will permit to interrupt the command after a given timeout time.

INTERRUPT pin_no, {OFF | label}

Specify a branch label for the interrupt to jump to when the designated input pin signal changes.

‘Pin_no’ defines the input pin - can be from 0 to 39

‘Label’ is the branch label where it will jump to ;

 putting OFF instead of the label will remove the interrupt

Example

INTERRUPT 5, pin5_change

IR.INIT pin_rx | OFF [, pin_tx]

Initialise the IR receiver and the IR transmitter

‘pin_rx’ is the pin where the IR receiver is connected

‘pin_tx’ is the pin where the IR led is connected

 

If ‘pin_rx’ is OFF, the receiver is disabled

If ‘pin_tx’ is not defined, the transmitter is disabled

Example :

IR.INIT 14, 12 ‘define the pin 14 for the receiver and the pin 12 for the transmitter

IR.SEND type, code$, bits

Send a code via the IR transmitter

‘type’ is the type of RC (3 = NEC, ...)

‘code$’ is the code in hexadecimal format

‘bits’ is the number of bits (32, ...)

JSCALL javaCode$

Send javascript content to the page of all the clients connected by Websockets.

This command is equivalent to TRACE "JSCALL:" + javaCode$

 

Check the chapter about html objects for more details

See also the commands TRACE, CLS, HTML, JSCRIPT, JSEXTERNAL, CSS and WLOG

JSCRIPT script$

Execute a javascript content in the page of all the clients connected by Websockets.

This command is equivalent to TRACE "jscript" + script$

 

Check the chapter about html objects for more details

See also the commands TRACE, CLS, HTML, JSCALL, JSEXTERNAL, CSS and WLOG

JSEXTERNAL file$

Define an external javascript file to be used in the page of all the clients connected by Websockets.

This command is equivalent to TRACE "extjs" + file$

 

Check the chapter about html objects for more details

See also the commands TRACE, CLS, HTML, JSCALL, JSCRIPT, CSS and WLOG

LCD.INIT address, cols, rows

Initialize a LCD display connected using I2C to the module.

‘address’ is the I2C slave address of the LCD display

‘cols’ is the number of columns of the LCD display

‘rows’ is the number of rows of the LCD display

 

Before using it, the I2C bus must be initialised with the command I2C.SETUP

 

Example:

I2C.SETUP 4,5 ‘init the I2C on pins 4 and 5

LCD.INIT 63, 20, 4  ‘init the LCD at I2C address 63 with 20 columns and 4 rows

LCD.PRINT 1,1 "HELLO WORLD"

LCD.CLS

Clear the content of the LCD display connected using I2C to the module

LCD.PRINT x, y, text$

Print a text on the LCD.

‘x’ and ‘y’ define the position where ‘text$’ will be printed

LOCAL var1 [,var2], ...

Defines local variables inside user named subroutines.

Using this command inside the subroutines, permit to create variables that exists only during the routine; they will vanish at the end of the routine. This will permit also to avoid to modify unintentionally variables with the same name that are already used elsewhere in the code.

See the paragraph "Scope of the variables" for more details.

Example:

  LOCAL I, A$

MAXDISPLAY.SETUP CS_pin

Setup a 8 digit 7-segments display based on the chip MAX7219.

The display must be connected using the SPI bus plus a CS_pin.

‘CS_pin’ defines the pin used for the CS signal

Example:

MAXDISPLAY.SETUP 15

MAXDISPLAY.PRINT msg$ [,‘brightness]

Print a message on the 8 digit 7-segments MAX7219 display.

All ASCII characters can be used but will be shown within the limitation of the 7 segments of the display.

‘msg$’ defines the message to be printed

‘brightness” defines the luminosity of the display from 0 (blank) to 15 (max)

By default the luminosity is at 15

MAXSCROLL.SETUP nb_devices, CS_pin

Setup a DotMatrix chain display based on the chip MAX7219.

The chain can be composed by one or more modules in daisy chain.

The display must be connected using the SPI bus plus a CS_pin.

‘Nb_devices’ defines how many modules are connected

‘CS_pin’ defines the pin used for the CS signal

Example for a 4 digit module available on ebay :

MAXSCROLL.SETUP 4, 15  ‘ 4 digits, CS on pin 15

MAXSCROLL.PRINT msg$

Print a message on the DotMatrix Display.

The message will be shown using the command MAXSCROLL.SCROLL

‘msg$’ defines the message to be shown

MAXSCROLL.NEXT msg$

Define the message that will be shown on the DotMatrix Display as soon as the message set with the command MAXSCROLL.PRINT is terminated.

Permit to maintains a continuity on the message shown.

‘msg$’ defines the message that will be printed

MAXSCROLL.TEXT msg$

Set a new message without resetting the message at the initial position.

Useful to modify the message while it’s already scrolling.

‘msg$’ defines the new message to be shown

MAXSCROLL.SHOW pos [, brightness]

Show in a given position the message defined with the command MAXSCROLL.PRINT or the command MAXSCROLL.NEXT

‘Pos’ define the position of the message (in pixels)

‘brightness” defines the luminosity of the display from 0 (blank) to 15 (max)

The position 1 if the rightmost line of the display and increasing this value will move the text more on the left. Decrementing (negative numbers) this value will move the text more on the right.

MAXSCROLL.SCROLL [brightness]

Execute a single pixel scroll from the right to left of the message set on the DotMatrix display. In order to maintain a continuity of the scrolling, this command must be called on a timed interval (using a timer)

‘brightness” defines the luminosity of the display from 0 (blank) to 15 (max)

MAXSCROLL.OSCILLATE [brightness]

Execute a single pixel scroll oscillating the message set on the DotMatrix display. In order to maintain a continuity of the scrolling, this command must be called on a timed interval (using a timer)

‘brightness” defines the luminosity of the display from 0 (blank) to 15 (max)

NEO.PIXEL led_pos, R, G, B [, disable]

Set, in a stripline, the led at position 'led_pos' with the color R,G,B.

The optional argument 'disable' (if = 1) is useful for updating several pixels together; it will write the new value into memory, but it will not be displayed until the next non-‘disable’ write causes all ‘disabled’ pixels to display their updated values at the same time.

NEO.PIXEL led_pos, COLOR [, disable]

Set, in a stripline, the led at position 'led_pos' with the color ‘COLOR’.

The content of ‘COLOR’ is a merged color value; it can be generated using the function NEO.RGB().

The optional argument 'disable' (if = 1) will permit to write in the memory without refreshing the strip; this is useful to show several leds at the same time

NEO.SETUP pin [,nb_led]

The NEOPIXEL are led strips based on the WS2812 Leds

define the pin to be used for the NEO PIXEL commands

‘Pin’ define the pin number to be used

Optionally it is possible to define the number of leds presents in the string.

By default the strip contains 512 leds.

NOTE: it is recommended to define the number of leds to have a faster refresh, in particular for small strips.

NEO.STRIP led_start_pos, led_end_pos, R, G, B [, disable]

Set, in a stripline, the leds from the position 'led_start_pos' to 'led_end_pos' with the color R,G,B.

The optional argument 'disable' (if = 1) will permit to write in the memory without refreshing the strip; this is useful to show several leds at the same time

NEO.STRIP led_start_pos, led_end_pos, COLOR [, disable]

Set, in a stripline, the leds from the position 'led_start_pos' to 'led_end_pos' with the color ‘COLOR’

The content of ‘COLOR’ is a merged color value; it can be generated using the function NEO.RGB().

The optional argument 'disable' (if = 1) will permit to write in the memory without refreshing the strip; this is useful to show several leds at the same time

NEOSCROLL.SETUP nb_devices, pin [,serpentine]

Setup a NeoMatrix chain display based on WS2812 dot matrix led modules.

The chain can be composed by one or more modules in daisy chain.

The display must be connected using a single pin

‘Nb_devices’ defines how many modules are connected

‘pin’ defines the pin used for the signal

‘Serpentine’ defines if the display is arranged as a serpentine; can be 0 (normal) or 1 (serpentine). By default is 0. 

Example for a 4 digit module available on ebay :

NEOSCROLL.SETUP 4, 15  ‘ 4 digits, using the pin 15

NEOSCROLL.PRINT msg$

Print a message on the NeoMatrix Display.

The message will be shown using the command NEOSCROLL.SCROLL

‘msg$’ defines the message to be shown

NEOSCROLL.NEXT msg$

Define the message that will be shown on the NeoMatrix Display as soon as the message set with the command NEOSCROLL.PRINT is terminated.

Permit to maintains a continuity on the message shown.

‘msg$’ defines the message that will be printed

NEOSCROLL.COLORS col$

Defines the colors associated with the character to be shown on the NeoMatrix display. The logic of the colors is described in the specific NeoMatrix chapter

NEOSCROLL. NEXTCOLORS col$

Defines the colors of the message defined with the command NEOSCROLL.NEXT

NEOSCROLL.SHOW pos [, brightness]

Show in a given position the message defined with the command NEOSCROLL.PRINT or the command NEOSCROLL.NEXT

‘Pos’ define the position of the message (in pixels)

‘brightness” defines the luminosity of the display from 0 (blank) to 255 (max)

The position 1 if the rightmost line of the display and increasing this value will move the text more on the left. Decrementing (negative numbers) this value will move the text more on the right.

NEOSCROLL.TEXT msg$

Set a new message without resetting the message at the initial position.

Useful to modify the message while it’s already scrolling.

‘msg$’ defines the new message to be shown

NEOSCROLL.SCROLL [‘brightness]

Execute a single pixel scroll from the right to left of the message set on the DotMatrix display. In order to maintain a continuity of the scrolling, this command must be called on a timed interval (using a timer)

‘brightness” defines the luminosity of the display from 0 (blank) to 255 (max)

NEOSCROLL.OSCILLATE [‘brightness]

Execute a single pixel scroll oscillating the message set on the DotMatrix display. In order to maintain a continuity of the scrolling, this command must be called on a timed interval (using a timer)

‘brightness” defines the luminosity of the display from 0 (blank) to 255 (max)

OLED.CLS

Clear the content of the OLED display connected using I2C to the module

OLED.INIT orientation

Initialize an OLED display connected using I2C to the module.

‘orientation’ is a number that can be 0 or 1 specifying the orientation:

0

Landscape

1

Landscape reversed

 

The OLED predefined I2C address is 60 (3c in hex).

Before using it, the I2C bus must be initialised with the command I2C.SETUP

 

Example :

I2C.SETUP 21, 21  ' set I2C port on pins 21 and 22

OLED.INIT 1 ‘ init OLED at landscape reversed

OLED.REFRESH fmt

Defines how the image is sent on the OLED after each drawing command.

If ‘fmt’ = 1, the image is automatically refreshed after each drawing command.

If ‘fmt’ = 0, the image must be manually refreshed with OLED.REFRESH 0

This method provides a double buffer permitting to draw several objects on the screen avoiding flickering.

OLED.COLOR color

Set the color used by the OLED drawing commands.

The color is defined as above:

 

0

Black

1

White

2

Reverse

OLED.PIXEL x, y

Draw a pixel at the position x, y on the OLED display

OLED.LINE x1, y1, x2, y2

Draw a line between the point (x1,y1) and  the point (x2,y2) on the OLED display

OLED.RECT x,y, width, height [,fill]

Draw a rectangle at the point (x,y) with the specified width, height on the OLED.

Specifying 1 for the argument fill, the rectangle will be filled.

OLED.CIRCLE x, y, radius [, fill]

Draw a circle at the point (x,y) with the specified radius on the OLED display.

Specifying 1 for the argument fill, the circle will be filled.

OLED.FONT font_num

Set the font used by the OLED.PRINT command.

The font_num is defined as above (by default the font 1 is selected)

 

1

Arial MT 10

Width : 10px

Height:13px

2

Arial MT 16

Width : 16px

Height:19px

3

Arial MT 24

Width : 24px

Height:28px

OLED.PRINT x, y, text$ [background]

Print a text on the OLED display.

‘x’ and ‘y’ define the position where ‘text$’ will be printed.

An optional ‘background’ parameter permit to specify the background color.

OLED.IMAGE x, y, image$

Shows an image in XBM format from the internal disk on the OLED display.

‘X’ and ‘y’ define the position where the image will be shown

‘image$’ is the name of the file containing the image

ONERROR ABORT or ONERROR IGNORE or ONERROR SKIP [nn] or ONERROR CLEAR or ONERROR GOTO label

This controls the action taken if an error occurs while running a program and applies to all errors including syntax errors.

ONERROR ABORT will display the error message and abort the program. This is the normal behaviour and is the default when a program starts running.

ONERROR IGNORE will cause any error to be ignored.

ONERROR SKIP will ignore an error in a number of commands (specified by the number 'nn') executed following this command. 'nn' is optional, the default if not specified is one.

After the number of commands has completed (with an error or not) the behaviour will revert to ONERROR ABORT.

If an error occurs and is ignored/skipped the read only variable BAS.ERRNUM will be set to non zero and BAS.ERRMSG$ will be set to the error message that would normally be generated. These are reset to zero and an empty string by ONERROR CLEAR. They are also cleared when the program is run and when ONERROR IGNORE and ONERROR SKIP are used. ONERROR IGNORE can make it very difficult to debug a program so it is strongly recommended that only ONERROR SKIP be used.

In addition the command ONERROR GOTO label permits to define a routine that can manage the error; issuing RETURN inside this routine, will return to the line following the error.

ONESPNOWERROR [label | OFF]

Define the label where the program will jump when an error occurs during the transmission  of an ESP-NOW  message.

This happen, in particular, when the receiver device has not received the message

ONESPNOWMSG [label | OFF]

Define the label where the program will jump when an ESP-NOW message is received

ONGESTURE [label | OFF]

Define a label where the program will jump when the APDS9960 sensor detects a gesture.  To disable ONGESTURE OFF

ONHTMLCHANGE [label | OFF]

Define a label where the program will jump when an html object present in the output html page change its value. The code must be terminated with ‘RETURN’. 

To disable ONHTMLCHANGE OFF

ONHTMLRELOAD [label | OFF]

Define a label where the program will jump when a reload of the output html page is requested or a new client connects to this page. The code must be terminated with ‘RETURN’.  To disable ONHTMLRELOAD OFF

ONINFRARED label

Define a label where the program will jump when a code is received by the Infrared receiver. The code must be terminated with ‘RETURN’. 

To disable ONINFRARED OFF

OnMQTT label

Define a label where the program will jump when an MQTT message is received

ONSERIAL [label | OFF]

Define a label where the program will jump when a message is received on the serial port (console). The code must be terminated with ‘RETURN’.

To disable ONSERIAL OFF

ONSERIAL2 [label | OFF]

Define a label where the program will jump when a message is received on the serial port #2. The code must be terminated with ‘RETURN’

To disable ONSERIAL2 OFF

ONTOUCH [label | OFF]

Define a label where the program will jump when the TFT screen is touched. The code must be terminated with ‘RETURN’

To disable ONTOUCH OFF.

Useful in combination with the functions TOUCH.X and TOUCH.Y

ONUDP [label | OFF]

Define a label where the program will jump when an UDP message is received. The code must be terminated with ‘RETURN’.

To disable ONUDP OFF

ONURLMESSAGE [label | OFF]

Define a label where the program will jump when an URL AJAX GET request is received. This is typically when the url http://local_ip/msg?param=value is accessed. For more detail refers to the dedicated paragraph..

To disable ONURLMESSAGE OFF.

Useful in combination with URLMSGRETURN and URLMSGGET$

More information here

ONWGETASYNC [label | OFF]

Define a label where the program will jump when a WGETASYNC message is received. The code must be terminated with ‘RETURN’.

To disable ONWGETASYNC OFF

OPTION.CPUFREQ 80|160

Define CPU speed in Mhz of the module.

The value can be 80 or 160.  The default value is 160Mhz.

Setting the speed at 80Mhz, will divide by 2 the speed of the module but lower the power requirement of the module by around 5mA

OPTION.LOWRAM[28] [29]  value

Define the RAM available lower limit. If during the execution of the program this limit is reached, the program automatically stops with an OUT OF MEMORY error message. By default the value is defined at 10000.

As it introduce a little overhead, it can be disabled setting this option at 0 (however this is not recommended).

PAUSE delay

Pause the module for ‘delay’ milliseconds.

During the pause, all the activities are not suspended (it is non-blocking).

This means that the all interrupts will continue to be managed.

PCA9685.SETUP addr

Setup a PWM / SERVO drive module based on the chip PCA 9685.

This module must be connected using the bus I2C.

‘Add’ defines the I2C address of the chip (normally 64)

Example:

PCA9685.SETUP 64 ‘ set the module at the I2C address 64 (40 in hexadecimal)

PCA9685.SETFREQ freq

Set the PWM frequency of the PWM / Servo module PCA 9685

‘Freq’ defines the frequency of the PWM signal

The value can be from  24 Hz to 1526 Hz.

To drive servos, the frequency must be 50 Hz

Example:

PCA9685.SETFREQ 50 ‘ set the PWM frequency at 50 Hz

PCA9685.PWM pin, value

Set the PWM signal on one of the 16 outputs of the PCA9685 module.

‘Pin’ can be from 0 to 15

‘Value’ can be from 0 to 4095.

Example:

PCA9685.PWM 0, 2048 ‘ put the output 0 at 50% duty cycle

PID1.INIT Kp, Ki, Kd

Initialise the PID controller with the Kp, Ki, and Kd parameters.

As there are 4 PID controllers, the prefix can be PID1, PID2, PID3 or PID4.

[30] PID1.LIMITS min, max

Set the output limits of the given PID controller.

If not defined the limits are defined as 0 to 255.

As there are 4 PID controllers, the prefix can be PID1, PID2, PID3 or PID4.

[31] PID1.PERIOD msec

Set the sampling period for the given PID controller.

If not defined the default value is 100 msec.

As there are 4 PID controllers, the prefix can be PID1, PID2, PID3 or PID4.

[32] PID1.PARAMS Kp, Ki, Kd

Modify the PID parameters for the given PID controller.

As there are 4 PID controllers, the prefix can be PID1, PID2, PID3 or PID4.

[33] PID1.SETMODE mode

Set the working mode of the given PID controller.

If ‘mode’ is set to 0, the controller will be stopped and the output value will be frozen.

By default the ‘mode’ is set to 1.

As there are 4 PID controllers, the prefix can be PID1, PID2, PID3 or PID4.

[34] PIN(pin_number) = val

Set the value of any external I/O pin.

The pin_number refers to GPIO and can be from 0 ... 5 or 12 ...33

The val can be 0 or 1 to set the pin to LOW or HIGH

Before be used, the pin must be set as OUTPUT with the command PIN.MODE

PIN.MODE pin_number, mode [,PULLUP | PULLDOWN ]

Set any pin to digital mode as input or output.

The ‘pin_number’ can be from 0 to 39.

The ‘mode can’ be INPUT or OUTPUT or SPECIAL

The optional parameter PULLUP permit to add a weak pullup resistor on the pin.

The optional parameter PULLDOWN permit to add a weak pulldown resistor on the pin.

The mode SPECIAL can be used to restore the normal functionality to any pin.

For example, if the pin GPIO1 (normally assigned to the TX functionality) has been defined as input (with the command PIN.MODE 1, INPUT), its normal functionality can be restored with the command

PIN.MODE 1, SPECIAL

PLAY.MP3 mp3$

Play mp3 files stored in the internal disk (SPIFFS or SD card).

The sound is played in the background, even if the program is stopped, until the end of the record or executing the command PLAY.STOP.

Example:

PLAY.MP3 “/mp3/music.mp3”

PLAY.NETWORKS stream$

Play an mp3 streaming web radio.

The sound is played in the background, even if the program is stopped, until the execution of the command PLAY.STOP.

Example:

PLAY.NETWORKS "http://91.121.159.124:8000/eko-des-garrigues-128k.mp3"

PLAY.SETUP dest

Set the destination output for the sound player commands.

If ‘dest = 0’, the sound will be sent to the internal speaker (pin GPIO25) (mono)

If ‘dest = 1’, the sound will be sent to the external DAC (stereo)

Example:

PLAY.SETUP 1 ‘ define the output to the external DAC

PLAY.SPEAK message$ [, phonetic]

Speaks a vocal message using the internal SAM speech synthesizer.

The message must be composed of english words and limited to 255 characters.

It can optionally talk using phonemes; in this case ‘phonetic’ must be 1.

Example :

PLAY.SPEAK “The quick brown fox jumps over the lazy dog”

PLAY.STOP

Stop the playing of sound

PLAY.VOICE "message", "language" [, "filename"] [, action]

Speaks a vocal message using the voice synthesis available in google translate.

PLAY.VOLUME volume

Defines the output volume.

It can be from 0 to 100 but greater than 100 values are accepted if the sound file was recorded with low volume

Example:

PLAY.VOLUME 50  ‘ set the sound at 50%

PLAY.WAV

Play wav files stored in the internal disk (SPIFFS or SD card).

The sound is played in the background, even if the program is stopped, until the end of the record or executing the command PLAY.STOP.

Example:

PLAYWAV “/wav/music.wav”

PRINT expression[[,; ]expression] ...

Outputs text to the serial port (console)

Multiple expressions can be used and must

be separated by either a:

-       Comma (,) which will output the tab character

-       Semicolon(;) which will not output anything (it is just used to separate expressions).

A semicolon (;) at the end of the expression list will suppress the automatic output of a carriage return/ newline at the end of a print statement.

Integers (whole numbers) are printed without a decimal point while fractions are printed with the decimal point and the significant decimal digits. Large floating point numbers are printed in scientific number format.

PRINT2 expression [[,; ]expression] ...

Outputs text to the serial port #2.

Multiple expressions can be used and must

be separated by either a:

-       Comma (,) which will output the tab character

-       Semicolon(;) which will not output anything (it is just used to separate expressions).

A semicolon (;) at the end of the expression list will suppress the automatic output of a carriage return/ newline at the end of a print statement.

Integers (whole numbers) are printed without a decimal point while fractions are printed with the decimal point and the significant decimal digits. Large floating point numbers are printed in scientific number format.

PWM.SETUP pin, chan, default,  [,freq] [,resol]

Attach a PWM channel to a given output pin.

‘pin’ can be any output pin

‘chan’ can be from 0 to 15.

‘default is the initial pwm value set to the output

‘freq’ is the pwm frequency; by default is 10KHz

‘resol’ is the resolution; by default is 8bits

 

Frequency limits depend on resolution.

For duty resolution of 8 bits, the maximal frequency is 312.5 kHz.

The available duty levels are (2^bit_num)-1, where bit_num can be 1-15.

The maximal frequency is 80000000 / 2^bit_num

NOTE for the M5stack:

The channel 0 is dedicated to the internal speaker (pin 25)

The channel 7 is dedicated to the TFT backlight (pin 32)

See the PWM chapter for more details

PWM.SETUP pin, OFF

Detach the pin from the PWM output.

PWM.OUT chan, value

Set a given value to the PWM channel.

The channel is associated to a given pin with the command PWM.SETUP

‘chan’ can be from 0 to 15

‘value’ can be from 0 to the max defined by the resolution (by default 0 to 255)

READ var1 [,var2] ...

Reads values from DATA statements and assigns these values to the named variables. Variable types in a READ statement must match the data types in DATA statements as they are

Read.

See also DATA and RESTORE.

REBOOT

Reboots the module (software reset)

REFRESH

Refresh (sync) the variables in the basic code with the corresponding variables in the input html page (one shot)

RESTORE

Resets the line and position counters for the READ statement at the beginning.

RTC.SETTIME Year, Month, Day, Hours, Minutes, Seconds

Set the RTC module (DS1307 or DS3231) with the date / time provided.

‘Year’ can be from 0 (for 2000) to 99 (for 2099)

‘Month’ can be from 1 (january) to 12 (december)

‘Day’ can be from 1 to 31

‘Hours’ can be from 0 to 23

‘Minutes’ can be from 0 to 59

‘Seconds’ can be from 0 to 59

See also RTC.DATE$ and RTC.TIME$

SERIAL.BYTE ch1 [,ch2] . . .

Send one or more byte to the serial port (console).

The bytes can be one or more separated by a comma.

The values can be any value from 0 to 255.

Example :

SERIAL.BYTE &h10, &h00, &h12, &h09

SERIAL2.BYTE ch1 [,ch2] . . .

Send one or more byte to the serial port #2.

The bytes can be one or more separated by a comma.

The values can be any value from 0 to 255.

Example :

SERIAL2.BYTE &h10, &h00, &h12, &h09

SERIAL.MODE baudrate

Set the speed for the Serial Port (console)

The format is fixed to 8 bits No parity 1 bit stop.

‘baudrate’ defines the speed (can be any allowed value)

SERIAL2.MODE baudrate, pin_tx, pin rx

Set the speed and the pins for the serial port #2

It is possible to specify any pin for the TX and RX signals.

The format is fixed to 8 bits No parity 1 bit stop.

‘baudrate’ defines the speed (can be any allowed value)

‘pin_tx’ defines the pin for the TX signal

‘pin_rx’ defines the pin for the RX signal.

SERVO id, value

Set the angle of servo connected on the channel ‘id’

‘id’ define the servo channel (from 1 to 4)

‘Value’ is the desired angle (from 0 to 180)

The pin is defined by the command SERVO.SETUP

SERVO.SETUP id, pin_number | OFF

Define the pin that must be used by the servo channel.

‘id’ define the servo channel (from 1 to 4)

The ‘pin_number’ can be from 0 to 16.

To detach the pin, use ‘OFF’ instead of the pin_number

SETTIME Year, Month, Day, Hours, Minutes, Seconds

Set the internal timekeeper with the date / time provided.

‘Year’ can be from 70 (for 1970) to 38 (for 2038); values >100 are accepted so 2017 can be specified as 17 or 117.

‘Month’ can be from 1 (january) to 12 (december)

‘Day’ can be from 1 to 31

‘Hours’ can be from 0 to 23

‘Minutes’ can be from 0 to 59

‘Seconds’ can be from 0 to 59

SLEEP value

Put the ESP in deep sleep (low energy) for 'value' seconds.

At the end of the period, the unit will reboot and reload the default basic program.

Note : GPIO16 must be connected to RST pin to wakeup from sleep

NOTE: Maximum time is 4294 seconds (around 71 minutes)

SOCKET client, msg$

Send a WebSocket message only to a specific client.

It will be probably removed.

‘client’ is the number of the client

‘msg$’ is the message to be sent

SPI.SETUP speed [,data_mode [, bit_order]]

Initialise the SPI port with the speed (bits/sec)

The speed can be max 80000000 (80MHz for CPU running at 160MHz)

The optional parameters are:

data_mode : can be 0 (default) 1, 2 or 3.

bit_order : can be 0 (lsb_first) or 1 (msb_first - default)

ST7920.INIT CS_pin

Initialize an ST7920 display connected using SPI to the module.

‘CS_pin’ defines the pin used for the CS signal

This command initialise automatically the SPI bus at 1 Mhz (max frequency allowed by the display)

 

Example :

 

ST7920.INIT 15 ‘ init the ST7920 with the CS at pin 16

ST7920.CLS

Clear the content of the ST7920 display connected using SPI to the module

ST7920.REFRESH fmt

Defines how the image is sent on the ST7920 after each drawing command.

If ‘fmt’ = 1, the image is automatically refreshed after each draawing command.

If ‘fmt’ = 0, the image must be manually refreshed with ST7920.REFRESH 0

This method provides a double buffer permitting to draw several objects on the screen avoiding flickering.

ST7920.COLOR color

Set the color used by the ST7920 drawing commands.

The color is defined as above:

 

0

Black

1

White

2

Reverse

ST7920.PIXEL x, y

Draw a pixel at the position x, y on the ST7920 display

ST7920.LINE x1, y1, x2, y2

Draw a line between the point (x1,y1) and  the point (x2,y2) on the ST7920 display

ST7920.RECT x,y, width, height [,fill]

Draw a rectangle at the point (x,y) with the specified width, height on the ST7920.

Specifying 1 for the argument fill, the rectangle will be filled.

ST7920.CIRCLE x, y, radius [, fill]

Draw a circle at the point (x,y) with the specified radius on the ST7920 display.

Specifying 1 for the argument fill, the circle will be filled.

ST7920.FONT font_num

Set the font used by the ST7920.PRINT command.

The font_num is defined as above (by default the font 1 is selected)

 

1

Arial MT 10

Width : 10px

Height:13px

2

Arial MT 16

Width : 16px

Height:19px

3

Arial MT 24

Width : 24px

Height:28px

ST7920.PRINT x, y, text$ [background]

Print a text on the ST7920 display.

‘x’ and ‘y’ define the position where ‘text$’ will be printed.

An optional ‘background’ parameter permit to specify the background color.

ST7920.IMAGE x, y, image$

Shows an image in XBM format from the internal disk on the ST7920 display.

‘X’ and ‘y’ define the position where the image will be shown

‘image$’ is the name of the file containing the image

TM1637.PRINT msg$ [, brightness [, dotpoints]]

Print a message on the display TM1637. The message can be up-to 4 chars. All ASCII characters can be used but will be shown within the limitation of the 7 segments of the display.

‘msg$’ defines the message to be printed

‘brightness” defines the luminosity of the display from 0 (blank) to 7 (max)

‘dotpoints’ defines if the two points in the middle of the display must be ON (255) or OFF (0).

By default the luminosity is at 7 and the dotpoints OFF

TM1637.SETUP data_pin, clock_pin [, bit_delay]

Defines the pins to be used for the display TM1637.

‘data_pin’ defines the pin allocated for the signal DIO of the display

‘clock_pin” defines the pin allocated for the signal CLK of the display

‘Bit_delay’ permit to add a delay when the display module is provided with capacitors on the input pin. Its value is 5 by default and should be defined at 100 in this case.

TM1638.PRINT msg$ [, brightness ]]

Print a message on the display TM1638. The message can be up-to 8 chars.

All ASCII characters can be used but will be shown within the limitation of the 7 segments of the display.

‘msg$’ defines the message to be printed

‘brightness” defines the luminosity of the display from 0 (blank) to 15 (max)

By default the luminosity is at 15

TM1638.SETUP data_pin, clock_pin, strobe_pin

Defines the pins to be used for the display TM1638.

‘data_pin’ defines the pin allocated for the signal DIO of the display

‘clock_pin” defines the pin allocated for the signal CLK of the display

‘strobe_pin” defines the pin allocated for the signal STB of the display

TM1638.LEDS val

Controls the 8 leds installed on the module TM1638.

‘Val’ is an 8-bits value where each bit is associated with a led.

Example :

TM1638.LEDS 1 ‘ illuminated the led 1

TFT.BMP filename$, [x, y [, back_color] ]

Display a bitmap file on the TFT display.

The file must be present on the local disk before use it.

The file format must be ".bmp" with 24 or 32 bits.

The image can be of any size but is limited at 320 x 240 (resolution of the display).

The position (x, y) is optional; if specified the image will be drawn from that point.

The back color is useful for 32bits images when a transparent color is defined; in this case the transparence will be replaced by the ‘back_color’.

Defining a back_color at -1, the transparence will be maintained, useful to put icons on the top of an image.

‘filename$’ is the name of the bmp file

‘x’ is the horizontal position of the image

‘y’ is the vertical position of the image

‘back_color’ (optional) is the background color (-1 by default)

Example

TFT.BMP "/icon1.bmp", 50, 50

TFT.BRIGHTNESS val

Set the TFT backlight intensity.

‘val’ can be from 0 (dark) to 255 (max)

Example:

TFT.BRIGHTNESS 128 ‘ set the luminosity at 50%

TFT.CIRCLE x, y, radius,color [, fill]

Trace a circle at the point (x,y) with the specified radius.

Specifying 1 for the argument fill, the circle will be filled.

Example

A filled circle at 20,20 radius 18, with a reddish color

TFT.CIRCLE 20,20,18,TFT.RGB(255,10,10),1

TFT.FILL color

Fill the whole screen with a given color.

‘color’ is the color; as it must be a 16 bit color (RGB565), its value can be from 0 to 65535.

The color can be obtained specifying the R,G,B components with the function TFT.RGB.

Example:

TFT.FILL 0  ‘ fill the screen with black (equivalent of CLS)

TFT.IMAGE filename$, [x, y [, back_color] ]

Display a BMP or JPG file on the TFT display.

The file must be present on the local disk before use it.

The file format must be ".bmp" with 24 or 32 bits or “.jpg”

The image can be of any size but is limited at 320 x 240 (resolution of the display).

The position (x, y) is optional; if specified the image will be drawn from that point.

The back color is useful for 32bits images when a transparent color is defined; in this case the transparence will be replaced by the ‘back_color’.

Defining a back_color at -1, the transparence will be maintained, useful to put icons on the top of an image.

‘filename$’ is the name of the image file

‘x’ is the horizontal position of the image

‘y’ is the vertical position of the image

‘back_color’ (optional) is the background color (-1 by default)

Example

TFT.IMAGE "/icon1.bmp", 50, 50

TFT.IMAGE “/roses.jpg”, 64, 64

TFT.INIT orientation

Initialize a TFT ILI9431 display connected to the module.

‘orientation’ is a number between 0 and 3 specifying the orientation:

 

0

Portrait

1

Landscape

2

Portrait reversed

3

Landscape reversed

 

Example :

TFT.INIT 1           ‘ Landscape

Check the chapter about the TFT display  for more details

TFT.JPG filename$, [x, y [, back_color] ]

Display a JPG file on the TFT display.

The file must be present on the local disk before use it.

The file format must be “.jpg”

The image can be of any size but is limited at 320 x 240 (resolution of the display).

[35] The position (x, y) is optional; if specified the image will be drawn from that point.

The back color is useful for 32bits images when a transparent color is defined; in this case the transparence will be replaced by the ‘back_color’.

Defining a back_color at -1, the transparence will be maintained, useful to put icons on the top of an image.

‘filename$’ is the name of the jpg file

‘x’ is the horizontal position of the image

‘y’ is the vertical position of the image

‘back_color’ (optional) is the background color (-1 by default)

Example

TFT.JPG “/roses.jpg”, 64, 64

TFT.LINE x1, y1, x2, y2, col

Trace a line on the TFT between the point (x1,y1) and  the point (x2,y2) with the color ‘col’

Example:

TFT.LINE 50, 50, 150, 150, TFT.RGB(255, 0, 0)

TFT.PRINT expression [[,; ]expression] ...

Draw a text on the TFT display.

Multiple expressions can be used and must be separated by either a:

-       Comma (,) which will output the tab character

-       Semicolon(;) which will not output anything (it is just used to separate expressions).

A semicolon (;) at the end of the expression list will suppress the automatic output of a carriage return/ newline at the end of a print statement.

Integers (whole numbers) are printed without a decimal point while fractions are printed with the decimal point and the significant decimal digits. Large floating point numbers are printed in scientific number format.

TFT.RECT x, y, width, height, color [ [,fill] ,[round_radius] ]

Trace a rectangle at the point (x,y) with the specified width, height and color.

Specifying 1 for the argument fill, the rectangle will be filled.

Specifying a value for ‘round_radius’, the rectangle will be rounded at the corners with the value specified.

Example:

TFT.RECT 100, 50, 50, 50, TFT.RGB(255, 128, 0)

TFT.TEXT.COL color [,backcolor]

Set the color and the background of the text that will be printed with the command TFT.PRINT

‘color’ define the color of the text

‘backcolor’ (optional) defines the background of the text

If ‘backcolor’ is not defined, the background will be black

TFT.TEXT.POS x, y

Position the text cursor at the point (x, y).

The text will be printed at that position with the command TFT.PRINT

TFT.TEXT.SIZE size

Set the size of the text that will be printed with the command TFT.PRINT

The ‘size’ can be from 1 to 8.

TIMER0 interval, label

Starts a timer causing the program to periodically jump to the defined label.

The RETURN at the end of the timer branch causes program control to return to where it was before being interrupted by TIMER0.

‘Interval’ defines the periodicity (milliseconds)

‘Label’ define the place where the timer will jump regularly.

Setting the interval to 0 will disable it.

Nota: The Timer0 has a higher priority than Timer1.

Example

TIMER0 1000, cycle  -> jumps to ‘cycle’ at each second

TIMER1 interval, label

Starts a timer causing the program to periodically jump to the defined label.

The RETURN at the end of the timer branch causes program control to return to where it was before being interrupted by TIMER1.

‘Interval’ defines the periodicity (milliseconds)

‘Label’ define the place where the timer will jump regularly.

Setting the interval to 0 will disable it.

Example

TIMER1 1000, cycle  -> jumps to ‘cycle’ at each second

TOUCH.CALIB

Start the calibration of the touch screen. The user will be asked to click on 4 crosses.

The calibration values will be stored inside the module and stay in effect even after restarts.

TRACE message

Send a message to all the clients connected by Websockets.

‘message’ can be a string or a number

In coordination with the javascript code present into the file /input.html, there are 4 kind-of commands available :

 

"cls"

Clear the html content of the page

"html"

Send html code to the page

"csscls"

Clear the css content of the page

"csshtml"

Send the css code to the page

 

Check the chapter about html objects for more details

See also the commands CLS, HTML, JSCALL, JSCRIPT, JSEXTERNAL, CSS and WLOG

UDP.BEGIN port

Start the UDP Server.

‘port’ is the udp port to be open (numerical).

All the messages received on this port can be read with the function UDP.READ$

UDP.REPLY msg$

Send an UDP message back to the original transmitter.

Permit to answer directly without specify the IP and port

UDP.STOP

Stop the UDP server.

UDP.WRITE ip, port, msg$

Send a UDP message to the client defined with the IP address ‘ip’ and the port ‘port". The message ‘msg$" must be a String.

UDP.Begin must be used to initialise the UDP port before using UDP.write

URLMSGRETURN msg$ [,content_type$]

Returns a message to the client that sent the URL AJAX GET request.

Is an async request so it can work in parallel with other tasks.

When the program is not running, any request will receive the message "STOPPED".

The message can be optionally composed of an hex string in the format of 2 hex char per byte (ex: “3a552b23”) associated with a content type string (ex: "image/gif").

For more detail refers to the dedicated paragraph..

Useful in combination with ONURLMESSAGE and URLMSGGET$

More information here

WAIT

Stops the execution of the program while waiting for events.

Useful when using "event driven" code (timers, interrupts, triggered events, ..)

WGETASYNC http_server$, port [,header]

Start a GET server request in async mode

‘http_server$’ is the server url request

‘port’ is the port number; if port=443, the connection will be done using SSL (secure).

‘header’, if =1, will include the header in the answer (useful for debug)

The program will continue and the answer will be received in background.

As soon as the answer is completed, the program will jump to the label defined with the command ONWGETASYNC.

To get the result, use the function WGETRESULT$.

Example :

ONWGETASYNC answer_done

WGETASYNC("www.fakeresponse.com/api/?sleep=5", 80)

For i = 0 to 10000

‘ a kind of sleep just to demonstrate that the code continue to run

Print i

Next i

Wait

answer_done:

Print WGETRESULT$

Return

WIFI.AWAKE

Wake Up the WiFi from the sleep mode triggered with the command WIFI.SLEEP

WIFI.CONNECT SSID, password

Connect the module to a WiFi network using the given SSID and password.

It is possible to gather the connection status using the function WIFI.STATUS

WIFI.POWER pow

Set the output power of WiFi

‘pow’ defines the value in dBm

The range is between 0 and 20.5

WIFI.SCAN

Starts to scan WiFi networks available.

Must be used in association with WIFI.NETWORKS

WIFI.SLEEP

Put the WiFi in sleep mode.

The module will be placed in “modem-sleep” mode.

This mode turns the WiFi OFF but the module will continue to work.

In this mode the power requirement is lowered to around 25mA.

Important: this will work only if the module is in AP mode with static IP address or in STA mode

WLOG [text$ | num]

Send text content to debug page.

This command is equivalent to TRACE "LOG:" + text$ or

                                                 TRACE "LOG:" + str$(num)

 

Check the chapter about html objects for more details

See also the commands TRACE, CLS, HTML, JSCRIPT, JSEXTERNAL, CSS and JSCALL

WORD.DELPARAM setting$, parameter$, [,separator$]

Delete a parameter from a string containing a series of parameters. If the parameter exists, it will be removed, otherwise the string will not be modified.

The parameters are stored as below :

param1=value1

param2=value2

…….

paramx=valuex

‘setting$’ defines the string containing the set of parameters

‘parameter$’ defines the parameters to be deleted.

‘separator$’ is an optional parameter specifying a different separator character.

Example, assuming that a$ is empty :

WORD.SETPARAM a$, "light", "on"

WORD.SETPARAM a$, "temp", "10"

WORD.SETPARAM a$, "pump", "off"

A$ will contains :

light=on

temp=10

pump=off

 

Using the following line:

WORD.DELPARAM a$, "temp"

A$ will contain :

light=on

pump=off

By default the separator is the character ‘=’.

Useful in combination with WORD.GETPARAM$, WORD.SETPARAM and FILE.SAVE

WORD.SETPARAM  setting$, parameter$, value$ [,separator$]

Put a parameter into a string containing a series of parameters. If the same parameter already exists, its value will be replaced with the new one.

The parameters are stored as below :

param1=value1

param2=value2

…….

paramx=valuex

‘setting$’ defines the string containing the set of parameters

‘parameter$’ defines the parameters to be set.

‘value$’ defines the value to be set.

‘separator$’ is an optional parameter specifying a different separator character.

Example, assuming that a$ is empty :

WORD.SETPARAM a$, "light", "on"

WORD.SETPARAM a$, "temp", "10"

WORD.SETPARAM a$, "pump", "off"

A$ will contains :

light=on

temp=10

pump=off

 

Using the following line:

WORD.SETPARAM a$, "temp", "20"

A$ will contains :

light=on

temp=20

pump=off

 

By default the separator is the character ‘=’.

Useful in combination with WORD.GETPARAM$, WORD.DELPARAM and FILE.SAVE

 

BASIC KEYWORDS

 

CASE

Keyword :  Used in combination with the SELECT command

DIM array(size) [, …]

Permit to define arrays.

The arrays can be floating point or string.

The number of dimensions (subscripts) is limited to 5.

Look at the chapter "Arrays" for more details

DO

The DO loop

ELSE

Keyword : Used in combination with the IF and SELECT commands

END [IF | SELECT | SUB]

Used in several forms:

END alone terminate the execution of the program

END IF  to terminate the IF

END SELECT : to terminate a SELECT CASE

END SUB : to terminate a SUB

ENDIF

Used in combination with the IF command; can be also written as END IF

EXIT {DO | SUB}

Permit to exit from a DO LOOP (EXIT DO) or a SUB (EXIT SUB)

FOR

FOR command;  Used in combination with the NEXT  command

GOSUB [label | lab$]

Jumps to a named label; the flow control will come back as soon as the command RETURN is reached.

The label must begin with a letter, not a number.

The contents of a string variable can be used instead of a static label name, allowing choice of destinations for creating dynamic function calls

 

GOTO label

Jumps to a named label; the label must begin with a letter, not a number.

IF

IF command; used in combination with THEN, ELSE ENDIF and END IF

LET var = expression

Optional for variable assignment

LOOP

Keyword : Used in combination with the DO command

NEXT

Keyword : Used in combination with the FOR  command

OFF

Keyword : used in combination with the INTERRUPT command

OUTPUT

Keyword : Used in combination with the PIN.MODE command

PULLUP

Keyword : Used in combination with the PIN.MODE command

REM

Define a comment(remark); the symbol ‘ can be used instead

RETURN

Returns to the caller after a Gosub or an Event happened

SELECT

The SELECT CASE

SPECIAL

Keyword : Used in combination with the PIN.MODE command

STEP

Keyword : Used in combination with the FOR  command

SUB

Defines "user named" subroutines.

Refer to the paragraph "SUB" and "Scope of the variables" for more details.

THEN

Keyword : Used in combination with the IF command; this keyword is optional in the IF command

TO

Keyword : Used in combination with the FOR  command

UNTIL

Keyword :  Used in combination with the DO command

WEND

Keyword : Used in combination with the WHILE  command

WHILE

The WHILE LOOP; also used as condition for the DO LOOP

 

 


NOT YET SH1106

To add the new events associated with the GUI

to include the MCP23017 as supported module

add in the commands table

To check if it works. The whole code should be changed using the internal ESP32 counters

To be implemented

to check if it works

Probably rename to PLAY.STREAM

Support to be included

To check if works the same

Eventually insert the schematic of the PCB

TO BE CHECKED

Maybe removed?

to add more colors

Perhaps possibility to read additional colour names + their defined values from an external "colours" file if available - works fine for me, allowing whatever new colours that the user wishes.

I did a snippet permitting to do that without creating another command

TO include in the line documentation

To add the background colors

TODO (maybe change the syntax)    TODO maybe add more events

to update

Actually works but not exactly as on the ESP8266. Pin and schematic must be updated

To check if it works and update the schematic

to check and update schematic

change schematic for the ESP32

Change the syntax of PID..

The same for the ESP8266

to be implemented / modified for the optional arguments

Will need updating for SD.

Perhaps file.save and file.read could be upgraded to return an error number like bas.load, rather than halt on error ?

Optional [branch] could offer option to jump to user error handler (for saving important variables etc before stopping).

This is covered with the command onerror goto

syntax to be modified and implemeted too

syntax to be modified and implemeted too

syntax to be modified and implemeted too

syntax to be modified and implemeted too

syntax to be modified and implemeted too

To confirm if the trasparency is applicable to jpg (normally don't)