Tutorial.SoftwareSerial History

Show minor edits - Show changes to markup

February 26, 2007, at 05:40 PM by David A. Mellis -
Added lines 3-4:

Note: If you just want to use a software serial interface, see the SoftwareSerial library included with Arduino 0007 and later. Read on if you'd like to know how that library works.

September 05, 2006, at 07:55 PM by Heather Dewey-Hagborg -
Changed lines 214-216 from:

}@]

to:

}@]

code and tutorial by Heather Dewey-Hagborg

August 29, 2006, at 07:46 PM by Heather Dewey-Hagborg -
Changed lines 53-54 from:
to:
Changed lines 57-58 from:
to:
August 29, 2006, at 07:34 PM by Heather Dewey-Hagborg -
Changed lines 11-12 from:

Returns a byte long integer value

to:

Returns a byte long integer value from the software serial connection

August 29, 2006, at 07:25 PM by Heather Dewey-Hagborg -
Changed line 10 from:

SWread();

to:

SWread();

Changed line 20 from:

SWprint();

to:

SWprint();

August 29, 2006, at 07:19 PM by Heather Dewey-Hagborg -
Added lines 10-13:

SWread();

Returns a byte long integer value

Example:

Changed lines 15-16 from:

SWread();

to:

byte RXval; RXval = SWread();

Changed lines 18-19 from:

Returns a byte long integer value

to:

SWprint();

Sends a byte long integer value out the software serial connection

Added line 24:
Changed lines 26-27 from:

byte RXval; RXval = SWread();

to:

byte TXval = 'h'; byte TXval2 = 126; SWprint(TXval); SWprint(TXval2);

Added line 32:

Definitions Needed:

Changed lines 34-37 from:

SWprint();

to:
  1. define bit9600Delay 84
  2. define halfBit9600Delay 42
  3. define bit4800Delay 188
  4. define halfBit4800Delay 94
Deleted lines 38-55:

Sends a byte long integer value out the software serial connection

Example:

byte TXval = 'h';
byte TXval2 = 126;
SWprint(TXval);
SWprint(TXval2);

Definitions Needed:

#define bit9600Delay 84  
#define halfBit9600Delay 42
#define bit4800Delay 188 
#define halfBit4800Delay 94

August 29, 2006, at 07:18 PM by Heather Dewey-Hagborg -
Added line 10:

[@

Added line 12:

@]

Added line 16:

[@

Changed lines 19-21 from:
to:

@]

[@

Added line 23:

@]

Added lines 27-28:

[@

Changed lines 33-34 from:
to:

@]

Changed line 36 from:
to:

[@

Changed line 41 from:
to:

@]

August 29, 2006, at 07:15 PM by Heather Dewey-Hagborg -
Changed lines 5-6 from:

other serial devices. Using software serial allows you to create a serial connection on any of the digital i/o pins on the Arduino. This should be used when multiple serial connections are necessary. If only one serial connection is necessary the hardware serial port should be used. This is a general purpose software tutorial, NOT a specific device tutorial. A tutorial on communicating with a computer is here. Device specific tutorials are on the Tutorial Page. For a good explanation of serial communication see Wikipedia.

to:

other serial devices. Using software serial allows you to create a serial connection on any of the digital i/o pins on the Arduino. This should be used when multiple serial connections are necessary. If only one serial connection is necessary the hardware serial port should be used. This is a general purpose software tutorial, NOT a specific device tutorial. A tutorial on communicating with a computer is here. Device specific tutorials are on the Tutorial Page. For a good explanation of serial communication see Wikipedia. The software serial connection can run at 4800 baud or 9600 baud reliably.

Functions Available:

SWread(); Returns a byte long integer value

Example: byte RXval; RXval = SWread();

SWprint(); Sends a byte long integer value out the software serial connection

Example: byte TXval = 'h'; byte TXval2 = 126; SWprint(TXval); SWprint(TXval2);

Definitions Needed:

  1. define bit9600Delay 84
  2. define halfBit9600Delay 42
  3. define bit4800Delay 188
  4. define halfBit4800Delay 94

These definitions set the delays necessary for 9600 baud and 4800 baud software serial operation.

