Parallax provides PBASIC code examples for many applications and devices, and many more examples can be found on the Parallax forums and other web sites. While some code examples include compiler directives that make them compatible with any 24-pin BASIC Stamp model, others are written for a single model, most often the BS2. If your BASIC Stamp model is different from the one the code is written for, portions of the program may need to be adjusted to accommodate differences in processor speed. This page provides some tips and examples of how to do this.
Many BASIC Stamp 2 application examples make use of time-sensitive commands, those which have one or more arguments that depend on some attribute of time such as frequency, duration, baud rate, decay time, or pulse duration. If the command generates a signal, one or more of its arguments may contain values that affect the signal’s timing. Likewise, if the command measures a signal, one or more of its arguments may affect the result. When executed by different BASIC Stamp 2 models, the units for each time-sensitive argument may differ, so if the program is not adjusted to account for these differences, signals may be generated or measured at different rates.
• COUNT | COUNT Pin, Duration, Variable | |||
• DTMFOUT | DTMFOUT Pin, {OnTime, OffTime, } [Tone {, Tone, ...}] | |||
• FREQOUT | FREQOUT Pin, Duration, Freq1 {, Freq2 } | |||
• POLLWAIT | POLLWAIT Duration | |||
• PULSIN | PULSIN Pin, State, Variable | |||
• PULSOUT | PULSOUT Pin, Duration | |||
• PWM | PWM Pin, Duty, Duration | |||
• RCTIME | RCTIME Pin, State, Variable | |||
• SERIN | SERIN Rpin {\Fpin}, Baudmode, {Plabel,} {Timeout, Tlabel, } [InputData] | |||
• SEROUT | SEROUT Tpin {\Fpin}, Baudmode, {Pace,} {Timeout, Tlabel,} [OutputData] |
If the BS2 application does not utilize any of the time-sensitive commands listed above, all that needs to change is the $STAMP directive. Here is an example BASIC Stamp 2 program that has no time-sensitive commands.
' Hello World.bs2 ' {$STAMP BS2} ' {$PBASIC 2.5} DEBUG "Hello world!" END
With this program, the only change that would need to be made to get this program to run properly with a BS2sx (for example), would be to update the $STAMP directive from BS2 to BS2sx. You can either manually modify the $STAMP directive, or click the BS2sx button on the BASIC Stamp Editor’s toolbar (recommended).
Tip: The BASIC Stamp Editor can detect if you are trying to load a program into a BASIC Stamp model that’s different from the one indicated in the program’s $STAMP directive. When this happens, it will ask you if you want it to automatically update the directive. Keep in mind that this directive update does not automatically update any time-sensitive command arguments.
In addition to updating the $STAMP directive, each line of code that uses a time-sensitive command will need to be examined and possibly adjusted. The PBASIC Command Reference has links to the documentation for each command, including Quick Facts tables with the units of time-based attributes for each BASIC Stamp model. In most cases, you can use the units for the model the code is written for along with the units for the new target model to make a fraction for converting a given time-sensitive command argument. The units value for the “Convert from” model should be in the numerator, and the units for the “Convert to” model should be in the denominator. Make sure to round the “New Argument Value” to the nearest integer before using it as a command argument in a time-sensitive PBASIC command.
Tip: The SERIN and SEROUT commands have baud rate arguments that don't use this adjustment method. The Quick Facts tables for SERIN and SEROUT have common baud rates listed, and the documentation also provides directions for calculating custom baud rates for all BASIC Stamp 2 models.
The “Old Argument Value” to “New Argument Value” calculation can be used in three different approaches for updating your code:
Let’s take a look at how each approach can be used with the time-sensitive FREQOUT command as an example, with the BS2 as the “Convert From” model and the BS2sx as the “Convert To” model.
Let’s say a speaker circuit is connected to BASIC Stamp I/O pin P6. If the BS2 executes the command:
FREQOUT 6, 100, 4500
... it sends a high-pitched alarm tone to the speaker for 100 ms at a frequency of 4500 Hz. A FREQOUT command with the same arguments executed by the BS2sx sends a tone that only last 40 ms at a frequency of 11,250 Hz. That’s a much shorter duration tone with a much higher pitch!
The FREQOUT command’s Quick Facts table indicates that the FREQOUT Duration argument is in terms of 1 ms units for the BS2, and in terms of 0.4 ms units for the BS2sx. Likewise, the BS2 units for Freq1 are 1 Hz, while the BS2sx Freq1 units are 2.5 Hz. You can use those values and the “Old Argument Value” to “New Argument Value” equation to convert a BS2 command like:
FREQOUT 6, 100, 4500
...for use with a BS2sx. In the figure below, the existing Duration argument of 100 gets multiplied by 1.0/0.4 with a result of 250. Likewise, the 4500 Freq1 argument gets multiplied by 1.0/2.5 with a nearest integer result of 1800. With these new values, the BS2sx version of the FREQOUT command is:
FREQOUT 6, 250, 1800
This command is now updated to make the BS2sx deliver a 4.5 kHz tone for 100 ms.
You can incorporate expressions with */ (Multiply Middle) operators to perform the conversions from approach 1 right inside a PBASIC program. The */ operator allows you to multiply a constant, variable or expression result by a number of 256ths. For example, 1/4 is the same as 64/256ths, so value */ 64 is the same as multiplying a value by 1/4.
Each of the fractions determined with the Quick Facts table above can also be expressed as a number of 256ths. The result is “*/Constant” that you can use to scale a constant, variable or expression result to adjust a command's argument for a different BASIC Stamp model.
*/Constant = Integer(256 x (Units in “Convert From” Model / Units in “Convert To” model))
Continuing the FREQOUT command example, the “*/Constant” to convert Duration from BS2 to BS2sx units would be Integer(256 x (1/0.4)) = 640. So, a BS2 Duration value */ 640 results in an approximate BS2sx Duration value.
Likewise, the“*/Constant” for converting Freq1 from BS2 to BS2sx is Integer(256 x (1/2.5)) = 102, and a BS2 Freq1 */ 102 results in an approximate BS2sx Freq1 value. You can incorporate these */ operations directly into a FREQOUT command’s Duration and Freq1 arguments like this:
FREQOUT 6, 100 */ 640, 4500 */ 102
Keep in mind that this approach works with constants (like 100 and 4500), and it also works with variables and expression results. The only caveat is that it does take a little extra code space and execution time for each added */ operation. A test program for the BS2sx with the updated FREQOUT command might look like this:
' Tenth Second 4.5 kHz Tone StarSlash.bsx ' {$STAMP BS2sx} ' {$PBASIC 2.5} FREQOUT 6, 100 */ 640, 4500 */ 102 END
Declaring constants for each of these */ multipliers makes it possible to update values once at the beginning for the program for multiple FREQOUT commands. With the constant declaration approach, our example program would looks like this:
' Tenth Second 4.5 kHz Tone StarSlash With Constants.bsx ' {$STAMP BS2sx} ' {$PBASIC 2.5} DurFactr CON 640 FreqFactr CON 102 FREQOUT 6, 100*/DurFactr, 4500*/FreqFactr END
The ** (Multiply High) operator multiplies a constant, variable or expression by a number of 65536ths, up to 65535. For fractional values less than one, it provides higher resolution than the */ operator. Since the fractional value for converting the FREQOUT command’s Freq1 argument is less than 1, the ** operator can provide a more precise conversion.
** Constant = Integer(65536 x (Units in “Convert From” Model / Units in “Convert To” model))
We can apply this to our BS2 to BS2sx Freq1 argument conversion with:
** Constant = Integer(65536 x (1 / 2.5)) = 26214
Now, the FREQOUT command with a more precise Freq1 argument conversion is:
FREQOUT 6, 100 */ 640, 4500 ** 26214
How much more precise is it? The BASIC Stamp always truncates to the integer in a calculation, so
4500 */ 102 = 4500 x 102 ÷ 256 = 1792
...truncated to the integer. For the BS2sx, that results in a frequency of 1792 x 2.5 Hz = 4480 Hz. That’s an error of 20 Hz, which is enough to be audible to sensitive ears or equipment. In contrast,
4500 ** 26214 = 4500 x 26214 ÷ 65536 = 1799
...truncated to the integer. This time, the BS2sx transmits a frequency of 1799 x 2.5 Hz = 4497.5 Hz, so the propagated error is now only 2.5 Hz! Here is a program that compares the tones:
' Tenth Second 4.5 kHz Tone Compare StarSlash and StarStar.bsx ' {$STAMP BS2sx} ' {$PBASIC 2.5} DurFactr CON 640 FreqFactr VAR Word FREQOUT 6, 250, 1800 ' Calculated by hand PAUSE 100 FreqFactr = 102 ' Multiplier for */ FREQOUT 6, 100*/DurFactr, 4500*/FreqFactr PAUSE 100 FreqFactr = 26214 ' Multiplier for ** FREQOUT 6, 100*/DurFactr, 4500**FreqFactr END
Tip: If you can't hear the difference in the tones, try multiplying each Duration argument by 4 with "4*" to increase the length time you hear each tone.
The results from approaches 1 and 2 can be incorporated into Conditional Compilation directives. Especially when the target BASIC Stamp module could be one of several different models, conditional compilation makes it possible to use the $STAMP directive to select which segments of code get compiled and downloaded to the BASIC Stamp. For example, code from approaches 1 and 2 can be nested into conditional compilation directives. Then, the code can be set to run in a BS2 and BS2sx by simply updating the $STAMP directive.
In this first example, the $STAMP directive identifies which BASIC Stamp model is being used at compile time, and then only the FREQOUT command for the model identified gets downloaded. Note that the FREQOUT command for the BS2sx uses the Duration and Freq1 argument values we determined earlier in approach 1.
' Tenth Second 4.5 kHz Tone Select Case.bs2 ' {$STAMP BS2} ' {$PBASIC 2.5} #SELECT $STAMP #CASE BS2 FREQOUT 6, 100, 4500 #CASE BS2sx FREQOUT 6, 250, 1800 #ENDSELECT END
In this second example (below), the */ operator is used to define constants as multipliers to apply to the Duration and Freq1 arguments. These same constant symbols could be applied to any other FREQOUT commands added to the program, regardless of the Duration and Freq1 arguments used, which could be variables, constants, or even expressions.
' Tenth Second 4.5 kHz Tone Select Case With Constants.bs2 ' {$STAMP BS2sx} ' {$PBASIC 2.5} #SELECT $STAMP #CASE BS2 DurFactr CON 256 FreqFactr CON 256 #CASE BS2sx DurFactr CON 640 FreqFactr CON 102 #ENDSELECT FREQOUT 6, 100*/DurFactr, 4500*/FreqFactr END
More example PBASIC programs that demonstrate conditional compilation for time-sensitive commands are included with the BASIC Stamp Editor. Just click File -> Open From -> Default BS2 directory, and select a program with a name like FREQOUT, PULSIN, or any of the other time-sensitive commands listed earlier.
BASIC Stamp Help Version 2.5.4
Copyright © Parallax Inc.
8/8/2012