Lab Exercise 6 - Wireless Communication

Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

Lab Exercise 6: Wireless Communication

Jack Donovan
Aaron Wilson

University of Vermont, Department of Electrical Engineering

CMPE 3815: Microcontroller Systems

Part 1: IR Remote

First we investigated an IR photodiode by reverse-biasing it and placing it in series with a


large resistor, 99.34 kOhms in our case. As it is a diode, when there is no IR light shining upon it
no current is conducted through it, and the voltage between the diode and resistor is zero. When
the photodiode revieces IR light, it is able to let some current flow in the opposite direction,
resulting in a voltage proportional to the amount of light. The circuit is shown below:

When shining a light at the sensor, it appeared that the voltage (analogReading on a scale
0-1024) would spike into the 100s, but only sporadically. There would be many zero readings in
this signal, likely due to the fact the remote is flashing rapidly to actually encode a message.
When attaching an IR receiver to an oscilloscope (after much difficulty scaling), resulted
in the following image:
From printing to the serial monitor, the code for the number 3 on our IR remote is
4061003530, or 11110010000011011111111100000000 in 32 bit binary. If the “double wide”
pulses on the oscilloscope are ones and the thin pulses are zeroes, then (reading it backwards) the
oscilloscope reading matches the purported code for the number 3 on the IR remote (cool!).
The code for reading the IR remote uses the IRremote.hpp library to decode the signals.
It intializes the receiver pin and if it is desired to use the on board arduino LED to indicate
signals. The loop stage, similar to a serial channel, uses
if (IrReceiver.decode()) {

To check if the IR receiver as seen any data. If it has:


read = IrReceiver.decodedIRData.decodedRawData;

Will store whatever it got into read. From appearance, this function grabs the raw data
from the IR (while I assume many a function can decode directly based on which protocol you
pick, but that is not what this class is about). Then, a which case statement will do something (in
this case print to the serial monitor) based on the case. Each case for our remote (I don’t know
about other protocols) are random 32 bit integers. Once we do what needs to be done:
IrReceiver.resume();

Will make the IR start listening again, and the cycle continues.
Here’s our little circuit:
And here is our code:
// There is an IR reciever library :)
#include <IRremote.hpp>
const int IR_RECEIVE_PIN = 2;

void setup()
{
Serial.begin(9600); // // Establish serial communication
// Ir initialization
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Start the receiver
}
void loop() {
static unsigned long read;
static unsigned long prevRead;
// check if anything has been received yet
if (IrReceiver.decode()) {
// this appartantly grabs the data
read = IrReceiver.decodedIRData.decodedRawData;
// for each recieve case (found by just prinitng out whatever the reiver
read for the relevant button presses.)
switch (read) {
case 3141861120:
Serial.println("LEFT");
break;
case 3158572800:
Serial.println("RIGHT");
break;
}
// basically turn it back on
IrReceiver.resume(); // Enable receiving of the next value
}
}

Part 2:

For this part we are using bluetooth communication. Thankfully bluetooth modules
communicate to the boards with UART. So it is as simple as opening a Serial channel and
communicating like it is a serial monitor. We could uses the designated RX and TX pins and
pretend the bluetooth module is the serial monitor, but thankfully the SoftwareSerial.h library
can turns any pins into RX and TX pins using:
SoftwareSerial bluetooth(8,9);

Where pins 8 and 9 are designated as RX and TX pins respectively for a serial channel
called “bluetooth”.

Connecting to the bluetooth module is as simple as powering it and connecting to it


through thre user’s favoirte stripped down mobile app for driectly exchanging with bluetooth
devices.
The code is very simple. All it has to do in loop() is to check if there is something on the
bluetooth channel and use parseInt() to grab it.
For our example we jused used this to command the servo to go to that position in
degrees.
The following picture applies to all parts of the lab (the bluetooth module is on the
breadboard as a vertical blue rectangle):

Code:
#include <SoftwareSerial.h>
#include <Servo.h>

const int servoDataPin = A0;


// intialize blutooth channel and servo
Servo myServo;
SoftwareSerial bluetooth(8,9);

void setup() {
Serial.begin(9600);
// bluetooth intitialization (not sure if bluetooth.listen() is needed, but
its doesn't hurt)
bluetooth.begin(9600);
bluetooth.listen();
bluetooth.write("Hello World");
// more servo initialization
myServo.attach(servoDataPin);
}

void loop() {
static int communicationVariableBLE;
// check if something is in bluetooth channel
while (bluetooth.available() > 0) {
// parse response as an int
communicationVariableBLE = bluetooth.parseInt();
Serial.println(communicationVariableBLE);
}
// command servo to that position
myServo.write(communicationVariableBLE);

}
}

Free Task:

Our free task involved using the IR remote input to command our servo. Similar the the
first example with the switch case, we simply added more cases to accommodate all 10 digits
and the ok button. This allowed to position the servo from 0 to 180 degrees in 18 degree
increments. Code below:
// Thank you libraries
#include <IRremote.hpp>
#include <Servo.h>
const int IR_RECEIVE_PIN = 2;
const int servoDataPin = A0;
// creative name for servo object
Servo servo;
const int servoRange = 180;

void setup()
{
Serial.begin(9600); // // Establish serial communication
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Start the receiver
servo.attach(servoDataPin); // tell servo object which pin to use
}

void loop() {
static unsigned long read;
static unsigned long prevRead;
// go to 90 degrees only on startup
static int SetAngle = 90;
// has the receiver seen anything
if (IrReceiver.decode()) {
// raw ir data
read = IrReceiver.decodedIRData.decodedRawData;
Serial.println(read);
// each case is a different button on remote (the button is printed inside)
// each case then goes to a different servo angle (evenly spaced from zero
to 180)
switch (read) {
case 2907897600:
Serial.println("0");
SetAngle = 0;
servo.write(SetAngle);
break;
case 3910598400:
Serial.println("1");
SetAngle = 18;
servo.write(SetAngle);
break;
case 3860463360:
Serial.println("2");
SetAngle = 36;
servo.write(SetAngle);
break;
case 4061003520:
Serial.println("3");
SetAngle = 54;
servo.write(SetAngle);
break;
case 4077715200:
Serial.println("4");
SetAngle = 72;
servo.write(SetAngle);
break;
case 3877175040:
Serial.println("5");
SetAngle = 90;
servo.write(SetAngle);
break;
case 2707357440:
Serial.println("6");
SetAngle = 108;
servo.write(SetAngle);
break;
case 4144561920:
Serial.println("7");
SetAngle = 126;
servo.write(SetAngle);
break;
case 3810328320:
Serial.println("8");
SetAngle = 144;
servo.write(SetAngle);
break;
case 2774204160:
Serial.println("9");
SetAngle = 162;
servo.write(SetAngle);
break;
case 3208707840:
Serial.println("ok");
SetAngle = 180;
servo.write(SetAngle);
break;
}
IrReceiver.resume(); // Enable receiving of the next value
}
}

Notebook:

You might also like