August 23, 2006, at 09:09 PM by Heather Dewey-Hagborg -
Changed line 113 from:

//Created July 2006

to:

//Created August 15 2006

August 23, 2006, at 09:08 PM by Heather Dewey-Hagborg -
Added lines 113-116:

//Created July 2006 //Heather Dewey-Hagborg //http://www.arduino.cc

August 16, 2006, at 03:16 AM by Tom Igoe -
Changed lines 38-39 from:

First we include the file ctype.h in our application. This gives us access to the toupper() function from the Character Operations C library which we will use later in our main loop. Next we establish our baudrate delay definitions. These are pre-processor directives that define the delays for different baudrates. The #define bit9600Delay 84 line causes the compiler to substitute the number 84 where ever it encounters the label "bit9600Delay". Pre-processor definitions are often used for constants because they don't take up any program memory space on the chip.

to:

First we include the file ctype.h in our application. This gives us access to the toupper() function from the Character Operations C library which we will use later in our main loop. This library is part of the Arduino install, so you don't need to do anything other than type the #include line in order to use it. Next we establish our baudrate delay definitions. These are pre-processor directives that define the delays for different baudrates. The #define bit9600Delay 84 line causes the compiler to substitute the number 84 where ever it encounters the label "bit9600Delay". Pre-processor definitions are often used for constants because they don't take up any program memory space on the chip.

Changed line 86 from:
    delayMicroseconds(halfbit9600Delay);
to:
    delayMicroseconds(halfBit9600Delay);
Changed line 160 from:
    delayMicroseconds(halfbit9600Delay);
to:
    delayMicroseconds(halfBit9600Delay);
August 15, 2006, at 09:32 PM by Heather Dewey-Hagborg -
Changed lines 19-20 from:

Attach: pwr_wires_web.jpg

to:
Changed lines 23-24 from:

Attach: ser_wires_web.jpg

to:
August 15, 2006, at 09:30 PM by Heather Dewey-Hagborg -
Changed lines 19-20 from:

picture of device with connections

to:

Attach: pwr_wires_web.jpg

Changed lines 23-24 from:

picture of device with serial connections

to:

Attach: ser_wires_web.jpg

August 15, 2006, at 06:44 PM by Heather Dewey-Hagborg -
August 15, 2006, at 06:42 PM by Heather Dewey-Hagborg -
Changed lines 78-79 from:

This is the SWprint function. First the transmit line is pulled low to signal a start bit. Then we itterate through a bit mask and flip the output pin high or low 8 times for the 8 bits in the value to be transmitted. Finally we pull the line high again to signal a stop bit. For each bit we transmit we hold the line high or low for the specified delay. In this example we are using a 9600 baudrate. To use 4800 simply replace the variable bit9600Delay with bit4800Delay.

to:

This is the SWprint function. First the transmit line is pulled low to signal a start bit. Then we itterate through a bit mask and flip the output pin high or low 8 times for the 8 bits in the value to be transmitted. Finally we pull the line high again to signal a stop bit. For each bit we transmit we hold the line high or low for the specified delay. In this example we are using a 9600 baudrate. To use 4800 simply replace the variable bit9600Delay with bit4800Delay.

August 15, 2006, at 06:40 PM by Heather Dewey-Hagborg -
August 15, 2006, at 06:37 PM by Heather Dewey-Hagborg -
Changed line 3 from:

In this tutorial you will learn how to implement serial

to:

In this tutorial you will learn how to implement Asynchronous serial

Changed lines 5-6 from:

other serial devices. Using software serial allows you to create a serial connection on any of the digital i/o pins on the Arduino. This should be used when multiple serial connections are necessary. If only one serial connection is necessary the hardware serial port should be used. This is a general purpose software tutorial, NOT a specific device tutorial. A tutorial on communicating with a computer is here. Device specific tutorials are on the Tutorial Page.

to:

other serial devices. Using software serial allows you to create a serial connection on any of the digital i/o pins on the Arduino. This should be used when multiple serial connections are necessary. If only one serial connection is necessary the hardware serial port should be used. This is a general purpose software tutorial, NOT a specific device tutorial. A tutorial on communicating with a computer is here. Device specific tutorials are on the Tutorial Page. For a good explanation of serial communication see Wikipedia.

