Silicon ChipThe Micromite: An Easily Programmed Microcontroller, Pt.2 - June 2014 SILICON CHIP
  1. Outer Front Cover
  2. Contents
  3. Publisher's Letter: Is a large loudspeaker an anachronism?
  4. Feature: Australian Electric Superbikes by Andy Marsh & Ross Tester
  5. Review: Micsig MS510S Handheld Multifunction Oscilloscope by Nicholas Vinen
  6. Project: The Majestic Loudspeaker System by Allan Linton-Smith
  7. Project: 2-Way Passive Loudspeaker Crossover Network by Nicholas Vinen
  8. Order Form
  9. Project: Touch-Screen Digital Audio Recorder, Pt.1 by Andrew Levido
  10. Product Showcase
  11. Project: The Micromite: An Easily Programmed Microcontroller, Pt.2 by Geoff Graham
  12. Feature: Fast Ethernet Connections Via 230VAC Mains by Leo Simpson
  13. Project: 40V Switchmode/Linear Bench Power Supply, Pt.3 by Nicholas Vinen
  14. Vintage Radio: The story of the RCA VoltOhmyst by Kevin Poulter
  15. Subscriptions
  16. Market Centre
  17. Notes & Errata
  18. Advertising Index
  19. Outer Back Cover

This is only a preview of the June 2014 issue of Silicon Chip.

You can view 37 of the 104 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 "The Majestic Loudspeaker System":
  • 2-Way Passive Crossover PCB [01205141] (AUD $20.00)
  • Acrylic pieces to make two inductor bobbins (Component, AUD $7.50)
  • 2-Way Passive Loudspeaker Crossover PCB pattern (PDF download) [01205141] (Free)
Articles in this series:
  • The Majestic Loudspeaker System (June 2014)
  • The Majestic Loudspeaker System (June 2014)
  • An Improved Tweeter Horn For The Majestic Loudspeaker (September 2014)
  • An Improved Tweeter Horn For The Majestic Loudspeaker (September 2014)
Items relevant to "2-Way Passive Loudspeaker Crossover Network":
  • 2-Way Passive Crossover PCB [01205141] (AUD $20.00)
  • 2-Way Passive Loudspeaker Crossover PCB pattern (PDF download) [01205141] (Free)
Items relevant to "Touch-Screen Digital Audio Recorder, Pt.1":
  • Touch-screen Audio Recorder PCB [01105141] (AUD $12.50)
  • PIC32MX695F512H-80I/PT programmed for the Touchscreen Digital Audio Recorder (Programmed Microcontroller, AUD $30.00)
  • Firmware for the Touchscreen Audio Recorder [0110514B.HEX] (Software, Free)
  • Touch-screen Audio Recorder PCB pattern (PDF download) [01105141] (Free)
  • Touch-screen Audio Recorder end panel artwork (PDF download) (Free)
Articles in this series:
  • Touch-Screen Digital Audio Recorder, Pt.1 (June 2014)
  • Touch-Screen Digital Audio Recorder, Pt.1 (June 2014)
  • Touch-Screen Digital Audio Recorder, Pt.2 (July 2014)
  • Touch-Screen Digital Audio Recorder, Pt.2 (July 2014)
Items relevant to "The Micromite: An Easily Programmed Microcontroller, Pt.2":
  • PIC32MX170F256B-50I/SP programmed for the Micromite Mk2 plus capacitor (Programmed Microcontroller, AUD $15.00)
  • PIC32MX170F256D-50I/PT programmed for the Micromite Mk2 (44-pin) (Programmed Microcontroller, AUD $15.00)
  • CP2102-based USB/TTL serial converter with 5-pin header and 30cm jumper cable (Component, AUD $5.00)
  • Firmware (HEX) file and user manual for the Micromite (Software, Free)
  • Firmware (HEX) file and user manual for the 44-pin Micromite (Software, Free)
  • 44-pin Micromite PCB pattern (PDF download) [24108141] (Free)
  • 44-pin Micromite PCB [24108141] (AUD $5.00)
Articles in this series:
  • The Micromite: An Easily Programmed Microcontroller, Pt.1 (May 2014)
  • The Micromite: An Easily Programmed Microcontroller, Pt.1 (May 2014)
  • The Micromite: An Easily Programmed Microcontroller, Pt.2 (June 2014)
  • The Micromite: An Easily Programmed Microcontroller, Pt.2 (June 2014)
  • Micromite, Pt.3: Build An ASCII Video Display Terminal (July 2014)
  • Micromite, Pt.3: Build An ASCII Video Display Terminal (July 2014)
  • The 44-pin Micromite Module (August 2014)
  • The 44-pin Micromite Module (August 2014)
Items relevant to "40V Switchmode/Linear Bench Power Supply, Pt.3":
  • 40V/5A Hybrid Switchmode/Linear Bench Supply PCB [18104141] (AUD $20.00)
  • SMD parts for the 40V/5A Hybrid Switchmode/Linear Bench Supply (Component, AUD $50.00)
  • 40V/5A Hybrid Switchmode/Linear Bench Supply PCB pattern (PDF download) [18104141] (Free)
  • 40V/5A Hybrid Switchmode/Linear Bench Supply panel artwork (PDF download) (Free)
Articles in this series:
  • 40V Switchmode Bench Power Supply, Pt.1 (April 2014)
  • 40V Switchmode Bench Power Supply, Pt.1 (April 2014)
  • 40V Switchmode/Linear Bench Power Supply, Pt.2 (May 2014)
  • 40V Switchmode/Linear Bench Power Supply, Pt.2 (May 2014)
  • 40V Switchmode/Linear Bench Power Supply, Pt.3 (June 2014)
  • 40V Switchmode/Linear Bench Power Supply, Pt.3 (June 2014)

Purchase a printed copy of this issue for $10.00.

