Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of...

13
University of Pennsylvania Department of Electrical and Systems Engineering ESE 111 Intro to Elec/Comp/Sys Engineering Created by Nick Howarth, EE ’13 Last updated: October 9, 2012 Lab 6 Introduction to Serial and Wireless Communication Introduction : Up to this point, you have only used sensors and pushbuttons to control the input to your Arduino. You will now learn how to receive communication signals or commands on the Arduino from the serial port. You have used Serial.print() to transmit communication signals to the serial monitor. Serial.read() will allow to you send characters from the input line on the serial monitor to the Arduino. First, you will learn how to send commands to the Arduino via the serial port using the keyboard and how to interpret the input. You will use these commands to control the behavior of an LED. Then, you will learn how to use two XBee modules to transmit and receive information wirelessly. XBee is a brand of low-power radio transmitter/receiver, based on the ZigBee digital communication protocol, which uses the serial port to communicate. You will program one Arduino board to transmit one byte per second through an XBee module. The other Arduino will receive the byte through an XBee module configured on the same channel as the transmitter, and it will turn an LED on or off based on the identity of the byte. Next, you will use the XBee modules to remotely control an LED on one Arduino with a photoresistor on another Arduino. Finally, you will transmit accelerometer data wirelessly to control the brightness of an LED using pulse width modulation (PWM). Figure 1: Transmitter and Receiver Modules

Transcript of Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of...

Page 1: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

University of Pennsylvania Department of Electrical and Systems Engineering

ESE 111 – Intro to Elec/Comp/Sys Engineering

Created by Nick Howarth, EE ’13 Last updated: October 9, 2012

Lab 6 – Introduction to Serial and Wireless Communication

Introduction:

Up to this point, you have only used sensors and pushbuttons to control the input to your

Arduino. You will now learn how to receive communication signals or commands on the

Arduino from the serial port. You have used Serial.print() to transmit communication

signals to the serial monitor. Serial.read() will allow to you send characters from the

input line on the serial monitor to the Arduino.

First, you will learn how to send commands to the Arduino via the serial port using the keyboard

and how to interpret the input. You will use these commands to control the behavior of an LED.

Then, you will learn how to use two XBee modules to transmit and receive information

wirelessly. XBee is a brand of low-power radio transmitter/receiver, based on the ZigBee digital

communication protocol, which uses the serial port to communicate. You will program one

Arduino board to transmit one byte per second through an XBee module. The other Arduino will

receive the byte through an XBee module configured on the same channel as the transmitter, and

it will turn an LED on or off based on the identity of the byte. Next, you will use the XBee

modules to remotely control an LED on one Arduino with a photoresistor on another Arduino.

Finally, you will transmit accelerometer data wirelessly to control the brightness of an LED

using pulse width modulation (PWM).

Figure 1: Transmitter and Receiver Modules

Page 2: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

2

Goals:

- To understand the basics of serial communication.

- To learn about ASCII encoding.

- To wirelessly control the lighting of an LED using Zigbee.

- To understand pulse width modulation (PWM).

1. Introduction to Serial Communication

(Adapted excerpt from BE 470, Lab 3; written by Prof. Dan Bogen)

Serial.read() is an Arduino function that allows to you send characters from the input line

on the serial monitor to the Arduino. The Serial.read() function is used like this:

int inputCharacter;

inputCharacter = Serial.read();

Serial.read() takes its input from the USB port, the same port that is used for

Serial.print(). To initialize both of these functions, you need to use the

Serial.begin(9600) instruction.

Serial.read() is a bit of a pain to use because it only can take in one character at a time. It

can’t just accept the number 123 and know that it means one-hundred-twenty-three. Instead, you

have to take in the ‘1’ character, ‘2’ character, and ‘3’ character, and then let the Arduino know

that you want the number 123.

The characters are received as numerical codes – a number corresponding to each alphanumeric

character on the keyboard. Part of the table of codes is shown below. For instance, the letter ‘a’

is coded by the number 97, and capital ‘A’ by 65. The ‘1’ character is coded by the number 49,

the ‘2’ character by the number 50, and so on.

One useful feature of the Arduino language is that the expression ‘X’ , where X is a single

character (i.e., a single character enclosed by single quotes) is equal to the numerical code for

that character. For instance ‘a’ = 95, ‘1’ = 49, etc. This will be useful in Arduino programming,

