This is only a preview of the May 2011 issue of Silicon Chip.
You can view 29 of the 104 pages in the full issue, including the advertisments.
Items relevant to "The SportSync Audio Delay Module":
Items relevant to "The Maximite Computer, Pt.3":
Items relevant to "12V 100W Converter With Adjustable 15-35V DC Output":
Items relevant to "Phone Line Polarity Checker":
Purchase a printed copy of this issue for $10.00.
Part 3 – by Geoff Graham Using The Maximite Over the past two months we introduced the Maximite, a tiny microcomputer that can turn its hand to many things, from teaching programming to controlling your greenhouse. In this final article we provide an introduction to the BASIC language running on the Maximite and show you how to use this tiny marvel for measurement and control. B efore you start, it would be worth downloading the “Maximite User Manual” from the SILICON CHIP website. The following description will give you a summary of the device but the user manual is the ultimate reference. We suggest too that as you go through this article, if programming is new to you, that you try out each of the examples to get the feel of them. If your Maximite is completed and ready to go, you can of course use it – but if not, you can get a version of BASIC which will load and run on your personal computer. It should even be available as a free download on the net. computer systems. There are quite a few versions of BASIC but that used by the Maximite is fairly close to the original. However, because it does have a couple of minor differ- A few bits of BASIC Fig.1: when you turn on the Maximite you are greeted with the prompt (>). You can try out the language simply by typing in a command and it will be executed immediately. This example shows the result of running the PRINT command with the argument of 1÷7. The Maximite runs the BASIC language (BASIC is an acronym for Beginner’s All-purpose Symbolic Instruction Code), a very common programming language used in many 66 Silicon Chip siliconchip.com.au USB 2.0 upload/download programs and data from your PC 20 I/O pins. Can be a combination of analog input or digital input/output Standard IBM PS/2 keyboard input External Power (7V to 15V DC) Composite Video 304x216 graphics (512 lines 50Hz) Select power from USB or external Bootload Button. Update the firmware via USB from a PC VGA Video 480x432 graphics (monochrome) Sound output 20Hz to 5kHz single tone under program control BASIC Interpreter with 128KB RAM. Similar to Microsoft BASIC with long variable names, arrays, floating point, string handling and graphic capabilities MMC/SD card. Save and load programs and data within BASIC in PC compatible formats The Maximite has a lot of capability built into a small package. The core component is the PIC32 microcontroller which in addition to running a powerful BASIC interpreter handles the video, keyboard, SD card, USB and sound. ences, we’ve called it MMBASIC. Oh, come on now . . . MaxiMite BASIC, OK? When you first turn on the Maximite you are presented with a prompt as shown in Fig.1. At this point you can type in a command and try it out. This is one of the reasons that MMBASIC is so easy to learn. Almost any command can be entered in this way and you can instantly see what it does. For example: > PRINT 1/7 0.142857 > The PRINT command will evaluate whatever is on its command line and display the result. In this case it evaluated the result of dividing 1 by 7 and printed the result, just like a pocket calculator. PRINT is one of the most commonly used commands in the MMBASIC language and it comes in handy when you are experimenting with expressions and functions. If you prefix the line with a number MMBASIC will save that line in memory along with any other lines prefixed with a line number. You can then run the program with the RUN command. For example, type in the following: > 10 A = 1/7 > 20 PRINT A > RUN 0.142857 > siliconchip.com.au Hey, you’ve just written your first computer “program”! It’s the same as the first example except that this time we evaluated the expression 1÷7 and saved the result in the variable “A”. Then, in line 20 we printed out the value of “A”. The RUN command then ran this program. You can delete a line in memory by entering the line number without a following command and you can replace a line with a new one simply by entering the new line using the same line number. Try it out with other variables, such as > 10 A = 12345-12344 Program lines are always executed in ascending numerical sequence so you can enter the lines in any order. And MMBASIC makes calculations following the standard rules of arithmetic/mathematics – ie, 1+2÷4 would be evaluated as 1.5, not 0.75. You can save programs on the Maximite’s SD card using +3.3V Fig.2: the input protection for the PIC32 consists of two reversebiased diodes. These are adequate for most tasks but will not protect ANALOG OR against a high-voltage DIGITAL input. INPUT PIC32 May 2011 67 MAXIMITE Fig.3: two additional resistors will provide extra protection for any Maximite pins configured as inputs. External input/output ANALOG OR DIGITAL INPUT R2 4.7k INPUT PIN R1 100k the SAVE command and later load them using the LOAD command. You can also list them on your monitor with the LIST command. Another valuable instruction is the IF … THEN command which is used for making decisions. For example: >A=3 > IF A < 5 THEN PRINT “Less than 5” Less than 5 > The “less than” symbol (<) is used in tests like this and if the value of A is less than 5 the command following the THEN is executed. Note that in this case we did not use line numbers so the commands were executed immediately they were typed in. Also note that we used a sequence of characters in the PRINT command. This is called a string and they can be saved in variables and manipulated in various ways. For example: > T$ = “Hello” > PRINT T$ Hello > When you use a string in your program it must be surrounded by double quotes. Also, string variables are terminated with the dollar character ($) to differentiate them from numeric variables. Other than this, strings are handled in a similar way as numbers. Variable names in MMBasic can be up to 32 characters long and can be any mix of uppercase or lowercase characters as MMBasic ignores character case. This means that you can use descriptive variable names such as “CurrentBalance” in your program. Similarly MMBasic ignores case in commands and function names, so “print”, “PRINT” and “Print” are all equivalent. This is a very quick introduction to the BASIC language but it should show you how easy the language is to use. At the risk of repeating ourselves, to learn more you should download the “Maximite User Manual” from the SILICON R xV R1 = 2 MAX – R2 VIN In most cases R2 should be 10k and VIN 3.3V, so 10000 x VMAX R1 = – 10000 3.3 MAXIMITE ANALOG OR DIGITAL INPUT (Vmax) R1 INPUT PIN R2 10k Fig.4: this circuit will be needed if the input to the Maximite will exceed 3.3V 68 Silicon Chip CHIP website and look on the Internet for a tutorial such as the one at http://tpub.com/progintro. Before we discuss the input/output facilities of the Maximite we should warn about two events that could damage the PIC32 chip. These are static discharge and SCR latch-up. The input/output pins on the PIC32 have some protection against static discharges. This is in the form of two reverse-biased diodes as shown in Fig.2. These diodes will conduct (and therefore protect the inputs) if the input voltage goes above 3.6V or below -0.3V and are adequate for moderate use (for example, when soldering a connector). However, you can still damage the chip if the static discharge is large enough (for example, if it is enough to produce a spark). That amount of energy will destroy the input circuitry and possibly the chip itself. The other dangerous circumstance is if you force too high a current (greater than 20mA) through the protective diodes, for example by directly connecting an input to a power supply that is set to a voltage greater than the supply voltage to the PIC32. This can cause a phenomenon called SCR latch up which will instantly destroy the chip. We could have included a protective circuit for every I/O pin in the Maximite but that would have doubled the PC board size and would have been unnecessary in the majority of applications. The solution is to be aware of these two factors and take some simple precautions. In the case of static electricity, do not handle the I/O pins unnecessarily and make sure that you are grounded by touching the shield on the USB connector before you touch an I/O pin. In any external circuitry where an I/O pin may be floating (not connected to anything), include a 100kΩ resistor to ground to discharge any static build up. To avoid SCR latch up you should include a series resistor of 1kΩ to 10kΩ in the input if there is any chance of the source being able to supply significant current. The input impedance of the PIC32 is quite high so a series resistance like this will not affect normal operation. Be particularly careful of circuits which might apply power to the external circuitry before you apply power to the Maximite as that is a common source of this phenomenon. Both of these precautions are illustrated in Fig.3. Digital input 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). In the digital world, voltages between 0.65 and 2.5 are indeterminant – depending on the circuit they are in they could be interpreted either way or simply ignored – and should be avoided. If the input voltage can be over 3.3V you should use a voltage divider on the input. Fig.4 shows the basic arrangement. R1 and R2 form a voltage divider and because the PIC32’s input impedance is very high (leakage is less than 1µA) you could use almost any values for the resistors so long as the ratio is correct. For example, in an automobile application R1 could be 22kΩ and R2 10kΩ with the result that logic high would be any voltage above 8V. In your BASIC program you would set the pin as a digital siliconchip.com.au program would be: +3.3V MAXIMITE R1 47k INPUT PIN Fig.5. To detect a switch’s position a pull-up resistor is required. SWITCH input and use the PIN() function to get its level. For example: 10 SETPIN 9, 1 20 IF PIN(9) = 1 THEN PRINT “High” Line 10, with 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 the program. Because the PIN() function will return 1 when the input is high and the IF … THEN command treats any non zero number in its conditional statement as true, you could rewrite line 20 in the above code fragment to read: 20 IF PIN(9) THEN PRINT “High” To sense the position of a switch you will need a pull-up resistor as illustrated in Fig.5. When the switch is open the PIN() function will return true and false when it is closed. A good value for R1 is 47kΩ but you could use anything from 1kΩ to 500kΩ. I/O pins 11 to 20 have the special facility of accepting input voltages of up to 5.5V and this means that you can connect them directly to 5V circuitry without the need for voltage dropping resistors. You do not have to do anything to enable this facility, it is automatically available. Analog input Pins 1 to 10 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. Again, the SETPIN command (this time with the number 2) configures the pin (9 in this case) as an analog input. For example: > SETPIN 9, 2 > PRINT PIN(9) 2.345 > > 10 SETPIN 9, 2 > 20 PRINT PIN(9) / 0.2041 > RUN 13.243 > The precision of the measurement would depend on the accuracy of the resistors used for R1 and R2 and to a lesser degree the value of the 3.3V power supply to the PIC32. Rather than finding precision resistors for the voltage divider, a better approach is to simply measure the input voltage using a digital meter and use that value in the BASIC program. For example, run this program to find out the voltage measured by the Maximite on pin 9: > SETPIN 9, 2 > PRINT PIN(9) 2.983 > At the same time measure the voltage at the input to the voltage divider. If you measured 13.1V on the input the resultant would be: 10 SETPIN 9, 2 20 PRINT PIN(9) / (2.983 / 13.11) Depending on the accuracy of your meter this will give you the voltage with an accuracy approaching that of a normal digital multimeter. Too easy! Small voltages For small voltages you may need an amplifier to bring the input voltage into a reasonable range for measurement. Fig.6 shows a typical arrangement using the popular and inexpensive LM324 quad operational amplifier. The LM324 can operate from a single 5V supply (as provided by the Maximite from CON8) and contains four identical amplifiers in the one 14-pin package. The gain of the amplifier is determined by the ratio of R2 to R1 plus 1 and using the components in Fig.6 the gain is 101. This number should be used in the BASIC program so that the readings are scaled to represent the input voltage. For example: +5V FROM MAXIMITE MAXIMITE INPUT 0–32mV 3 1/4 2 LM324 11 LM324 You will need a voltage divider if you want to measure voltages greater than 3.3V as shown in Fig.4. Note that to retain the accuracy of the reading, the source resistance needs to be 10kΩ or less. This means that in most circuits R2 should be 10kΩ or less. The reading also needs to be scaled in the BASIC program to allow for the voltage divider. For example, to measure a car’s battery voltage you might use 39kΩ for R1 and 10kΩ for R2 giving a divide ratio of 0.2041 [R1/ (R1+R2)] and a range of about 16V full scale. The BASIC siliconchip.com.au 4 TOP VIEW AOUT AIN– AIN+ V+ BIN+ BIN– BOUT 1 2 14 AD 3 4 5 6 7 BC DOUT 13 DIN– 12 DIN+ 11 GND 10 CIN+ 9 CIN– 8 COUT 1 10k INPUT PIN R2 1M R1 10k Fig.6: this simple amplifier will allow the Maximite to measure voltages as little as a few millivolts. May 2011 69 20 PRINT PIN(9) / 101 Again, you could just measure the input voltage and use that value to scale the input. For better accuracy, use lower value feedback resistors to minimise bias current error. Even better would be a precision DC op amp (such as an OPA251) but the improved accuracy may be at the expense of higher power consumption. Temperature measurement There are many ways to measure temperature but for a simple solution the circuit in Fig.7 is hard to beat. The output of an LM335Z is a voltage proportional to its temperature. An output of 2.73V represents 0°C and a change of 10mV is equivalent to a 1°C change. The accompanying BASIC program would be: 10 SETPIN 9, 1 20 PRINT (PIN(9) – 2.73) * 100 This would print the current temperature in degrees Celsius from -40°C up to a maximum of 57°C at which point the output of the LM335Z would be at 3.3V. If you wanted to measure higher temperatures you should use a voltage divider on the output of the sensor and scale the reading in your program. Because the output from the LM335Z has a large offset at zero degrees (2.73V) this amplifies any error in measuring the voltage. The accuracy of the Maximite’s measurement is in turn dictated by the accuracy of the 3.3V supply voltage which is used as the reference when making voltage measurements. For this reason you should measure the supply voltage of your Maximite using a digital voltmeter and use this value in your program to correct for any error. The following fragment illustrates how to do this. 20 V = PIN(9) * x.xx / 3.3 30 PRINT (V - 2.73) * 100 Line 20 measures the voltage and corrects for any error (you should substitute x.xx with the measured supply voltage). The corrected voltage measurement is saved in the variable V and then used in line 30 to calculate the temperature. 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 volt- +5V FROM MAXIMITE Fig.7. Temperature measurement is a common requirement and this is about the simplest way to measure it using the Maximite. INPUT PIN + LM335Z TS1 LM335Z ADJ – 70 Silicon Chip + ADJ MAXIMITE R1 1.8k – age output from these sensors and scale the reading to a meaningful number. Frequency and period measurement Again using the SETPIN command, this time with the operator 3, pins 11 to 14 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 11: > SETPIN 11, 3 > PRINT PIN(11) 110374 > In this case the frequency is 110.374kHz. The frequency response is up to 200kHz and the measurement is returned in Hz with a resolution of 1Hz. The value is updated once a second (ie, the gate time is 1 second). For accurate measurement of signals less than 10Hz it is generally better to measure the period of the signal. When set to this mode the Maximite will measure the number of milliseconds between sequential rising edges of the input signal. The value is updated on the low to high transition so if your signal has a period of (say) 100 seconds you should be prepared to wait that amount of time before the PIN() function will return an updated value. Pins 11 to 14 can also count the number of pulses on their input. When a pin is configured as a counter (for example, SETPIN 13,5) the counter will be reset to zero and Maximite will then count every transition from a low to high voltage up to a maximum count of 4,294,967,295. 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 Maximite can count pulses as narrow as 10ns (although the maximum frequency of the pulse stream is still limited to 200kHz). As an example of using this facility you could count the number of contact bounces when the switch in Fig.5 was closed. You could also count the number of objects on a conveyor belt, number of people through a door or anything that takes your fancy. 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 0V and when set high it will pull its output to 3.3V. In BASIC 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. Incidentally, any non zero value can be used to set the output high. When operating in this mode, a pin is capable of sourcing or sinking 10mA to 18mA (depending on the required output voltage) which is sufficient to drive a LED or other logic circuits running at 3.3V. Pins 11 to 20 have a couple of additional properties that make it easy to connect to 5V circuitry. As already mentioned, as inputs they can be directly connected to a circuit that generates up to 5V without the need for the voltage dropping resistors. When configured as outputs these pins can also be set siliconchip.com.au siliconchip.com.au May 2011 71 +5V FROM MAXIMITE MAXIMITE R1 10k OUTPUT PIN D G S LOGIC HIGH = 5V LOGIC LOW = 0V (OPEN DRAIN) Fig.8: so-called “open collector” outputs (actually, in this case they’re open drain outputs) allow the Maximite to drive circuits that require a 5V signal. up to have an open-collector output. 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. Fig.8 illustrates how an open-collector system works. To set an output as open collector you use the SETPIN command in BASIC (for example SETPIN 15,9 will set pin 15 to an open collector output). Note that the circuit should really be called open drain because the PIC32 uses a FET as the driver but open collector is a more common term and for consistency we will keep using it. For driving high voltage and/or high current loads you should use an external transistor (either bipolar or FET) to drive the load. Fig.9 provides an example of using an inexpensive power FET for driving a large load, in this case a power relay. To provide sufficient voltage to turn on the FET, a pullup resistor to 5V is used and the output pin is configured as open collector. This circuit can switch a load of up to 50V and 20A with the RFP30N06LE, so it could be used to drive larger loads such as the solenoid valves used in irrigation systems. Switching mains This is not for the inexperienced. Normally we wouldn’t suggest it but we know that some readers will want to use the Maximite to switch mains devices on and off. All we can say is be careful – and if you don’t know what you’re doing, don’t! You could use a standard (and appropriately rated) relay to switch 230V AC (as shown in Fig.9) but a more elegant RELAY VOLTAGE (EG, 12V) RELAY K +5V FROM MAXIMITE D1 A MAXIMITE 10k OUTPUT PIN (OPEN DRAIN) D 10 G S Q1 RFP30N06LE Q1 D1: 1N4004 A K G D D S Fig.9. To drive high powered devices such as relays or solenoids a power MOSFET can be used. 72 Silicon Chip solution is to use a solid state relay such as the Jaycar SY4080. These have full isolation between their input and output and can switch 230V AC loads with a current of up to 3A. The SY-4080 will turn on with an input level greater than 3V so it can be directly connected to a Maximite pin configured as a standard digital output. Other solid state relays may need a drive voltage over 4V and in that case you will need to use an open collector output and a pull up resistor. Another useful output device is the reed relay. They can be directly driven by an output pin but generally they need a minimum of 5V to turn on so you would need to configure the output as open collector and connect the reed relay between 5V and the output pin. Most reed relays can switch up to 50V at 500mA and come in a DIP plastic package (ie, they look like an IC). A reed relay should include a reverse diode between the open drain and 5V (eg a 1N4148) to prevent destroying the internal mosfet (as shown in Fig.12) 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 more cleaner and readable program. When an interrupt occurs the MMBasic interpreter will execute a special section of code and when finished return to the main program. The main program is completely unaware of the interrupt and carries on as normal. As an example, the following code fragment will detect if the user has pressed a button (connected to pin 16) and, if so, will set the output of pin 15 high (this could operate a relay or something similar). 10 SETPIN 15, 8 20 SETPIN 16, 7, 100 30 DO 40 ‘ main processing loop 50 ‘ more processing 60 LOOP 80 ‘ 90 ‘ 100 ‘ interrupt routine 110 PIN(9) = 1 120 IRETURN In line 10 we configure pin 15 as an output (this will drive our relay or whatever) and in line 20 we configure pin 16 to be a digital input that will generate an interrupt on the high to low transition. The interrupt code starts at line 100 and this is specified as the third parameter to the SETPIN command. Lines 30 to 60 represent the main processing loop which runs forever. If the user presses the button connected to pin 16, MMBasic will automatically interrupt the main program and execute the program starting at line 100. This routine is very short; it just sets the output high and returns from the interrupt (the IRETURN command). Meanwhile the main processing loop is completely oblivious to the interrupt. An interrupt can be set on any pin and can be triggered on a low to high, or a high to low transition of the input. siliconchip.com.au How Good Is Your Refrigerator? A simple demonstration of the capabilities of the Maximite is to use it to monitor the temperature regulation of your refrigerator. This project will measure up to five temperatures within your refrigerator and also detect if the door is open or closed. This data is saved to the SD card in a format that you can load into a spreadsheet to draw graphs, calculate temperature variations and generally analyse. Because most SD cards have a large capacity you could log the data for months to get an accurate long term picture of your refrigerator’s performance. Fig.11 shows the basic circuit. There are five temperature monitors which are based on the LM335Z temperature sensor described in the main text. The sixth input comes from an LDR (light dependent resistor) which is used to detect when the fridge door is opened. Because the circuit is so simple we built it on a piece of strip prototype board and used a length of ribbon cable with a crimped 26 pin IDC socket for connection to the Maximite. We placed the Maximite on top of the refrigerator and ran fine wires (so as not to break the refrigerator’s door seal) to the sensors inside. Two were placed in the freezer compartment (one at the back and the other at the front near the door). The remaining three were placed in the main body of the fridge – one at the top back, the second at the bottom back and the third in the middle of +5V FROM MAXIMITE MAXIMITE R1 1.8k PIN 1 + TS1 LM335Z ADJ PIN 2 – TO TS2 – TS4* PIN 3 PIN 4 R5 1.8k PIN 5 + TS5 LM335Z ADJ – * CIRCUITS FOR TS2 – TS4 ARE IDENTICAL TO THOSE FOR TS1 AND TS5 3.3V R6 10k PIN10 LM335Z LDR GND – + ADJ Fig.11: schematic for the refrigerator monitor and logger. Over a long period it will log up to five temperatures and the status of the door for later analysis. siliconchip.com.au 100 FOR i = 1 TO 5 : SETPIN i, 1 : NEXT i 110 SETPIN 10, 2 120 OPEN “TEMPLOG.XLS” FOR OUTPUT AS #1 130 PRINT #1, “DATE”, “TIME”, “T1”, “T2”, “T3”, “T4”, “T5”, “DOOR” 140 CLOSE #1 150 DO 160 OPEN “TEMPLOG.XLS” FOR APPEND AS #1 170 PRINT #1, DATE$, TIME$,; 180 FOR i = 1 TO 5 190 t = (PIN(i) / 3.3 * x.xx - 2.73) * 100 200 PRINT #1, FORMAT$(t, “%4.1f”),; 210 NEXT i 220 IF PIN(10) THEN PRINT #1, “CLOSED” ELSE PRINT #1, “OPEN” 230 CLOSE #1 240 PAUSE 2000 250 LOOP the door. Finally, we placed the LDR where it would be illuminated by the fridge light. The BASIC program is listed above and is also available for download from the SILICON CHIP website. This will record the data into a file called TEMPLOG.XLS which can then be read by most spreadsheet software. Line 240 sets the recording frequency which is every 2000ms (or every 2 seconds) and you can change that (or anything else) to suit your requirements. Because the temperature measurement is sensitive to the value of the 3.3V supply (which is used by the PIC32 as the reference voltage) you must measure this voltage with a digital multimeter and, before you run the program, insert its value in line 190 replacing the x.xx characters. The program should be saved to your SD card with the name AUTORUN.BAS. This means that it will automatically start running when you apply power to the Maximite and you therefore do not need to connect a monitor or keyboard. One important feature of the program is that it always closes the data file after any data is written (see line 230). Closing the file means that any data buffered in memory is immediately written to the SD card and that allows you to stop the recording by turning off the Maximite without corrupting the data file. By the way, creating an Excel compatible spreadsheet file is easy. All you need to do is write the data out as plain text with a TAB character between each data element. This is done in line 200. The comma (,) near the end of the line will output a TAB character while the following semicolon (;) tells the PRINT command to not output the normal carriage return and line feed characters. Lines 100 and 110 setup the inputs, lines 120 to 140 write the header to the spreadsheet file and lines 150 to 250 form a continuous loop that reads the data (line 190) from each sensor and writes it (line 200) to the file. Line 240 controls how often the data is recorded. May 2011 73 Because there are 20 pins you can have up to 20 interrupts with each interrupt executing separate or shared sections of code. All that matters is that the interrupt routine must be terminated with an IRETURN statement. Normally MMBasic will respond to a single interrupt within 100s so you can use interrupts to catch reasonably fast events (for example, ignition pulses in a petrol engine). Timing MMBasic has a number of features that make it easy to time events and control external circuitry that needs timing. The PAUSE command 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: 10 SETPIN 4, 8 20 PIN(4) = 1 30 PAUSE 12 40 PIN(4) = 0 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. This is handy for timing events as illustrated in the following code fragment: 10 SETPIN 4, 8 20 PIN(4) = 1 30 TIMER = 0 40 GOSUB 1000 ‘ do some work 50 IF TIMER < 12 THEN GOTO 40 60 PIN(4) = 0 This is similar to the previous code fragment in that it will generate a 12ms pulse but it allows your program to do some work while waiting for the pulse to finish rather than simply freezing the program’s execution. Line 30 sets the TIMER to zero and then line 40 will keep calling the subroutine at line 1000 until the TIMER function has counted up to 12ms. A very useful timing function is 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. For example, the following code fragment will save the current time and the voltage on pin 1 in a file (called “DFILE”) on the SD card every second. This process will run independently of the main program which could be doing something completely unrelated. 10 SETPIN 1, 1 20 SETTICK 1000, 500 30 DO 40 ‘ main processing loop 50 LOOP 60 ‘ 500 ‘ tick interrupt 510 OPEN “DFILE” FOR APPEND AS #1 520 WRITE #1, TIME$, PIN(1) 530 CLOSE #1 540 IRETURN Line 20 sets up the “tick” interrupt, the first parameter of SETTICK is the period of the interrupt (1000ms) and the second is the starting line of the interrupt code. Every second (ie, 1000ms) the main processing loop will be interrupted and the program starting at line 500 will be executed. This simply appends the current reading to the data file and returns to the main program. Loading and saving programs When you have entered your program into the Maximite’s memory you will then need to save it, otherwise it The rear panel of the Maximite is a busy place with connectors for the VGA video, keyboard, external input/output, USB and power. Two headers on the main board provide the composite video and sound outputs. Inset at top is the input/ output connector, viewed from the back (as show in the photograph). You’ll need to refer to this when connecting inputs and outputs to the Maximite. 74 Silicon Chip siliconchip.com.au will be lost when the power is turned off. The Maximite treats the SD memory card as disk storage and there are a number of commands that you can use to save and load programs. The command SAVE “FILENAME” will save your program in the current folder with the name FILENAME. BAS. Note that the double quotes are necessary and that MMBasic will automatically add the .BAS extension if none is supplied. Later you could load the program using the LOAD “FILENAME” command. You can also load and run the program by adding the filename to the RUN command. For example: > RUN “FILENAME” As well as being run from the command input this command can be used within a running program and it enables you to launch one program from within another. The argument to all these commands can also be a string variable, so the following fragment will run a program called “TT.BAS” from within another program. to change up to the parent directory. Eg, the following will change back to the parent of the BACKUP directory. > CHDIR “..” You can also create directories using the MKDIR command and delete them using the RMDIR command. All these commands can be used at the command prompt or within a running program. File Input/Output An important feature of MMBasic is the ability to save data on the SD card. To do this you must first “open” the file on the SD card using the appropriately named OPEN command. The following example will open the file “TST.DAT” for writing: 10 OPEN “TST.DAT” FOR OUTPUT AS #1 You can then use the file number (#1) in a print command to write data to the SD card: 20 PRINT #1, VAR1, VAR2 10 FNAME$ = “TT.BAS” 20 RUN FNAME$ All file and directory names must use the 8.3 format. This means that the maximum file name length is 8 characters followed by a full stop (.) and up to 3 more characters for the file extension. File names can be in either upper or lowercase. Unfortunately Microsoft has patented a portion of the mechanism used for long file name support with the result that we were prevented from implementing that feature. All BASIC programs are saved to the SD card as straight text files and you can edit them using a desktop computer. If you do this you must make sure that your editor uses standard ASCII characters. This means that in the Windows world you should use Notepad and not Wordpad or MS Word, both of which embed strange characters in normal looking text. To find out what is on the SD card you can use the FILES command. For example: Each time the print command is run it will save a line to the SD card containing the data that you specified (in this case the contents of the variables VAR1 and VAR2). When you have finished you need to close the file using the CLOSE command. 30 CLOSE #1 The close command will flush any data held in memory to the SD card and update the file records on the card to show that this is a valid file. You should never remove the SD card before the CLOSE command as that might result in a corrupt file or even render the SD card unreadable. The above example opened the file for “OUTPUT” which means that when the file was created it would have overwritten a file with the same file name. You can also open a file for “APPEND” which means that the file will also be > FILES Directory: \ BACKUP <DIR> DATALOG.BAS 2090 DATALOG.XLS 8032 GRAPH.BAS 3093 HAMURABI.BAS 4362 The first entry in this particular listing is a directory (marked with the <DIR> symbol) and MMBasic includes a number of commands to work with these. The command CHDIR “directory” will change to a directory, for example the following code fragment will change to the directory in the previous files listing: > CHDIR “BACKUP” The special directory of “..” is used siliconchip.com.au An example of the graphical capabilities of the Maximite. The line graph is the voltage on pin 1 while the bar graphs show the voltage level on all 10 analog inputs. This graph can update rapidly to show the voltages in real time. May 2011 75 opened for writing but it will not overwrite an existing file, instead any writes to the file will be appended to the end of it. Similar to writing to a file, you can also open a file for reading using the INPUT mode. You could then read from the file using the INPUT command as follows: 10 OPEN “INP.DAT” FOR INPUT AS #1 20 INPUT #1, DAT1, DAT2, DAT3 30 CLOSE #1 Note that the INPUT command requires that the data elements in the file be separated by commas and terminated with a carriage return/line feed combination. You can also use the LINE INPUT command to read the whole line into a string variable in one go and then pull the data line apart using the string manipulation functions in the BASIC language. MMBasic allows you to have up to 10 files simultaneously open. For each file you would use a unique file number, for example, #1, #2, #3, etc. Other commands and functions within MMBasic allow you to delete files, rename files and tell when you have reached the end of a file. Graphics The old adage “a picture is worth a thousand words” is true in computer output too. Within MMBasic you can draw fancy graphs like that shown aboove. This shows the voltage on pins 1 to 10 as a bar graph and the voltage on pin 1 as a line graph. You cannot see it in the photograph but the Maximite has enough speed to update the graph rapidly showing any variations on the inputs in real time. The simplest graphic commands are the PSET and PRESET commands. These will turn off or on any pixel on the screen. You also have at your disposal the workhorse of the graphics commands, the LINE command which will draw either a line, or a rectangle, or a filled rectangle. The LINE command can also be used to erase a portion of the screen as well as drawing lines. The CIRCLE command will draw a circle (actually an oval as the Maximite’s pixels are not exactly square). As with the LINE command, the circle can be filled with pixels that are turned off or on. Finally there is the LOCATE command which is used to position the next output of the print command to anywhere on the screen. All graphics commands use screen coordinates expressed in pixels. The top left hand corner of the screen is the zero position (x = 0 and y = 0) while the bottom left coordinate will vary depending on the video configuration (VGA or composite). Battery Capacity Meter Another excellent demonstration of the Maximite’s capabilities is to use it as the brains behind a battery capacity meter. Like most people we have amassed a collection of AA and AAA rechargeable batteries (mostly NiMh chemistry), some of which have reached the end of their life. But, which ones? And, how good are the good ones? It would also be interesting to test new batteries when we purchase them. Do they really match the rating printed on the outside? You could test each battery by fitting it into a piece of equipment and timing how long it lasted before the equipment stopped - but that is tedious and not very accurate. A much better solution is to build a low cost add-on to the Maximite designed to measure a battery’s capacity. Fig.12 shows the circuit of this add-on. Each of the four reed relays can switch a load resistor across the battery and by turning on a combination of the reed relays the BASIC program can vary the load on the battery in 16 steps. At the same time, the program can determine the battery’s level of charge by measuring the voltage on pin 1. To avoid the need to purchase accurate resistors the program is designed so that you can measure the resistors using a digital multimeter and enter the values as constants into the BASIC program. The program will then use these numbers to determine what relays to turn on/ off to maintain the desired load and also calculate the current drain on the battery. Note that when you are measuring the resistance of R3 and R4 you need to measure the total resistance of the Possibilities The Maximite was conceived as an enabling piece of technology, something that would enable readers to build more sophisticated devices without having to spend a lot of money and learn a specialised programming language such as C or C++. The two boxes “How Good Is Your Refrigerator?” and “Battery Capacity Meter” give a couple of interesting examples where the Maximite could be used. Do you have an interesting project in mind? For up to date errata, notes and new firmware for the Maximite go to http://geoffg.net/maximite.html 76 Silicon Chip The battery test add-on connected to a prototype of the Maximite. The reed relays and load resistors are contained in the UB5 jiffy box and connected to the Maximite via 26 way cable and IDC connector. siliconchip.com.au to use. Most batteries are tested at 0.2C or 0.1C which is another way of saying 20% or 10% of the batteries PIN 1 claimed capacity. +5V We were testing a 1000mAH battery so 200mA repreR1 51 sents the 0.2C current drain. K Our circuit has four relays and therefore 16 different REED levels of load and this results in a rather D1 RELAY coarse control of the load. That is not a 1 A PIN 11 + + concern as it will have little effect on the R2 22 resulting battery capacity measurement and it is a much simpler technique than AAA AA K BATTERY BATTERY trying to accurately control a FET to proMAXIMITE REED HOLDER HOLDER D2 RELAY duce a specific load current. 2 A The software also asks for the terminaPIN 12 – – tion voltage. When that voltage is reached 18 the program will remove the load and print R3 out the resultant battery capacity. K REED 15 The photo at left shows the completed D3 RELAY battery tester with a prototype of the 3 A 3 x 10 PIN 13 Maximite. We mounted two battery holders (AA R4 and AAA) on the top of a UB5 jiffy box and K built the circuit on a piece of strip protoREED D4 DIL REED RELAY type board inside the box. A short length RELAY TOP VIEW 14 13 9 8 4 of 26-way ribbon cable and a crimped IDC A PIN 14 socket completed the device. D1–D4: 1N4004 All the necessary power is supplied by GND A K the Maximite and when you want to test a 1 2 6 7 battery it is simply a case of plugging the Fig.12. Schematic of the battery tester. The Maximite add-on into the Maximite and running the can control the relays to provide different levels of load BATTERY.BAS program from the SD card. on the battery while monitoring its level of charge. The program will monitor the battery paralleled resistors. At the start of the BASIC program while it is discharging and at completion it will display you will find a series of assignments as follows: the battery’s capacity. You can then unplug the add-on and use the Maximite for something else. 145 R1 = 56.00 You could add many other features to the program, 150 R2 = 22.00 for example the ability to draw a graph of the discharge 155 R3 = 8.20 curve or the ability to store the battery’s performance in 160 R4 = 3.33 a data file on the SD card for later comparison when you test the battery again. This is where you need to enter the measured values Ah, the possibilities !! SC for R1, R2, R3 and R4. Note that the resistors do not need to be in an exact binary sequence (ie, 1 -2 -4 -8) as you would normally expect. The program will work with whatever values you use and calculate the combination necessary to maintain the load as near as possible to the specified value. Using some simple calculations it is then easy to add up the current drain over time to come up with the battery’s capacity in milliamp-hours. The program is too large to list here but it is also available on the SILICON CHIP website for download. Because it is written in BASIC you can easily modify it for other tasks such as testing higher voltage battery packs or different types of batteries. Fig.13 shows the opening screen of the pro- Fig.13: when you run the battery test software it will request the gram. First the program requests the current drain desired test current and the terminating voltage. 4.7k siliconchip.com.au May 2011 77