SoftwareSerial Library

While Listing 10-2 could work fine with the RFID reader connected to the RX pin, or pin 0 on the Arduino board, it would be a pain to have to disconnect the reader each time we want to upload a new sketch. Or we might have a second serial device that we need to talk to in addition to the RFID reader. In order to have more serial ports than what our hardware comes with, we can use a library that will create a software serial port for us that act almost like the hardware version. To create software-based serial ports, we need to use the SoftwareSerial library, an all-new library as of Arduino version 1.0, based on the previous library formally known as NewSoftSerial, written by Mikal Hart. This new library replaces the old library of the same name and brings with it many improvements and a couple of trade-offs. At the time of this writing, the best place to find out more about the SoftwareSerial library is at the NewSoftSerial web page at http://arduiniana.org/libraries/newsoftserial.

The SoftwareSerial library will allow us to emulate the serial RX and TX pins of a serial port on any of the available I/O pins on the Arduino Uno board. (This library may only work on certain pins on other versions of the Arduino hardware.) While this “virtual” serial port lacks the buffer memory like the native hardware serial (so it cannot receive data in the background), it does share most of the same functions that the Serial library contains, with similar syntax and functionality. The newest version of this library is interrupt driven, which means that it will conflict with hardware interrupts like we used in Chapter 7, as well as the newest Servo library, which is also interrupt driven. If we absolutely must use interrupts in our code, we would either need to use a different or older version of either the SoftwareSerial or Servo libraries. Finally, SoftwareSerial also slows things down a bit, so we should avoid excessively slow data rates and generally stick with hardware serial–unless we absolutely need the extra serial port.

So, let's look at a few of the functions that make our project code work. If we don't discuss most of the functions that we used, that's because they work identically to those same functions in the Serial library.

SoftwareSerial()

To create a new instance of this library we need to use the SoftwareSerial() function to give it a name and specify the RX and TX pin numbers. The syntax follows:

SoftwareSerial name(rxPin, txPin)

The first thing we need to set is the name for our instance. We could use mySerial, softSerial, or anything else we want that's not already taken, including George, but it's probably a good idea to give it a name that relates to the device connected to the serial port and to avoid any confusion should we want to use the hardware Serial functions as well. In our example we used the following statement:

SoftwareSerial rfid(2,3);

Here, we are calling our software serial port rfid to remind us which device that we're talking to. While it is possible to have multiple instances of the SoftwareSerial library, we can only read from or send to one at a time. The timing of these operations could get tricky as we get more devices going at the same time. For example, if we were sending data through a wireless adapter on one serial port, we might miss an incoming tag that needed to be read from the RFID serial port.

The final two parameters that we specified in our example as 2 and 3 are the pin numbers that we will use as receive, RX, and transmit, TX, pins. These can be any of the I/O pins on the Arduino Uno, so long as they are not in use by anything else.

begin()

The begin() function is identical in form to the same function found in the Serial library. Give the function an instance name, in our example rfid, and specify a data rate in bits per second and all should be fine. Although because we are using software on an already burdened microcontroller to emulate what is often done with dedicated hardware, things don't always go according to plan. Data rates of 300 bps or 1200 bps are nearly unusable and you might be pushing your luck with 57,600 bps and over. Just keep in mind that when specifying data rates for software serial ports, if unusual behavior crops up, this data rate may be suspect.

flush()

While the flush() function is the same for the Serial library, we didn't talk about it before because we didn't have a good reason for it. The syntax is another simple one, as follows:

name.flush()

Where name is the name of your serial instance and beyond that there are no parameters and nothing is returned. This function's sole purpose in life is to clear the serial buffer of any waiting data or in the case of SoftwareSerial, to clear any forthcoming data on the serial line. We used this function in our most recent sketch so that we didn't need to worry about the last three characters that the RFID reader sends down the line, whether we want it to or not. We have to do something to either read this data and put it somewhere or simply get rid of it because our code is executed so quickly that these remaining bytes will be taken for tag information and consequently confuse things. Since we know there are 12 bytes that we are interested in and our communications are reasonably accurate, this gives us a way to just get rid of the extra data.

strncmp()

Our last function to talk about here is not actually a function of the Serial libraries, but is rather a part of the standard C library on which Arduino is built. The function strncmp() is used to compare two text strings and is an example of string manipulation. We use this function in our example code to compare the text strings from two different tags to see if they match—kind of like a lock and key. While the Arduino has a String class available with much more advanced capabilities, this function works well enough for our purposes. It has the following syntax:

strncmp(string1, string2, numberOfCharacters)

This function will compare string1 to string2 up to the maximum number of characters specified. If the two strings are identical, this function will return the value 0. Take the following hypothetical example:

if (strncmp("goodnight", "room", 4) == 0) Serial.print("goodnight moon");

In this example, the strncmp() function would compare the string "goodnight" to the string "moon" up to a maximum four characters. If these two strings were the same, then the expression would evaluate as true and the following call to Serial.print would be executed. Each of these strings needs to be specified as either the string itself or a pointer to the string. In our example code, it is as follows:

if (strncmp(tag01, tagString, 12) == 0) return " Tag 1";

Here we are using the names of the arrays tag01[] and tagString[] as pointers to the first byte in the array and are then comparing the full 12 digits of each array. If these arrays match, then we can perform an action such as printing the tag's name or some other activity. If they do not match, we can continue to compare the tag that we just read with other known tags to see if there is a match.

While not generally discussed through the official Arduino channels, string manipulation and other functions of the standard C library can be quite useful in the right circumstances. There are many more string functions as well that can be found in a good book on C programming or with a little digging in the great interweb.

From here though, we are going to look at a little different kind of serial communication called I2C that is designed to talk with other kinds of hardware. While many different devices exist, we will start with an easy-to-use, real-time clock module that keeps an accurate time and date with a battery backup for standby operation. With the right commands, it will fairly accurately tell us “when” we are.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.23.101.60