# SERIN

{PBASIC 2.5}

SERIN Examples

Syntax : SERIN Rpin, Baudmode, {(Qualifier),} {#} InputData
Syntax : SERIN Rpin {\Fpin}, Baudmode, {Plabel,} {Timeout, Tlabel,} [InputData]

## Function

Receive asynchronous serial data (e.g., RS-232 data).

- Rpin is a variable/constant/expression* (0 - 16) that specifies the I/O pin through which the serial data will be received. This pin will be set to input mode. On the BS2, BS2e, BS2sx, BS2p, BS2pe, and BS2px, if Rpin is set to 16, the BASIC Stamp uses the dedicated serial-input pin (SIN, physical pin 2), which is normally used by the Stamp Editor during the download process.
- Fpin is an optional variable/constant/expression* (0 - 15) that specifies the I/O pin to indicate flow control status on. This pin will be set to output mode.
- Baudmode is variable/constant/expression* (0 - 7 on the BS1, 0 - 65535 on all other BASIC Stamp models) that specifies serial timing and configuration.
- Qualifier is an optional variable/constant (0 - 255) indicating data that must be received before execution can continue. Multiple qualifiers can be indicated with commas separating them.
- Plabel is an optional label indicating where the program should go in the event of a parity error. This argument should only be provided if Baudmode indicates 7 bits, and even parity.
- Timeout is an optional variable/constant/expression* (0 - 65535) that tells SERIN how long to wait for incoming data. If data does not arrive in time, the program will jump to the address specified by Tlabel.
- Tlabel is an optional label that must be provided along with Timeout, indicating where the program should go in the event that data does not arrive within the period specified by Timeout.
- InputData‡ is a list of variables and formatters that tells SERIN what to do with incoming data. SERIN can store data in a variable or array, interpret numeric text (decimal, binary, or hex) and store the corresponding value in a variable, wait for a fixed or variable sequence of bytes, or ignore a specified number of bytes. These actions can be combined in any order in the InputData list.

* Note: expressions are not allowed as arguments on the BS1. The range of the Pin argument on the BS1 is 0–7.

‡ Note: The BS1's InputData argument can only be a list of variables and the optional decimal modifier (#).

(Jump down to Baudmode Calculation; Baud Rate Tables; Decimal Formatter Specifics; Conversion Formatter Table; Special Formatter Tables; SERIN Troubleshooting)

## Quick Facts

| BS1 | BS2 and BS2e | BS2sx | BS2p | BS2pe | BS2px
Units in Timeout | N/A | 1 ms | 0.4 ms | 0.4 ms | 1 ms | 0.4 ms
Baud Range | 300, 600, 1200, and 2400 only | 243 to 50K | 608 to 115.2K | 608 to 115.2K | 243 to 50K | 972 to 115.2K
Baud Limit with Flow Control | N/A | 19.2K | 19.2K | 19.2K | 19.2K | 19.2K
Limit to Qualifiers | Unlimited | 6 (in WAIT formatter)
I/O Pins Available | 0 - 7 | 0 - 15 | 0 - 15 | 0 - 15 (in current I/O block) | 0 - 15 (in current I/O block) | 0 - 15 (in current I/O block)
Other Serial Port Pins | N/A | SIN pin (physical pin 2) when Rpin= 16
Related Commands | SEROUT | SEROUT, DEBUGIN

## Explanation

One of the most popular forms of communication between electronic devices is serial communication. There are two major types of serial communication; asynchronous and synchronous. The SERIN and SEROUT commands are used to receive and send asynchronous serial data. See the SHIFTIN and SHIFTOUT commands for information on the synchronous method.

SERIN can wait for, filter and convert incoming data in powerful ways. SERIN deserves some lengthy discussion, below, since all this power brings some complexity.

The term asynchronous means "no clock." More specifically, "asynchronous serial communication" means data is transmitted and received without the use of a separate "clock" wire. Data can be sent using as little as two wires; one for data and one for ground. The PC's serial ports (also called COM ports or RS-232 ports) use asynchronous serial communication. Note: the other kind of serial communication, synchronous, uses at least three wires; one for clock, one for data and one for ground.

RS-232 is the electrical specification for the signals that PC serial ports use. Unlike normal logic, where a 5 volts is a logic 1 and 0 volts is logic 0, RS-232 uses -12 volts for logic 1 and +12 volts for logic 0. This specification allows communication over longer wire lengths without amplification.

Most circuits that work with RS-232 use a line driver/receiver. This component does two things: (1) it converts the ±12 volts of RS-232 to TTL-compatible 0 to 5-volt levels and (2) it inverts the relationship of the voltage levels, so that 5 volts = logic 1 and 0 volts = logic 0. Note: When connecting a line driver/receiver to the BASIC Stamp, make sure to power the line driver/receiver with 5 volts DC from a regulated source other than BASIC Stamp's 5-volt VDD pin; the BASIC Stamp's on-board regulator may be unable to provide the required amount of current to the line driver/receiver chip.

All BASIC Stamp models (except the BS1) have a line receiver on its SIN pin (Rpin = 16). The SIN pin goes to a PC's serial data-out pin on the DB-9 connector built into BASIC Stamp development boards. The connector is wired to allow both programming and run-time serial communication (unless you are using the Stamp 2 Carrier Board which is only designed for programming). For the built-in serial port set the Rpin argument to 16 in the SERIN command.

All BASIC Stamp models (including the BS1) can also receive RS-232 data through any of their I/O pins (Rpin = 0 - 7 for BS1, Rpin = 0 - 15 on all other BASIC Stamp models). The I/O pins don't need a line receiver, just a 22 kΩ resistor. The resistor limits current into the I/O pin's built-in clamping diodes, which keep input voltages within a safe range.

Note: The connections shown in red are normally not necessary. They indicate optional connections to defeat hardware handshaking requirements.

Note: A line driver may have to be used between the I/O pin and the receiving serial port to ensure proper communication.

Function | DB-9 | DB-25
Data Carrier Detect (DCD) | 1 | 8
Receive Data (RD) | 2 | 3
Transmit Data (TD) | 3 | 2
Data Terminal Ready (DTR) | 4 | 20
Signal Ground (SG) | 5 | 7
Data Set Ready (DSR) | 6 | 6
Request To Send (RTS) | 7 | 4
Clear To Send (CTS) | 8 | 5

The figure above shows the pinouts of the two styles of PC serial ports and how to connect them to the BASIC Stamp's I/O pin (the 22 kΩ resister is not needed if connecting to the SIN pin). Though not normally needed, the figure also shows loop back connections that defeat hardware handshaking used by some PC software. Note that PC serial ports are always male connectors. The 25-pin style of serial port (called a DB-25) looks similar to a printer (parallel) port except that it is male, whereas a parallel port is female.

Asynchronous serial communication relies on precise timing. Both the sender and receiver must be set for identical timing, usually expressed in bits per second (bps) called baud.

On all BASIC Stamp models, SERIN requires a value called Baudmode that tells it the important characteristics of the incoming serial data; the bit period, number of data and parity bits, and polarity.

On the BS1, serial communication is limited to: no-parity, 8-data bits and 1-stop bit at one of four different speeds: 300, 600, 1200 or 2400 baud. The table below indicates the Baudmode value or symbols to use when selecting the desired mode.

Baudmode Value | Symbol | Baud Rate | Polarity
0 | T2400 | 2400 | TRUE
1 | T1200 | 1200 | TRUE
2 | T600 | 600 | TRUE
3 | T300 | 300 | TRUE
4 | N2400 | 2400 | INVERTED
5 | N1200 | 1200 | INVERTED
6 | N600 | 600 | INVERTED
7 | N300 | 300 | INVERTED

On the BS2, BS2e, BS2sx, BS2p, BS2pe, and BS2px, serial communication is very flexible. The Baudmode argument for SERIN accepts a 16-bit value that determines its characteristics: 1-stop bit, 8-data bits/no-parity or 7-data bits/even-parity and virtually any speed from as low as 300 baud to greater than 100K baud (depending on the BASIC Stamp). The information below shows how Baudmode is calculated and show common baud modes for standard serial baud rates.

### Baudmode Calculation

1. Determine the bit period (bits 0 - 11)
   - BS2, BS2e, and BS2pe = INT(1,000,000 ÷ baud rate) - 20
   - BS2sx and BS2p = INT(2,500,000 ÷ baud rate) - 20
   - BS2px = INT(4,000,000 ÷ baud rate) - 20
     Note: INT means 'Convert to integer.' -- drop the numbers to the right of the decimal point.
2. Set data bits and parity (bit 13)
   - 8-bit / No Parity = 0 ($0000)
   - 7-bit / Even Parity = 8192 ($2000)
3. Select polarity bit (bit 14)
   - True = 0 ($0000)
   - Inverted = 16384 ($4000)

### Baud Rate Tables

These tables give common baud rates and their corresponding Baudmode values.

BS2, BS2e, BS2pe

Baud Rate | 8-bit No Parity INVERTED | 8-bit No Parity TRUE | 7-bit Even Parity INVERTED | 7-bit Even Parity TRUE
300 | 19697 ($4CF1) | 3313 ($0CF1) | 27889 ($6CF1) | 11505 ($2CF1)
600 | 18030 ($466E) | 1646 ($066E) | 26222 ($666E) | 9838 ($266E)
1200 | 17197 ($432D) | 813 ($032D) | 25389 ($632D) | 9005 ($232D)
2400 | 16780 ($418C) | 396 ($018C) | 24972 ($618C) | 8588 ($218C)
4800 | 16572 ($40BC) | 188 ($00BC) | 24764 ($60BC) | 8380 ($20BC)
9600 | 16468 ($4054) | 84 ($0054) | 24660 ($6054) | 8276 ($2054)

Tip: The BS2, BS2e, and BS2pe may have trouble synchronizing with the incoming serial stream at this 4800 baud and higher while using certain complex expressions, arrays, and/or formatters. Try using simple variables and WAIT or WAITSTR formatters to achieve the necessary results.

BS2sx, BS2p

Baud Rate | 8-bit No Parity INVERTED | 8-bit No Parity TRUE | 7-bit Even Parity INVERTED | 7-bit Even Parity TRUE
1200 | 18447 ($480F) | 2063 ($080F) | 26639 ($680F) | 10255 ($280F)
2400 | 17405 ($43FD) | 1021 ($03FD) | 25597 ($63FD) | 9213 ($23FD)
4800 | 16884 ($41F4) | 500 ($01F4) | 25076 ($61F4) | 8692 ($21F4)
9600 | 16624 ($40F0) | 240 ($00F0) | 24816 ($60F0) | 8432 ($20F0)

Tip: The BS2sx and BS2p may have trouble synchronizing with the incoming serial stream at this 4800 baud and higher while using certain complex expressions, arrays, and/or formatters. Try using simple variables and WAIT or WAITSTR formatters to achieve the necessary results.

BS2px

Baud Rate | 8-bit No Parity INVERTED | 8-bit No Parity TRUE | 7-bit Even Parity INVERTED | 7-bit Even Parity TRUE
1200 | 19697 ($4CF1) | 3313 ($0CF1) | 27889 ($6CF1) | 11505 ($2CF1)
2400 | 18030 ($466E) | 1646 ($066E) | 26222 ($666E) | 9838 ($266E)
4800 | 17197 ($432D) | 813 ($032D) | 25389 ($632D) | 9005 ($232D)
9600 | 16780 ($418C) | 396 ($018C) | 24972 ($618C) | 8588 ($218C)

If you're communicating with existing software or hardware, its speed(s) and mode(s) will determine your choice of baud rate and mode. In general, 7-bit/even-parity (7E) mode is used for text, and 8-bit/no-parity (8N) for byte-oriented data. Note: the most common mode is 8-bit/no-parity, even when the data transmitted is just text. Most devices that use a 7-bit data mode do so in order to take advantage of the parity feature. Parity can detect some communication errors, but to use it you lose one data bit. This means that incoming data bytes transferred in 7E (even-parity) mode can only represent values from 0 to 127, rather than the 0 to 255 of 8N (no-parity) mode.

Usually a device requires only one stop bit per byte. Occasionally, however, you may find a device that requires 2 or more stop bits. Since a stop bit is really just a delay between transmitted bytes (leaving the line in a resting state) the BASIC Stamp can receive transmissions with multiple stop bits per byte without any trouble. In fact, sometimes it is desirable to have multiple stop bits (see the "SERIN Troubleshooting" section, below, for more information).

The example below will receive a single byte through I/O pin 1 at 2400 baud, 8N1, inverted:

    SYMBOL  sData   = B0

    Main:
      SERIN 1, N2400, sData
      END

    sData   VAR     Byte

    Main:
      SERIN 1, 16780, [sData]                       ' baudmode set for BS2
      END

Here, SERIN will wait for and receive a single byte of data through pin 1 and store it in the variable sData. If the BASIC Stamp were connected to a PC running a terminal program (set to the same baud rate) and the user pressed the "A" key on the keyboard, after the SERIN command executed, the variable sData would contain 65, the ASCII code for the letter "A".

What would happen if, using the example above, the user pressed the "1" key? The result would be that sData would contain the value 49 (the ASCII code for the character "1"). This is a critical point to remember: every time you press a character on the keyboard, the computer receives the ASCII value of that character. It is up to the receiving side (in serial communication) to interpret the values as necessary. In this case, perhaps we actually wanted sData to end up with the value 1, rather than the ASCII code 49.

The SERIN command provides a formatter, called the decimal formatter, which will interpret this for us. Look at the following code:

    SYMBOL  sData   = B2

    Main:
      SERIN 1, N2400, #sData
      END

    sData   VAR     Byte

    Main:
      SERIN 1, 16780, [DEC sData]
      END

Notice the decimal formatter in the SERIN command. It is the "#" (for the BS1) or "DEC" (for the other BASIC Stamp models) that appears just to the left of the sData variable. This tells SERIN to convert incoming text representing decimal numbers into true-decimal form and store the result in sData. If the user running the terminal software pressed the "1", "2" and then "3" keys followed by a space or other non-numeric text, the value 123 will be stored in sData. Afterwards, the program can perform any numeric operation on the number just like with any other number. Without the decimal formatter, however, you would have been forced to receive each character ("1", "2" and "3") separately, and then would still have to do some manual conversion to arrive at the number 123 (one hundred twenty three) before you can do the desired calculations on it.

### Decimal Formatter Specifics

The decimal formatter is designed to seek out text that represents decimal numbers. The characters that represent decimal numbers are the characters "0" through "9". Once the SERIN command is asked to use the decimal formatter for a particular variable, it monitors the incoming serial data, looking for the first decimal character. Once it finds the first decimal character, it will continue looking for more (accumulating the entire multi-digit number) until is finds a non-decimal numeric character. Keep in mind that it will not finish until it finds at least one decimal character followed by at least one non-decimal character.

To further illustrate this, consider the following examples (assuming we're using the same code example as above):

1. Serial input: ABC
   Result: The BASIC Stamp halts at the SERIN command, continuously waiting for decimal text.
2. Serial input: 123 (with no characters following it)
   Result: The BASIC Stamp halts at the SERIN command. It recognizes the characters "1", "2" and "3" as the number one hundred twenty three, but since no characters follow the "3", it waits continuously, since there's no way to tell whether 123 is the entire number or not.
3. Serial input: 123 (followed by a space character)
   Result: Similar to example 2, above, except once the space character is received, the BASIC Stamp knows the entire number is 123, and stores this value in sData. The SERIN command then ends, allowing the next line of code, if any, to run.
4. Serial input: 123A
   Result: Same as example 3, above. The "A" character, just like the space character, is the first non-decimal text after the number 123, indicating to the BASIC Stamp that it has received the entire number.
5. Serial input: ABCD123EFGH
   Result: Similar to examples 3 and 4 above. The characters "ABCD" are ignored (since they're not decimal text), the characters "123" are evaluated to be the number 123 and the following character, "E", indicates to the BASIC Stamp that it has received the entire number.

Of course, as with all numbers in the BASIC Stamp, the final result is limited to 16 bits (up to the number 65535). If a number larger than this is received by the decimal formatter, the end result will look strange because the result rolled-over the maximum 16-bit value.

While BS1 is limited to the decimal formatter (#) shown above, the BS2, BS2e, BS2sx, BS2p, BS2pe, and BS2px have many more conversion formatters available for the SERIN command. If not using a BS1, see the "Additional Conversion Formatters" section below for more information.

The SERIN command can also be configured to wait for specified data before it retrieves any additional input. For example, suppose a device that is attached to the BASIC Stamp is known to send many different sequences of data, but the only data you desire happens to appear right after the unique characters, "XYZ". The BS1 has optional Qualifier arguments for this purpose. On the BS2, BS2e, BS2sx, BS2p, BS2pe, and BS2px a special formatter called WAIT can be used for this.

    SYMBOL  sData   = B2

    Main:
      SERIN 1, N2400, ("XYZ"), #sData
      END

    sData   VAR     Byte

    Main:
      SERIN 1, 16780, [WAIT("XYZ"), DEC sData]
      END

The above code waits for the characters "X", "Y" and "Z" to be received, in that order, and then it looks for a decimal number to follow. If the device in this example were to send the characters "XYZ100" followed by a carriage return or some other non-decimal numeric character, the sData variable would end up with the number 100 after the SERIN line finishes. If the device sent some data other than "XYZ" followed by a number, the BASIC Stamp would continue to wait at the SERIN command.

The BS1 will accept an unlimited number of Qualifiers. The BS2, BS2e, BS2sx, BS2p, BS2pe, and BS2px will only accept up to six bytes (characters) in the WAITformatter.

Keep in mind that when we type "XYZ" into the SERIN command, the BASIC Stamp actually uses the ASCII codes for each of those characters for its tasks. We could also have typed: 88, 89, 90 in place of "XYZ" and the code would run the same way since 88 is the ASCII code for the "X" character, 89 is the ASCII code for the "Y" character, and so on. Also note, serial communication with the BASIC Stamp is case sensitive. If the device mentioned above sent, "xYZ" or "xyZ", or some other combination of lower and upper-case characters, the BASIC Stamp would have ignored it because we told it to look for "XYZ" (all capital letters).

The BS1's SERIN command is limited to previously-mentioned features. If you are not using a BS1, please continue reading about the additional features below.

The decimal formatter is only one of a whole family of conversion formatters available with SERIN on the BS2, BS2e, BS2sx, BS2p, BS2pe, and BS2px. See the table below for a list of available conversion formatters. All of the conversion formatters work similar to the decimal formatter (as described in the "Decimal Formatter Specifics" section, above). The formatters receive bytes of data, waiting for the first byte that falls within the range of characters they accept (e.g., "0" or "1" for binary, "0" to "9" for decimal, "0" to "9" and "A" to "F" for hex, and "+" or "-" for signed variations of any type). Once they receive a numeric character, they keep accepting input until a non-numeric character arrives or (in the case of the fixed length formatters) the maximum specified number of digits arrives.

While very effective at filtering and converting input text, the formatters aren't completely foolproof. As mentioned before, many conversion formatters will keep accepting text until the first non-numeric text arrives, even if the resulting value exceeds the size of the variable. After SERIN, a byte variable will contain the lowest 8 bits of the value entered and a word would contain the lowest 16 bits. You can control this to some degree by using a formatter that specifies the number of digits, such as DEC2, which would accept values only in the range of 0 to 99.

### Conversion Formatter Table

Conversion Formatter | Type of Number | Numeric Characters Accepted | Notes
DEC{1..5} | Decimal, optionally limited to 1 - 5 digits | 0 through 9 | 1
SDEC{1..5} | Signed decimal, optionally limited to 1 - 5 digits | -, 0 through 9 | 1,2
HEX{1..4} | Hexadecimal, optionally limited to 1 - 4 digits | 0 through 9, A through F | 1,3
SHEX{1..4} | Signed hexadecimal, optionally limited to 1 - 4 digits | -, 0 through 9, A through F | 1,2,3
IHEX{1..4} | Indicated hexadecimal, optionally limited to 1 - 4 digits | $, 0 through 9, A through F | 1,3,4
ISHEX{1..4} | Signed, indicated hexadecimal, optionally limited to 1 - 4 digits | -, $, 0 through 9, A through F | 1,2,3,4
BIN{1..16} | Binary, optionally limited to1 - 16 digits | 0, 1 | 1
SBIN{1..16} | Signed binary, optionally limited to 1 - 16 digits | -, 0, 1 | 1,2
IBIN{1..16} | Indicated binary, optionally limited to 1 - 16 digits | %, 0, 1 | 1,4
ISBIN{1..16} | Signed, indicated binary, optionally limited to 1 - 16 digits | -, %, 0, 1 | 1,2,4
NUM | Generic numeric input; hex or binary number must be indicated | $, %, 0 through 9, A through F | 1,3,4
SNUM | Similar to NUM with value treated as signed with range -32768 to +32767 | -, $, %, 0 through 9, A through F | 1,2,3,4

1. All numeric conversions will continue to accept new data until receiving either the specified number of digits (ex: three digits for DEC3) or a non-numeric character.
2. To be recognized as part of a number, the minus sign (-) must immediately precede a numeric character. The minus sign character occurring in non-numeric text is ignored and any character (including a space) between a minus and a number causes the minus to be ignored.
3. The hexadecimal formatters are not case-sensitive; "a" through "f" means the same as "A" through "F".
4. Indicated hexadecimal and binary formatters ignore all characters, even valid numerics, until they receive the appropriate prefix ($ for hexadecimal, % for binary). The indicated formatters can differentiate between text and hexadecimal (ex: ABC would be interpreted by HEX as a number but IHEX would ignore it unless expressed as $ABC). Likewise, the binary version can distinguish the decimal number 10 from the binary number %10. A prefix occurring in non-numeric text is ignored, and any character (including a space) between a prefix and a number causes the prefix to be ignored. Indicated, signed formatters require that the minus sign come before the prefix, as in -$1B45.

### Special Formatter Tables

The BS2, BS2e, BS2sx, BS2p, BS2pe, and BS2px also have special formatters for handling a string of characters, a sequence of characters and undesirable characters. See the table below for a list of these special formatters.

Special Formatter | Action
STR ByteArray \L {\E} | Input a character string of length L into an array. If specified, an end character E causes the string input to end before reaching length L. Remaining bytes are filled with 0s (zeros).
WAIT (Value) | Wait for a sequence of bytes specified by value. Value can be numbers separated by commas or quoted text (ex: 65, 66, 67 or "ABC"). The WAIT formatter is limited to a maximum of six characters.
WAITSTR ByteArray {\L} | Wait for a sequence of bytes matching a string stored in an array variable, optionally limited to L characters. If the optional L argument is left off, the end of the array-string must be marked by a byte containing a zero (0).
SKIP Length | Ignore Length bytes of characters.

Special Formatter | Action
SPSTR L | Buffer length L bytes (up to 126) of serial characters to Scratchpad RAM, starting at location 0. Use GET to retrieve the characters.

The string formatter is useful for receiving a string of characters into a byte array variable. A string of characters is a set of characters that are arranged or accessed in a certain order. The characters "ABC" could be stored in a string with the "A" first, followed by the "B" and then followed by the "C." A byte array is a similar concept to a string; it contains data that is arranged in a certain order. Each of the elements in an array is the same size. The string "ABC" could be stored in a byte array containing three bytes (elements).

Here is an example that receives nine bytes through I/O pin 1 at 9600 bps, N81/inverted and stores them in a 10-byte array:

    serStr  VAR     Byte(10)                        ' Make a 10-byte array

    Main:
      serStr(9) = 0                                 ' Put 0 in last byte
      SERIN 1, 16468, [STR serStr\9]                ' Get 9-byte string
      DEBUG STR serString                           ' Display the string
      END

If the serial input were "hello*" DEBUG would display "hello" since it collects bytes up to (but not including) the end character. It fills the unused bytes up to the specified length with 0s. DEBUG's normal STR formatter understands a 0 to mean end-of-string. However, if you use DEBUG's fixed-length string modifier, STR ByteArray\L, you will inadvertently clear the DEBUG screen. The fixed-length specification forces DEBUG to read and process the 0s at the end of the string, and 0 is equivalent to DEBUG's CLS (clear-screen) instruction! Be alert for the consequences of mixing fixed- and variable-length string operations.

As shown before, SERIN can compare incoming data with a predefined sequence of bytes using the WAIT formatter. The simplest form waits for a sequence of up to six bytes specified as part of the InputData list, like so:

      SERIN 1, 16468, [WAIT ("SESAME")]             ' Wait for word SESAME
      DEBUG "Password accepted"

SERIN will wait for that word, and the program will not continue until it is received. Since WAIT is looking for an exact match for a sequence of bytes, it is case-sensitive-"sesame" or "SESAmE" or any other variation from "SESAME" would be ignored.

SERIN can also wait for a sequence that matches a string stored in an array variable with the WAITSTR formatter. In the example below, we'll capture a string with STR then have WAITSTR look for an exact match:

    serStr  VAR     Byte(10)                        ' Make a 10-byte array

    Main:
      serString(9) = 0                              ' Put 0 in last byte
      SERIN 1, 16468, [STR serStr\9\"!"]            ' Input password string
      DEBUG "Waiting for: ", STR serString, CR
      SERIN 1, 16468, [WAITSTR  serStr]             ' Wait for the password
      DEBUG "Password accepted!", CR
      END

You can also use WAITSTR with fixed-length strings as in the following example:

    serStr  VAR     Byte(4)                         ' Make a 4-byte array

    Main:
      DEBUG "Enter a 4-character password", CR
      SERIN 1, 16468, [STR serStr\4]                ' Get the string
      DEBUG "Waiting for: ", STR serStr\4, CR
      SERIN 1, 16468, [WAITSTR serStr\4]            ' Wait for a match
      DEBUG "Password accepted!", CR
      END

SERIN's InputData can be structured as a sophisticated list of actions to perform on the incoming data. This allows you to process incoming data in powerful ways. For example, suppose you have a serial stream that contains "pos: xxxx yyyy" (where xxxx and yyyy are 4-digit numbers) and you want to capture just the decimal y value. The following code would do the trick:

    yCoord  VAR     Word                            ' y coordinate

    Main:
      SERIN 1, 16468, [WAIT ("pos: "), SKIP 4, DEC yCoord]
      DEBUG ? yCoord
      END

The items of the InputData list work together to locate the label "pos: ", skip over the four-byte x data, then convert and capture the decimal y data. This sequence assumes that the x data is always four digits long; if its length varies, the following code would be more appropriate:

    yCoord  VAR     Word

    Main:
      SERIN 1, 16468, [WAIT ("pos: "), DEC yCoord, DEC yCoord]
      DEBUG ? yOffset
      END

The unwanted x data is stored in yCoord then replaced by the desired y data. This is a sneaky way to filter out a number of any size without using an extra variable. With a little creativity, you can combine the InputData modifiers to filter and extract almost any data.

Parity is a simple error-checking feature. When a serial sender is set for even parity (the mode the BASIC Stamp modules support) it counts the number of 1s in an outgoing byte and uses the parity bit to make that number even. For instance, if it is sending the 7-bit value: %0011010, it sets the parity bit to 1 in order to make an even number of 1s (four).

The receiver also counts the data bits to calculate what the parity bit should be. If it matches the parity bit received, the serial receiver assumes that the data was received correctly. Of course, this is not necessarily true, since two incorrectly received bits could make parity seem correct when the data was wrong, or the parity bit itself could be bad when the rest of the data was okay.

Many systems that work exclusively with text use (or can be set for) 7-bit/even-parity mode. The tables above show appropriate BaudMode settings for different BASIC Stamp models. For example, with the BS2, to receive one data byte through pin 1 at 9600 baud, 7E, inverted:

    sData   VAR     Byte

    Main:
      SERIN 1, 24660, [sData]
      END

That instruction will work, but it doesn't tell the BS2 what to do in the event of a parity error. Here's an improved version that uses the optional Plabelargument:

    sData   VAR     Byte

    Main:
      SERIN 1, 24660, Bad_Data, [sData]
      DEBUG ? sData
      STOP

    Bad_Data:
      DEBUG  "Parity error"
      STOP

If the parity matches, the program continues at the DEBUG instruction after SERIN. If the parity doesn't match, the program goes to the label Bad_Data. Note that a parity error takes precedence over other InputData specifications (as soon as an error is detected, SERIN aborts and goes to the Plabel routine).

In all the examples above, the only way to end the SERIN instruction (other than RESET or power-off) is to give SERIN the serial data it wants. If no serial data arrives, the program is stuck. However, you can tell the BASIC Stamp to abort SERIN if it doesn't receive data within a specified number of milliseconds. For instance, to receive a decimal number through pin 1 at 9600 baud, 8N, inverted and abort SERIN after two seconds (2000 milliseconds) of inactivity on the serial input.

    result  VAR     Byte

    Main:
      SERIN 1, 16468, 2000, No_Data, [DEC result]
      DEBUG CLS, ? result
      STOP

    No_Data:
      DEBUG CLS, "Timed out"
      STOP

If no data arrives within two seconds, the program aborts SERIN and continues at the label No_Data. Note that on multi-byte input, the timeout timer is reset after the receipt of any valid data byte; with long timeout values this factor could have an adverse affect on program operation if data packets are transmitted with gaps between individual data bytes. Finally, be cautious when using very short timeout values. Without external flow control, very short timeout values may cause the program to branch to the Tlabel address unnecessarily.

Here's a very important concept: this timeout feature is not picky about the kind of data SERIN receives; if any serial data is received, it prevents the timeout. In the example above, SERIN wants a decimal number. But even if SERIN received letters "ABCD..." at intervals of less than two seconds, it would never abort.

You can combine parity and serial timeout. Here is an example for the BS2 designed to receive a decimal number through pin 1 at 2400 baud, 7E, inverted with a 10-second timeout:

    result  VAR     Byte

    Again:
      SERIN 1, 24660, Bad_Data, 10000, No_Data, [DEC result]
      DEBUG CLS, ? result
      GOTO Again

    No_Data:
      DEBUG CLS, "Timed out"
      GOTO Again

    Bad_Data:
      DEBUG CLS, "Parity error"
      GOTO Again

When you design an application that requires serial communication between BASIC Stamp modules, you have to work within these limitations:

- When the BASIC Stamp is sending or receiving data, it can't execute other instructions.
- When the BASIC Stamp is executing other instructions, it can't send or receive data. The BASIC Stamp does not have a serial buffer as there is in PCs. At most serial rates, the BASIC Stamp cannot receive data via SERIN, process it, and execute another SERIN in time to catch the next chunk of data, unless there are significant pauses between data transmissions.

These limitations can sometimes be addressed by using flow control; the Fpin option for SERIN and SEROUT (at baud rates of up to the limitation shown above). Through Fpin, SERIN can tell a BASIC Stamp sender when it is ready to receive data. (For that matter, Fpin flow control follows the rules of other serial handshaking schemes, but most computers other than the BASIC Stamp cannot start and stop serial transmission on a byte-by-byte basis. That's why this discussion is limited to communication between BASIC Stamp modules).

Here's an example using flow control on the BS2 (data through I/O pin 1, flow control through I/O pin 0, 9600 baud, N8, non-inverted):

    sData   VAR     Byte

    Main:
      SERIN 1\0, 84, [sData]
      STOP

When SERIN executes, I/O pin 1 (Rpin) is made an input in preparation for incoming data, and I/O pin 0 (FPin) is made output low, to signal "go" to the sender. After SERIN finishes receiving, I/O pin 0 goes high to tell the sender to stop. If an inverted BaudMode had been specified, the FPin's responses would have been reversed. Here's the relationship of serial polarity to FPin states.

| Ready to Receive ("Go") | Not Ready to Receive ("Stop")
Inverted | Fpin is High (1) | Fpin is Low (0)
Non-Inverted | Fpin is Low (0) | Fpin is High (1)

See the example program for a flow control example using two BS2s. In the demo program example, without flow control, the sender would transmit the whole word "HELLO!" in about 1.5 ms. The receiver would catch the first byte at most; by the time it got back from the first 1-second PAUSE, the rest of the data would be long gone. With flow control, communication is flawless since the sender waits for the receiver to catch up.

In the figure below, I/O pin 0, FPin, is pulled to ground through a 10 kΩ resistor. This is to ensure that the sender sees a stop signal (0 for inverted communications) when the receiver is being programmed.

###
SERIN Troubleshooting

Serial communication, because of its complexity, can be very difficult to work with at times. Please follow these guidelines when developing a project using the SERIN and SEROUT commands:

1. Always build your project in steps.
   1. Start with small, manageable pieces of code, that deals with serial communication) and test them, one at a time.
   2. Add more and more small pieces, testing them each time, as you go.
   3. Never write a large portion of code that works with serial communication without testing its smallest workable pieces first.
2. Pay attention to timing.
   1. Be very careful to calculate and overestimate the amount of time operations should take within the BASIC Stamp. Misunderstanding the timing constraints is the source of most problems with code that communicate serially.
   2. If the serial communication in your project is bidirectional, the above statement is even more critical.
3. Pay attention to wiring.
   1. Take extra time to study and verify serial communication wiring diagrams. A mistake in wiring can cause strange problems in communication, or no communication at all. Make sure to connect the ground pins (Vss) between the devices that are communicating serially.
4. Verify port setting on the PC and in the SERIN/SEROUT commands.
   1. Unmatched settings on the sender and receiver side will cause garbled data transfers or no data transfers. If the data you receive is unreadable, it is most likely a baud rate setting error.
5. If receiving data from another device that is not a BASIC Stamp, try to use baud rates of 4800 and below.
   1. Because of additional overhead in the BASIC Stamp, and the fact that the BASIC Stamp has no hardware receive buffer for serial communication, received data may sometimes be missed or garbled. If this occurs, try lowering the baud rate (if possible), adding extra stop bits, and not using formatters in the SERIN command. Using simple variables (not arrays) and no formatters will increase the chance that the BASIC Stamp can receive the data properly.
6. Be sure to study the effects of SERIN formatters
   1. Because of additional overhead in the BASIC Stamp, and the fact that the BASIC Stamp has no hardware receive buffer for serial communication, received data may sometimes be missed or garbled. If this occurs, try lowering the baud rate (if possible), adding extra stop bits, and not using formatters in the SERIN command. Using simple variables (not arrays) and no formatters will increase the chance that the BASIC Stamp can receive the data properly.
7. When using a BS2-family module, you can simplify Baudmode parameter selection by using conditional compilation. The example below can be included in the standard programming template and will handle most serial IO requirements. Remember that defining constants does not affect compiled program space, and yet does make program debugging easier.

    ' {$PBASIC 2.5}

    #SELECT $STAMP
      #CASE BS2, BS2E, BS2PE
        T1200       CON     813
        T2400       CON     396
        T4800       CON     188
        T9600       CON     84
        T19K2       CON     32
        T38K4       CON     6
      #CASE BS2SX, BS2P
        T1200       CON     2063
        T2400       CON     1021
        T4800       CON     500
        T9600       CON     240
        T19K2       CON     110
        T38K4       CON     45
      #CASE BS2PX
        T1200       CON     3313
        T2400       CON     1646
        T4800       CON     813
        T9600       CON     396
        T19K2       CON     188
        T38K4       CON     84
    #ENDSELECT

    SevenBit        CON     $2000
    Inverted        CON     $4000
    Open            CON     $8000

    Baud            CON     T9600 + Inverted        ' match DEBUG

Go to Welcome page

BASIC Stamp Help Version 2.5.4

Copyright © Parallax Inc.

8/8/2012