Changed lines 27-28 from:

Now we will write the code to enable serial data transmission. This program will simply wait for a character to arrive in the serial recieving port and then spit it back out in uppercase out the transmit port. This is a good general purpose serial debugging program and you should be able to extrapolate from this example to cover all your basic serial needs. We will walk through the code in small sections.

to:

Now we will write the code to enable serial data communication. This program will simply wait for a character to arrive in the serial recieving port and then spit it back out in uppercase out the transmit port. This is a good general purpose serial debugging program and you should be able to extrapolate from this example to cover all your basic serial needs. We will walk through the code in small sections.

August 15, 2006, at 06:22 PM by Heather Dewey-Hagborg -
Changed lines 36-37 from:

Here we set up our pre-processor directives. Pre-processor directives are processed before the actual compilation begins. They start with a "#" and do not end with semi-colons. First we include the file ctype.h in our application. This gives us access to the toupper() function from the Character Operations C library which we will use later in our main loop. Next we establish our baudrate delay definitions. These are pre-processor directives that define the delays for different baudrates. The #define bit9600Delay 84 line causes the compiler to substitute the number 84 where ever it encounters the label "bit9600Delay". Pre-processor definitions are often used for constants because they don't take up any program memory space on the chip.

to:

Here we set up our pre-processor directives. Pre-processor directives are processed before the actual compilation begins. They start with a "#" and do not end with semi-colons.

First we include the file ctype.h in our application. This gives us access to the toupper() function from the Character Operations C library which we will use later in our main loop. Next we establish our baudrate delay definitions. These are pre-processor directives that define the delays for different baudrates. The #define bit9600Delay 84 line causes the compiler to substitute the number 84 where ever it encounters the label "bit9600Delay". Pre-processor definitions are often used for constants because they don't take up any program memory space on the chip.

August 15, 2006, at 06:21 PM by Heather Dewey-Hagborg -
Changed lines 36-37 from:

Here we import the file ctype.h to our application. This gives us access to the toupper() function from the Character Operations C library. Next we establish our baudrate delay definitions. These are pre-processor directives that define the delays for different baudrates.

to:

Here we set up our pre-processor directives. Pre-processor directives are processed before the actual compilation begins. They start with a "#" and do not end with semi-colons. First we include the file ctype.h in our application. This gives us access to the toupper() function from the Character Operations C library which we will use later in our main loop. Next we establish our baudrate delay definitions. These are pre-processor directives that define the delays for different baudrates. The #define bit9600Delay 84 line causes the compiler to substitute the number 84 where ever it encounters the label "bit9600Delay". Pre-processor definitions are often used for constants because they don't take up any program memory space on the chip.

August 15, 2006, at 05:57 PM by Heather Dewey-Hagborg -
Changed lines 104-105 from:

Finally we implement our main program loop. In this program we simply wait for characters to arrive, chnge them to uppercase and send them back. This is always a good program to run when you want to make sure a serial connection is working properly.

to:

Finally we implement our main program loop. In this program we simply wait for characters to arrive, change them to uppercase and send them back. This is always a good program to run when you want to make sure a serial connection is working properly.

August 13, 2006, at 06:19 PM by Heather Dewey-Hagborg -
Changed line 101 from:
    SWprint(to_upper(SWval));
to:
    SWprint(toupper(SWval));
Changed line 173 from:
    SWprint(to_upper(SWval));
to:
    SWprint(toupper(SWval));
August 13, 2006, at 06:12 PM by Heather Dewey-Hagborg -
Changed lines 36-37 from:

Here we import the file ctype.h to our application. This gives us access to the toupper() function from the standard C library. Next we establish our baudrate delay definitions. These are pre-processor directives that define the delays for different baudrates.

to:

Here we import the file ctype.h to our application. This gives us access to the toupper() function from the Character Operations C library. Next we establish our baudrate delay definitions. These are pre-processor directives that define the delays for different baudrates.

August 13, 2006, at 06:03 PM by Heather Dewey-Hagborg -
Changed lines 5-6 from:

other serial devices. Using software serial allows you to create a serial connection on any of the digital i/o pins on the Arduino. This should be used when multiple serial connections are necessary. If only one serial connection is necessary the hardware serial port should be used. This is a general purpose software tutorial, NOT a specific device tutorial. A tutorial on communicating with a computer is here. Device specific tutorials are on the Tutorial Page.

to:

other serial devices. Using software serial allows you to create a serial connection on any of the digital i/o pins on the Arduino. This should be used when multiple serial connections are necessary. If only one serial connection is necessary the hardware serial port should be used. This is a general purpose software tutorial, NOT a specific device tutorial. A tutorial on communicating with a computer is here. Device specific tutorials are on the Tutorial Page.

Added line 48:
  digitalWrite(13,HIGH); //turn on debugging LED
Changed lines 54-55 from:

Here we initialize the lines and print a debugging message to confirm all is working as planned. We can pass inidvidual characters or numbers to the SWprint function.

to:

Here we initialize the lines, turn on our debugging LED and print a debugging message to confirm all is working as planned. We can pass inidvidual characters or numbers to the SWprint function.

Added line 126:
  digitalWrite(13,HIGH); //turn on debugging LED
August 13, 2006, at 06:00 PM by Heather Dewey-Hagborg -
Changed lines 39-41 from:

byte tx = 7;@] byte SWval;

to:

byte tx = 7; byte SWval;@]

Added lines 102-172:

Finally we implement our main program loop. In this program we simply wait for characters to arrive, chnge them to uppercase and send them back. This is always a good program to run when you want to make sure a serial connection is working properly.

For lots of fun serial devices check out the Sparkfun online catalog. They have lots of easy to use serial modules for GPS, bluetooth, wi-fi, LCDs, etc.

For easy copy and pasting the full program text of this tutorial is below:

#include <ctype.h>

#define bit9600Delay 84  
#define halfBit9600Delay 42
#define bit4800Delay 188 
#define halfBit4800Delay 94 

byte rx = 6;
byte tx = 7;
byte SWval;

void setup() {
  pinMode(rx,INPUT);
  pinMode(tx,OUTPUT);
  digitalWrite(tx,HIGH);
  SWprint('h');  //debugging hello
  SWprint('i');
  SWprint(10); //carriage return
}

void SWprint(int data)
{
  byte mask;
  //startbit
  digitalWrite(tx,LOW);
  delayMicroseconds(bit9600Delay);
  for (mask = 0x01; mask>0; mask <<= 1) {
    if (data & mask){ // choose bit
     digitalWrite(tx,HIGH); // send 1
    }
    else{
     digitalWrite(tx,LOW); // send 0
    }
    delayMicroseconds(bit9600Delay);
  }
  //stop bit
  digitalWrite(tx, HIGH);
  delayMicroseconds(bit9600Delay);
}

int SWread()
{
  byte val = 0;
  while (digitalRead(rx));
  //wait for start bit
  if (digitalRead(rx) == LOW) {
    delayMicroseconds(halfbit9600Delay);
    for (int offset = 0; offset < 8; offset++) {
     delayMicroseconds(bit9600Delay);
     val |= digitalRead(rx) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit9600Delay); 
    delayMicroseconds(bit9600Delay);
    return val;
  }
}

void loop()
{
    SWval = SWread(); 
    SWprint(to_upper(SWval));
}
August 13, 2006, at 05:55 PM by Heather Dewey-Hagborg -
Changed lines 29-31 from:

[@#define bit9600Delay 84

to:

[@#include <ctype.h>

  1. define bit9600Delay 84
Changed lines 36-37 from:

Here we establish our baudrate delay definitions. These are pre-processor directives that define the delays for different baudrates.

to:

Here we import the file ctype.h to our application. This gives us access to the toupper() function from the standard C library. Next we establish our baudrate delay definitions. These are pre-processor directives that define the delays for different baudrates.

Changed lines 40-42 from:

Here we set our transmit (tx) and recieve (rx) pins. Change the pin numbers to suit your application.

to:

byte SWval;

Here we set our transmit (tx) and recieve (rx) pins. Change the pin numbers to suit your application. We also allocate a variable to store our recieved data in, SWval.

Added lines 96-101:
void loop()
{
    SWval = SWread(); 
    SWprint(to_upper(SWval));
}
August 13, 2006, at 05:48 PM by Heather Dewey-Hagborg -
Changed lines 78-79 from:
  // confirm that this is a real start bit, not line noise
to:
  //wait for start bit
Deleted lines 79-80:
    // frame start indicated by a falling edge and low start bit
    // jump to the middle of the low start bit
Deleted lines 80-81:
    // offset of the bit in the byte: from 0 (LSB) to 7 (MSB)
Deleted line 81:
     // jump to middle of next bit
Deleted lines 82-83:
     // read bit
Changed line 85 from:
    //pause for stop bit
to:
    //wait for stop bit + extra
Added line 93:
August 13, 2006, at 05:47 PM by Heather Dewey-Hagborg -
Changed lines 5-6 from:

other serial devices. Using software serial allows you to create a serial connection on any of the digital i/o pins on the Arduino. This should be used when multiple serial connections are necessary. If only one serial connection is necessary the hardware serial port should be used. This is a general purpose software tutorial, NOT a specific device tutorial. A tutorial on communicating with a computer is here. And device specific tutorials are on the Tutorial Page.

to:

other serial devices. Using software serial allows you to create a serial connection on any of the digital i/o pins on the Arduino. This should be used when multiple serial connections are necessary. If only one serial connection is necessary the hardware serial port should be used. This is a general purpose software tutorial, NOT a specific device tutorial. A tutorial on communicating with a computer is here. Device specific tutorials are on the Tutorial Page.

Added lines 73-101:
int SWread()
{
  byte val = 0;
  while (digitalRead(rx));

  // confirm that this is a real start bit, not line noise
  if (digitalRead(rx) == LOW) {
    // frame start indicated by a falling edge and low start bit
    // jump to the middle of the low start bit
    delayMicroseconds(halfbit9600Delay);

    // offset of the bit in the byte: from 0 (LSB) to 7 (MSB)
    for (int offset = 0; offset < 8; offset++) {
     // jump to middle of next bit
     delayMicroseconds(bit9600Delay);

     // read bit
     val |= digitalRead(rx) << offset;
    }
    //pause for stop bit
    delayMicroseconds(bit9600Delay); 
    delayMicroseconds(bit9600Delay);
    return val;
  }
}

This is the SWread function. This will wait for a byte to arrive on the recieve pin and then return it to the allocated variable. First we wait for the recieve line to be pulled low. We check after a half bit delay to make sure the line is still low and we didn't just recieve line noise. Then we iterate through a bit mask and shift 1s or 0s into our output byte based on what we recieve. Finally we allow a pause for the stop bit and then return the value.

August 13, 2006, at 05:38 PM by Heather Dewey-Hagborg -
Changed lines 72-73 from:

This is the SWprint function. First the transmit line is pulled low to signal a start bit. Then we itterate through a bit mask and flip the output pin high or low 8 times for the 8 bits in the value to be transmitted. Finally we pull the line high again to signal a stop bit. For each bit we transmit we hold the line high or low for the specified delay. In this example we are using a 9600 baudrate. To use 4800 simply replace the variable "bit9600Delay" with "bit4800Delay".

to:

This is the SWprint function. First the transmit line is pulled low to signal a start bit. Then we itterate through a bit mask and flip the output pin high or low 8 times for the 8 bits in the value to be transmitted. Finally we pull the line high again to signal a stop bit. For each bit we transmit we hold the line high or low for the specified delay. In this example we are using a 9600 baudrate. To use 4800 simply replace the variable bit9600Delay with bit4800Delay.

August 13, 2006, at 05:38 PM by Heather Dewey-Hagborg -
Changed line 29 from:

[@#define bit9600Delay 84 //total 104us

to:

[@#define bit9600Delay 84

Changed line 31 from:
  1. define bit4800Delay 188 //total 208us
to:
  1. define bit4800Delay 188
Changed lines 34-35 from:
to:

Here we establish our baudrate delay definitions. These are pre-processor directives that define the delays for different baudrates.

byte rx = 6;
byte tx = 7;

Here we set our transmit (tx) and recieve (rx) pins. Change the pin numbers to suit your application.

void setup() {
  pinMode(rx,INPUT);
  pinMode(tx,OUTPUT);
  digitalWrite(tx,HIGH);
  SWprint('h');  //debugging hello
  SWprint('i');
  SWprint(10); //carriage return
}

Here we initialize the lines and print a debugging message to confirm all is working as planned. We can pass inidvidual characters or numbers to the SWprint function.

void SWprint(int data)
{
  byte mask;
  //startbit
  digitalWrite(tx,LOW);
  delayMicroseconds(bit9600Delay);
  for (mask = 0x01; mask>0; mask <<= 1) {
    if (data & mask){ // choose bit
     digitalWrite(tx,HIGH); // send 1
    }
    else{
     digitalWrite(tx,LOW); // send 0
    }
    delayMicroseconds(bit9600Delay);
  }
  //stop bit
  digitalWrite(tx, HIGH);
  delayMicroseconds(bit9600Delay);
}

This is the SWprint function. First the transmit line is pulled low to signal a start bit. Then we itterate through a bit mask and flip the output pin high or low 8 times for the 8 bits in the value to be transmitted. Finally we pull the line high again to signal a stop bit. For each bit we transmit we hold the line high or low for the specified delay. In this example we are using a 9600 baudrate. To use 4800 simply replace the variable "bit9600Delay" with "bit4800Delay".

August 13, 2006, at 05:27 PM by Heather Dewey-Hagborg -
Added lines 22-36:

picture of device with serial connections

Program the Arduino

Now we will write the code to enable serial data transmission. This program will simply wait for a character to arrive in the serial recieving port and then spit it back out in uppercase out the transmit port. This is a good general purpose serial debugging program and you should be able to extrapolate from this example to cover all your basic serial needs. We will walk through the code in small sections.

#define bit9600Delay 84  //total 104us
#define halfBit9600Delay 42
#define bit4800Delay 188 //total 208us
#define halfBit4800Delay 94 

August 13, 2006, at 05:19 PM by Heather Dewey-Hagborg -
Changed lines 17-19 from:

Insert the device you want to communicate with in the breadboard. Connect ground on the breadboard to ground from the microcontroller. If your device uses 5v power connect 5v from the microcontoller to 5v on the breadboard. Otherwise connect power and ground from an alternate power source to the breadboard in the same fashion. Make any other connections necessary for your device.

picture of device with connections

to:

Insert the device you want to communicate with in the breadboard. Connect ground on the breadboard to ground from the microcontroller. If your device uses 5v power connect 5v from the microcontoller to 5v on the breadboard. Otherwise connect power and ground from an alternate power source to the breadboard in the same fashion. Make any other connections necessary for your device. Additionally you may want to connect an LED for debugging purposes between pin 13 and Ground.

picture of device with connections

Decide which pins you want to use for transmitting and receiving. In this example we will use pin 7 for transmitting and pin 6 for receiving, but any of the digital pins should work.

August 13, 2006, at 05:05 PM by Heather Dewey-Hagborg -
Changed lines 17-19 from:

Insert the device you want to communicate with in the breadboard.

to:

Insert the device you want to communicate with in the breadboard. Connect ground on the breadboard to ground from the microcontroller. If your device uses 5v power connect 5v from the microcontoller to 5v on the breadboard. Otherwise connect power and ground from an alternate power source to the breadboard in the same fashion. Make any other connections necessary for your device.

picture of device with connections

August 13, 2006, at 04:51 PM by Heather Dewey-Hagborg -
Added lines 1-17:

Arduino Software Serial Interface

In this tutorial you will learn how to implement serial communication on the Arduino in software to communicate with other serial devices. Using software serial allows you to create a serial connection on any of the digital i/o pins on the Arduino. This should be used when multiple serial connections are necessary. If only one serial connection is necessary the hardware serial port should be used. This is a general purpose software tutorial, NOT a specific device tutorial. A tutorial on communicating with a computer is here. And device specific tutorials are on the Tutorial Page.

Materials needed:

  • Device to communicate with
  • Solderless breadboard
  • Hookup wire
  • Arduino Microcontroller Module
  • Light emitting Diode (LED) - optional, for debugging

Prepare the breadboard

Insert the device you want to communicate with in the breadboard.

Share