as we will see a little later. These codes are called ASCII codes, ASCII standing for American

Standard Code for Information Interchange. A table of ASCII representations can be found at

the following link (you only need to focus on the “Dec” and “Char” columns:

http://www.asciitable.com/

Page 3: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

3

Other functions related to Serial.read() are:

Serial.flush() – The serial port has an input buffer, so there may be some

characters “left over” in the buffer that you don’t want to read. Serial.flush()

empties this buffer so that you can read new characters.

Serial.available() – This function returns the number of characters in the input

buffer. So, Serial.available > 0 means that there is something to read.

Notes:

1. Serial.read() will wait until a character is available before returning a value. So if

there is nothing there, it will hang until there is. This means that it sometimes makes sense to

check whether there are characters present (using Serial.available()) before using

Serial.read().

2. Serial.available() will indicate that there are characters present as soon as there are

some. But if a whole string of characters is being sent to the Arduino,

Serial.available() will be > 0 before all the characters “get to” the Arduino. For this

reason, sometimes it makes sense to wait a few milliseconds (maybe 5) after

Serial.available() > 0 before reading the characters in so that you know that they

are all there.

Here are some code fragments that demonstrate how to use Serial.read() to control the

Arduino.

Fragment #1 – Using letter “commands” from the serial monitor to control the Arduino.

int inputChar;

if Serial.available() > 0 {

inputChar = Serial.read();

if (inputChar == ‘a’;) {

// do something }

if (inputChar == ‘b’) {

// do something else }

}

Page 4: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

4

Fragment #2 — Reading a number into the Arduino from the serial monitor

int inputChar;

int inputNumber;

inputNumber = 0;

if Serial.available() > 0 {

delay(5);

while Serial.available() > 0 { // build the number as long as

there are characters

inputChar = Serial.read();

// “build number from left to right, shifting left by

multiplying by 10

inputNumber = inputNumber * 10 + (inputChar - ‘0’);

// why inputChar – ‘0’ ? Make sure you understand this!

}

}

2. Control of an LED using input from keyboard

1) Write a program that accepts a character input from the serial monitor. The on-board

LED connected to pin 13 should turn on if the input is ‘H’, and the LED on pin 13 should

turn off if the input is ‘L’. Otherwise, nothing should happen.

a. Remember to initialize serial communication by putting

Serial.begin(9600) in setup().

b. Remember to set pin 13 to an output by adding pinMode(13, OUTPUT)in

setup().

c. Copy this code into a text file. You will use it in the next section.

2) Write a program that reads in a number from the serial monitor. Use the input number to

control the flashing rate of the LED on pin 13; that is, use the input number as the

argument in your delay functions.

a. Copy this code into a text file. You will use it in section 5.

3. Remote Control of an LED using XBees

In this section, you will wirelessly transmit ‘H’ and ‘L’ characters from one Arduino to another

Arduino (instead of from keyboard to Arduino), and the receiver will turn on or off an LED

accordingly, as in the previous section. This wireless communication is possible using XBees.

The XBee modules work by transmitting data in the form of bytes (e.g. ASCII characters)

through the serial port. This means that any character that is printed to the serial monitor (from

the transmitter) is received on the other module. You can fetch these characters on the receiving

end the same way you would if you were just entering characters directly into the serial monitor.

Only XBees that are on the same channel will be able to communicate with each other; this is

Page 5: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

5

what allows us to have multiple pairs of XBees communicating in one room without

interference. Make sure that your XBee modules have the same number written on them.

It is important to note that the XBee has two different modes: USB (Programming) mode and

XBee mode (Figure 2). The USB mode is used when you are uploading code to your Arduino,

and the XBee mode is used when you want to run the code (i.e. to transmit/receive data). These

modes are determined by the position of small jumpers on the XBee Arduino shield. A close-up

view of the jumper positions is shown in Figure 3. If you receive an error when trying to

upload your code, first check that the jumpers are removed!

Figure 2: USB (Programming) mode vs. XBee mode

Figure 3: Close-up of jumper position for XBee mode. (Note: just take jumpers off for USB mode.)

Page 6: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

6

Receiver Module

a. Connect the XBee Shield and set the Receiver Arduino module in USB Programming mode

Connect the XBee Shield to the Arduino Board as shown in Figure 2 (or Figure 5). Remove the

jumpers to set the XBee module in USB programming mode. Please do not lose the jumpers

(Figure 4)!

Figure 4: Jumpers (DO NOT LOSE!)

Figure 5: Arduino XBee Shield in USB Programming Mode

b. Upload the receiver code to the Arduino

Upload your code from part 1) of the previous section. This code should accept a character input

from the serial monitor. The on-board LED connected to pin 13 should turn on if the input is

‘H’, and the LED on pin 13 should turn off if the input is ‘L’.

d. Set the Receiver Arduino module in XBee mode

Connect the jumpers to the XBee shield, as shown in Figure 3 (or Figure 6), to set it in XBee mode. This

will be the receiver Arduino module.

Page 7: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

7

Figure 6: Arduino XBee Shield in XBee Mode

Transmitter Module

f. Follow step ‘a’ to set the Transmitter Arduino module in USB Programming mode

g. Upload the following code to the Transmitter Arduino module

void setup(){

Serial.begin(9600); // initialize serial communication

}

void loop(){

Serial.print(‘L’);

delay(1000);

Serial.print(‘H’);

delay(1000);

}

h. Set the Transmitter Arduino module in XBee mode as in step ‘d’, by connecting the jumper

wires

i. Observe the flashing LED

In the Arduino window containing the code for the transmitter, open the serial monitor by

pressing the “Serial Monitor” button to the right of the “Upload” button. You should see

alternating L’s and R’s appear every second. The LED on the receiver module should blink on

and off based on the serial data transmitted from the transmitter module.

Page 8: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

8

4. Remote control of an LED using a photoresistor circuit and XBees

This part requires you to construct a circuit on both the receiving and transmitting Arduino

boards. However, there is no room to fit a breadboard on the Arduino since it is occupied by the

XBee shield. For this reason, we have constructed extension shields that can hold a breadboard

shield, XBee shield, and LCD screen all on one shield. The only limitation is that each

component occupies a number of digital I/O pins; consequently, only two components can be

used at a time. In this part of the lab, you will use the extension shield to hold the XBee shield

and the breadboard shield.

Connect your shields as shown in Figure 7.

Figure 7: Configuration of Arduino Shields on Extension Shield

Transmitter Module

a. Construct the circuit given by the schematic in Figure 8. Choose any analog pin (0-5).

Figure 8: Transmitter voltage divider circuit

Transmitter Receiver

Page 9: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

9

b. Set the Arduino in USB Programming mode (remove jumpers) and upload the following

code:

int analogPin = ***; // change *** to the pin number you're reading from

int value;

void setup(){

Serial.begin(9600); // initialize serial communication

pinMode(analogPin, INPUT);

}

void loop(){

value = analogRead(analogPin);

if(value >= 150){ // you may need to modify this argument

Serial.print(‘L’);

delay(500);

}

if(value < 150){ // you may need to modify this argument

Serial.print(‘D’);

delay(500);

}

}

c. Set the Transmitter Arduino in XBee mode by connecting the jumpers.

Receiver Module

d. Construct the circuit given by the schematic in Figure 9.

Figure 9 - Receiver LED circuit

e. Set the Arduino in USB Programming mode (remove jumpers) and copy the following

code into the Arduino IDE window.

Page 10: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

10

const int ledPin = 12; // the pin that the LED is attached to

int incomingByte; // a variable to read incoming serial data into

void setup() {

Serial.begin(9600); // initialize serial communication

pinMode(ledPin, OUTPUT); // initialize the LED pin as an output

}

void loop() {

// your code here

}

f. Finish writing the code above such that the LED turns on when the photocell on the

transmitter is covered and is off otherwise.

g. Set the Arduino in XBee mode by connecting the jumpers.

Demonstrate to a TA that your system works!

5. Remote control of an LED using an accelerometer and XBees

For many applications of wireless communication, it is desirable to transmit a continuous, analog

signal, such as data from an accelerometer or electromyograph (EMG). However, the XBee can

only transmit and receive data in packets, where each packet is one byte, and one byte contains 8

bits (0 or 1) of information. (Note that in the previous part we were transmitting characters

[designated by single quotes ‘ ’], which only store one byte of information.) So how do we break

up an analog signal (imagine a sine wave) into bytes? Well, we can sample the signal at regular

time intervals to obtain the integer values that make up the signal. An integer stores 2 bytes of

information, so it cannot be sent in this form through the serial port. Instead, integers are printed

one byte at a time using ASCII characters corresponding to each digit. For example, if we were

to transmit the number 4316 through the serial port, it would transmit the ASCII representations

of 4, 3, 1, and 6 in series. These bytes can then be regrouped into an int on the receiving end,

thus reconstructing the original integer.

In this section, you will transmit integer values from an accelerometer and reconstruct them on

the receiver. You will then use this data to control the brightness of an LED on the receiver.

This is done using a technique pulse width modulation (PWM).

For an good explanation of PWM, read the following reference page:

- http://www.arduino.cc/en/Tutorial/PWM

Page 11: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

11

An easy way to implement PWM is by using the Arduino’s analogWrite() function.

- http://arduino.cc/en/Reference/AnalogWrite

Note that this function only works on digital pins 3, 5, 6, 9, 10, and 11 (and has no connection

to analogRead() or the analog pins). By using the map() function from Lab 4, we can map

the accelerometer values to a range of 0 to 255 (the range accepted by analogWrite()).

Transmitter Module

a. Connect an accelerometer to your transmitter module.

b. Complete the following code so that the transmitter sends the y-axis value to the receiver

every 250 seconds. Set the Arduino in USB mode and upload your code.

const int groundpin = 18; // analog input pin4 -- ground (GND)

const int powerpin = 19; // analog input pin5 -- voltage (Vcc)

const int ypin = 16; // analog input pin2 -- y-axis pin

int yvalue;

void setup() {

Serial.begin(9600);

pinMode(ypin, INPUT);

pinMode(groundpin, OUTPUT);

pinMode(powerpin, OUTPUT);

digitalWrite(groundpin, LOW); // make analog pin (4) equivalent to GND (ground)

digitalWrite(powerpin, HIGH); // make analog pin (5) equivalent to Vcc (voltage source)

}

void loop(){

// your code here

}

c. Set the Transmitter Arduino in XBee mode by connecting the jumpers.

d. Using the output on the serial monitor, determine the minimum and maximum y-axis

values.

Page 12: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

12

Receiver Module

e. Construct the circuit given by the schematic in Figure 10.

Figure 10: Receiver LED circuit

f. Set the Arduino in USB Programming mode (remove jumpers) and copy the following

code into the Arduino IDE window.

int ymin = ***; // Replace with measured minimum yvalue

int ymax = ***; // Replace with measured maximum yvalue

int yval; // incoming y-axis value

void setup() {

Serial.begin(9600);

}

void loop() {

// insert code to reconstruct yval

pwm = map(yval, ymin, ymax, 0, 255);

analogWrite(9, pwm);

}

g. Replace *** with the values that you found in part d. Finish writing the code to

reconstruct the transmitted value from the accelerometer. Hint: look at Fragment #2 on

page 4).

h. Upload the finished code to the Arduino.

i. Tilt the accelerometer on the transmitter and observe the LED brightness on the receiver.

Demonstrate to a TA that your system works!

Page 13: Lab 6 Introduction to Serial and Wireless Communicationese111/Fall2012labs/Lab6.pdfUniversity of Pennsylvania Department of Electrical and Systems Engineering ESE 111 – Intro to

13

6. Thinking Further – Biomedical Application

With technology rapidly evolving, it is becoming possible for medical professionals to remotely

observe and treat patients. This new form of medicine, called telemedicine, allows people in

need of medical surveillance to move around comfortably at home while their physiological

signals, such as heart rate, brain and muscle activity, etc., are wirelessly transmitted to a

computer and sent to a medical center to be analyzed.

Imagine a digital communication system consisting of two XBee modules (one transmitter and

one receiver), two Arduinos, and a biomedical sensor such as an electrocardiograph (ECG),

which records electrical currents associated with heart muscle activity (shown in Figure 9). The

signal from the ECG is directly connected to the transmitter, which then wirelessly transmits the

signal to the receiver. The data can then be transferred from the receiver onto a computer and

sent to a medical center via an internet connection.

With your group, briefly discuss the following:

- What are some factors that might interfere with the quality of the transmitted signal?

- Do you think that this could be an effective system for remote patient monitoring?

- Could a similar type of system be used by a doctor to remotely treat a patient?

Figure 8 - Electrocardiograph

(http://www.instrumentalanalysis.com/en/projects/fv_fum.php)