Using the By GEOFF GRAHAM Micromite, Pt.2 Interfacing & controlling external devices Now that you know how the Micromite works, we’ll dive right in with some useful programming tips and show how to control external devices. In particular, we’ll show how to use it for infrared (IR) remote control, to measure temperature, control a servo, interface to an LCD and keypad and much more. L AST MONTH, we introduced the Micromite – a low-cost 28-pin microcontroller running a Microsoftcompatible BASIC interpreter called MMBasic. MMBasic is easy to use and gives your Micromite-based project the ability to measure, react to and control all sorts of external parameters and devices. In particular, MMBasic includes a number of powerful commands that allow you to measure voltages, respond to an infrared remote control, display data on an LCD, measure distance and much more. This month, we’re going to show you how to use these commands and more. To make it easier for a program to interact with external devices, the Micromite includes drivers for a number of common peripheral devices. In some cases, it’s possible to achieve the same outcome by manipulating the Micromite’s I/O pins in BASIC but these drivers have the convenience of packaging the requirement into one or two easy-to-use commands. If you want to go beyond these commands and access various specialised features of an external device, you can always develop your own driver to directly drive the I/O pins. IR remote control decoder Adding an infrared remote control to your project requires very little effort thanks to the IR command in MMBasic. When enabled, this function runs in the background and interrupts the running program whenever a key is pressed on the IR remote. It will work with any Sony-compatible remote, including controls using 15-bit or 20-bit messages (most cheap universal remote controls can generate Sony commands). To detect the IR signal, you need an IR receiver connected to the Micromite’s IR pin (pin 16) – see Fig.1. The receiver will sense the IR light, demodulate the signal and present it as a TTL voltage level signal to this pin. Set-up 64  Silicon Chip of the I/O pin (pin 16) is automatically carried out by the IR command. Sony-compatible remote controls use a 40kHz modulation frequency but receivers for that frequency can be hard to find. Generally, 38kHz receivers will work fine but maximum sensitivity will be achieved with a 40kHz device such as the Vishay TSOP4840. Examples of 38kHz receivers that work include the Vishay TSOP4838, Jaycar ZD1952 and Altronics Z1611A. To set-up the decoder you use the command IR dev, key, interrupt where dev is a variable that will be updated with the device code and key is the variable to be updated with the key code. Interrupt is the interrupt label to call when a new key press has been detected (interrupts are described in detail later in this article). The IR decoding is done in the background and the program will continue after this command without interruption. The following example shows how to use the IR decoder: IR DevCode, KeyCode, IR_Int ' start the IR decoder DO < body of the program > LOOP IR_Int: ' a key press has been detected PRINT "Received device = " DevCode " key = " KeyCode IRETURN Sony remote controls can address many different devices (DVDs, TVs etc) so the program would normally examine the device code first to determine if the signal was intended for the program. If it was, it then takes action based on the key pressed. There are many different devices and key codes so the best method of determining what codes your siliconchip.com.au The Vishay TSOP4838 is a typical infrared receiver that will work with the Micromite. By using this and any Sony compatible remote control, you can add infrared remote control to your Micromite based project. +5V +3.3V IR RECEIVER 100Ω MICROMITE remote generates is to use the above program. 16 100nF IR remote control transmitter The IR SEND command allows you to transmit a 12-bit Sony-compatible infrared remote control signal. This could be used to control a Sony product that uses 12-bit codes or communicate with another Micromite. Fig.2 shows what’s required. A transistor (Q1) is used to drive the infrared LED because the output of the Micromite is limited to about 10mA, which would not provide a very bright infrared signal. This circuit provides about 50mA to the LED which is much better. To send a signal, you use the command Fig.1: this circuit will add an infrared remote control decoder to your Micromite project. The receiver can be a Vishay TSOP4838, Jaycar ZD1952 or Altronics Z1611A and the remote control can be any Sony com­ patible infrared remote control, including controls using 15 or 20-bit messages. +5V +3.3V IR SEND 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 (the IR SEND command will automatically do that). Note that the modulation frequency used is 38kHz and this matches the common IR receivers (described above) for maximum sensitivity when communicating between two Micromites. Measuring temperature The DS18B20() function in MMBasic will get the temperature from a DS18B20 temperature sensor. This device can be purchased on eBay for about $5 in a variety of packages, including a waterproof probe version. The DS18B20 can be powered separately from a 3-5V supply (see data sheet) or it can operate on “parasite power” from the Micromite’s data line as shown in Fig.3. Multiple sensors can be used but note that a separate I/O pin and pull-up resistor is required is required for each one. To get the current temperature, you just use the DS18B20() function in an expression. For example: PRINT "Temperature: " DS18B20(pin) where pin is the I/O pin to which the sensor is connected. You do not have to configure the I/O pin; that’s handled by MMBasic. The returned value is in °C with a resolution of 0.25°C and is accurate to ±0.5°C. The time required for the overall measurement is 200ms and the running program will pause for this period while the measurement is being made. This also means that interrupts will be disabled for this period. If you don’t want this to happen, you can separately trigger the measurement then return later to retrieve the reading. That’s done with the DS18B20 START command as described in the Micromite User Manual (available for download from the SILICON CHIP website). Real time clock interface Using the RTC GETTIME command, it’s easy to get the current time from a PCF8563 real time clock. This intesiliconchip.com.au 56Ω IRLED A λ MICROMITE K I/O PIN 1k B IR LED K A C BC338 BC338 B E E C Fig.2: this is all you need to generate Sony compatible 12-bit remote control signals. This could be used to control a Sony product or communicate with another Micromite. +3V – +5V MA 1 8 B 2 X IM 0 4.7k GND ANY MICROMITE I/O PIN DQ VDD Fig.3: measuring temperature is easy using the DS­ 18B20 temperature sensor. It can operate on parasitic power from the Micromite with VDD grounded as shown here or it can be powered separately by a 3-5V supply directly connected to the VDD terminal. The DS18B20 temperature sensor comes in many forms. This waterproof probe version comes from Australian Robotics (photo: Australian Robotics). June 2014  65 +3.3V 4.7k 4.7k 18 5 17 6 MICROMITE 3V LITHIUM BUTTON CELL 8 2 PCF8563 RTC 3 4 1 32.768kHz CRYSTAL 32pF Fig.4: adding a PCF8563 real time clock means that your Micromite-based project will always know the correct time. Because the PCF8563 draws very little current it can be permanently connected to a 3V cell as shown here. The 32pF adjustable capacitor is used to trim the crystal frequency for very accurate timekeeping but can be left out completely. The LCD command will work with 1, 2 or 4-line LCD modules that use the KS0066, HD44780 or SPLC780 controller chip. This is a typical example supplied by NexusCyber Electronics. the clock inside the Micromite. Normally, this command will be placed at the beginning of the program so that the time is set at power-up. Left to its own devices, the clock in the Micromite can drift by as much as two or three seconds in an hour. If an accurate time is required over a long period, the PCF8563 can be polled at regular intervals using the SETTICK command, eg: RTC GETTIME SETTICK 12 * 3600000, SetTime, 4 < normal program > This is a typical pre-assembled real time clock module using the PCF8563 chip. Photo by www.wvshare.com SetTime: RTC GETTIME IRETURN ' set the time at startup ' interrupt every 12 hours ' interrupt called every 12 hours ' reset the time LCD readout grated circuit is popular and cheap and will keep accurate time to about ±50ppm, even with the power removed (it’s battery backed). The PCF8563 can be purchased for around $5 on eBay and complete modules using the PCF8563 along with a battery can be found for as little as $10. This is an I2C device and it should be connected to the 2 I C I/O pins of the Micromite. Also, because the PCF8563 draws very little current (even when communicating via I2C), it can be permanently connected to the lithium cell (typical cell life is 15 years). Fig.4 shows the circuit details. The 32pF adjustable capacitor is used to trim the crystal frequency for very accurate timekeeping. However, that can be tedious as it will involve checking the time for drift over several days or even weeks. If you don’t want to do that, you can substitute a 10pF capacitor or leave it out completely and the timekeeping will still be quite good. Before you can use the PCF8563, its time must first be set. That’s done with the RTC SETTIME command which uses the format RTC SETTIME year, month, day, hour, minute, second. Note that the year is just the last two digits (ie, 14 for 2014) and the hour is in 24-hour format. For example, the following will set the PCF8563 to 4PM on the 10th November, 2014: RTC SETTIME 14, 11, 10, 16, 0, 0 To retrieve the time, you use the RTC GETTIME command which will read the time from the PCF8563 and set 66  Silicon Chip The LCD command will display text on a standard LCD module with just a few lines of BASIC. It will work with LCD modules that use the KS0066, HD44780 or SPLC780 controller chip and have 1, 2 or 4-line displays. Suitable modules include Altronics Z7001, Jaycar QP5512 and Futurlec LCD16X2. eBay is another good source and prices typically range from $10 to $50. A keypad is a low-tech method of entering data into a Micromite-based system and it’s easy to connect a 4x3 keypad like this to your project. Photo by Vetco. siliconchip.com.au +3.3V +5V RS 4 EN MICROMITE D7 D6 D5 D4 6 2 Vdd RS LCD MODULE CONTRAST 3 VR1 10k EN D7 D6 D5 D4 D3 D2 D1 D0 GND 1 14 13 12 11 10 9 8 7 R/W 5 +3.3V Fig.6: a keypad is a simple & convenient method of entering data into a Micromite based system. The Micromite supports either a 4x3 or a 4x4 keypad and the monitoring and decoding of key presses is done in the background while your program keeps running in the foreground. R1 R2 MICROMITE To set-up the display, you use the LCD INIT command as follows: LCD INIT d4, d5, d6, d7, rs, en where d4, d5, d6 & d7 are the I/O pins that connect to inputs D4, D5, D6 & D7 on the LCD module (inputs D0-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); and en is the pin connected to the enable or chip select input on the module. Any I/O pins on the Micromite can be used and you do not have to set them up beforehand (the LCD command automatically does that for you). Fig.5 shows a typical set up. To display characters on the module, you use the LCD command, as follows: LCD line, pos, data$ Where line is the line on the display (1-4), pos is the position on the line where the data is to be written (the first position on the line is 1) and data$ is a string containing the data to write to the LCD display. The characters in data$ will overwrite whatever was on that section of the LCD line. The following shows a typical usage: LCD INIT 2, 3, 4, 5, 23, 24 LCD 1, 2, "Temperature" LCD 2, 6, STR$(DS18B20(15)) Note that this example also uses the DS18B20 function to get the temperature (described above) and that the sensor is connected to pin 15. Keypad interface A keypad provides a simple method of entering data into siliconchip.com.au Fig.5: adding a 1, 2 or 4-line LCD to a Micromite is easy. Any I/O pins on the Micromite can be used and you do not have to set them up beforehand – the LCD command automatically does that for you. R3 R4 C1 C2 C3 1 2 3 A 4 5 6 B 7 8 9 C * 0 # D C4 a Micromite-based system. The Micromite supports either a 4x3 or a 4x4 keypad and key presses are monitored and decoded in the background. An example of a 4x3 keypad is the Altronics S5381, while the Altronics S5383 is a 4x4 keypad. When a key press is detected, an interrupt is issued and during this interrupt routine, the program can take whatever action is required (interrupts are described later). 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; int is the label of the interrupt to call when a new key press has been detected; r1, r2, r3 & r4 are the pin numbers used for the four row connections to the keypad (see Fig.6); and c1, c2, c3 & c4 are the column connections. Note that c4 is used only with 4x4 keypads and should be omitted if you are using a 4x3 keypad. Fig.6 shows the circuit. 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. 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 (these are listed in the Micromite User Manual). Then the interrupt subroutine will be called, eg: Keypad KeyCode, KP_Int, 1, 2, 3, 4, 8, 9, 10 ' 4x3 keyboard DO < body of the program > LOOP KP_Int: ' a key press has been detected PRINT "Key press = " KeyCode IRETURN June 2014  67 Table 1: CPU Speed vs Current CPU Speed Current Draw 48MHz 25mA 40MHz (default) 21mA 30MHz 16mA 20MHz 12mA 10MHz 7mA 5MHz 4mA given or the STOP option is used (which will terminate the output). As another example, the following will swing two servos connected to outputs PWM 1A and PWM 1B back and forth alternatively every five seconds: DO SERVO 1, 0.8, 2.2 PAUSE 5000 SERVO 1, 2.2, 0.8 PAUSE 5000 LOOP Controlling a servo Measuring distance A servo is basically a motor with integrated gears and a control system that allows its shaft position to be precisely controlled. The Micromite can simultaneously control up to five servos. Standard servos allow the shaft to be positioned at various angles, usually between -90° and +90°. Continuous rotation servos also allow the shaft rotation to be set to various speeds. The position of the servo is controlled by a signal pulse which is repeated every 20ms. Generally, a pulse width of 0.8ms will position the rotor at -90°, a pulse width of 2.2ms will position it at +90° and a pulse width of 1.5ms will centre the rotor. However, note that these numbers can vary between manufacturers. Most servos require a high current 5V power source and have two power leads, red for +V and black for ground. The third wire is the control signal which should be connected to a Micromite SERVO I/O pin. Depending on their size, servos can be quite powerful but the control signal used remains the same. The Micromite has two servo controllers, the first capable of controlling up to three servos and the second two servos. To drive a servo, you use this command for the servos connected to controller 1: By using an HC-SR04 ultrasonic sensor and the DISTANCE() function, you can measure the distance to a target. The HC-SR04 device can be found on eBay for about $5 and it will measure distances from about 30mm out to 3m. It works by transmitting an ultrasonic sound pulse and the Micromite then measures the time it takes for the echo to be returned. The DISTANCE function is used as follows: SERVO 1, 1A, 1B, 1C Similarly, this is the command for the servos connected to controller 2: SERVO 2, 2A, 2B The labels 1A, 1B, 1C, 2A etc are the desired pulse widths in milliseconds for each output of the channel. The output pins are designated as PWM 1A, PWM 1B, PWM 2A etc (the PWM and SERVO commands are closely relat­ed and use the same I/O pins). These I/O pin functions were shown in Fig.1 in last month’s article which introduced the Micromite. If you want to control less than the maximum number of servos, you can simply leave the unused output off the list and use that pin as a general purpose I/O. The pulse width can be specified with a high resolution (about 0.005ms). For example, the following will position the rotor of the servo connected to channel 1A to a position near its centre: SERVO 1, 1.525 Following the SERVO command, the Micromite will continue to generate a stream of pulses with this duty cycle in the background until another servo command is 68  Silicon Chip d = DISTANCE(trig, echo) where trig is the I/O pin connected to the sensor’s trigger input and echo is the pin connected to the sensor’s echo output. Note that the HC-SR04 ultrasonic sensor is a 5V device and so the echo pin should be a 5V-capable pin. As with previous functions, the Micromite’s I/O pins are automatically configured by the distance function. The value returned is the distance in centimetres to the target or -1 if no target is detected. If you want to use multiple sensors, they can share the same trig output from the Micromite but you must use different I/O pins for the echo input. You can also use 3-pin devices and in that case only one pin number need be specified. Saved variables Because the Micromite does not have a normal storage system (such as an SD card) it needs a facility to save information when the power is switched off. That’s done with the VAR SAVE command which will take a number of variables on its command line and will save their values in non-volatile flash memory. The space reserved for saved variables is 1.5KB. These variables can be restored later with the VAR RESTORE command which will add 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 when the Micromite is powered up. This facility is intended for saving data such as calibration data, user selected options and other items which change infrequently. It should not be used for frequent saves as this could wear out the flash memory. The flash in the PIC32MX150/250 series of chips has a high endurance of over 20,000 writes and erases. With normal use, this will never be reached but it could 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 memory in six hours, while a program that saved the same data once a day would run siliconchip.com.au for over 50 years and still not wear out the flash memory. CPU speed control MMBasic can control the Micromite’s clock speed via the CPU command. At start-up, the chip will run at 40MHz but the speed can be changed under program control from 5MHz to 48MHz. The current drawn by the chip is proportional to the clock speed so this command can be used to balance performance against current consumption. Table 1 (measured on a PIC32MX150F128B-I/SP) illustrates this. When the clock speed is changed all the serial ports (including the console) will be unaffected although there may be a small glitch during any change. The internal clocks and timers will also be unaffected. By contrast, the PWM, SPI and I2C functions will have their speeds changed proportionally so if this is not desired, they should be shut down before the change and restarted again afterwards. The Micromite can control up to five servos like this unit. Photo courtesy Wikimedia Commons. The HC-SR04 distance measuring sensor will enable your Micromite project to measure the distance to an object. It’s useful for robotics, tank level monitoring and many other applications. Photo by Robotsoft Systems. CPU sleep For battery-powered operation, it’s handy to be able to power the chip down completely and start it up again on some event. With the Micromite, you can use the CPU SLEEP command which will put the processor to sleep with a current drain of about 80µA. While it’s asleep, the chip monitors the WAKEUP pin which is automatically set up as a digital input by the CPU SLEEP command. The CPU will then be woken up when the WAKEUP pin changes state (ie, goes from high to low or low to high). The program will then continue with the command following the CPU SLEEP command. The wake-up signal could be a button press, an incoming signal or some other external interrupt. The infrared remote control function uses the same I/O pin as the wake-up signal and it’s possible to combine the two so that an incoming IR signal will wake the Micromite which will then decode that signal. In this way, you can have a Micromite running on battery power that will wake up on an IR signal, do something based on that signal, then go back to a low-power sleep mode. The following is an example: IR DevCode, KeyCode, IR_Int ' start the IR decoder DO CPU SLEEP ' now sleep until a signal LOOP IR_Int: ' a key press has been detected < do some work based on the key press > IRETURN ' return to sleep again 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 specific task. The end user need not know anything about what is running inside the chip. However, it’s possible 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 siliconchip.com.au 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 in MMBasic that counts down to zero and when it reaches zero the processor is automatically rebooted (the same as when power was first applied), even if MMBasic was sitting at the command prompt. In practice, the WATCHDOG command should be placed in strategic locations in the program so that it keeps resetting the timer and thus prevents the counter from reaching zero. Then, if a fault occurs, the program will stop running and the timer will not be reset. As a result, it will now count down zero and the program will be restarted (assuming the AUTORUN option has been set). PIN security Sometimes, it’s important to keep the data and the program in an embedded controller secret. This can be done in the Micromite by using the OPTION PIN command. This command will set a PIN number (which is stored in flash memory) and whenever the Micromite returns to the console (for whatever reason) the user will be prompted to enter the PIN. Without the correct PIN, the user cannot get to the command prompt. The only options are to enter the correct PIN or reboot the Micromite. However, if it’s rebooted, the user will still need the correct PIN to access the command prompt. Because an intruder cannot reach the command prompt, they cannot list or copy a program, nor can they June 2014  69 change the program or change any aspect of MMBasic or the Micromite. Once set, the PIN can only be removed by providing the correct PIN in the first place. If the number is lost, the only method of recovery is to reset MMBasic as described later (which will erase the program). Note that there are complicated (and expensive) methods of accessing the data on the chip even if a PIN has been set (eg, by removing the plastic packaging and physically accessing the silicon die). The serial console Using the OPTION BAUDRATE command, the baud rate of the console can be changed to any speed up to 230,400bps. Changing the console baud rate to a higher speed makes the full screen editor much faster when it comes to redrawing the screen. So, if you have a reliable connection to the Micromite, it’s worth changing the speed to at least 115,200bps. When running as an embedded controller the serial console may no longer be required for programming. This means that it can then be used as a third serial port, with OPTION BAUDRATE used to set the required speed. If you do this, it might be worth using the OPTION BREAK command to disable the break key to prevent an unintended CTRL-C in the console receive data from halting the running program. Once changed, the console baud rate will be permanently remembered unless another OPTION BAUDRATE command is used to change it. Note that when using this command it’s possible to accidentally set the baud rate to an invalid speed. If that happens, the only way out is to reset MMBasic as described later. 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 increase the input voltage to make an accurate measurement. One small point here is that when the Micromite measures voltage, it uses pin 28 (analog power) as its reference and assumes that this pin is at exactly 3.3V. If you use a different supply voltage, you will need to scale the reading in your BASIC program to compensate. For example: Volts = PIN(pin) / 3.3 * Vdd where Vdd is the supply voltage. Many devices generate an output voltage that represents a physical quantity. Examples include accelerometers, strain gauges, pressure sensors and humidity sensors. You can use this same technique to measure the voltage output from these sensors and scale the reading to a meaningful number. Counting inputs The pins marked as COUNT (ie, pins 15-18) can be configured as counting inputs to measure frequency or period, or to just count pulses on the input. For example, the following will print the frequency of the signal on pin 15: > SETPIN 15, 3 > PRINT PIN(15) 110374 > The SETPIN command configures pin 9 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 this case, the frequency is 110.374kHz. The frequency response ranges up to 200kHz maximum and the measurement is returned in Hz with a resolution of 1Hz. The value is updated once a second (ie, the gating period is 1s). For accurate measurement of signals less than 10Hz, it’s generally better to measure the period of the signal. When set to this mode, the Micromite will measure the number of milliseconds between sequential rising edges of the input waveform. The value is updated on the low to high transition so if your signal has a period of (say) 100 seconds you must wait for that amount of time in order for the PIN() function to return an updated value. The COUNT pins can also count the number of pulses on their input. When a pin is configured as a counter (eg, SETPIN 15,CIN), the counter will be reset to zero and the Micromite will then count every low to high voltage transition. The counter can be reset to zero again by executing the SETPIN command a second time (even though the input was already configured as a counter). The response to input pulses is very fast and the Micr­ omite can count pulses as narrow as 20ns (although the maximum frequency of the pulse stream is still limited to 200kHz). Analog inputs Digital outputs Digital inputs A digital input is the simplest type of input pin configuration. If the input voltage is higher than 2.5V, the logic level will be high (numeric value of 1), while anything below 0.65V will be low (numeric value of 0). The digital inputs all use Schmitt trigger logic, so anything in between these levels will retain the previous logic level. 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" Pins marked as ANALOG can be configured to measure the voltage on the pin. The input range is from 0V to 3.3V and the PIN() function will return the voltage. For example: > SETPIN 23, AIN > PRINT PIN(23) 2.345 > 70  Silicon Chip All I/O pins can be configured as standard digital outputs. This means that when an output pin is set to logic low it will be pulled to 0V and when set high it will be pulled to 3.3V. In MMBasic, this is done with the PIN command. For example PIN(15) = 0 will set pin 15 low, while PIN(15) = 1 will set it high. When operating in this mode, a pin is capable of sourcing 10mA which is sufficient to drive a LED or other logic siliconchip.com.au circuits running at 3.3V. Pins marked as 5V have a couple of additional properties that make it easy to connect to 5V circuitry. First, as inputs, they can be directly connected to a circuit that generates up to 5V without the need for voltage dropping resistors. These pins can also be set up to be open collector outputs. The term ‘open collector output’ 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 the output, 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. Pulse width modulation The PWM (Pulse Width Modulation) command allows the Micromite to generate square waves with a programcontrolled duty cycle. By varying the duty cycle, you can generate a program-controlled output voltage and this could in turn be used to control external devices that require an analog input (power supplies, motor controllers, etc). Five PWM outputs are available in two groups and the frequency of each group can be independently set from 20Hz to 500kHz (see Pt.1 last month). The duty cycle for each output can also be independently set from 0-100% with 0.1% resolution when the frequency is below 25kHz. Above 25kHz, the resolution is 1% or better up to 250kHz. When the Micromite is powered up or the PWM OFF command is used the PWM outputs will be set to high impedance (they are neither off nor on). So, if you want the PWM output to be low by default (zero power in most applications), you should use a resistor to pull the output to ground when it is set to high impedance. Alternatively, if you want the default to be high (full power), you should connect the resistor to 3.3V. 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. You could insert code after each statement to check if a button has been pressed but an interrupt makes for a cleaner and more readable program. When an interrupt occurs, MMBasic executes a special section of code and then returns to the main program when it has finished. The main program will be unaffected by this interrupt and will then carry on as normal. I/O pins designated as INT (see Fig.1 in Pt.1 last month) can be configured to generate an interrupt using the SETPIN command. Many interrupts (including the tick interrupt, IR interrupt, etc) can be active at any one time. Interrupts can be set to occur on a rising or falling digital input signal (or both) and will cause an immediate branch to a specified line number, label or user defined subroutine. The target can be the same or different for each interrupt. If two or more interrupts occur at the same time, they are processed in order of pin numbers (ie, an interrupt on pin 2 will have the highest priority). All other interrupts are disabled during the processing of an interrupt until the interrupt routine returns with an IRETURN. During an interrupt (and at all other times), the state of the pin that caused the interrupt can be determined using the PIN() function. For most programs, MMBasic siliconchip.com.au will respond to an interrupt in under 50μs. To prevent slowing the main program too much, an interrupt should be short and exit as soon as possible. You must also remember to disable an interrupt when you have finished with it – background interrupts can cause bugs which are difficult to find. Timing MMBasic maintains an internal clock which will provide the current date and time using the DATE$ and TIME$ functions. You can also set the date/time by assigning the new date and time to these functions. This makes it easy to time events and control external circuitry that needs timing. On power-up, the calendar starts from midnight on the 1st January 2000 but by using the RTC command (see above) you can correct the time maintained by a PCF8563 real time clock (RTC) chip. Another timing function is the PAUSE command which will freeze the execution of the program for a specified number of milliseconds. So, to create a 12ms wide pulse, you could use the following: SETPIN 4, DOUT PIN(4) = 1 PAUSE 12 PIN(4) = 0 You can also create a pulse using the PULSE command. This can generate very narrow pulses (eg, 20μs) or long pulses lasting up to several days. Long pulses are run in the background and the program will continue uninterrupted. Another useful feature is the TIMER function which acts like a stopwatch. You can set it to any value (usually zero) and it will count upwards every millisecond. A timing function is also provided by the SETTICK command. This command will generate an interrupt at regular intervals (specified in milliseconds). Think of it as the regular ‘tick’ of a watch. As an example, the following code fragment will print the current time and the voltage on pin 2 every second. This process will run independently of the main program which could be doing something completely unrelated: SETPIN 2, AIN SETTICK 1000, DOINT DO ' main processing loop LOOP DOINT: PRINT TIME$, PIN(2) IRETURN The second line sets up the ‘tick’ interrupt, the first parameter of SETTICK is the period of the interrupt (1000ms) and the second is the label of the interrupt code. Every second (ie, every 1000ms), the main processing loop will be interrupted and the program at the label DOINT will be executed. Up to four ‘tick’ interrupts can be set up. This type of interrupt has the lowest priority. Serial communications Two serial ports are available for asynchronous serial communications. These are labelled COM1: and COM2: June 2014  71 +3.3V K MICROMITE PIN 22 A 1N4148 OR SIMILAR 22k PIN 21 RS-232 DEVICE TRANSMIT DATA RS-232 DEVICE RECEIVE DATA SIGNAL GROUND Fig.7: many devices use RS-232, including modems, hardwired serial ports on a PC and test equipment. Here’s a low-cost method of connect­ing such devices to the Micromite. and after being opened they have an associated file number. You you can use any commands that operate with a file number to read and write to/from a serial port. A serial port is also closed using the CLOSE command. The following is an example: OPEN "COM1:4800" AS #5 PRINT #5, "Hello" dat$ = INPUT$(20, #5) CLOSE #5 This opens COM1: with a speed of 4800 baud and then transmits the string “Hello”. It then gets up to 20 characters from the port and closes it. This isn’t a very useful example but it does show how simple it is to use a serial port. By the way, the syntax was defined by Bill Gates in the 1970s – MMBasic tries to keep as close to Microsoft BASIC as possible. The baud rate can be up to 230,400 on COM1 and 19,200 on COM2. There are other options that can be applied including nine data bits, two stop bits and data enable for RS-484 compatibility. These options are explained in greater detail in the Micromite User Manual. The signal polarity is standard for devices running at TTL voltages (see section below for RS-232 voltages). Idle is voltage high, the start bit is voltage low, data uses a high voltage for logic 1 and the stop bit is voltage high. These signal levels allow you to directly connect to devices like GPS modules (which generally use TTL voltage levels). Low-cost RS-232 interface The RS-232 signalling system is used by modems, hardwired serial ports on a PC, test equipment etc. It is the same as the serial TTL system used on the Micromite with two exceptions: (1) The voltage levels for RS-232 are +12V and -12V, whereas TTL serial uses +3.3V and 0V. (2) The signalling is inverted (ie, the idle voltage is -12V, the start bit is +12V etc). Cheap RS-232-to-TTL converters can be purchased on the internet. However, if cable lengths are kept short, you can directly connect the Micromite to RS-232 provided you add a resistor and a diode as shown in Fig.7. First, the signalling polarity needs to be inverted. On the Micromite, COM1: can be specified to invert both the 72  Silicon Chip transmit and receive signals (the INV option), so that’s an easy fix. For the receive data (ie, the ±12V signal from the remote RS-232 device), the signal voltage can be limited using a 22kΩ series resistor and a diode that clamps the maximum positive signal level to the +3.3V rail (there is no internal clamp diode as it is a 5V tolerant input). The Micromite’s input impedance is very high so the resistor will not cause a voltage drop. However, it does mean that when the signal swings to the maximum +12V, it will be safely clipped by the diode. Similarly, when it swings to -12V it will be clipped by an internal protection diode on pin 22 of the Micromite. The transmit signal (ie, from pin 21) can be directly connected to the input of the RS-232 device. The Micromite will only swing the signal from 0V to +3.3V but most RS232 inputs have a threshold of about +1V so the Micromite’s transmit data will still be interpreted as a valid signal. These measures break the rules for RS-232 signalling but it should work fine if you only want to use it over a short distance (a metre or two). Once it’s connected, all you need do is open COM1: with the invert option, eg: OPEN “COM1: 4800, INV” AS #1 I2C communications The Inter Integrated Circuit (I2C) bus was developed by Philips (now NXP) to transfer data between ICs. Many devices can now communicate using I2C and it’s especially useful for communicating between Micromites. Two signals are used for communications: (1) the data line (called SDA) and (2) the clock line (called SCL). Both should be pulled up to +3.3V or +5V (depending on the device) by resistors (typically 4.7kΩ). Both the Micromite and the other device signal each other by pulling these lines low. Within MMBasic, there are commands to open the connection, write data, read data and close the connection. Normally, the Micromite would operate in master mode so that it controls the communications but it can also work in slave mode. Full details on the relevant commands are in the Micromite User Manual. Fig.8 shows an example of I2C being used for communications between two Micromites, in this case to offload the keypad and LCD functions from the master device. Taken together, these functions use up to 14 I/O pins so it’s convenient to assign responsibility for handling them to a slave Micromite as shown. After all, a Micromite chip doesn’t cost very much. Using just a few lines of code, the master Micromite can query the slave Micromite to determine if a key on the keypad has been pressed. It can also send some data to the slave to be displayed on the LCD. Fig.9 shows the code that needs to be running on the slave, while Fig.10 is all that you need on the master to update the display and get the last key pressed on the keypad (just six lines in total). 1-Wire & SPI communications To round out the communications facilities, MMBasic also includes support for 1-Wire and SPI communications. The 1-Wire protocol was developed by Dallas Semiconductor to communicate with chips using a single signalling line. It’s commonly used for communicating with the siliconchip.com.au +3.3V +3.3V +3.3V 1 2 3 A 4 5 6 B 7 8 9 C R1 R2 R3 R4 +5V RS 4 EN 6 * 2x 10k MICROMITE #1 (MASTER) 0 # D C4 C3 C2 C1 18 17 2 18 2 17 I C DATA I C CLOCK MICROMITE #2 (SLAVE) D7 D6 D5 2 Vdd RS EN 16 x 2 LCD MODULE CONTRAST D7 D6 D5 D4 D3 D2 D1 D0 GND 1 14 13 12 11 10 9 8 7 3 VR1 10k R/W 5 D4 Fig.8: this diagram illustrates how to connect two Micromites together so that the LCD and keypad interfaces can be offloaded to the second (slave) Micromite using I2C communications. Together these functions use up to 14 I/O pins so this is a handy and low cost method of freeing up I/O pins on the master Micromite. DS18B20 temperature sensor but MMBasic has an inbuilt function for dealing with that device that’s much more convenient to use. Other 1-Wire devices include memory chips and security devices. SPI has been around a long time and many devices use that protocol including memory chips, accelerometers, environment sensors and a host of others. Rather than go into the detail here, you can download the Micromite User Manual which provides a detailed explanation of the commands and functions which support these protocols. Defined subroutines & functions MMBasic allows you to define your own subroutines and functions in your programs. These are modern programming techniques that are useful in organising programs so that they are easy to modify and read. They will be new to many readers so we will take a little time to explain how they work. A defined subroutine or function is simply a block of programming code that is self-contained and can be ‘called’ from anywhere within your program. It is the same as if you have added your own command or function to the language. For example, assume that you would like to have the command FLASH added to MMBasic and its job would be to flash a LED on pin 2. You could define a subroutine like this: Sub FLASH SETPIN 2, DOUT Pin(2) = 1 Pause 100 Pin(2) = 0 End Sub With this subroutine in place, you now just use the command FLASH to flash the LED, eg: IF A < B THEN FLASH Defined subroutines can have ‘arguments’ (sometimes called parameter lists). In the definition of the subroutine they look like this: siliconchip.com.au Sub MYSUB (arg1, arg2$, arg3) <statements> <statements> End Sub When you call the subroutine you can assign values to the arguments, eg: MYSUB 23, "Cat", 55 In this case, variable arg1 will have the value “23”, arg2$ the value “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). Local variables Inside a subroutine, you will need to use variables for various tasks. In reusable code, you don’t want the name you chose for any such variable to clash with a variable of the same name in the main program. This can be ensured by defining a variable as LOCAL. For example, this is our FLASH subroutine again but this time we have extended it to take an argument (nbr) that specifies how many times to flash the LED: Sub FLASH ( nbr ) Local count SETPIN 2, DOUT For count = 1 To nbr    Pin(2) = 1   Pause 100    Pin(2) = 0   Pause 150 Next count End Sub The counting variable (count) is declared as local which 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 it will be separate from the variable count in your subrouJune 2014  73 LCD INIT 2, 3, 4, 5, 6, 7 KEYPAD pad, PadI, 9, 8, 14, 15, 16, 24, 25, 26 I2C SLAVE OPEN &H26, 0, 0, WriteD, ReadD ' slave’s address is 26 (hex) DO WATCHDOG 1000 LOOP ' the program loops forever ' this will recover from errors ReadD: I2C SLAVE READ 18, msg$, recvd LCD ASC(msg$), ASC(MID$(msg$, 2, 1), MID$(msg$, 3) IRETURN ' received a message ' get the message ' display it ' return from the interrupt WriteD: I2C SLAVE WRITE &H26, pad IRETURN ' request from the master ' send the last key press ' return from the interrupt PadI: IRETURN ' key down on the keypad ' we do not do anything Fig.9: this is the program running on the slave Micromite which is handling an LCD display module and a 4x4 keypad. The program waits for data, in which case it will send it to the LCD display. It also waits for a request from the master and in that case it will send the last key pressed on the keypad. The watchdog timer is set running so that if an error occurs the Micromite will automatically restart itself. tine. If you do not declare the variable as local, it will be created ‘globally’ in your program and be visible in the main program and subroutines, just like a normal variable. You can define multiple items with the one LOCAL command and if an item is an array, the LOCAL command will also dimension the array (ie, you do not need the DIM command). Defined functions Defined functions are similar to defined subroutines, the main difference being that the function is used to return a value in an expression. 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 You could then use it in an expression, as follows: SetPin 1, 1 : SetPin 2, 1 Print "The highest voltage is" Max(Pin(1), Pin(2)) 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 (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 ‘$’ the function will return a string, otherwise it will return a number. Within the function, the function’s name acts like a standard variable. As another example, let’s assume that you need a function to format time in AM/PM format. The code is as follows: 74  Silicon Chip Function MyTime$(hours, minutes) Local h h = hours If hours > 12 Then h = h – 12 MyTime$ = Str$(h) + ":" + Str$(minutes) If hours <= 12 Then    MyTime$ = MyTime$ + "AM" Else    MyTime$ = MyTime$ + "PM" EndIf End Function As you can see, the function name is used as an ordinary local variable inside the subroutine. It’s only when the function returns that the value assigned to MyTime$ is made available to the expression that called it. This example also illustrates that you can use local variables within functions just like subroutines. Passing arguments by reference If you use an ordinary variable (ie, not an expression) as the value when calling a subroutine or a function, the argument within the subroutine/function will point back to the variable used in the call. In addition, any changes to the argument in your routine will also be made to the supplied variable. This is called passing arguments by reference. For example, you might define a subroutine to swap two values, as follows: Sub Swap a, b Local t t=a a=b b=t End Sub In your calling program, you would use variables for both arguments as follows: siliconchip.com.au s$ = chr$(1) + chr$(1) + "Hello Micromite" I2C OPEN 100, 1000 I2C WRITE &H26, 0, 18, s$ I2C READ &H26, 0, 1, pad IF MM.I2C THEN ERROR "Slave did not respond" I2C CLOSE Fig.10: this is all that is needed to send data to the LCD connected to the slave and get the last key pressed on they keypad. First an 18-character string is built up – the first character is the line on the LCD to place the text and the second is the column position. The rest of the string is the data to display. After that has been sent, the program gets one byte from the slave which is stored in the variable ‘pad’. This is the value of the last key pressed on the keypad. Swap nbr1, nbr2 The result will be that the values of nbr1 and nbr2 will be swapped. Unless you need to return a value via the argument, you should not use an argument as a general-purpose variable inside a subroutine or function. This is because another user of your routine may unwittingly use a variable in their call and that variable will be ‘magically’ changed by your routine. It’s much safer to assign the argument to a local variable and manipulate that instead. PIN and then forget the number. In this case, MMBasic can be reset to its original configuration using either of two methods: (1) reprogram the chip with the Micromite firmware using a PIC32 programmer; or (2) short pins 11 & 12 together while applying power. Following this, you then need to wait a couple of seconds and remove the power and the short. 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. Coming next month Next month, we will describe the SILICON CHIP ASCII Video Terminal. This is a stand-alone serial terminal that you can attach to a Micromite to create and edit your program or you can just use it to display data. The ASCII Video Terminal can drive a VGA or composite monitor and will accept a standard PS2 keyboard for input, so it is the perfect companion for the Micromite. It connects to the Micromite via a serial interface and can SC also connect to your PC via USB. Proposed Format for KitStop ¼ Page Ad Silicon Chip Magazine June 2014 Resetting MMBasic It’s possible to get MMBasic into a state where Ctrl-C on the console will not be recognised, eg, if you set a security Where To Get The Micromite A pre-programmed Micromite chip is available for $15 plus p&p from the SILICON CHIP Online Shop (includes the 47μF capacitor). MMBasic and a User Manual are also available on the SILICON CHIP website (free of charge). Remote Control Made Really Easy The KSRC2 UHF set controls appliances, lighting, scoreboards & models over 40metres. Its two independent receiver relay outputs are rated to 500Watts Fully Assembled Special S.C Project Offer!!! $22.30 inc. GST Plus $7.50 P & P Digital Panel Meters at Analogue Prices KSDVM-30 ULTRA-COMPACT 4.5-30VDC Digital Panel Meter Features: Bright 0.36” Red LED Digits, $6.70 Snap-Fit Housing, Range optimized for inc. GST solar, automotive and trucking applications. Plus $4.50 P & P MXA026 Fully Assembled Stop-Watch & Clock Six, daylight-visible 60mm Digits Timing Down to 100th sec. Battery Back-up circuit Really easy to use and install. Special Low Price $93.70 inc. GST plus $11.50 post and Pack www.kitstop.com.au P.O. Box 5422 Clayton Vic.3168 Tel:0432 502 755 siliconchip.com.au June 2014  75