Lab Exercise 6 - Wireless Communication
Lab Exercise 6 - Wireless Communication
Lab Exercise 6 - Wireless Communication
Jack Donovan
Aaron Wilson
Part 1: IR Remote
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()) {
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”.
Code:
#include <SoftwareSerial.h>
#include <Servo.h>
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: