Silicon ChipMicromite Tutorial, Part 3: strings and arrays - May 2017 SILICON CHIP
  1. Outer Front Cover
  2. Contents
  3. Publisher's Letter: Going off-grid could be a bad idea
  4. Feature: Technorama – a Community Radio Station Initiative by John Maizels
  5. Feature: Industrial Robots – coming to a workplace near you! by Dr David Maddison
  6. PartShop
  7. Project: Turn your 10MHz counter into a 6GHz+ counter by Nicholas Vinen
  8. Feature: Micromite Tutorial, Part 3: strings and arrays by Geoff Graham
  9. Product Showcase
  10. Feature: Check your tyre pressures from inside the car by Leo Simpson and Nicholas Vinen
  11. Project: The Microbridge: universal PIC32 programmer plus! by Geoff Graham
  12. Subscriptions
  13. Serviceman's Log: Getting sucked in by a vacuum cleaner by Dave Thompson
  14. Project: New Marine Ultrasonic Anti-Fouling Unit by John Clarke
  15. Project: Micromite BackPack V2 with touch-screen and USB by Geoff Graham
  16. Review: The latest digital hearing aids from BlameySaunders by Ross Tester
  17. Vintage Radio: HMV’s 64-52 Little Nipper by Charles Kosina
  18. PartShop
  19. Market Centre
  20. Advertising Index
  21. Outer Back Cover: Hare&Forbes MachineryHouse

This is only a preview of the May 2017 issue of Silicon Chip.

You can view 39 of the 112 pages in the full issue, including the advertisments.

For full access, purchase the issue for $10.00 or subscribe for access to the latest issues.

Items relevant to "Turn your 10MHz counter into a 6GHz+ counter":
  • 1000:1 6GHz+ Prescaler PCB [04112162] (AUD $7.50)
  • 1000:1 6GHz+ Prescaler PCB pattern (PDF download) [04112162] (Free)
  • 1000:1 6GHz+ Prescaler panel artwork (PDF download) (Free)
Articles in this series:
  • Getting Started with the Micromite (February 2017)
  • Getting Started with the Micromite (February 2017)
  • Getting Started with the Micromite, Part Two (March 2017)
  • Getting Started with the Micromite, Part Two (March 2017)
  • Micromite Tutorial, Part 3: strings and arrays (May 2017)
  • Micromite Tutorial, Part 3: strings and arrays (May 2017)
  • Getting Started with the Micromite, Part 4 (June 2017)
  • Getting Started with the Micromite, Part 4 (June 2017)
Items relevant to "The Microbridge: universal PIC32 programmer plus!":
  • Microbridge PCB [24104171] (AUD $2.50)
  • PIC16F1455-I/P programmed for the Microbridge [2410417A.HEX] (Programmed Microcontroller, AUD $10.00)
  • MCP1700 3.3V LDO (TO-92) (Component, AUD $2.00)
  • Microbridge complete kit (Component, AUD $20.00)
  • Software for the Microbridge (Free)
  • Microbridge PCB pattern (PDF download) [24104171] (Free)
Items relevant to "New Marine Ultrasonic Anti-Fouling Unit":
  • New Marine Ultrasonic Anti-Fouling Unit PCB [04104171] (AUD $15.00)
  • PIC16F88-I/P programmed for the New Marine Ultrasonic Anti-Fouling Unit [0410417A.HEX] (Programmed Microcontroller, AUD $15.00)
  • One 40kHz 50W ultrasonic transducer (Component, AUD $55.00)
  • ETD29 transformer components (AUD $15.00)
  • IPP80N06S4L-07 high-current N-channel Mosfet (TO-220) (Component, AUD $2.00)
  • New Marine Ultrasonic Anti-fouling unit lid panel artwork (PDF download) (Free)
Articles in this series:
  • New Marine Ultrasonic Anti-Fouling Unit (May 2017)
  • New Marine Ultrasonic Anti-Fouling Unit (May 2017)
  • New Marine Ultrasonic Anti-Fouling Unit, Part 2 (June 2017)
  • New Marine Ultrasonic Anti-Fouling Unit, Part 2 (June 2017)
Items relevant to "Micromite BackPack V2 with touch-screen and USB":
  • Micromite LCD BackPack V2 PCB [07104171] (AUD $7.50)
  • PIC16F1455-I/P programmed for the Microbridge [2410417A.HEX] (Programmed Microcontroller, AUD $10.00)
  • PIC32MX170F256B-50I/SP programmed for the Micromite Mk2 plus capacitor (Programmed Microcontroller, AUD $15.00)
  • 2.8-inch TFT Touchscreen LCD module with SD card socket (Component, AUD $25.00)
  • MCP1700 3.3V LDO (TO-92) (Component, AUD $2.00)
  • Micromite LCD BackPack V2 complete kit (Component, AUD $70.00)
  • Matte/Gloss Black UB3 Lid for 2.8-inch Micromite LCD BackPack (PCB, AUD $5.00)
  • Clear UB3 Lid for 2.8-inch Micromite LCD BackPack (PCB, AUD $5.00)
  • Gloss Black UB3 Lid for 2.8-inch Micromite LCD BackPack (PCB, AUD $4.00)
  • Software for the Microbridge (Free)
  • Firmware (HEX) file and documents for the Micromite Mk.2 and Micromite Plus (Software, Free)
  • Micromite LCD BackPack V2 PCB pattern (PDF download) [07104171] (Free)

Purchase a printed copy of this issue for $10.00.

