Micromite Manual
Micromite Manual
Micromite Manual
User Manual
MMBasic Ver 5.05.05
The compiled object code (the .hex file) for the Micromite is free software: you can use or redistribute it as you
please. The source code is available via subscription (free of charge) to individuals for personal use or under a
negotiated license for commercial use. In both cases go to http://mmbasic.com for details.
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.
Contributions
Acknowledgement and thanks to Phil Boyce (WhiteWizard) for supporting the Micromite's development with
much needed hardware, Peter Carnegie (G8JCF) for his help in developing the CFunction functionality and
Gerard Sexton who developed the I2C and 1-Wire support for the original Maximite.
A very big thanks to Peter Mather (matherp) for his ongoing support including introducing low cost LCD
panels, writing the ILI9341 and ST7735S drivers, doing the original port to the MX470 and MZ chips, porting
the M-Stack USB/CDC and FatFs drivers, pushing the implementation of CFunctions to new heights and the
uncountable number of bugs that he has found and documented. Thank you very much Peter.
Also thanks to the members of the Back Shed forum who have beta tested the Micromite firmware over the past
few years and reported many, many bugs. Thanks guys.
28-pin Chips
The best chip to use is the PIC32MX170F256B-50I/SP which is guaranteed to run up to 48MHz (the maximum
Micromite speed) and is in a 28-pin DIL package. It costs about $4 direct from Microchip. There is a 40 MHz
variant (the PIC32MX170F256B-I/SP) which is a little cheaper. All of the 40 MHz chips tested have run fine at
48 MHz so this chip is also a good option.
The following is a summary of the recommended chips for the Micromite in a 28-pin package:
PIC32MX170F256B-50I/SP Guaranteed to run at 48 MHz. 28-pin DIL package.
PIC32MX170F256B-50I/SO As above but is in a surface mount SOIC package
PIC32MX170F256B-I/SP Should run at 48 MHz despite its 40 MHz spec. 28-pin DIL package.
PIC32MX170F256B-I/SO As above but is in a surface mount SOIC package
The firmware will also run on the PIC32MX270F256 series of chips. These have built in USB (which is not
supported in the Micromite) and therefore you lose access to two I/O pins (pins 15 and 23) which are used in
the chip for dedicated USB functions. In addition pins 21 and 22 are not 5V tolerant.
44-pin Chips
The best chip to use is the PIC32MX170F256D-50I/PT which is guaranteed to run up to 48 MHz and costs a
little over $4 when purchased from Microchip. Similar to the 28-pin package there are versions rated at 40
MHz and versions with USB - with the latter MMBasic does not support USB and you lose access to two I/O
pins which are reserved for USB functions (pins 10 and 42).
The following is a summary of the recommended chips for the Micromite in a 44-pin package:
PIC32MX170F256D-50I/PT Guaranteed to run at 48 MHz.
PIC32MX170F256DI/PT Should run at 48 MHz despite its 40 MHz rating.
These chips are in a TQFP surface mount package with a lead pitch of 0.8mm. This is reasonably easy to
solder and the chip can be mounted on a carrier board (for example futurlec.com part code 44PINTQFP) which
brings the pins out on an easy to use 0.1 inch grid.
The Micromite firmware file will work with either the 28 or 44-pin chips. The only difference is that the 44-
pin chip has an extra fourteen I/O pins that are accessible from within MMBasic.
The notation is as follows (the mnemonic in brackets is the mode used in the SETPIN command):
ANALOG These pins can be used to measure voltage (AIN).
DIGITAL Can be used for digital I/O including digital input (DIN) and digital output (DOUT).
COUNT Can be used to measure frequency (FIN), period (PIN) or counting (CIN).
5V These pins can be connected to 5V circuits. All other I/O pins are strictly 3.3V maximum.
COM xxx Can be used for serial communications (see Appendix A).
2
I C xxx Can be used for I2C communications (see Appendix B).
SPI xxx Can be used for SPI I/O (see Appendix D).
PWM xxx Can be used for PWM or SERVO output (see the PWM and SERVO commands).
IR This can be used to receive signals from an infrared remote control (see the IR command).
WAKEUP This pin can be used to wake the CPU from a sleep (see the CPU SLEEP command).
Pins 27 and 28 are the ground and power for analog measurements. Normally they are connected to the general
ground and power (pins 8 and 13) but if you require noise free and accurate analog readings you should make
sure that the power on pin 28 is regulated to precisely 3.3V and well filtered. Also your analog inputs should
be referenced to pin 27 (the analog ground).
Within MMBasic the SETPIN command is used to set the function of an I/O pin for general I/O. The PIN
command or function is then used to interact with the pin. For example, this will print out the voltage on pin 7:
SETPIN 7, AIN
PRINT "The voltage is" PIN(7) "V"
This voltage reading is referenced to pin 28 and assumes that the supply voltage on this pin is exactly 3.3V.
You will need to scale the readings in your BASIC program if you use a supply voltage other than this.
Pin 23
Pin 34
Pin 12
Pin 1
Pin Pin
ANALOG | DIGITAL | PWM 1C 23 22 PWM 1B | DIGITAL | ANALOG
ANALOG | DIGITAL | COM1: ENABLE 24 21 PWM 1A | DIGITAL | ANALOG
ANALOG | DIGITAL 25 20 SPI OUT (MOSI) | DIGITAL | ANALOG
ANALOG | DIGITAL 26 19 DIGITAL | ANALOG
ANALOG | DIGITAL 27 18 RESET Wired to +V directly or via 10K resist
POWER (+2.3 to +3.6V) 28 17 ANALOG POWER (+2.3 to +3.6V)
GROUND 29 16 ANALOG GROUND
DIGITAL | COM2: TRANSMIT 30 15 PWM 2A | DIGITAL | ANALOG
DIGITAL | COM2: RECEIVE 31 14 SPI CLOCK | DIGITAL | ANALOG
DIGITAL | 5V 32 13 5V | DIGITAL
CONSOLE Tx (DATA OUT) 33 12 5V | DIGITAL
PICKit 3 1 28
Connector
10K
1 - MCLR 27
2 - Vcc 4
3 - GND
4 - PGD
5 - PGC
6 - NC 5
8
20
+
19 47µF 16V
Ceramic or
Tantalum
13
44-pin Chips
Programming these is similar to programming the 28-pin version. Refer to the following table for the pin
connections on the microcontroller:
PICkit 3 Description 44-pin chip
47µF 16V Tantalum Capacitor to GND 7
1 - MCLR Master Reset (active low) 18
2 - Vcc Power Supply (3.3V) 17, 28 and 40
3 - GND Ground 6, 16, 29 and 39
4- PGD Programming Data 21
5 - PGC Programming Clock 22
6 - NC Not used
Notes:
A pullup resistor of 10 K is required between the MCLR pin and Vcc.
The microcontroller being programmed can be powered by the PICkit 3 but it is recommended that a
separate power supply be used. When the PICkit 3 supplies the power pin 2 (Vcc) on the PICkit 3 will
become an output supplying the power to the chip being programmed.
CP2102
USB – Serial
Converter
When you plug the USB side of the converter into your
computer you may have to load a driver to make it work with
the operating system. Once this is done you should note the port
number created by your computer for the virtual serial
connection. In Windows this can be done by starting Device
Manager and checking the "Ports (COM & LPT)" entry for a
new COM port as shown on the right.
Terminal Emulator
You also need a terminal emulator program on your desktop
computer. This program acts like an old fashioned computer
terminal where it will display text received from a remote
computer and any key presses will be sent to the remote
computer over the serial link.
The terminal emulator that you use should support VT100
emulation as that is what the editor built into the Micromite
expects. For Windows users it is recommended that you use
Tera Term as this has a good VT100 emulator and is known to
work with the XModem protocol which you can use to transfer
programs to and from the Micromite (Tera Term can be
downloaded from: http://tera-term.en.lo4d.com/).
The terminal emulator and the serial port that it is using should be
set to the Micromite standard of 38400 baud, 8 data bits and one
stop bit. The screen shot on the right shows the setup for Tera
Term. Note that the "Port:" setting will vary depending on which
USB port your USB to TTL serial converter was plugged into.
Troubleshooting
If you cannot see the startup banner try disconnecting the USB-serial converter and join its TX and RX pins.
Then try typing something into the terminal emulator. You should see your characters echoed back, if not it
indicates a fault with the converter or the terminal emulator.
If the USB-serial converter checks out the fault could be related to the console connection to the Micromite.
Make sure that TX connects to RX and vice versa and that the baudrate is 38400. If you have an oscilloscope
you should be able to see a burst of activity on the Micromite's TX line on power up. This is the Micromite
sending its startup banner.
Apple Macintosh
The Apple Macintosh (OS X) is somewhat easier as it has the device driver and terminal emulator built in.
First start the application ‘Terminal’ and at the prompt list the connected serial devices by typing in:
ls /dev/tty.*.
The USB to serial converter will be listed as something like /dev/tty.usbmodem12345. While still at the
Terminal prompt you can run the terminal emulator at 38400 baud by using the command:
screen/dev/tty.usbmodem12345 38400
By default the function keys will not be correctly defined for use in the Micromite's built in program editor so
you will have to use the control sequences as defined in the section Full Screen Editor of this manual.. To
avoid this you can reconfigure the terminal emulator to generate these codes when the appropriate function
keys are pressed.
Shortcut Keys
When you are using a VT100 compatible terminal emulator on the console you can use the following function
keys to insert a command at the command prompt:
F2 RUN
F3 LIST
F4 EDIT
F10 AUTOSAVE
F11 XMODEM RECEIVE
F12 XMODEM SEND
Pressing the key will insert the text at the command prompt, just as if it had been typed on the keyboard.
Basic Circuit
The basic circuit for the 28-pin Micromite is shown below. It is recommended that you experiment with it
using a plug in breadboard with jumper leads. Later, when you have finalised your design, you can create a
printed circuit board to hold the final circuit.
Note that the 10K resistor is necessary if you later need to update the Micromite firmware using a PIC
programmer. If this will never happen you can replace it with a wire link (ie, connect pin 1 direct to 3.3V).
Power Supply
2.3 to 3.6V 26mA
Can be 2 x AA batteries
or a nominal 3.3V
power supply 1 28
10K
27
Serial Console
VT100 Terminal or
USB to TTL Converter
38400 baud
8 bits no parity one stop bit 8
20
TTL Voltage Levels
+
Data from Micromite 19 47µF 16V
Rx
11
Ceramic or
Serial
Tx
Data to Micromite 12 Tantalum
Terminal
Gnd
13
Power Supply
The Micromite needs a power supply between 2.3V and 3.6V connected as shown above. Normally the current
drain is 26mA plus the drain of any external components (LEDS, etc). Two alkaline AA cells can provide a
convenient power source or you can use a conventional power supply.
Generally it is a good design technique to place a 100nF ceramic capacitor close to each of the power supply
pins but this is not critical and they are not shown in this diagram.
The capacitor connected to pin 20 is used to decouple and stabilise the 1.8V voltage regulator internal to the
PIC32 chip. It must be a high quality capacitor (not an electrolytic) and should have a minimum value of 10 µF
with an ESR (Equivalent Series Resistance) of less than 1Ω. The recommended capacitor is a 47 µF 16V
tantalum or a 10 µF 16V X7R multilayer ceramic.
A Simple Program
Assuming that you have correctly connected a terminal emulator to the Micromite and have the command
prompt (the greater than symbol as shown above, ie, > ) you can enter a command line followed by the enter
key and it will be immediately run.
For example, if you enter the command PRINT 1/7 you should see this:
> PRINT 1/7
0.142857
Flashing a LED
Connect a LED to pin 15 as shown in the diagram on the right.
Then use the EDIT command to enter the following program:
SETPIN 15, DOUT
DO 15
PIN(15) = 1
PAUSE 300 82 LED
PIN(15) = 0 ohms
PAUSE 300
LOOP
When you have saved and run this program you should be greeted by the LED flashing on and off. It is not a
great program but it does illustrate how your Micromite can interface to the physical world via your
programming.
The chapter "Using the I/O pins" later in this manual provides a full description of the I/O pins and how to
control them.
Running Programs
A program is set running by the RUN command. You can interrupt MMBasic and the running program at any
time by typing CTRL-C on the console input and MMBasic will return to the command prompt.
You can list a program in memory with the LIST command. This will print out the program while pausing
every 24 lines.
You can completely erase the program by using the NEW command.
A program in the Micromite is held in non volatile flash memory. This means that it will not be lost if the
power is removed and, if you have the AUTORUN feature turned on, the Micromite will start by automatically
running the program when power is restored (use the OPTION command to turn AUTORUN on).
Setting Options
Many options can be set by using commands that start with the keyword OPTION. They are listed in the
commands section of this manual. For example, you can set the baud rate of the console with the command:
OPTION BAUDRATE 9600
Saved Variables
Because the Micromite does not necessarily have a normal storage system (such as an SD card) it needs to have
a facility to save some data that can be recovered when power is restored. This can be done with the VAR
SAVE command which will save the variables listed on its command line in non volatile flash memory. The
space reserved for saved variables is 2KB on the standard Micromite and 4K on the Micromite Plus.
These variables can be restored with the VAR RESTORE command which will add all the saved variables to
the variable table of the running program. Normally this command is placed near the start of a program so that
the variables are ready for use by the program.
This facility is intended for saving calibration data, user selected options and other items which change
infrequently. It should not be used for high speed saves as you may wear out the flash memory.
The flash in the PIC32 chips used for the Micromite have a high endurance of over 20,000 writes and erases.
With normal use this will never be reached but it can be exceeded by a program that repeatedly saves variables.
For example, a program that saved a set of variables once a second would wear out the flash in six hours while
a program that saved the same data once a day would run for over 50 years and still not wear out the flash.
If you do want to save data often it would be worth adding a real time clock chip to the Micromite design. The
RTC SETREG and RTC GETREG commands can then be used to store and retrieve data from the RTC's
battery backed memory. See the RTC command for more details. Another option is to use a Microchip 11XX
series EEPROM which can be rewritten up to a million times. A driver for these is included in the Embedded C
Modules folder in the Micromite firmware zip file.
Watchdog Timer
The main use for the Micromite is as an embedded controller. It can be programmed in MMBasic and when
the program is debugged and ready for "prime time" the AUTORUN configuration setting can be turned on.
The chip will then automatically run its program when power is applied and act as a custom integrated circuit
performing some special task. The user need not know anything about what is running inside the chip.
However there is the possibility that a fault in the program could cause MMBasic to generate an error and
return to the command prompt. This would be of little use in an embedded situation as the Micromite would
not have anything connected to the console. Another possibility is that the BASIC program could get itself
stuck in an endless loop for some reason. In both cases the visible effect would be the same… the program
would stop running until the power was cycled.
To guard against this the watchdog timer can be used. This is a timer that counts down to zero and when it
reaches zero the processor will be automatically restarted (the same as when power was first applied), this will
occur even if MMBasic was sitting at the command prompt. Following the restart the automatic variable
MM.WATCHDOG will be set to true to indicate that the restart was caused by a watchdog timeout.
The WATCHDOG command should be placed in strategic locations in the program to keep resetting the timer
and therefore preventing it from counting down to zero. Then, if a fault occurs, the timer will not be reset, it
will count down to zero and the program will be restarted (assuming the AUTORUN option is set).
PIN Security
Sometimes it is important to keep the data and program in an embedded controller confidential. In the
Micromite this can be done by using the OPTION PIN command. This command will set a pin number (which
Resetting MMBasic
MMBasic can be reset to its original configuration using either one of two methods:
The chip can be reprogrammed with the Micromite firmware using a PIC32 programmer.
Sending a stream of exclamation marks (!) to the console Rx pin at 38400 baud during its startup.
In the first 100 ms after powering up the Micromite will set the console to 38400 baud and check to see if
an exclamation mark is received. If so, it will then wait for two seconds to see if it is going to get more
than 30 of them in that time. If this is the case the Micromite will reset itself to its initial defaults and
send the message "MMBasic reset completed" to the console.
This reset can be accomplished by simply setting the terminal emulator to 38400 baud and holding down
the exclamation key and rely on the automatic keyboard repeat while powering up the Micromite (on
most keyboards this requires holding down shift and the number one key). This will even work if the
console has been set to a non standard baud rate.
Either method will result in the program memory and saved variables being completely erased and all options
(security PIN, console baud rate, etc) will be reset to their initial defaults.
The following table lists the connections required between the LCD display board and the Micromite:
Configuring MMBasic
To use the display MMBasic must be configured using the OPTION LCDPANEL command which is normally
entered at the command prompt. Every time the Micromite is restarted MMBasic will automatically initialise the
display. This command can also be embedded in a program with certain conditions – see the section "Special
Functions and the Library" for more details.
The syntax is:
OPTION LCDPANEL controller, orientation, D/C pin, reset pin [,CS pin]
Where:
'controller' can be either ILI9341 or ILI9341_I. Most panels require ILI9341 however some TFT panels require
that the colours be inverted and in that case ILI9341_I should be specified.
'orientation' can be LANDSCAPE, PORTRAIT, RLANDSCAPE or RPORTRAIT. These can be abbreviated to
L, P, RL or RP. The R prefix indicates the reverse or "upside down" orientation.
'D/C pin' and 'reset pin' are the Micromite I/O pins to be used for these functions. Any free pin can be used.
'CS pin' can also be any free I/O pin but is optional. If a touch controller is not used this parameter can be left off
the command and the CS pin on the LCD display wired permanently to ground. If the touch controller is used this
pin must then be specified and connected to a Micromite I/O pin.
As an example, this is the command that will configure the Micromite for the display used in the Micromite LCD
Backpack project:
OPTION LCDPANEL ILI9341, L, 2, 23, 6
In some circumstances it may be necessary to interrupt power to the LCD panel while the Micromite is running
(eg, to save battery power) and in that case the GUI RESET LCDPANEL command can be used to reinitialise
the display the same as in power up.
If the LCD panel is no longer required the command OPTION LCDPANEL DISABLE can be used which will
return the I/O pins for general use.
To test the display you can enter the command GUI TEST LCDPANEL. You should see an animated display of
colour circles being rapidly drawn on top of each other. Press the space key on the console’s keyboard to stop the
test.
Important: The above test may not work if the display has a touch controller and the touch controller has not been
configured (ie, the touch Chip Select pin is floating). In this case configure the touch controller (see below) and
then retry GUI TEST LCDPANEL.
NOTE: The CPU speed must be 20 MHz or greater.
To verify the configuration you can use the command OPTION LIST to list all options that have been set
including the configuration of the LCD panel.
Configuring Touch
To use the touch facility MMBasic must be configured using the OPTION TOUCH command which is normally
entered at the command prompt. This should be done after the LCD panel has been configured. Every time the
Micromite is restarted MMBasic will automatically initialise the touch controller. This command can also be
embedded in a program with certain conditions – see the section "Special Functions and the Library".
The syntax is:
OPTION TOUCH T_CS pin, T_IRQ pin
Where:
'T_CS pin' and 'T_IRQ pin' are the Micromite I/O pin numbers to be used for chip select and touch interrupt
respectively (any free pins can be used).
If the touch facility is no longer required use the command OPTION TOUCH DISABLE to disable the touch
feature and return the I/O pins for general use (the 'T_CS pin' should be held high to disable the controller).
Touch Functions
To detect if and where the screen is touched you can use the following functions in a BASIC program:
TOUCH(X)
Returns the X coordinate of the currently touched location.
TOUCH(Y)
Returns the Y coordinate of the currently touched location.
Both functions return -1 if the screen is not being touched. The Micromite Plus also provides a number of
additional functions. See the Micromite Plus Manual for more details.
Touch Interrupts
An interrupt can be set on the IRQ pin number that was specified when the touch facility was configured. To
detect touch down the interrupt should be configured as INTL (ie, high to low).
For example, if the command OPTION TOUCH 7, 15 was used to configure touch the following program will
print out the X and Y coordinates of any touch on the screen:
SETPIN 15, INTL, MyInt
DO : LOOP
SUB MyInt
PRINT TOUCH(X) TOUCH(Y)
END SUB
The interrupt can be cancelled with the command SETPIN pin, OFF.
Colours
Colour is specified as a true colour 24 bit number where the top eight bits represent the intensity of the red
colour, the middle eight bits the green intensity and the bottom eight bits the blue. The easiest way to generate
this number is with the RGB() function which has the form:
RGB(red, green, blue)
A value of zero for a colour represents black and 255 represents full intensity. The RGB() function also
supports a shortcut where you can specify common colours by naming them. For example, RGB(red) or
RGB(cyan). The colours that can be named using the shortcut form are white, black, blue, green, cyan, red,
magenta, yellow, brown and gray.
MMBasic will automatically translate all colours to the format required by the individual display controller
which, in the case of the ILI9341 controller, is 64K colours in the 565 format.
Note that the 24 bit number representing colour (ie, returned by the RGB() function) is too large to be accurately
stored in a floating point variable, instead the variable should be declared as an integer. Similarly, arguments
should be declared as integer if you are passing a colour value to a subroutine or function.
The default for commands that require a colour parameter can be set with the COLOUR command. This is
handy if your program uses a consistent colour scheme, you can then set the defaults and use the short version
of the drawing commands throughout your program.
The COLOUR command takes the format:
COLOUR foreground-colour, background-colour
Fonts
MMBasic for the 28 and 44-pin Micromites includes one built in font which is 8 pixels wide by 13 pixels high
and includes all 95 standard ASCII characters with the back quote character (60 hex or 96 decimal) replaced
with the degree symbol (º). Within MMBasic this is referred to as font #1. The Micromite Plus has six built in
fonts (refer to the Micromite Plus Manual for more details).
If required, additional fonts can be embedded in a BASIC program. The MMBasic firmware zip file includes
over a dozen fonts covering a wide range of character sets including a symbol font (Dingbats) which is handy
for creating on screen icons, etc. These fonts work exactly same as the built in font (ie, selected using the
FONT command or specified in the TEXT command).
The format of an embedded font is:
DefineFont #Nbr
hex [[ hex[…]
hex [[ hex[…]
END DefineFont
Drawing Commands
Most drawing commands have optional parameters. You can completely leave these off the end of a command
or you can use two commas in sequence to indicate a missing parameter. For example, the fifth parameter of
the LINE command is optional so you can use this format:
LINE 0, 0, 100, 100, , rgb(red)
Optional parameters are indicated below by italics, for example: font.
In the following commands C is the drawing colour and defaults to the current foreground colour. FILL is the
fill colour which defaults to -1 which indicates that no fill is to be used.
The drawing commands are:
CLS C
Clears the screen to the colour C. If C is not specified the current default background colour will be used.
PIXEL X, Y, C
Illuminates a pixel. If C is not specified the current default foreground colour will be used.
LINE X1, Y1, X2, Y2, LW, C
Draws a line starting at X1 and Y1 and ending at X2 and Y2.
LW is the line’s width and is only valid for horizontal or vertical lines. It defaults to 1 if not specified or if
the line is a diagonal.
BOX X, Y1, W, H, LW, C, FILL
Draws a box starting at X and Y1 which is W pixels wide and H pixels high.
LW is the width of the sides of the box and can be zero. It defaults to 1.
RBOX X, Y1, W, H, R, C, FILL
Draws a box with rounded corners starting at X and Y1 which is W pixels wide and H pixels high.
R is the radius of the corners of the box. It defaults to 10.
CIRCLE X, Y, R, LW, A, C, FILL
Draws a circle with X and Y as the centre and a radius R. LW is the width of the line used for the
circumference and can be zero (defaults to 1). A is the aspect ratio which is a floating point number and
defaults to 1. For example, an aspect of 0.5 will draw an oval where the width is half the height.
TEXT X, Y, STRING, ALIGNMENT, FONT, SCALE, C, BC
Displays a string starting at X and Y. ALIGNMENT is 0, 1 or 2 characters (a string expression or variable
is also allowed) where the first letter is the horizontal alignment around X and can be L, C or R for LEFT,
CENTER or RIGHT aligned text and the second letter is the vertical alignment around Y and can be T, M
or B for TOP, MIDDLE or BOTTOM aligned text. The default alignment is left/top. The Micromite Plus
can also use an additional code letter to rotate the text (see the Micromite Plus Manual for the details).
Example
As an example the following program will draw a simple digital clock on an ILI9341 based LCD display. The
program will terminate and return to the command prompt if the display screen is touched.
First the display and touch options must be configured by entering commands similar to these at the command
prompt:
OPTION LCDPANEL ILI9341, L, 2, 23, 6
OPTION TOUCH 7, 15
These settings specify an ILI9341 based display in the landscape orientation and uses pins 2, 23 and 6 for the
LCD and pins 7 and 15 for the touch controller (all on the 28-pin Micromite). They suit the Micromite LCD
Backpack (see next chapter) but your configuration could be different.
Next the touch feature should be calibrated by entering this command and following the calibration procedure.
GUI CALIBRATE
DO
TEXT MM.HRes/2, MM.VRes/4, TIME$, "CM", 1, 4, RGB(CYAN), DBlue
TEXT MM.HRes/2, MM.VRes*3/4, DATE$, "CM"
IF TOUCH(X) <> -1 THEN END
LOOP
The program starts by defining a constant with a value corresponding to a dark blue colour and then sets the
defaults for the colours and the font. It then draws a box with red walls and a dark blue interior.
Following this the program enters a continuous loop where it performs three functions:
1. Displays the current time inside the previously drawn box. The string is drawn centred both horizontally
and vertically in the middle of the box. Note that the TEXT command overrides both the default font and
colours to set its own parameters.
2. Draws the date centred in the lower half of the screen. In this case the TEXT command uses the default
font and colours previously set.
3. Checks for a touch on the screen. This is indicated when the TOUCH(X) function returns something
other than -1. In that case the program will terminate.
The screen display should look like this (the font used in this illustration is different):
Configuring MMBasic
With the console connected you should have access to the console and the command prompt ">". You then
need to configure the Micromite for the LCD and touch connections to suit the Micromite LCD Backpack. To
do this you should issue the following commands at the command prompt:
OPTION LCDPANEL ILI9341, L, 2, 23, 6
OPTION TOUCH 7, 15
You then need to calibrate the touch panel using this command:
GUI CALIBRATE
This will cause MMBasic to draw a sequence of four targets (the first is
shown on the right). Using a pointy but blunt object (eg, a toothpick) press
on the exact centre of the target and MMBasic will step onto the next target
and so on until all four targets have been processed.
The full details of these setup commands are described in the previous
chapters of this manual.
3.3V +5V
Infrared Remote Control Transmitter
Using the IRSEND command you can transmit a 12 bit Sony infrared
remote control signal. This is intended for Micromite to Micromite 58 ohms
communications but it will also work with Sony equipment that uses
12 bit codes. Note that all Sony products require that the message be
sent three times with a 26 ms delay between each message. IR
In previous versions of the Micromite firmware this command was Micromite LED
built into MMBasic but now it is distributed as a CSub module
which works exactly the same. See the file IRSend.pdf which is BC338
1K
included in the Embedded C Modules folder in the Micromite
firmware zip file.
The circuit on the right illustrates what is required. The transistor is
used to drive the infrared LED because the output of the Micromite is limited to about 10mA. This circuit
provides about 50 mA to the LED.
To send a signal you use the command:
IRSEND pin, dev, key
Where pin is the I/O pin used, dev is the device code to send and key is the key code. Any I/O pin on the
Micromite can be used and you do not have to set it up beforehand (IRSEND will automatically do that).
The modulation frequency used is 38 kHz and this matches the common IR receivers (described in the previous
page) for maximum sensitivity when communicating between two Micromites.
Measuring Temperature
The TEMPR() function will get the temperature from a DS18B20
temperature sensor. This device can be purchased on eBay for about $5 in a
3V to
variety of packages including a waterproof probe version. 5V
The DS18B20 can be powered separately by a 3V to 5V supply or it can 4.7K
operate on parasitic power from the Micromite as shown on the right. Any
Multiple sensors can be used but a separate I/O pin and a 4.7K pullup resistor Micromite
is required for each one. I/O Pin
To get the current temperature you just use the TEMPR() function in an Normal Power
expression. For example:
PRINT "Temperature: " TEMPR(pin)
Where 'pin' is the I/O pin to which the sensor is connected. You do not have
3V to
to configure the I/O pin, that is handled by MMBasic. 5V
The returned value is in degrees C with a resolution of 0.25 ºC and is accurate 4.7K
to ±0.5 ºC. If there is an error during the measurement the returned value Any
will be 1000. Micromite
I/O Pin
The time required for the overall measurement is 200ms and the running
program will halt for this period while the measurement is being made. This
Parasitic Power
also means that interrupts will be disabled for this period. If you do not want
this you can separately trigger the conversion using the TEMPR START
Measuring Distance
Using a HC-SR04 ultrasonic sensor and the DISTANCE() CFunction you can measure the distance to a target.
This device can be found on eBay for about $4 and it will measure the distance to a target from 3cm to 3m. It
works by sending an ultrasonic sound pulse and measuring the time it
takes for the echo to be returned.
Compatible sensors are the SRF05, SRF06, Parallax PING and the DYP-
ME007 (which is waterproof and therefore good for monitoring the level
of a water tank).
In previous versions of the Micromite firmware this function was built
into MMBasic but now it is distributed as a CFunction module which
works the same. See the file Distance.pdf which is included in the
Embedded C Modules folder in the Micromite firmware zip file.
On the Micromite you use the DISTANCE function as follows:
d = DISTANCE(trig, echo)
Where trig is the I/O pin connected to the "trig" input of the sensor and echo is the pin connected the "echo"
output of the sensor. You can also use 3-pin devices and in that case only one pin number is specified.
The value returned is the distance in centimetres to the target. The I/O pins are automatically configured by
this function but note that they should be 5V capable as the HC-SR04 is a 5V device.
LCD Display
The LCD command will display text on a standard LCD module with the
minimum of programming effort.
This command will work with LCD modules that use the KS0066,
HD44780 or SPLC780 controller chip and have 1, 2 or 4 lines. Typical
displays include the LCD16X2 (futurlec.com), the Z7001
(altronics.com.au) and the QP5512 (jaycar.com.au). eBay is another
good source where prices can range from $10 to $50.
To setup the display you use the LCD INIT command:
LCD INIT d4, d5, d6, d7, rs, en
d4, d5, d6 and d7 are the numbers of the I/O pins that connect to inputs D4, D5, D6 and D7 on the LCD module
(inputs D0 to D3 and R/W on the module should be connected to ground). 'rs' is the pin connected to the
register select input on the module (sometimes called CMD or DAT). 'en' is the pin connected to the enable or
chip select input on the module.
The following shows a typical usage where d4 to d7 are connected to pins 2 to 4 on the Micromite, rs is
connected to pin 23 and en to pin 24..
Note that this example also uses the TEMPR() function to get the temperature (described above).
Keypad Interface
A keypad is a low tech method of entering data into a Micromite based system. The Micromite supports either
a 4x3 keypad or a 4x4 keypad and the monitoring and decoding of key presses is done in the background.
When a key press is detected an interrupt will be issued where the program can deal with it.
Examples of a 4x3 keypad and a 4x4 keypad are the Altronics S5381 and S5383 (go to www.altronics.com).
To enable the keypad feature you use the command:
KEYPAD var, int, r1, r2, r3, r4, c1, c2, c3, c4
Where var is a variable that will be updated with the key code and int is the name of the interrupt subroutine to
call when a new key press has been detected. r1, r2, r3 and r4 are the pin numbers used for the four row
connections to the keypad (see the diagram below) and c1, c2, c3 and c4 are the column connections. c4 is only
used with 4x4 keypads and should be omitted if you are using a 4x3 keypad.
Any I/O pins on the Micromite can be used and you do not have to set them up beforehand, the KEYPAD
command will automatically do that for you.
R1
1 2 3 20
R2
4 5 6 21
R3
7 8 9 22
R4
10 0 11 23
Micromite
C1
C2
C3
C4
The detection and decoding of key presses is done in the background and the program will continue after this
command without interruption. When a key press is detected the value of the variable var will be set to the
number representing the key (this is the number inside the circles in the diagram above). Then the interrupt
will be called.
For example:
Keypad KeyCode, KP_Int, 2, 3, 4, 5, 21, 22, 23 ' 4x3 keyboard
DO
< body of the program >
LOOP
The full screen program editor is invoked with the EDIT command. The cursor will be automatically
positioned at the last place that you were editing at or, if your program had just been stopped by an error, the
cursor will be positioned at the line that caused the error.
If you are used to an editor like Notepad you will find that the operation of this editor is familiar. The arrow
keys will move your cursor around in the text, home and end will take you to the beginning or end of the line.
Page up and page down will do what their titles suggest. The delete key will delete the character at the cursor
and backspace will delete the character before the cursor. The insert key will toggle between insert and
overtype modes. About the only unusual key combination is that two home key presses will take you to the
start of the program and two end key presses will take you to the end.
At the bottom of the screen the status line will list the various function keys used by the editor and their action.
In more details these are:
ESC This will cause the editor to abandon all changes and return to the command prompt with
the program memory unchanged. If you have changed the text you will be asked if you
really what want to abandon your changes.
F1: SAVE This will save the program to program memory and return to the command prompt.
F2: RUN This will save the program to program memory and immediately run it.
F3: FIND This will prompt for the text that you want to search for. When you press enter the
cursor will be placed at the start of the first entry found.
SHIFT-F3 Once you have used the search function you can repeatedly search for the same text by
pressing SHIFT-F3.
F4: MARK This is described in detail below.
F5: PASTE This will insert (at the current cursor position) the text that had been previously cut or
copied (see below).
You can also use control keys instead of the functions keys listed above. These control keystrokes are:
LEFT Ctrl-S RIGHT Ctrl-D UP Ctrl-E DOWN Ctrl-X
HOME Ctrl-U END Ctrl-K PageUp Ctrl-P PageDn Ctrl-L
DEL Ctrl-] INSERT Ctrl-N F1 Ctrl-Q F2 Ctrl-W
F3 Ctrl-R ShiftF3 Ctrl-G F4 Ctrl-T F5 Ctrl-Y
If you are using Tera Term, Putty, MMEdit or GFXterm as the terminal emulator it is also possible to position
the cursor by left clicking the PC's mouse in the terminal emulator's window.
The best way to learn the full screen editor is to simply fire it up and experiment.
The editor is a very productive method of writing a program. With the command EDIT you can write your
program on the Micromite. Then, by pressing the F2 key, you can save and run the program. If your program
stops with an error you can press the function key F4 which will run the command EDIT and place you back in
the editor with the cursor positioned at the line that caused the error. This edit/run/edit cycle is very fast.
Using the OPTION BAUDRATE command the baud rate of the console can be changed to any speed up to
230400 bps. Changing the console baud rate to a higher speed makes the full screen editor much faster in
redrawing the screen. If you have a reliable connection to the Micromite it is worth changing the speed to at
least 115200.
The editor expects that the terminal emulator is set to 24 lines per screen with each line 80 characters wide.
Both of these assumptions can be changed with the OPTION DISPLAY command to suit non standard
displays.
Note that a terminal emulator can lose its position in the text with multiple fast keystrokes (like the up and
down arrows). If this happens you can press the HOME key twice which will force the editor to jump to the
start of the program and redraw the display.
OPTION DEFAULT
A variable can be used without a suffix (ie, !, % or $) and in that case MMBasic will use the default type of
floating point. For example, the following will create a floating point variable:
Nbr = 1234
However the default can be changed with the OPTION DEFAULT command. For example, OPTION
DEFAULT INTEGER will specify that all variables without a specific type will be integer. So, the following
will create an integer variable:
OPTION DEFAULT INTEGER
Nbr = 1234
The default can be set to FLOAT (which is the default when a program is run), INTEGER, STRING or NONE.
In the latter case all variables must be specifically typed otherwise an error will occur.
The OPTION DEFAULT command can be placed anywhere in the program and changed at any time but good
practice dictates that if it is used it should be placed at the start of the program and left unchanged.
OPTION EXPLICIT
By default MMBasic will automatically create a variable when it is first referenced. So, Nbr = 1234 will
create the variable and set it to the number 1234 at the same time. This is convenient for short and quick
programs but it can lead to subtle and difficult to find bugs in large programs. For example, in the third line of
this fragment the variable Nbr has been misspelt as Nr. As a consequence the variable Nr would be created
with a value of zero and the value of Total would be wrong.
Nbr = 1234
Incr = 2
Total = Nr + Incr
The OPTION EXPLICIT command tells MMBasic to not automatically create variables. Instead they must be
explicitly defined using the DIM or LOCAL commands (see below) before they are used.
CONST
Often it is useful to define an identifier that represents a value without the risk of the value being accidently
changed - which can happen if variables were used for this purpose (this practice encourages another class of
difficult to find bugs).
Using the CONST command you can create an identifier that acts like a variable but is set to a value that cannot
be changed. For example:
CONST InputVoltagePin = 26
CONST MaxValue = 2.4
The identifiers can then be used in a program where they make more sense to the casual reader than simple
numbers. For example:
IF PIN(InputVoltagePin) > MaxValue THEN SoundAlarm
A number of constants can be created on the one line:
CONST InputVoltagePin = 26, MaxValue = 2.4, MinValue = 1.5
The value used to initialise the constant is evaluated when the constant is created and can be an expression
including user defined functions.
The type of the constant is derived from the value assigned to it; so for example, MaxValue above will be a
floating point constant because 2.4 is a floating point number. The type of a constant can also be explicitly set
by using a type suffix (ie, !, % or $).
Digital Inputs
A digital input is the simplest type of input configuration. If the input voltage is higher than 2.5V the logic
level will be true (numeric value of 1) and anything below 0.65V will be false (numeric value of 0). The inputs
use a Schmitt trigger input so anything in between these levels will retain the previous logic level. Pins marked
as 5V are 5V tolerant and can be directly connected to a circuit that generates up to 5.5V without the need for
voltage dropping resistors.
In your BASIC program you would set the input as a digital input and use the PIN() function to get its level.
For example:
SETPIN 23, DIN
IF PIN(23) = 1 THEN PRINT "High"
The SETPIN command configures pin 23 as a digital input and the PIN() function will return the value of that
pin (the number 1 if the pin is high). The IF command will then execute the command after the THEN
statement if the input was high. If the input pin was low the program would just continue with the next line in
the program.
The SETPIN command also recognises a couple of options that will connect an internal resistor from the input
to either the supply or ground. This is called a "pullup" or "pulldown" resistor and is handy when connecting to
a switch as it saves having to install an external resistor to place a voltage across the contacts.
Analog Inputs
Pins marked as ANALOG can be configured to measure the voltage on the pin. The input range is from zero to
3.3V and the PIN() function will return the voltage. For example:
> SETPIN 23, AIN
> PRINT PIN(23)
2.345
>
You will need a voltage divider if you want to measure voltages greater than 3.3V. For small voltages you may
need an amplifier to bring the input voltage into a reasonable range for measurement.
The measurement uses the analog power pin (pin 28 on the 28-pin chip and 17 on the 44-pin chip) as the
reference voltage and MMBasic scales the reading by assuming that the voltage on this pin is exactly 3.3V.
Normally the Micromite is powered from a voltage regulator so this assumption is correct. However, when
battery power is used, the supply voltage can vary which will cause inaccurate readings. In that case the
program should scale the reading accordingly. For example:
A = (PIN(x) / 3.3) * PowerV
where "PowerV" is the voltage on the analog power pin.
The measurement of voltage is very sensitive to noise on the Analog Power and Ground pins. For accurate and
repeatable voltage measurements care should be taken with the PCB design to isolate the analog circuit from
the digital circuits and ensure that the Analog Power supply is as noise free as possible. Note that if the voltage
on an analog input is greater than the voltage on the Analog Power pin it can cause damage or a “CPU
Exception” (ie, crash) when an attempt is made to read that voltage.
Counting Inputs
The pins marked as COUNT can be configured as counting inputs to measure frequency, period or just count
pulses on the input.
For example, the following will print the frequency of the signal on pin 15:
> SETPIN 15, FIN
> PRINT PIN(15)
110374
>
In this case the frequency is 110.374 kHz.
Digital Outputs
All I/O pins can be configured as a standard digital output. This means that when an output pin is set to logic
low it will pull its output to zero and when set high it will pull its output to 3.3V. In MMBasic this is done
with the PIN command. For example PIN(15) = 0 will set pin 15 to low while PIN(15) = 1 will set it
high. When operating in this mode, a pin is capable of sourcing 10 mA which is sufficient to drive a LED or
other logic circuits running at 3.3V.
The "OC" option on the SETPIN command makes the output pin open collector. This means that the output
driver will pull the output low (to zero volts) when the output is set to a logic low but will go to a high
impedance state when set to logic high. If you then connect a pull-up resistor to 5V (on pins that are 5V
tolerant) the logic high level will be 5V (instead of 3.3V using the standard output mode). The maximum pull-
up voltage in this mode is 5.5V.
Interrupts
Interrupts are a handy way of dealing with an event that can occur at an unpredictable time. An example is
when the user presses a button. In your program you could insert code after each statement to check to see if
the button has been pressed but an interrupt makes for a cleaner and more readable program.
Subroutine Arguments
Defined subroutines can have arguments (sometimes called parameter lists). In the definition of the subroutine
they look like this:
SUB MYSUB (arg1, arg2$, arg3)
<statements>
<statements>
END SUB
And when you call the subroutine you can assign values to the arguments. For example:
MYSUB 23, "Cat", 55
Inside the subroutine arg1 will have the value 23, arg2$ the value of "Cat", and so on. The arguments act
like ordinary variables but they exist only within the subroutine and will vanish when the subroutine ends. You
can have variables with the same name in the main program and they will be different from arguments defined
for the subroutine (at the risk of making debugging harder).
When calling a subroutine you can supply less than the required number of values. For example:
MYSUB 23
In that case the missing values will be assumed to be either zero or an empty string. For example, in the above
case arg2$ will be set to "" and arg3 will be set to zero. This allows you to have optional values and, if the
value is not supplied by the caller, you can take some special action.
You can also leave out a value in the middle of the list and the same will happen. For example:
MYSUB 23, , 55
Will result in arg2$ being set to "".
Rather than using the type suffix (eg, the $ in arg2$) you can use the suffix AS <type> in the definition of the
subroutine argument and then the argument will be known as the specified type, even when the suffix is not
used. For example:
SUB MYSUB (arg1, arg2 AS STRING, arg3)
IF arg2 = "Cat" THEN …
END SUB
If you do not define the type of the argument it will default to float or that set by OPTION DFAULT. Further,
if you used OPTION DEFAULT NONE to force you to define the type of all variables you will also have to
define them in the subroutine or function definition.
Defined Functions
Defined functions are similar to defined subroutines with the main difference being that the function is used to
return a value in an expression. For example, if you wanted a function to convert a temperature from degrees
Celsius to Fahrenheit you could define:
FUNCTION Fahrenheit(C)
Fahrenheit = C * 1.8 + 32
END FUNCTION
Then you could use it in an expression:
Input " Enter a temperature in Celsius: ", t
PRINT "That is the same as" Fahrenheit(t) "F"
You could also define the reverse:
FUNCTION Celsius(F)
Celsius = (F - 32) * 0.5556
END FUNCTION
The rules for the argument list in a function are similar to subroutines. The only difference is that brackets are
required around the argument list when you are calling a function, even if there are no arguments (they are
optional when calling a subroutine).
To return a value from the function you assign a value to the function's name within the function. If the
function's name is terminated with a $, a % or a ! the function will return that type, otherwise it will return
whatever the OPTION DEFAULT is set to.
Passing Arrays
Single elements of an array can be passed to a subroutine or function and they will be treated the same as a
normal variable. For example, this is a valid way of calling the Swap subroutine (discussed above):
Swap dat(i), dat(i + 1)
This type of construct is often used in sorting arrays.
You can also pass one or more complete arrays to a subroutine or function by specifying the array with empty
brackets instead of the normal dimensions. For example, a(). In the subroutine or function definition the
associated parameter must also be specified with empty brackets. The type (ie, float, integer or string) of the
argument supplied and the parameter in the definition must be the same.
In the subroutine or function the array will inherit the dimensions of the array passed and these must be
respected when indexing into the array. If required the dimensions of the array could be passed as additional
arguments to the subroutine or function so it could correctly manipulate the array. The array is passed by
Early Exit
There can be only one END SUB or END FUNCTION for each definition of a subroutine or function. To exit
early from a subroutine (ie, before the END SUB command has been reached) you can use the EXIT SUB
command. This has the same effect as if the program reached the END SUB statement. Similarly you can use
EXIT FUNCTION to exit early from a function.
Recursion
Recursion is where a subroutine or function calls itself. You can do recursion in MMBasic but there are a
number of issues (these are a direct consequence of the limited memory on microcontrollers):
There is a fixed limit to the depth of recursion. In the Micromite and Micromite Plus this is 50 levels.
If you have many arguments to the subroutine or function and many LOCAL variables (especially
strings) you could easily run out of memory before reaching the 50 level limit.
Any FOR…NEXT loops and DO…LOOPs will be corrupted if the subroutine or function is recursively
called from within these loops.
Embedded C Routines
It is possible to add program modules that are written in the C language or MIPS assembler to MMBasic. They
are called CFunctions or CSubs and to the BASIC program they look the same as the MMBasic built in
functions and subroutines. Generally these modules can run much faster than a BASIC program and can more
easily access the special hardware features of the PIC32 microcontroller.
The firmware distribution for the Micromite includes a subdirectory titled "Embedded C Modules" which
contains a selection of embedded C routines and fonts plus notes on how use this feature and write your own
embedded C modules and create embedded fonts.
The Library
Using the LIBRARY feature it is possible to create BASIC functions, subroutines and embedded fonts and add
them to MMBasic to make them permanent and part of the language. For example, you might have written a
series of subroutines and functions that perform sophisticated bit manipulation; these could be stored as a
library and become part of MMBasic and perform the same as other built in functions that are already part of
the language. An embedded font can also be added the same way and used just like a normal font.
To install components into the library you need to write and test the routines as you would with any normal
BASIC routines. When they are working correctly you can use the LIBRARY SAVE command. This will
transfer the routines (as many as you like) to a non visible part of flash memory where they will be available to
any BASIC program but will not show when the LIST command is used and will not be deleted when a new
program is loaded or NEW is used. However, the saved subroutines and functions can be called from within
the main program and can even be run at the command prompt (just like a built in command or function).
Some points to note:
Library routines act exactly like normal BASIC code and can consist of any number of subroutines,
functions, embedded C routines and fonts. The only difference is that they do not show when a program
is listed and are not deleted when a new program is loaded.
Library routines can create and access global variables and are subject to the same rules as the main
program – for example, respecting OPTION EXPLICIT if it is set.
When the routines are transferred to the library MMBasic will compress them by removing comments,
extra spaces, blank lines and the hex codes in embedded C routines and fonts. This makes the library
space efficient, especially when loading large fonts. Following the save the program area is cleared.
You can use the LIBRARY SAVE command multiple times. With each save the new contents of the
program space are appended to the already existing code in the library.
You can use line numbers in the library but you cannot use a line number on an otherwise empty line as
the target for a GOTO, etc. This is because the LIBRARY SAVE command will remove any blank lines.
You can use READ commands in the library but they will default to reading DATA statements in the
main program memory. If you want to read from DATA statements in the library you must use the
RESTORE command before the first READ command. This will reset the pointer to the library space.
As an example you could save the following into the library:
CFunction CPUSpeed
00000000 3c02bf81 8c45f000 8c43f000 3c02003d 24420900 7ca51400 70a23002
3c040393 34848700 7c6316c0 00c41021 00621007 3c03029f 24636300 10430005
00402021 00002821 00801021 03e00008 00a01821 3c0402dc 34846c00 00002821
00801021 03e00008 00a01821
End CFunction
This would have the effect of adding a new function (called CPUSpeed) to MMBasic. You could even run it at
the command prompt:
> PRINT CPUSpeed()
40000000
Program Initialisation
The library can also include code that is not contained within a subroutine or function. This code (if it exists)
will be run automatically before a program starts running (ie, via the RUN command). This feature can be used
to initialise constants or setup MMBasic in some way. For example, if you wanted to set some constants you
could include the following lines in the library code:
CONST TRUE = 1
CONST FALSE = 0
For all intents and purposes the identifiers TRUE and FALSE have been added to the language and will be
available to any program that is run on the Micromite.
MM.STARTUP
There may be a need to execute some code on initial power up, regardless of the program in main memory.
Perhaps to initialise some hardware, set some options or print a custom startup banner. This can be
accomplished by creating a subroutine with the name MM.STARTUP and saving it in the library space (see
above). When the Micromite is first powered up or reset it will search for this subroutine and, if found, it will
be run once.
For example, if the Micromite has a real time clock attached, the library could contain the following code:
SUB MM.STARTUP
RTC GETTIME
END SUB
This would cause the internal clock within MMBasic to be set to the current time on every power up or reset.
Using MM.STARTUP is similar to using the OPTION AUTORUN feature, the difference being that the
AUTORUN option will cause the whole program in memory to be run from the start where MM.STARTUP
will just run the code within the subroutine. The AUTORUN option and MM.STARTUP can be used together
and in that case the MM.STARTUP subroutine is run first, then the program in main memory.
Note that you should not use MM.STARTUP for general setup of MMBasic (like dimensioning arrays, opening
communication channels, etc) before running a program. The reason is that when you use the RUN command
MMBasic will clear the interpreter's state ready for a fresh start. If you do want to setup MMBasic like this you
can place the code for this in the LIBRARY (but not in a subroutine or function) as this is run after the RUN
command has reset the interpreter's state but before the program in main memory is run.
MM.PROMPT
If a subroutine with this name exists it will be automatically executed by MMBasic instead of displaying the
command prompt. This can be used to display a custom prompt, set colours, define variables, etc all of which
will be active at the command prompt.
This subroutine can be located in the library space (recommended) or in the main program.
Note that MMBasic will clear all variables and I/O pin settings when a program is run so anything set in this
subroutine will only be valid for commands typed at the command prompt (ie, in immediate mode). To
initialise variables, constants, communications, etc for use inside a BASIC program the code for this should be
placed in the LIBRARY (but not in a subroutine or function).
As an example the following will display a custom prompt:
SUB MM.PROMPT
PRINT TIME$ "> ";
END SUB
Note that while constants can be defined they will not be visible because a constant defined inside a subroutine
is local to a subroutine. However, DIM will create variables that are global that that should be used instead.
Digital Inputs
Logic Low: 0 to 0.65V
Logic High: 2.5V to 3.3V on normal pins
2.5V to 5.5V on pins rated at 5V
Input Impedance: >1 MΩ. All digital inputs are Schmitt Trigger buffered.
Frequency Response: Up to 300 kHz (pulse width 20 nS or more) on the counting inputs (pins 15 to 18).
Analog Inputs
Voltage Range: 0 to 3.3V
Accuracy: Analog measurements are referenced to the supply voltage on pin 28 and the
ground on pin 27. If the supply voltage is precisely 3.3V the typical accuracy of
readings will be ±1%.
Input Impedance: >1 MΩ (for accurate readings the source impedance should be < 5K)
Digital Outputs
Typical current draw or sink ability on any I/O pin: 10 mA
Absolute maximum current draw or sink on any I/O pin: 15 mA
Absolute maximum current draw or sink for all I/O pins combined: 200 mA
Maximum open collector voltage: 5.5V
Timing Accuracy
All timing functions (the timer, tick interrupts, PWM frequency, baud rate, etc) are dependent on the
internal clock. The Micromite uses a fast RC oscillator which has a specified tolerance of ±0.9% but
typically is within ±0.1% at 24ºC.
PWM Output
Frequency range: 20 Hz to 500 kHz
Duty cycle: 0% to 100% with 0.1% resolution below 25 kHz
Flash Endurance
Over 20,000 erase/write cycles.
Every program save incurs one erase/write cycle. In a normal program development it is highly unlikely
that more than a few hundred program saves would be required.
Saved variables (VAR SAVE command) and configuration options (the OPTION command) also use one
erase/write cycle each time the command is used. Usage of the VAR SAVE command should be limited to
an average of once a day over the entire life of the chip (50 years).
Constants
Numeric constants may begin with a numeric digit (0-9) for a decimal constant, &H for a hexadecimal
constant, &O for an octal constant or &B for a binary constant. For example &B1000 is the same as the
decimal constant 8. Constants that start with &H, &O or &B are always treated as 64-bit integer constants.
Decimal constants may be preceded with a minus (-) or plus (+) and may be terminated with 'E' followed by an
exponent number to denote exponential notation. For example 1.6E+4 is the same as 16000.
If the decimal constant contains a decimal point or an exponent, it will be treated as a floating point constant;
otherwise it will be treated as a 64-bit integer constant.
String constants are surrounded by double quote marks ("). Eg, "Hello World".
Arithmetic operators:
^ Exponentiation (eg, b^n means bn)
* / \ MOD Multiplication, division, integer division and modulus (remainder)
+ - 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.
Logical operators:
NOT invert the logical value on the right (eg, NOT a=b is a<>b)
<> < > <= =< Inequality, less than, greater than, less than or equal to, less than or
>= => equal to (alternative version), greater than or equal to, greater than or
equal to (alternative version)
= equality
AND OR XOR Conjunction, disjunction, exclusive or
String operators:
+ Join two strings
<> < > <= =< Inequality, less than, greater than, less than or equal to, less than or
>= => equal to (alternative version), greater than or equal to, greater than or
equal to (alternative version)
= Equality
String comparisons respect case. For example "A" is greater than "a".
Implementation Characteristics
Maximum program size (as plain text) is 53KB. Note that MMBasic tokenises the program when it is stored in
flash so the final size in flash might vary from the plain text size.
Maximum length of a command line is 255 characters.
Maximum length of a variable name or a label is 32 characters.
Maximum number of dimensions to an array is 8.
Maximum number of arguments to commands that accept a variable number of arguments is 50.
Maximum number of nested FOR…NEXT loops is 10.
Maximum number of nested DO…LOOP commands is 10.
Maximum number of nested GOSUBs, subroutines and functions (combined) is 50.
Maximum number of nested multiline IF…ELSE…ENDIF commands is 10.
Maximum number of user defined subroutines and functions (combined): 100 (200 in the Micromite Plus)
Maximum number of interrupt pins that can be configured: 10
Numbers are stored and manipulated as single precision floating point numbers or 64-bit signed integers. The
maximum floating point number allowable is 3.40282347e+38 and the minimum is 1.17549435e-38. The
Micromite Plus uses double precision (see the Micromite Plus User Manual).
The range of 64-bit integers (whole numbers) that can be manipulated is ± 9223372036854775807.
Maximum string length is 255 characters.
Maximum line number is 65000.
Maximum number of background pulses launched by the PULSE command is 5.
Compatibility
MMBasic implements a large subset of Microsoft’s GW-BASIC. There are numerous differences due to
physical and practical considerations but most standard BASIC commands and functions are essentially the
same. An online manual for GW-BASIC is available at http://www.antonis.de/qbebooks/gwbasman/index.html
and this provides a more detailed description of the commands and functions.
MMBasic also implements a number of modern programming structures documented in the ANSI Standard for
Full BASIC (X3.113-1987) or ISO/IEC 10279:1991. These include SUB/END SUB, the DO WHILE …
LOOP, the SELECT…CASE statements and structured IF .. THEN … ELSE … ENDIF statements.
MM.VER The version number of the firmware as a floating point number in the form
aa.bbcc where aa is the major version number, bb is the minor version
number and cc is the revision number. For example version 5.03.00 will
return 5.03 and version 5.03.01 will return 5.0301.
MM.DEVICE$ A string representing the device or platform that MMBasic is running on.
Currently this variable will contain one of the following:
"Maximite" on the standard Maximite and compatibles.
"Colour Maximite" on the Colour Maximite and UBW32.
"Colour Maximite 2" on the Colour Maximite 2.
"DuinoMite" when running on one of the DuinoMite family.
"DOS" when running on Windows in a DOS box.
"Generic PIC32" for the generic version of MMBasic on a PIC32.
"Micromite" on the PIC32MX150/250
"Micromite MkII" on the PIC32MX170/270
"Micromite Plus" on the PIC32MX470
"Micromite Extreme" on the PIC32MZ series
MM.ERRNO If a statement caused an error which was ignored these variables will be set
MM.ERRMSG$ accordingly. MM.ERRNO is a number where non zero means that there was
an error and MM.ERRMSG$ is a string representing the error message that
would have normally been displayed on the console. They are reset to zero
and an empty string by RUN, ON ERROR IGNORE or ON ERROR SKIP.
MM.HRES Integers representing the horizontal and vertical resolution of the LCD
MM.VRES display panel (if configured) in pixels.
MM.FONTHEIGHT Integers representing the height and width of the current font (in pixels).
MM.FONTWIDTH
MM.I2C Following an I2C write or read command this integer variable will be set to
indicate the result of the operation as follows:
0 = The command completed without error.
1 = Received a NACK response
2 = Command timed out
MM.ONEWIRE Following a 1-Wire reset function this integer variable will be set to indicate
the result of the operation as follows:
0 = Device not found.
1 = Device found
‘ (single quotation mark) Starts a comment and any text following it will be ignored. Comments can
be placed anywhere on a line.
? (question mark) Shortcut for the PRINT command.
AUTOSAVE Enter automatic program entry mode.
or This command will take lines of text from the console serial input and save
AUTOSAVE CRUNCH them to memory. This mode is terminated by entering Control-Z which will
then cause the received data to be saved into program memory overwriting
the previous program.
The CRUNCH option instructs MMBasic to remove all comments, blank
lines and unnecessary spaces from the program before saving. This can be
used on large programs to allow them to fit into limited memory. CRUNCH
can be abbreviated to the single letter C.
At any time this command can be aborted by Control-C which will leave
program memory untouched.
This is one way of transferring a BASIC program into the Micromite. The
program to be transferred can be pasted into a terminal emulator and this
command will capture the text stream and store it into program memory. It
can also be used for entering a small program directly at the console input.
BOX x, y, w, h [, lw] [,c] Draws a box on the attached LCD panel with the top left hand corner at 'x'
[,fill] and 'y' with a width of 'w' pixels and a height of 'h' pixels.
'lw' is the width of the sides of the box and can be zero. It defaults to 1.
'c' specifies the colour and defaults to the default foreground colour if not
specified.
'fill' is the fill colour. It can be omitted or set to -1 in which case the box will
not be filled.
See the chapter "Basic Drawing Commands" for a definition of the colours
and graphics coordinates.
CFUNCTION name type [,type] Defines the binary code for an embedded machine code program module
hex [[ hex[…] written in C or MIPS assembler. The module will appear in MMBasic as the
command or function 'name' and can be used in the same manner as a built-
hex [[ hex[…]
in command or function.
END CFUNCTION
This command specifies the hex codes for the module. This code is
automatically programmed into MMBasic when the program is saved. Each
or 'hex' must be exactly eight hex digits representing the bits in a 32-bit word.
Each 'hex' word must be separated by one or more spaces and multiple
CSUB name(type [, type]) rtype lines of 'hex' words can be used. The command must be terminated by
hex [[ hex[…] a matching END CSUB or END CFUNCTION.
hex [[ hex[…] The first 'hex' word must be the offset (in 32-bit words) to the entry
point of the embedded routine (usually the function main()).
END CSUB
Multiple embedded routines can be used in a program with each
defining a different module with a different 'name'.
During execution MMBasic will skip over any CSUB or CFUNCTION
commands so they can be placed anywhere in the program.
Any errors in the data format will be reported when the program is saved.
The type of each parameter can be specified in the definition. For example:
CSub MySub integer, integer, string
Notes:
Memory usage is rounded to the nearest 1K byte.
Program memory is cleared by the NEW command.
General memory is used by serial I/O buffers, etc.
Variables and the general memory spaces are cleared by many
commands (eg, NEW, RUN, etc) as well as the specific commands
CLEAR and ERASE.
When a program is loaded it is first buffered in RAM which limits the
maximum program size. MMBasic tokenises the program when it is
stored in flash so the final size in flash might vary from this.
NEW Deletes the program in flash and clears all variables including saved
variables.
NEXT [counter-variable] [, NEXT comes at the end of a FOR-NEXT loop; see FOR.
counter-variable], etc The ‘counter-variable’ specifies exactly which loop is being operated on. If
no ‘counter-variable’ is specified the NEXT will default to the innermost
loop. It is also possible to specify multiple counter-variables as in:
NEXT x, y, z
ON ERROR ABORT This controls the action taken if an error occurs while running a program and
or applies to all errors discovered by MMBasic including syntax errors, wrong
data, missing hardware, etc.
ON ERROR IGNORE
ON ERROR ABORT will cause MMBasic to display an error message, abort
or
the program and return to the command prompt. This is the normal behaviour
ON ERROR SKIP [nn] and is the default when a program starts running.
or ON ERROR IGNORE will cause any error to be ignored.
ON ERROR CLEAR ON ERROR 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 of MMBasic will revert to ON ERROR ABORT.
If an error occurs and is ignored/skipped the read only variable MM.ERRNO
will be set to non zero and MM.ERRMSG$ will be set to the error message
that would normally be generated. These are reset to zero and an empty string
by ON ERROR CLEAR. They are also cleared when the program is run and
when ON ERROR IGNORE and ON ERROR SKIP are used.
ON ERROR IGNORE can make it very difficult to debug a program so it is
strongly recommended that only ON ERROR SKIP be used.
OPTION TAB 2 | 4 | 8 Set the spacing for the tab key. Default is 2.
This option will be remembered even when the power is removed.
OPTION TOUCH T_CS pin, Configures MMBasic for the touch sensitive feature of an attached LCD panel.
T_IRQ pin 'T_CS pin' and 'T_IRQ pin' are the Micromite I/O pins to be used for chip
or select and touch interrupt respectively (any free pins can be used).
OPTION TOUCH DISABLE
PAUSE delay Halt execution of the running program for ‘delay’ ms. This can be a
fraction. For example, 0.2 is equal to 200 µs. The maximum delay is
2147483647 ms (about 24 days).
Note that interrupts will be recognised and processed during a pause.
PIN( pin ) = value For a ‘pin’ configured as digital output this will set the output to low
(‘value’ is zero) or high (‘value’ non-zero). You can set an output high or
low before it is configured as an output and that setting will be the default
output when the SETPIN command takes effect.
See the function PIN() for reading from a pin and the command SETPIN for
configuring it. Refer to the chapter "Using the I/O pins" for a general
description of the Micromite's input/output capabilities.
PIXEL x, y [,c] Set a pixel on an attached LCD panel to a colour. 'x' is the horizontal
coordinate and 'y' is the vertical coordinate of the pixel. 'c' is a 24 bit
number specifying the colour. 'c' is optional and if omitted the current
foreground colour will be used.
See the chapter "Basic Drawing Commands" for a definition of the colours
and graphics coordinates.
POKE BYTE addr%, byte Will set a byte or a word within the PIC32 virtual memory space.
or POKE BYTE will set the byte (ie, 8 bits) at the memory location 'addr%' to
POKE WORD addr%, word% 'byte'. 'addr%' should be an integer.
or POKE WORD will set the word (ie, 32 bits) at the memory location 'addr%'
to 'word%'. 'addr%' and 'word%' should be integers.
POKE INTEGER addr%, int%
POKE INTEGER will set the MMBasic integer (ie, 64 bits) at the memory
or
location 'addr%' to int%'. 'addr%' and int%' should be integers.
POKE FLOAT addr%, float!
POKE FLOAT will set the word (ie, 32 bits) at the memory location 'addr%'
or to 'float!'. 'addr%' should be an integer and 'float!' a floating point number.
ABS( number ) Returns the absolute value of the argument 'number' (ie, any negative sign is
removed and a positive number is returned).
ACOS( number ) Returns the inverse cosine of the argument 'number' in radians.
ASC( string$ ) Returns the ASCII code (ie, byte value) for the first letter in ‘string$’.
ASIN( number ) Returns the inverse sine value of the argument 'number' in radians.
BIN$( number [, chars]) Returns a string giving the binary (base 2) value for the 'number'.
'chars' is optional and specifies the number of characters in the string with
zero as the leading padding character(s).
CINT( number ) Round numbers with fractional portions up or down to the next whole
number or integer.
For example, 45.47 will round to 45
45.57 will round to 46
-34.45 will round to -34
-34.55 will round to -35
See also INT() and FIX().
DATE$ Returns the current date based on MMBasic’s internal clock as a string in the
form "DD-MM-YYYY". For example, "28-07-2022".
The internal clock/calendar will keep track of the time and date including
leap years. To set the date use the command DATE$ =.
EOF( [#]nbr ) For a serial communications port this function will return true if there are no
characters waiting in the receive buffer. #0 can be used which refers to the
console's input buffer.
The # is optional. Also see the OPEN, INPUT and LINE INPUT commands
and the INPUT$ function.
EXP( number ) Returns the exponential value of 'number', ie, ex where x is 'number'.
HEX$( number [, chars]) Returns a string giving the hexadecimal (base 16) value for the 'number'.
'chars' is optional and specifies the number of characters in the string with
zero as the leading padding character(s).
INKEY$ Checks the console input buffer and, if there is one or more characters
waiting in the queue, will remove the first character and return it as a single
character in a string.
If the input buffer is empty this function will immediately return with an
empty string (ie, "").
INPUT$(nbr, [#]fnbr) Will return a string composed of ‘nbr’ characters read from a serial
communications port opened as 'fnbr'. This function will return as many
characters as are waiting in the receive buffer up to ‘nbr’. If there are no
characters waiting it will immediately return with an empty string.
#0 can be used which refers to the console's input buffer.
The # is optional. Also see the OPEN command.
INSTR( [start-position,] string- Returns the position at which 'string-pattern$' occurs in 'string-searched$',
searched$, string-pattern$ ) beginning at 'start-position'. If 'start-position' is not provided it will default
to 1.
Both the position returned and 'start-position' use 1 for the first character, 2
for the second, etc.
The function returns zero if 'string-pattern$' is not found.
INT( number ) Truncate an expression to the next whole number less than or equal to the
argument. For example 9.89 will return 9 and -2.11 will return -3.
This behaviour is for Microsoft compatibility, the FIX() function provides a
true integer function.
See also CINT() .
LEFT$( string$, nbr ) Returns a substring of ‘string$’ with ‘nbr' of characters from the left
(beginning) of the string.
LOC( [#]fnbr ) For a serial communications port opened as 'fnbr' this function will return the
number of bytes received and waiting in the receive buffer to be read.
#0 can be used which refers to the console's input buffer.
The # is optional.
MAX( arg1 [, arg2 [, …]] ) Returns the maximum or minimum number in the argument list.
or Note that the comparison is a floating point comparison (integer arguments
MIN( arg1 [, arg2 [, …]] ) are converted to floats) and a float is returned.
MID$( string$, start ) Returns a substring of ‘string$’ beginning at ‘start’ and continuing for ‘nbr’
or characters. The first character in the string is number 1.
MID$( string$, start, nbr ) If ‘nbr’ is omitted the returned string will extend to the end of ‘string$’
OCT$( number [, chars]) Returns a string giving the octal (base 8) representation of 'number'.
'chars' is optional and specifies the number of characters in the string with
zero as the leading padding character(s).
PEEK(BYTE addr%) Will return a byte or a word within the PIC32 virtual memory space.
or BYTE will return the byte (8-bits) located at 'addr%'
PEEK(WORD addr%) WORD will return the word (32-bits) located at 'addr%'
or INTEGER will return the integer (64-bits) located at 'addr%'
PEEK(INTEGER addr%) FLOAT will return the floating point number (32-bits) located at 'addr%'
or VARADDR will return the address (32-bits) of the variable 'var' in memory.
PEEK(FLOAT addr%) An array is specified as var().
or CFUNADDR will return the address (32-bits) of the CFunction 'cfun' in
memory. This address can be passed to another CFunction which can then
PEEK(VARADDR var)
call it to perform some common process.
or
VAR, will return a byte in the memory allocated to 'var'. An array is
PEEK(CFUNADDR cfun) specified as var().
or VARTBL, will return a byte in the memory allocated to the variable table
PEEK(VAR var, ±offset) maintained by MMBasic. Note that there is a comma after the keyword
or VARTBL.
PEEK( VARTBL, ±offset) PROGMEM, will return a byte in the memory allocated to the program.
or Note that there is a comma after the keyword PROGMEM.
PEEK( PROGMEM, ±offset) Note that 'addr%' should be an integer.
For backwards compatibility PEEK( hiword, loword ) is still accepted. In
this case the address is specifies by ‘hiword’ which is the top 16 bits of the
address while ‘loword’ is the bottom 16 bits.
This command is for expert users only. The PIC32 maps all control
registers, flash (program) memory and volatile (RAM) memory into a single
address space so there is no need for INP or OUT commands. The
PIC32MX170 Family Data Sheet lists the details of this address space (RAM
starts at 0xA0000000, Program Flash starts at 0x9D000000 and Boot Flash
starts at 0x9FC00000).
PORT(start, nbr [,start, nbr]…) Returns the value of a number of I/O pins in one operation.
'start' is an I/O pin number and its value will be returned as bit 0. 'start'+1 will
be returned as bit 1, 'start'+2 will be returned as bit 2, and so on for 'nbr'
number of bits. I/O pins used must be numbered consecutively and any I/O pin
that is invalid or not configured as an input will cause an error. The start/nbr
pair can be repeated up to 25 times if additional groups of input pins need to
be added.
This function will also return the state of a pin configured as an output. It
can be used to conveniently communicate with parallel devices like memory
chips. Any number of I/O pins (and therefore bits) can be used from 1 to the
number of I/O pins on the chip.
See the PORT command to simultaneously output to a number of pins.
PULSIN( pin, polarity ) Measures the width of an input pulse from 1µs to 1 second with 0.1µs
or resolution.
PULSIN( pin, polarity, t1 ) 'pin' is the I/O pin to use for the measurement, it must be previously
configured as a digital input. 'polarity' is the type of pulse to measure, if
or
zero the function will return the width of the next negative pulse, if non zero
PULSIN( pin, polarity, t1, t2 ) it will measure the next positive pulse.
't1' is the timeout applied while waiting for the pulse to arrive, 't2' is the
timeout used while measuring the pulse. Both are in microseconds (µs) and
are optional. If 't2' is omitted the value of 't1' will be used for both timeouts.
If both 't1' and 't2' are omitted then the timeouts will be set at 100000 (ie,
100ms).
This function returns the width of the pulse in microseconds (µs) or -1 if a
timeout has occurred. With a CPU speed of 40MHz the measurement is
accurate to ±0.5% and ±0.5µs. At other speeds the measurement is slightly
less accurate.
Note that this function will cause the running program to pause while the
measurement is made and interrupts will be ignored during this period.
SGN( number ) Returns the sign of the argument 'number', +1 for positive numbers, 0 for 0,
and -1 for negative numbers.
STR$( number ) Returns a string in the decimal (base 10) representation of 'number'.
or If 'm' is specified sufficient spaces will be added to the start of the number to
STR$( number, m ) ensure that the number of characters before the decimal point (including the
negative or positive sign) will be at least 'm' characters. If 'm' is zero or the
or
number has more than 'm' significant digits no padding spaces will be added.
STR$( number, m, n )
If 'm' is negative, positive numbers will be prefixed with the plus symbol and
or negative numbers with the negative symbol. If 'm' is positive then only the
STR$( number, m, n, c$ ) negative symbol will be used.
'n' is the number of digits required to follow the decimal place. If it is zero
the string will be returned without the decimal point. If it is negative the
output will always use the exponential format with 'n' digits resolution. If 'n'
is not specified the number of decimal places and output format will vary
automatically according to the number.
'c$' is a string and if specified the first character of this string will be used as
the padding character instead of a space (see the 'm' argument).
Examples:
STR$(123.456) will return "123.456"
STR$(-123.456) will return "-123.456"
STR$(123.456, 1) will return "123.456"
STR$(123.456, -1) will return "+123.456"
STR$(123.456, 6) will return " 123.456"
STR$(123.456, -6) will return " +123.456"
STR$(-123.456, 6) will return " -123.456"
STR$(-123.456, 6, 5) will return " -123.45600"
STR$(-123.456, 6, -5) will return " -1.23456e+02"
STR$(53, 6) will return " 53"
STR$(53, 6, 2) will return " 53.00"
STR$(53, 6, 2, "*") will return "****53.00"
STRING$( nbr, ascii ) Returns a string 'nbr' bytes long consisting of either the first character of
or string$ or the character representing the ASCII value 'ascii' which is an
integer or float number in the range of 0 to 255.
STRING$( nbr, string$ )
TAB( number ) Outputs spaces until the column indicated by 'number' has been reached on
the console output.
TIME$ Returns the current time based on MMBasic's internal clock as a string in the
form "HH:MM:SS" in 24 hour notation. For example, "14:30:00".
To set the current time use the command TIME$ = .
TIMER Returns the elapsed time in milliseconds (eg, 1/1000 of a second) since reset.
The timer is reset to zero on power up or a CPU restart and you can also
reset it by using TIMER as a command. If not specifically reset it will
continue to count up forever (it is a 64 bit number and therefore will only
roll over to zero after 200 million years).
VAL( string$ ) Returns the numerical value of the ‘string$’. If 'string$' is an invalid number
the function will return zero.
This function will recognise the &H prefix for a hexadecimal number, &O
for octal and &B for binary.
Note that these commands may be removed in the future to recover memory for other features.
GOSUB target Initiates a subroutine call to the target, which can be a line number or a label.
The subroutine must end with RETURN.
New programs should use defined subroutines (ie, SUB…END SUB).
IF condition THEN linenbr For Microsoft compatibility a GOTO is assumed if the THEN statement is
followed by a number. A label is invalid in this construct.
New programs should use: IF condition THEN GOTO linenbr | label
IRETURN Returns from an interrupt when the interrupt destination was a line number
or a label.
New programs should use a user defined subroutine as an interrupt
destination. In that case END SUB or EXIT SUB will cause a return from
the interrupt.
ON nbr GOTO | GOSUB ON either branches (GOTO) or calls a subroutine (GOSUB) based on the
target[,target, target,...] rounded value of 'nbr'; if it is 1, the first target is called, if 2, the second
target is called, etc. Target can be a line number or a label.
New programs should use SELECT CASE.
SPC( number ) This function returns a string of blank spaces 'number' bytes long. It is
similar to the SPACE$() function and is only included for Microsoft
compatibility.
POS For the console, returns the current cursor position in the line in characters.
Baud Rate
On the 28 and 44-pin Micromites COM1: is implemented using the onboard UART in the PIC32 while COM2: is
implemented in software and therefore cannot run as fast. The maximum speed for both COM ports is limited by
the CPU's speed as listed below (the CPU speed can be changed with the CPU SPEED command):
Note that below these limits any baud rate can be chosen, for example 1111 bps is a valid speed for both ports.
On the Micromite Plus much greater speeds can be specified for all four possible serial ports (see the Micromite
Plus Manual for the details).
Examples
Opening a serial port using all the defaults:
OPEN "COM2:" AS #2
Opening a serial port specifying only the baud rate (4800 bits per second):
OPEN "COM2:4800" AS #1
Opening a serial port specifying the baud rate (9600 bits per second) and receive buffer size (1KB):
OPEN "COM1:9600, 1024" AS #8
The same as above but with two stop bits enabled:
OPEN "COM1:9600, 1024, S2" AS #8
An example specifying everything including an interrupt, an interrupt level, inverted and two stop bits:
OPEN "COM1:19200, 1024, ComIntLabel, 256, INV, S2" AS #5
Interrupts
The interrupt subroutine (if specified) will operate the same as a general interrupt on an external I/O pin (see
the chapter "Using the I/O pins" for a description).
When using interrupts you need to be aware that it will take some time for MMBasic to respond to the interrupt
and more characters could have arrived in the meantime, especially at high baud rates. For example, if you
have specified the interrupt level as 200 characters and a buffer of 256 characters then quite easily the buffer
will have overflowed by the time the interrupt subroutine can read the data. In this case the buffer should be
increased to 512 characters or more. Similarly, if the interrupt has been set to trigger on a certain character
there may have been more characters received following that character by the time the interrupt subroutine has
been called.
IEEE 485
The 'DE' option in the OPEN comspec$ for COM1: specifies that the Data output Enable (ENABLE) signal for
the IEEE 485 protocol will be generated. This signal will appear on pin 7 on the 28-pin chip and is normally
high. Just before a byte is transmitted this output will go low and when the byte has finished transmission the
output will go high again. Note that this polarity is the opposite of that used in the Maximite family and an
inverter is normally required to drive the DE input of an IEEE 485 transceiver.
Many IEEE 485 systems also use 9 bits of data for transmit and receive. The 9th bit is used to indicate that an
address is being sent or received. To accommodate this the '9BIT' option in the OPEN comspec$ for COM1:
can be used. With this option all data sent must be sent in pairs of bytes – the first byte is the 9th bit and the
second is the data (the other 8 bits). The first byte should be either the ASCII character '1' to indicate that the
9th bit should be set or '0' for not set. This 9th bit is then applied to the second byte in the pair and together they
represent the 9 bits of data to send.
For example, the following fragment of code will send three 9 bit data items. The first is an address (bit 9 is
high) and the second two are the data (bit 9 is low):
OPEN "COM1: 4800, 9BIT" as #1
PRINT "1" + CHR$(211);
PRINT "0" + CHR$(23);
PRINT "0" + CHR$(0);
Note that in the PRINT commands the automatic CR/LF is suppressed by the use of the semicolon.
Received data is similar. The 9bit data is translated into two characters – the first is the ASCII character '1' or
'0' indicating the state of the 9th bit in the data received and the second character is the other 8 bits. This means
that a BASIC program must read the data as pairs and apply logic to determine the value of the 9th bit (the first
character) and then take the appropriate action with the second character.
For example:
IF LOC(#1) >= 2 THEN ' check that we have at least two bytes
A$ = INPUT$(1, #1) : B$ = INPUT$(1, #1)
IF A$ = "1" THEN
' B$ contains an address
ELSE
' B$ contains some data
ENDIF
ENDIF
I2C READ addr, Get data from the I2C slave device.
option, rcvlen, rcvbuf ‘addr’ is the slave’s I2C address.
‘option’ is a number between 0 and 3 (normally this is set to 0)
1 = Keep control of the bus after the command (a stop condition will not be sent
at the completion of the command)
2 = Treat the address as a 10 bit address
3 = Combine 1 and 2 (hold the bus and use 10 bit addresses).
‘rcvlen’ is the number of bytes to receive.
‘rcvbuf’ is the variable or array used to save the received data - this can be:
A string variable. Bytes will be stored as sequential characters in the string.
A one dimensional array of numbers specified with empty brackets. Received
bytes will be stored in sequential elements of the array starting with the first.
Example: I2C READ &H6F, 0, 3, ARRAY()
A normal numeric variable (in this case rcvlen must be 1).
And similarly there are four commands for the slave mode:
I2C SLAVE WRITE Send the data to the I2C master. This command should be used in the send
sendlen, senddata interrupt (ie in the 'send_int' subroutine when the master has requested data).
[,sendata ....] Alternatively a flag can be set in the interrupt subroutine and the command
invoked from the main program loop when the flag is set.
‘sendlen is the number of bytes to send.
‘senddata’ is the data to be sent. This can be specified in various ways, see the I2C
WRITE commands for details.
I2C SLAVE READ Receive data from the I2C master device. This command should be used in the
rcvlen, rcvbuf, rcvd receive interrupt (ie in the 'rcv_int' subroutine when the master has sent some
data). Alternatively a flag can be set in the receive interrupt subroutine and the
command invoked from the main program loop when the flag is set.
‘rcvlen’ is the maximum number of bytes to receive.
‘rcvbuf’ is the variable to receive the data. This can be specified in various ways,
see the I2C READ commands for details.
‘rcvd’ is a variable that, at the completion of the command, will contain the actual
number of bytes received (which might differ from ‘rcvlen’).
I2C SLAVE CLOSE Disables the slave I2C module and returns the external I/O pins 12 and 13 to a "not
configured" state. They can then be configured using SETPIN.
Following an I2C write or read command the automatic variable MM.I2C will be set to indicate the result of the
operation as follows:
0 = The command completed without error.
1 = Received a NACK response
2 = Command timed out
10 Bit Addressing
10-bit addressing was designed to be compatible with 7-bit addresses, allowing developers to mix the two types
of devices on a single bus. Devices that use 10-bit addresses will be clearly identified as such in their data
sheets.
In 10-bit addressing the slave address is sent in two bytes with the first byte beginning with a special bit pattern
to indicate that a 10 bit address is being used. This process is automatically managed by MMBasic when the
'option' argument is set for 10-bit addressing. 10-bit addresses can be in the range of 0 to 3FF (hex).
Master/Slave Modes
The master and slave modes can be enabled simultaneously; however, once a master command is in progress,
the slave function will be "idle" until the master releases the bus. Similarly, if a slave command is in progress,
the master commands will be unavailable until the slave transaction completes.
In master mode, the I2C send and receive commands will not return until the command completes or a timeout
occurs (if the timeout option has been specified).
The slave mode uses an MMBasic interrupt to signal a change in status and in this routine the Micromite should
write/read the data as specified by the I2C master. This operates the same as a general interrupt on an external
I/O pin.
I/O Pins
Refer to pinout charts at the beginning of this manual for the pin numbers used for the I2C data line (SDA) and
clock (SCL). Both of these pins should have external pullup resistors installed (typical values are 10 KΩ for
100 kHz or 2 KΩ for 400 kHz). Weak pullups (about 100K) on both the clock and data lines can also be
specified in the I2C OPEN command. I2C normally requires lower value resistors but for short signal lines at
slow speeds this may be all that is required.
When the I2C CLOSE command is used the I/O pins are reset to a "not configured" state. Then can then be
configured as per normal using SETPIN.
When running the I2C bus at above 150 kHz the cabling between the devices becomes important. Ideally the
cables should be as short as possible (to reduce capacitance) and also the data and clock lines should not run
next to each other but have a ground wire between them (to reduce crosstalk).
If the data line is not stable when the clock is high, or the clock line is jittery, the I2C peripherals can get
"confused" and end up locking the bus (normally by holding the clock line low). If you do not need the higher
speeds then operating at 100 kHz is the safest choice.
The 1-Wire protocol is often used in communicating with the DS18B20 temperature measuring sensor and to
help in that regard MMBasic includes the TEMPR() function which provides a convenient method of directly
reading the temperature of a DS18B20 without using these functions.
I/O Pins
The SPI OPEN command will automatically configure the relevant I/O pins. The SPI pinouts are listed at the
start of the manual. MISO stands for Master In Slave Out and because the Micromite is always the master that
pin will be configured as an input. Similarly MOSI stands for Master Out Slave In and that pin will be
configured as an output.
When the SPI CLOSE command is used these pins will be returned to a "not configured" state. They can then
be configured as per normal using SETPIN.
SPI Open
To use the SPI function the SPI channel must be first opened.
The syntax for opening the SPI channel is:
SPI OPEN speed, mode, bits
Where:
‘speed’ is the speed of the clock. It is a number representing the clock speed in Hz. The maximum is
one quarter the CPU speed (ie, 10000000 at a CPU speed of 40 MHz).
'mode' is a single numeric digit representing the transmission mode – see Transmission Format below.
'bits' is the number of bits to send/receive. This can be 8, 16 or 32.
It is the responsibility of the program to separately manipulate the CS (chip select) pin if required.
Transmission Format
The most significant bit is sent and received first. The format of the transmission can be specified by the 'mode'
as shown below. Mode 0 is the most common format.
Mode Description CPOL CPHA
0 Clock is active high, data is captured on the rising edge and output on the falling edge 0 0
1 Clock is active high, data is captured on the falling edge and output on the rising edge 0 1
2 Clock is active low, data is captured on the falling edge and output on the rising edge 1 0
3 Clock is active low, data is captured on the rising edge and output on the falling edge 1 1
For a more complete explanation see: http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
Standard Send/Receive
When the SPI channel is open data can be sent and received using the SPI function. The syntax is:
received_data = SPI(data_to_send)
Note that a single SPI transaction will send data while simultaneously receiving data from the slave.
‘data_to_send’ is the data to send and the function will return the data received during the transaction.
‘data_to_send’ can be an integer or a floating point variable or a constant.
If you do not want to send any data (ie, you wish to receive only) any number (eg, zero) can be used for the
data to send. Similarly if you do not want to use the data received it can be assigned to a variable and ignored.
Bulk Send/Receive
Data can also be sent in bulk:
SPI WRITE nbr, data1, data2, data3, … etc
or
SPI WRITE nbr, string$
or
SPI WRITE nbr, array()
SPI Close
If required the SPI channel can be closed as follows (the I/O pins will be set to inactive):
SPI CLOSE
Using the SPI with the Colour LCD and Touch Features
The standard 28 and 44-pin Micromites have only one SPI channel so this must be shared between the display
and touch controllers (if these features are used) and the BASIC program. The Micromite Plus has two SPI
channels so this issue does not occur with this version.
To share the SPI port with a LCD display on the standard Micromite it must be opened in BASIC and closed
again without any intervening commands that might cause MMBasic to send/receive data to the display or
touch controllers. This includes commands such as CLS, LINE, etc and the TOUCH() function.
The following provides an example. The SPI port is opened and closed within the one function with no
intervening graphic or touch commands:
PIN(26) = 1 ' preset the pin high before it is setup
SETPIN 26, DOUT ' pin 26 will be used as the enable signal
CIRCLE 100, 100, 50 ' draw a circle (uses the SPI port)
nbr% = ReadSPI%() ' get the SPI data
x% = TOUCH(X) ' get the X touch location (uses the SPI port)
nbr2% = ReadSPI%() ' get the SPI data for a second time
y% = TOUCH(Y) ' get the Y touch location (uses the SPI port)
END
Examples
The following example shows how to use the SPI port for general I/O. It will send a command 80 (hex) and
receive two bytes from the slave SPI device using the standard send/receive function:
PIN(10) = 1 : SETPIN 10, DOUT ' pin 10 will be used as the enable signal
SPI OPEN 5000000, 3, 8 ' speed is 5 MHz and the data size is 8 bits
PIN(10) = 0 ' assert the enable line (active low)
junk = SPI(&H80) ' send the command and ignore the return
byte1 = SPI(0) ' get the first byte from the slave
byte2 = SPI(0) ' get the second byte from the slave
PIN(10) = 1 ' deselect the slave
SPI CLOSE ' and close the channel