Getting Started with the Micromite, Part 3 by Geoff Graham So far, we have covered some of the basic concepts involved with programming in MMBasic such as input/output commands, making decisions, looping and drawing graphics. Now we will move on to more advanced subjects such as data types, arrays and drawing text on the LCD screen. S o far in this series, all the numbers and variables that we have used were floating point types. Just to re-cap, a floating point number can contain a decimal point. For example, 123.45 is a floating point number; so is 17.0 (or even 17). Often the term “floating point” will be abbreviated to just “float” and MMBasic uses that abbreviation also. Most numbers that we use in everyday life (and programming) can be expressed as floats and so they are the default in MMBasic if you do not specify a number’s type. However, the limitation of floating point is that it stores numbers as an approximation with an accuracy of only 6 or 7 digits. For example, if you stored the number 1234.56789 in a floating point variable then printed it out, you would get 1234.57. You can try it out for yourself: a = 1234.56789 PRINT a 1234.57 Usually this is not a problem but there are some cases where you need to accurately store large numbers. Examples include tracking a GPS latitude/longitude to specify a location 40  Silicon Chip on the planet’s surface, the number of seconds since midnight on January 1st 1970, or interfacing with digital frequency synthesisers. As another example, say you want to store a colour value in a variable. We covered LCD panels and colours last month but as a quick reminder, MMBasic uses a 24-bit number to represent colour. The top eight bits are the intensity of the red colour (decimal 0 to 255), the middle eight bits represents the intensity of green and the bottom eight the blue colour. Any one of the 16 million possible colours can be specified using this single 24-bit number. Last month, we also described the RGB() function which can be used to generate this 24-bit number. It looks like this: RGB(red, green, blue) Where red is the intensity of the red colour (0 to 255) and similar for green and blue. Also, as explained last month, you could fill the screen with a colour by using the CLS command. For example: CLS RGB(255, 0, 255) Fills the screen with purple (generated by mixing red and blue but not green): All well and good but you might want to store this colour in a variable called “purp” and then use that variable instead of the long RGB function. So now your program is: purp = RGB(255, 0, 255) CLS purp If you run this program, you will find that the screen is filled with a funny pink colour, not purple. Try it yourself, type in the above two fragments of code and see. What is going on here? The answer is that we tried to store a 24-bit number (which has eight decimal digits) in a floating point variable which is only good for holding six or seven significant digits. The floating point variable “lost” the least significant four or five bits which are part of the eight bits that define the intensity of the blue component. This is where integer variables come in. Integer variables An integer variable in MMBasic takes up 64 bits (8 bytes) of RAM siliconchip.com.au and can accurately hold numbers up to 9,223,372,036,854,775,807 (or 19 digits), which is a very large number indeed – roughly the number of grains of sand on planet Earth. So an integer in MMBasic is big enough to hold a 24-bit number representing colour. It is easy to create integer variables; just add the percent symbol (%) as a suffix to a variable name. For example, “purp%” is an integer variable. So the above program to fill the screen with purple becomes: purp% = RGB(255, 0, 255) CLS purp% This works perfectly. The downside of an integer is that it cannot store fractions (ie, numbers after the decimal point). Any calculation that produces a fractional result will be rounded up or down to the nearest whole number when assigned to an integer. You can mix integers and floating point values within a program and MMBasic will make the necessary conversions, but if you want to maintain the full precision of integers you should avoid mixing the two. Strings Strings are another variable type (like floating point and integers). Strings are used to hold a sequence of characters. For example, in the command: equal), < (less than), etc. Comparisons like less than or greater than test for string sort order, so for example, “Abc” < “Abd” will test as true. Another example: IF Car$ = "Audi" OR Car$ = "BMW" OR Car$ = "Mercedes" THEN PRINT "German" String handling is one of MMBasic’s strengths and there are many ways to join, pull apart and generally manipulate strings using specialised string functions. For example, INSTR() will search a string to see if it contains a particular sub-string, MID$() will extract part of a string from another and VAL() will convert a string of digits into a numeric value that can be stored in a float or integer variable. For more details on these functions, refer to the Functions section of the Micromite User Manual. Displaying text on an LCD Last month we explained how to draw lines, circles etc on an LCD screen but equally important is the ability to display text on screen. This is done with the TEXT command which has the following syntax: TEXT x, y, string, justification, font, scale, colour, back-colour This has a lot of parameters and the following description might sound confusing but we will go through it in stages. First, x and y are the coordinates (in pixels) of where the text is to be positioned on the screen and string is the text that you want to display. justification is a two-letter code which specifies how to align the text, eg, whether it is left justified, centred, right justified etc (more on this later). Editor’s Note: left and right justified are not the correct terms. The proper terms would be left aligned or ragged right and right aligned or ragged left. These terms describe which side of the text is flush and which is “ragged”. font is the font number that should be used (the Micromite can have up to 16 fonts installed) and scale is the magnification factor applied; 1 is the normal font size, 2 doubles its height and width, 3 triples it etc. The last two parameters should be obvious; colour is the colour of the text itself and back-colour is the background colour for the text, ie, the colour for the pixels surrounding the letters. Most of these parameters are optional so you can just use the following to print the word “Hello” near the centre of the screen: TEXT 160, 120, "Hello" PRINT "Hello" “Hello” is a string constant. Note that string constants are always surrounded by double quotes. String variables names use the dollar symbol ($) as a suffix to identify them as a string instead of a normal floating point variable and you can use ordinary assignment to set their value. Here are some examples: Greeting$ = "Hello there" Car$ = "Holden" You can also join strings using the plus symbol (operator): Word1$ = "Hello" Word2$ = "World" Greeting$ = Word1$ + " " + Word2$ PRINT Greeting$ As you may have figured out, this will print “Hello World”. Strings can also be compared using operators such as = (equals), <> (not siliconchip.com.au Fig.1: when you run the demonstration text program, this is what you should see. The word “Hello” is displayed in all four corners of the screen using font 1 (the default built-in font) doubled in size. It demonstrates how the justification parameter can be used to position text. May 2017  41 The justification defaults to left-top (as explained below), the font defaults to font #1, the scale to 1, the colour to white and the background to black. Note that the current default font and colours can be changed in your program to avoid you needing to provide them to every TEXT command. The justification code consists of zero, one or two letters. The first letter can be L, C or R. These specify that the text should be horizontally positioned such that the left edge, centre or right edge is at the specified x coordinate. The second letter is the vertical placement around the y coordinate and can be T for top, M for middle or B for bottom. For example, to perfectly centre the text on a 320x240 pixel screen you can use: TEXT 160, 120, "Centred", CM The 28 and 44-pin Micromite each come with one default font installed while the 64-pin and 100-pin Micromite Plus come with eight fonts. On all of these devices, you can embed additional fonts in your BASIC program, up to a maximum of 16 total. The fonts are numbered from 1 to 16 and this is the number that you use in the TEXT command. The standard font on the 28-pin Micromite (font 1) is rather tiny so you will normally scale it by two or three times. For example, this is the previous example with the text tripled in size: TEXT 160, 120, "Centred", CM, 1, 3 Just to bring this together, the following will print the word “Hello” in all four corners of the screen using font 1 doubled in size (see Fig.1): TEXT 0, 0, "Hello", , 1, 2 TEXT 320, 0, "Hello", R, 1, 2 TEXT 0, 240, "Hello", B, 1, 2 TEXT 320, 240, "Hello", RB, 1, 2 Note that the TEXT command only accepts a string parameter for the text, so if you want to display a number (integer or float), you most convert it to a string first. The most convenient way to do this is with the STR$() function. For example, the following will display 123 in the centre of the screen: spd = 123 TEXT 160, 120, STR$(spd), CM You can always join strings together using the plus character (+) and this is handy when you want to build a string 42  Silicon Chip for the TEXT command. For example: spd = 123 TEXT 160, 120, "Speed: " + STR$(spd), CM Arrays Arrays are something which you will probably not think of as useful at first glance but when you do need to use them, you will find them very handy. An array is best thought of as a large number of variables which are created at the same time with each variable being identified by a number, which is called the index. A good way to think of an array is like the mailbox for an apartment building, where each box is numbered starting from one and each box is identical. An array is created by the DIM command, for example: DIM n(300) This creates an array of 301 elements. Note that in MMBasic, array elements are numbered starting at zero, so this is why there seems to be an extra element, making the total 301. If you want to set element number 100 in this array to (say) the number 876, you would do it this way: n(100) = 876 Arrays can contain floating point numbers, integers or even strings. The index used to access elements of the array need not be a constant number as shown above, it can be a variable which is changed to access different array elements. As an example of how you might use an array, consider the case where you would like to record the temperature for each day of the year and, at the end of the year, calculate the overall average. You could use ordinary variables to record the temperature for each day but you would need 365 of them and that would make your program very unwieldy indeed. Instead, you could define an array to hold the values like this: DIM daily_temp(365) Every day you would need to save the temperature in the correct location in the array (“day” is variable set to the day number): daily_temp(day) = temperature At the end of the year, it is simple to calculate the average for the year: sum = 0 FOR day = 1 TO 365 sum = sum + daily_temp(day) NEXT day PRINT "Average is: " sum/365 This is much easier that adding up and averaging 365 individual variables! The above arrays have a single dimension but you can have multiple dimensions if you wish. Going back to the mailbox analogy, this is similar to each row of mailboxes being for the apartments on a single floor and then having multiple rows, one for each floor. This is similar to a two-dimensional array, where you can identify a single mailbox using two numbers; the floor number and the apartment door number. For example, if you wished to record the temperature over five years you could dimension the array like this: DIM daily_temp(365, 5) The first index is the day in the year and the second is a number representing the year, between 1 and 5. The first element in an array You may note that above, we explained that MMBasic arrays start with element 0 but in the last example, we started indexing the array at index number one. Traditionally, in BASIC, the first element of an array is number one. But in more advanced programming languages, for many good reasons, the first element is normally numbered 0 instead. You can ignore element 0 and use only elements starting with 1, as we did above. However, this is a little wasteful as memory is allocated for element 0, whether or not you use it. If you consistently access array elements starting with index 1, you can save this memory by using the command “OPTION BASE 1” at the top of your program. Accessing element 0 in your program will then cause an error. The DIM command We have mentioned the DIM command above for defining arrays but it can also be used to create ordinary variables. For example, siliconchip.com.au Sample Program: Twinkle Twinkle Little Star The following is a fun little program that fills the LCD screen with a thousand and one twinkling multicoloured points of light (like twinkling stars). It is also a useful demonstration of how arrays can be used. The idea is that we want to fill the screen with lots of illuminated pixels but not too many. If we kept turning on pixels, eventually all of them will be turned on and the screen would look a mushy grey. This means that we must limit the number of pixels on at any time by turning off old pixels to make way for the new ones. And that in turn means that we must track the location of each pixel that we have turned on; a perfect job for arrays. Here it is: CLS DIM X(1000), Y(1000) DO FOR idx = 0 TO 1000 PIXEL X(idx), Y(idx), RGB(BLACK) X(idx) = RND * 320 Y(idx) = RND * 240 R = CINT(RND) * 255 G = CINT(RND) * 255 B = CINT(RND) * 255 PIXEL X(idx), Y(idx), RGB(R, G, B) NEXT idx LOOP We track the coordinate of each pixel that has been turned on using two arrays, “X” for the horizontal coordinates and “Y” for vertical. The variable “idx” is used to step through the elements of each array. The program first turns off the pixel identified by “idx” (sets its colour to black) and then it generates a new pair of random coordinates which are stored in the same location Fig.2: this the result of running the program described in the text, which in the arrays (ie, it overwrites the old pair). fills the LCD screen with a thousand and one twinkling multicoloured These coordinates are then used to turn points of light (like twinkling stars). It is a useful demonstration of how on the pixel at those coordinates with a ran- arrays can be used. dom colour. The method of generating the random coordinates and colours was described in last month’s tutorial. The FOR loop will increment “idx” from zero to 1000, stepping through all the elements (ie, stars) in the arrays. When the FOR loop has finished, the endless DO-LOOP which encapsulates it will then restart the process, erasing the last 1001 pixels set (one at a time) and turning on a new pixel as it erases an old one. This means that the program will run forever turning on and off pixels (remember that you can use CTRL-C to halt the program). When an array is created, MMBasic will automatically set each value to zero. Accordingly, for the first run through the FOR loop, the program will repeatedly set the pixel at coordinates 0, 0 (upper left corner) to black. However, that is not an issue because it was already black and with subsequent loops the program will run as expected, turning off pixels that were previously illuminated. Refer to Fig.2 to see what the result looks like. you can create a number of string variables like this: DIM STRING Car, Name, Street, City Note that because we defined these variables as strings using DIM, we do not need the $ suffix; the definition alone is enough for MMBasic to identify their type. When you use these variables in an expression you also do not need the type suffix, for example: City = "Sydney" You can also use the keyword INTEGER to define integer variables and FLOAT to do the same for floatsiliconchip.com.au ing point variables. This type of notation can also be used to define arrays. For example: DIM INTEGER seconds(200) The advantage of defining variables in this way is that they are clearly defined (generally at the start of the program) and their type (float, integer or string) is not subject to misinterpretation. You can strengthen this by using the following commands at the very top of your program: OPTION EXPLICIT OPTION DEFAULT NONE The first specifies to MMBasic that all variables must be defined using the DIM command before they can be used. The second specifies that the type of all variables must be specified when they are created. Why are these commands important? They avoid common programming errors, for example, if you accidentally misspell a variable’s name. Say your program has the current temperature saved in a variable called Temp but at one point you misspell it as Tmp. This will cause MMBasic to automatically May 2017  43 Now that you know how to write text on the touchscreen, next month we’ll explain how to create on-screen buttons and how to build graphical user interfaces using what you’ve learnt so far. This, plus what you’ve already learnt, will allow you to build projects with more intuitive controls. create a variable called Tmp and set its value to zero. This is obviously not what you intended and it could introduce a subtle error which could be hard to find – even if you were aware that something was not right. On the other hand, if you used the OPTION EXPLICIT command at the start of your program, MMBasic would refuse to automatically create the variable and instead would throw an error, thereby saving you from a probable headache. For small, quick and dirty programs, it is fine to allow MMBasic to automatically create variables but in larger programs you should always disable this feature with OPTION EXPLICIT. When a variable is created, it is set to zero (for float and integers) or an empty string (ie, contains no characters – “”) for a string variable. You can set its initial value to something else when it is created using DIM. For example: DIM FLOAT nbr = 12.56 DIM STRING Car = "Holden", City = "Adelaide" Subroutines A subroutine is a block of program code that is treated as a module and can be called from anywhere within your program. This is effectively equivalent to copying and pasting that code to the location where it is called, except that if you did that, you would have to maintain multiple copies of the code 44  Silicon Chip (and it would waste valuable flash space). A subroutine acts like a builtin command and can be used in the same manner. For example, let’s say you need a command that would drive pin number 14 high for 10ms and then return it to a low state. MMBasic already has a command for this (called PULSE) but let’s say that, for the sake of argument, it didn’t. You could define the subroutine like this: SUB PulsePin14 SETPIN 14, DOUT PIN(14) = 1 PAUSE 10 PIN(14) = 0 END SUB This first command sets the I/O pin as an output (which defaults to being low), then sets it high, waits for 10ms, sets it low again and the subroutine terminates. It does not matter that pin 14 might have already been set to an output (SETPIN will not complain) so this subroutine can be used multiple times without error. In your program, you just use the command PulsePin14 whenever you want to, like a built in MMBasic command. For example: IF A > B THEN PulsePin14 The definition of the PulsePin14 subroutine can be anywhere in the program but typically it is at the start or end. If MMBasic runs into the definition while running your program, it will simply skip over it. This is handy enough but it would be better if you could use it on any I/O pin rather than being limited to pin 14. This can be done by passing a number to the subroutine as an argument (sometimes called a parameter). In this case, the definition of the subroutine would look like this: SUB PulsePin PinNbr SETPIN PinNbr, DOUT PIN(PinNbr) = 1 PAUSE 10 PIN(PinNbr) = 0 END SUB Now, when you call the subroutine, you can supply the pin number on the command line. For example: PulsePin 3 PulsePin 14 PulsePin (x + 1) * 2 This way, the subroutine becomes more generalised and you can use it on multiple I/O pins as we did above. A subroutine can have any number of arguments which can be float, integer or string, with each argument separated by a comma. To define an integer argument, add the suffix % to the argument name and $ for a string (just like when you define variables). Within the subroutine, the arguments act like ordinary variables but they exist only within the subroutine and vanish when the subroutine ends. If any variables with the same name have been defined in the main program, they are simply hidden while siliconchip.com.au LOOKING FOR A PCB? PCBs for most recent (>2010) SILICON CHIP projects are available from the SILICON CHIP On-Line Shop – see the On-Line Shop pages in this issue or log onto siliconchip.com.au/PCBs You’ll also find some of the hard-to-get components to build your SILICON CHIP project, back issues, software, panels, binders, books, DVDs and much more! the subroutine is running (effectively overridden by the parameters) and they re-appear with their previous values when it finishes. Variable name clashes like this are best avoided, however, as it may confuse you and make debugging more difficult. By the way, if you pass a variable to a subroutine and the subroutine changes its value, the change occurs for the calling code too (this is known as “passing arguments by reference”). Local variables Inside a subroutine, you will need to use variables for various tasks. You do not want to accidentally change the value of a variable in the main program if you have forgotten that there is a variable with that name already. To this end, you can define a LOCAL variable within the subroutine. The syntax for LOCAL is identical to the DIM command, which means that the variable can be an array, you can set the type of the variable and you can initialise it to some value. For example, taking our PulsePin command defined above, we might extend it so that it will generate a number of 10ms pulses, each separated by 20ms. Using a local variable, the new subroutine could look like this: SUB PulsePin PinNbr, NbrPulses LOCAL count SETPIN PinNbr, DOUT FOR count = 1 TO NbrPulses PIN(PinNbr) = 1 PAUSE 10 PIN(PinNbr) = 0 PAUSE 20 NEXT count END SUB The variable “count” is declared as local within the subroutine, which siliconchip.com.au means that (like the argument list) it only exists within the subroutine and will vanish when the subroutine exits. You can have a variable called “count” in your main program and its value will not be affected when you use the PulsePin subroutine. Using this new version of our subroutine is similar to the previous examples: IF A > B THEN PulsePin 14, 5 This will generate five pulses on I/O pin number 14 if the value of A is greater than B. You should always use local variables for operations within your subroutine because they help make the subroutine self-contained and portable and you avoid accidentally “clobbering” (unintentionally changing the value of) “global” (ie, non-local) variables. Functions Functions are similar to subroutines with the main difference being that a function can be used in an expression as it evaluates to something (returns a value, such as a number or string). For example, if you wanted a function to select the maximum of two values you could define: FUNCTION Max(a, b) IF a > b Max = a ELSE Max = b ENDIF END FUNCTION Then you could use it in an expression: x = 21 y = 25 PRINT "The highest number is " Max(x, y) The rules for the argument list in a function are similar to that for subroutines. The only difference is that brackets are required around the argument list when you are defining or calling a function (they are optional for subroutines). To return a value from the function, you assign that value to an implicit variable with the same name as the function. If the function’s name is terminated with a type suffix (eg, $ or %) the function will return an integer or string respectively, otherwise it returns a float. For example, if you wanted a function to return the word “high” or “low” for the current state of an I/O pin configured as an input, you could define a function like this: FUNCTION PinState$(PinNbr) IF PIN(PinNbr) = 0 THEN PinState$ = "low" ELSE PinState$ = "high" ENDIF END FUNCTION As you can see, the function name is defined like a string and is used as an ordinary string variable inside the subroutine. It is only when the function returns that the value assigned to the function name is made available to the expression that called it. For example: TEXT 160, 120, "Pin 14 is " + PinState$(14) If pin 14 was low, this would display on the LCD screen the message “Pin 14 is low”. “Black Box” components The above code examples illustrate one of the important benefits of using subroutines and functions – ie, when written and fully tested, they can be treated as a trusted “black box” which does not need to be opened. For example, once you have tested the PulsePin subroutine, you can ignore what is going on inside it and simply use it. Even better, you can copy it to another program and use it there without concern. Subroutines and functions have one entry point and a limited number of exits so they are much easier for a programmer who is not familiar with the program to understand. Remember that after just a few months, this programmer could be you! So you should use subroutines and functions to “package up” portions of code, even if they are only called once in the program. A good example of this is the code needed to set up everything before the maim program starts. If you put this in a subroutine called SetUp it would be obvious to another programmer what it does and he/she can more easily verify that the code in the subroutine is doing what is required. By now you should be well on your way to writing your own programs for the Micromite but we still have a little more to explain. Next month, we delve into creating on-screen buttons, interrupts and introduce some special but handy features of the Micromite. SC May 2017  45