Lab 5: Biomedical Signals and Wireless Communication

In Lab 5, I worked on building a heartbeat sensor and integrating wireless communication with a remote and IR receiver. I started with initial code provided to us, which read optical signals from the KY-039 heartbeat sensor. This code delivered unfiltered values that I had to interpret to deliver a reliable, upgraded heartbeat sensor. This process is detailed below.

Part I:

In the first portion of the lab, I began to make upgrades to the heartbeat sensor. First, I removed background noise by recording the initial value of the sensor in the setup portion of the code. I considered this as background noise and subtracted it from the calculation, providing a steady value of 0 when my finger wasn’t in the sensor. Next, I actually calculated the heartbeat and change in heartbeat and utilized the Kalman filter below. For the baseline value, I calculated my actual heartbeat at different rates and applied a ratio of the value to my heartbeat, as values were initially around 600 (although change in heartbeat was always accurate, and the more relevant portion of the device). I maintained consistency of lighting environment to mitigate the effects of any noise. If the device was subject to different environments, I would’ve built a cover around the actual filter to mitigate noise, but that was not necessary here.

To improve the design of the heartbeat sensor, I also added an LED alarm that lit up if the heartbeat dropped below a certain threshold (50 BPM) or above a certain threshold (100 BPM). I would’ve used more extreme values, but wanted to ensure it was working properly. If I were to launch to market, these thresholds would change to 30 and 140, respectively. Additionally, if the heartbeat changed by more than 10BPM in between reads, the LED lit up. All of this functionality can be seen below.

Code: 

#define HEART_PIN A5

#define DELAY_MS 10

double threshold;

static double oldValue = 0; //previous value 

double alpha = 0.7; //filter coefficient  was .7

double newValue;

double filterOutput;

double avg;

double change;

void setup() {

  // put your setup code here, to run once:

  pinMode(HEART_PIN, INPUT);

  Serial.begin(9600);

  newValue = analogRead(HEART_PIN);

  if(newValue < 50){

    threshold = newValue;

  }

}

void loop() {

  // put your main code here, to run repeatedly:

  avg = 0;

//  read new analog value

  newValue = analogRead(HEART_PIN) – threshold;

  //calculate weighted average

  double filterOutput = alpha * oldValue + (1 – alpha) * newValue;

  //output raw and filtered heart signal

  //Serial.print(oldValue);

  //Serial.print(“,”);

  change = (filterOutput – oldValue);

  Serial.println(.1 * filterOutput + change);

  oldValue = filterOutput;

  if((abs(change) > 10 || .1 * filterOutput + change > 100 || .1 * filterOutput + change < 50)){

    digitalWrite(6, HIGH);

  } else {

    digitalWrite(6, LOW);

  }

  delay(DELAY_MS); 

}

Video: https://drive.google.com/file/d/1A5Rbf4CL4K2DyE7ad5Vm3OFQjuBWR-gU/view?usp=sharing

Results:

Bluetooth Integration

In the next portion of the lab I utilized Arduino’s IR Remote library to incorporate a remote control and bluetooth to upgrade the heartbeat monitor. The physical setup otherwise remained the same, except with the addition of this remote functionality. I added the following functionalities for four different remote buttons: 4 turned the LED on when it was off, 5 turned the LED off when it was on (i.e. silencing the alarm, until 4 was pressed again), 8 turned the readings off (set heartbeat to 0), and 2 turned the readings back on. All of this functionality is displayed in the below video. I was able to achieve these results by interpreting the hexadecimal outputs of the remote from the IR reader. Initially, the IR reader was giving different hexadecimal results for the same button, but that issue fortunately ending up resolving itself.

#include <IRremote.h>

#define HEART_PIN A5

#define DELAY_MS 10

double threshold;

static double oldValue = 0; //previous value 

double alpha = 0.7; //filter coefficient  was .7

double newValue;

double filterOutput;

double avg;

double change;

int RECV_PIN = 11;

int val = 1; 

int pwr = 0;

unsigned long four = 0xFF10EF;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup() {

  // put your setup code here, to run once:

  pinMode(HEART_PIN, INPUT);

  Serial.begin(9600);

  newValue = analogRead(HEART_PIN);

  if(newValue < 50){

    threshold = newValue;

  }

  irrecv.enableIRIn();

}

void loop() {

  // put your main code here, to run repeatedly:

  avg = 0;

//  read new analog value

  newValue = analogRead(HEART_PIN) – threshold;

  //calculate weighted average

  double filterOutput = alpha * oldValue + (1 – alpha) * newValue;

  //output raw and filtered heart signal

  //Serial.print(oldValue);

  //Serial.print(“,”);

  change = (filterOutput – oldValue);

  if(pwr == 0){

    Serial.println(.1 * filterOutput + change);

  } else {

    Serial.println(0);

  }

  oldValue = filterOutput;

  if(val == 1 && (abs(change) > 10 || .1 * filterOutput + change > 100 || .1 * filterOutput + change < 50)){

    digitalWrite(6, HIGH);

  } else {

    digitalWrite(6, LOW);

  }

  if(irrecv.decode(&results)){

        int resultsvalue = results.value;

        if(String(results.value, HEX) == “ff10ef”){

          //4

          digitalWrite(6, HIGH);

          irrecv.resume();

          val = 1;

        }else if(String(results.value, HEX) == “ff38c7”){

          //5

          digitalWrite(6, LOW);

          val = 0; 

          irrecv.resume();

        } else if(String(results.value, HEX) == “ff18e7”){

          //2

          pwr = 1;

          irrecv.resume();

        } else if(String(results.value, HEX) == “ff4ab5”){

          // 8

          pwr = 0;

          irrecv.resume();

        }

        irrecv.resume();

    }

  delay(DELAY_MS); 

}

Video:

https://drive.google.com/file/d/11PL7IvNzL4pYJfN4XYcbD-GrxRjrXbK2/view?usp=sharing

Output:

Physical Setup:

Lab 4: Nonvolatile Memory and Servos

In lab 4, we learned about EEPOM and Servo motors. EEPROM is relevant to store longer-term medical data for interpretation even long after the use of a medical device (or after it is powered down). Learning about Servo motors opens doors to build motion-based medical devices, which are often necessary. 

Part I: Getting Started with EEPROM

In this portion of the lab we were introduced to EEPROM. Typical data stored in the Arduino disappears when power is turned off, however, with the EEPROM, memory is stored and can be read back even after the device is powered down. This is illustrated in the below video. This is important as memory can be saved indefinitely, and data is no longer volatile. 

This portion was a soft introduction to the concept. I wrote an array containing 6 numbers, wrote the data into the EEPROM, unplugged the Arduino, plugged it back in, and printed the array back on the Serial Monitor. EEPROM would destroy the onboard memory if simply put into an endless loop, so I had it nested inside of an if statement executed only when certain characters were typed into the Serial Monitor: ‘w’ for write and ‘r’ for read. Code, images, and video all below:

https://drive.google.com/file/d/1R-IQMeHa_SFKbSQ_C_QoJjIZxfKqMy8x/view?usp=sharing

Part II: Build a Datalogger

Setup:

Code: 

Output:

Part III: Servo

This portion of the lab introduced us to Servo and motion. In the first portion, I learned to make the Servo move. This was done by sending a high voltage pulse to the Servo, delaying for a short period of time, then sending a low pulse to the Servo followed by another delay. 

Video: https://drive.google.com/file/d/17p9CEelz96Cwjhep-yRsVzEnHqnplsLs/view?usp=sharing

Next, we commanded the Servo to move to a certain angular position. I prompted users to enter the angle to the Serial Monitor and calculated the duration of the pulse accordingly, by normalizing it. 

Video: https://drive.google.com/file/d/1_XvOQjjGz_BOeVHZ5iFVUMFD5ZRFQeop/view?usp=sharing

Next I wrote a script to make the Servo rotate between two positions. I did so by creating two functions, one representing each position. Code and video below:

Video:

https://drive.google.com/file/d/1Zdl3cGcwCVje3SKQUGppQwaBnfVS5eOW/view?usp=sharing

Next, I controlled the speed of the servo through the Serial Monitor. The speed

started as fast in the video below, and then I changed it to slow by changing

the delay time. 

Video: https://drive.google.com/file/d/1QcXlC24lKIvjj2fQKu0y0ugiV_1vx7Lh/view?usp=sharing

Control w/ potentiometer

Next, I controlled the Servo through the potentiometer by setting the angle according to the value read by the potentiometer. I could similarly control through the potentiometer by setting the input PIN to analog and writing the voltage.

https://drive.google.com/file/d/1H7Z2jqdfctxzaeVTAEm_fmn8NgXT1sp6/view?usp=sharing

Angle and Speed

Next, I controlled the angle and speed of the potentiometer with the below code. I was able to parse both a number and character through the switch functionality. The user is easily able to understand the functionality, as it takes the format of  one character and one number: ex f45 for fast 45º, s90 for slow 90º.

Finally, I attempted to position the Servo over a hole. I was able to  link the Servo behavior to the potentiometer as per the code below.  However, the mechanism I built couldn’t easily maneuver over the holes, perhaps due to weight. I was able to get the Servo to move or not move based on the readings of the potentiometer, but it struggled to move with the  physical setup pictured below, despite multiple attempts. 

Physical Setup

Lab 2 – Analog I/O

Abstract: The focus of this lab is on analog inputs and outputs, and more generally, on using a microcontroller to both generate and measure signals. There are multiple components focusing on signal generation, analog outputs, analog inputs, and a medical device project.

PART I: Signal Generation

The signal generation component consisted of three parts: writing a numerical ramp output, generating a sine wave on the serial plotter, and writing a program to generate two signals at once. Code and images are given below:

RAMP OUTPUT

int val = 4;

void setup() {

  Serial.begin(9600);

}

void loop() {

   Serial.println(val);

   if(val < 20) {

    val = val + 2;

   } else {

    val = 0;

   }

   delay(200);

}

SINE WAVE

void setup() {

  Serial.begin(9600);

}

void loop() {

   Serial.println(0);

   Serial.println(.288);

   Serial.println(.5);

   Serial.println(.7071);

   Serial.println(.866);

   Serial.println(.9659);

   Serial.println(1);

   Serial.println(.9659);

   Serial.println(.866);

   Serial.println(.7071);

   Serial.println(.5);

   Serial.println(.288);

   Serial.println(0);

   Serial.println(-.288);

   Serial.println(-.5);

   Serial.println(-.7071);

   Serial.println(-.866);

   Serial.println(-.9659);

   Serial.println(-1);

   Serial.println(-.9659);

   Serial.println(-.866);

   Serial.println(-.7071);

   Serial.println(-.5);

   Serial.println(-.288);

}

TWO SIGNALS

nt val = 0;

int val2 = 0;

void setup() {

  Serial.begin(9600);

}

void loop() {

   if(val < 20) {

    val = val + 2;

   } else {

    val = 0;

   }

   if(val2 < 50) {

     val2 = val2 + 10;

   } else {

    val2 = -50;

   }

   Serial.println(val);

   Serial.print(“,”);

   Serial.println(val2);

}

PART II: Generating Sound

In this component of the lab we generated sound using the Arduino and a Piezzo buzzer. The task here was to make five sounds, the code and videos for which are given below:

Fast Sound:

https://drive.google.com/file/d/1ZkJ12g-ztMeo-hcLgRDit145VRIl6QDD/view?usp=sharing

FAST Sound:

void setup() {

  Serial.begin(9600);

  pinMode(7, OUTPUT);

}

void loop() {

  tone(7, 1000, 2);

  tone(7, 500, 2);

  tone(7, 200, 2);

  tone(7, 500, 2);

  delay(200);

}

NO Sound:

https://drive.google.com/file/d/1NR98jWow7tEza5nXwWxU8EmQpeZ1t0IY/view?usp=sharing

void setup() {

  Serial.begin(9600);

  pinMode(7, OUTPUT);

}

void loop() {

  tone(7, 1000, 500);

  tone(7, 500, 2);

  tone(7, 200, 2);

  tone(7, 500, 2);

}

YES Sound:

https://drive.google.com/file/d/1wL5EfeN3hpdM6mBw-4AjwEbYYHf7h7in/view?usp=sharing

void setup() {

  Serial.begin(9600);

  pinMode(7, OUTPUT);

}

void loop() {

  tone(7, 440);

  delay(700);

  tone(7, 660);

  delay(700);

  noTone(7);

  delay(5000);

}

EMERGENCY Sound:

https://drive.google.com/file/d/1zxqiONZ_t1lPTD1GYRVzEz9zNTrSKarf/view?usp=sharing

void setup() {

  Serial.begin(9600);

  pinMode(7, OUTPUT);

}

void loop() {

  tone(7, 770);

  delay(700);

  tone(7, 880);

  delay(700);

  tone(7, 480);

  delay(700);

  tone(7, 880);

  noTone(7);

  delay(5000);

}

SLOW Sound:

https://drive.google.com/file/d/1QB70gN0ABei9TnyPl-CuU38oKNghmsXN/view?usp=sharing

void setup() {

  Serial.begin(9600);

  pinMode(7, OUTPUT);

}

void loop() {

  tone(7, 240);

  delay(700);

  tone(7, 120);

  delay(700);

  tone(7, 220);

  delay(700);

}

All of these sounds could be used on a medical device as an indicator. Additionally, these videos show that the Arduino is capable of connection to the Oscilloscope.

Part III: Controlling LED Brightness

The next portion of the lab covered controlling LED brightness and using Analog Inputs to control the LED. Find all code and some photos below:

LED Brightness (25%)

int brightness = 25;

void setup() {

  Serial.begin(9600);

  pinMode(7, OUTPUT);

}

void loop() {

  digitalWrite(7, HIGH);

  delay(brightness);

  digitalWrite(7, LOW);

  delay(100 – brightness);

}

LED Brightness (90%)

int brightness = 90;

void setup() {

  Serial.begin(9600);

  pinMode(7, OUTPUT);

}

void loop() {

  digitalWrite(7, HIGH);

  delay(brightness);

  digitalWrite(7, LOW);

  delay(100 – brightness);

}

ANALOG WRITE BRIGHTNESS (2)

int brightness = 2;

void setup() {

  Serial.begin(9600);

  pinMode(6, OUTPUT);

}

void loop() {

  analogWrite(6, brightness);

}

ANALOG WRITE BRIGHTNESS (25)

int brightness = 25;

void setup() {

  Serial.begin(9600);

  pinMode(6, OUTPUT);

}

void loop() {

  analogWrite(6, brightness);

}

ANALOG WRITE BRIGHTNESS (225)

int brightness = 255;

void setup() {

  Serial.begin(9600);

  pinMode(6, OUTPUT);

}

void loop() {

  analogWrite(6, brightness);}

Analog Brightness (255)

Brightness Control (25%)

Finally, for this portion of the lab, we did something fun with brightness control, so I made a siren – code and video below:

https://drive.google.com/file/d/1ph9eIf5TZX26X7ssyfmF7C0HnXmkDV_V/view?usp=sharing

int brightness = 255;

int LED_PIN = 6;

void setup() {

  Serial.begin(9600);

  pinMode(6, OUTPUT);

}

void loop() {

  while(brightness > 0){

    lowerBrightness();

  }

  delay(200);

  brightness = 0;

  while(brightness < 255){

    raiseBrightness();

  }

  delay(200);

}

void raiseBrightness() {

  analogWrite(LED_PIN, brightness);

  brightness = brightness + 1;

  delay(10);

}

void lowerBrightness() {

  analogWrite(LED_PIN, brightness);

  brightness = brightness – 1;

  delay(10);

}

Section 4: Variable Resistance Sensor

In this section of the lab, we measured resistance using a photo-resistor, the voltage divider circuit, and analogRead(). Code, image and video below:

voltage divider circuit

https://drive.google.com/file/d/1ph9eIf5TZX26X7ssyfmF7C0HnXmkDV_V/view?usp=sharing

Photoresistor:

void setup() {

  Serial.begin(9600);

  pinMode(2, INPUT);

}

void loop() {

  int x = analogRead(2);

  Serial.println(x);

}

Next, we used a capacitor to replicate the approach:

// RCtime — modified version

#define MAX_COUNT 400000 //define a macro (token: “MAX_COUNT”) (expression: “400,000”) to use later

int sensorPin = 4; // 220 or 1k resistor connected to this pin

long result = 0;

void setup() {

Serial.begin(9600);

Serial.println(“Testing RCtime”);

}

void loop() // run over and over again

{

Serial.println( RCtime(sensorPin) );

delay(10);

}

long RCtime(int sensorPin) {

  long result = 0;

  pinMode(sensorPin, OUTPUT); // make pin OUTPUT

  digitalWrite(sensorPin, HIGH); // make pin HIGH to discharge capacitor – study the schematic

  delay(1); // wait ~1ms to make sure cap is discharged

  pinMode(sensorPin, INPUT); // turn pin into an input and time till pin goes low

  digitalWrite(sensorPin, LOW); // turn pullups off – or it won’t work

  while (digitalRead(sensorPin)) {  // wait for pin to go low

     result++;

     if (result == MAX_COUNT) break; // don’t wait forever for pin to go low

  // if result reaches the maximum value we defined earlier (400,000) stop waiting.

// this means that if RCtime returns 400,000, it really

// means that RCtime is >= 400,000.

// you can change this value of 400,000 to something else by changing the macro definition.

// there is nothing magic about the number, 400,000.

  }

  return result; // report 

}

w/ potentiometer

int count = 0;

void setup() {

  Serial.begin(9600);

  pinMode(2, INPUT);

  Serial.println(“Start!”);

}

void loop() {

  millis();

  while(millis() < 5000){

    if(digitalRead(2) == 1){

      count = count + 1;

      while(digitalRead(2) == 1){

        continue;

      }

    }

  }

  Serial.print(count/5.0);

  Serial.println(” steps taken per second!”);

  delay(5000);

  count = 0;

}

Setup

Output

Part IV:

Finally, we created a medical device to see how fast one could press a button:

int count = 0;

void setup() {

Serial.begin(9600);

pinMode(2, INPUT);

Serial.println(“Start!”);

}

void loop() {

millis();

while(millis() < 5000){

if(digitalRead(2) == 1){

  count = count + 1;

  while(digitalRead(2) == 1){

    continue;

  }

}

}

Serial.print(count/5.0);

Serial.println(” steps taken per second!”);

delay(5000);

count = 0;

}

Lab 1 – Arduino Basics

Abstract:

This lab introduced me to the basics of Arduino and circuitry. I learned how to power up LEDs, an LCD, use a pushbutton, and integrate with the Arduino. The lab itself was broken up into small, independent subcomponents.

Part I: Writing Your First Programs

Serial Output

  • Change the program, changing “setup” to “Setup.” What happens?

“Error compiling board for Arduino”

  • Try the below program

The program prints “my first arduino sketch “ endlessly

  • Try these little experiments:
  • Change Serial.print to Serial.println

This prints each statement on a new line

  • Change Serial.begin to serial.begin

This causes an error: “serial was not declared in this scope”

  • Change Serial.begin(9600) to Serial.begin(4800)

This prints the below odd characters

  • Leave off the “;” at the end of a line.

Error: “Expected ‘;’ before ‘}’ token”

Variables and Numbers

Input:

Output:

These two programs have the same output as above

This program adds a 200 millisecond delay between each loop

  • Now, try making a program where x changes at each iteration (x = 1, 2, 3, 4, etc). Have it increment by 1,2,10, or some other number. Try a large number, sucas 100. What happens? (You might not want to print out “my number is” all the time. Try commenting it out by adding two forward slashes (“//”) in front of it.

Input:

Output:

Digital Output

Blinking LED

Video: https://drive.google.com/file/d/1BimiJ-olYdppzwJCyMqCO2CtyvwNmb9c/view?usp=sharing

Faster flashing

Video: https://drive.google.com/file/d/1ICSzGOPNn7mLOv14dg6VXsCYnkRba9aW/view?usp=sharing

2 LEDs alternating

https://drive.google.com/file/d/1ZU9wsz_szElPw4G-HbldJQZBmgVAbmNM/view?usp=sharing

Digital Input

Using If Statements

https://drive.google.com/file/d/18BPOiJIjxc29U-onBSEWuzNj_-J_Y8Vg/view?usp=sharing

int buttonState = 1;

void setup() {

  Serial.begin(9600);

  pinMode(8, INPUT);

  pinMode(7, OUTPUT);

}

void loop() {

  buttonState = digitalRead(8);

  if(buttonState == 0){

    digitalWrite(7, HIGH);

  } else {

    digitalWrite(7, LOW);

  }

  Serial.print(buttonState);

}

Your First LCD Project

Video: https://drive.google.com/file/d/1KWtQSsBJva-ZFv-HhUdGEPnRvIRAmOTP/view?usp=sharing

Your First Medical Device

Printed two statements with 30 second (30000ms) delay, stopwatch recorded 31.87 and 31.65 seconds for an average of 31.76s. This represents a 5.7% difference. 

Millis input

Millis output

Part II: Our First Medical Devices

Abstract: This block covered two simple medical devices, described below.

Reaction Time:

The first experiment measured reaction time. I had the Arduino light up an LED and after it lit up the user would have to press the pushbutton (which the Arduino would read as a 1) and then their reaction time would be reported. Below is the code and video for the device.

#include <LiquidCrystal.h>

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

void setup() {

  Serial.begin(9600);

  pinMode(13, OUTPUT);

  pinMode(2, INPUT);

  delay(300);

  digitalWrite(13, HIGH);

  millis();

  while(digitalRead(2) == 0){

    continue;

  }

  Serial.println(millis());

  digitalWrite(13, LOW);

}

void loop() {

}

https://drive.google.com/file/d/1Qu80YgSQ6G7MBQJO75EOHh8apeCow18k/view?usp=sharing

Step counter: The second device was a step counter. The Arduino measured how many times a pushbutton was pressed in a given time and reported it via the Serial Monitor. Below is the code and video.

int count = 0;

void setup() {

  Serial.begin(9600);

  pinMode(2, INPUT);

  Serial.println(“Start!”);

}

void loop() {

  millis();

  while(millis() < 5000){

    if(digitalRead(2) == 1){

      count = count + 1;

      while(digitalRead(2) == 1){

        continue;

      }

    }

  }

  Serial.print(count);

  Serial.println(” steps taken!”);

  delay(5000);

  count = 0;

}

Video: https://drive.google.com/file/d/1-idzt424F55KLm-j63S72kY4G9cO8fWV/view?usp=sharing

Lab 3: Controlling the Arduino and Interfacing with Sensor Modules

PART I: Serial.Read()

Objectives and Abstract:

The first portion of the lab involved using Serial.read() functions to control the Arduino. There was an exploratory segment where we played around with Serial.read() to learn how it works. Upon completing this section, the lab involved an exercise where we controlled the Arduino through the Serial Monitor via Serial.read(). I choose to turn the Arduino into a keyboard, using the Piezzo buzzer and using notes A though G (no sharps or flats) in the third octave.

Code

void setup() {

  pinMode(12, OUTPUT);

  Serial.begin(9600);

}

void loop() {

  if (Serial.available()) {

    delay(100);

    char ch = Serial.read();

    if (ch == ‘a’) {

        tone(12, 440, 350);

        delay(100);

    }

    if (ch == ‘b’) {

      tone(12, 493, 350);

      delay(150);

    }

    if (ch == ‘c’) {

      tone(12, 261, 350);

      delay(150);

    }

    if (ch == ‘d’) {

      tone(12, 293, 350);

      delay(150);

    }

    if (ch == ‘e’) {

      tone(12, 329, 350);

      delay(100);

    }

    if (ch == ‘f’) {

      tone(12, 349, 350);

      delay(150);

    }

    if (ch == ‘g’) {

      tone(12, 392, 350);

      delay(150);

  }

  }

}

Setup and Output

The setup and output of the keyboard is provided in the video link below. These are the notes provided into the serial monitor:

CCGGAAG

FFEEDDC

GGFFEED

GGFFEED

CCGGAAG

FFEEDDC

https://drive.google.com/file/d/13-TJOHDtP8JxhguFTGPBElL2ifwsa8xx/view?usp=sharing

The piezzo buzzer was connected directly into the Arduino and ran through 5V and Pin 12.

PART II: ColorPal

Objectives and Abstract:

The objective of the second portion of the lab was to set up the ColorPal and use it to identify colors. Color identification can be particularly relevant to medical devices, especially if done on a more granular level (i.e. analyzing tissue). For this lab, the procedure was more straightforward and did not go quite as into depth. After setting up the ColorPal, we established scaling using a black object and a white object, to mitigate the effects of environmental noise. Within the code, I applied the below standardization formulas – C represents standardized value, U represents the original value, W represents the white scaling, and K represents the black scaling (RGB subscripts are red/green/blue).

Finalized Code:

/==================================================== / Connect ColorPAL SIG signal to Arduino pin 2 and 3 / Add 2K pullup resistor from pins 2 & 3 to +5v / Baud Rate = 9600 kbps / Read signal on 9600 in HEX /====================================================/

include

OldSoftwareSerial Color90(2, 3); // rx = 2, tx = 3

int red;
int grn;
int blu;
int blackRed;
int blackBlue;
int blackGreen;
int whiteRed;
int whiteBlue;
int whiteGreen;

int gotcolor = 0;
int letter;

void setup()
{

Serial.begin(9600); // Start communication with serial port read value
Color90.begin(4800); // Send signal to led to read value

pinMode(2,INPUT); // serial pin out from color pal
pinMode(3,INPUT); // from same serial pin, signal pulls up, sends, pulls down, reads
digitalWrite(2,HIGH); // Enable the pull-up resistor
digitalWrite(3,HIGH); // Enable the pull-up resistor

pinMode(2,OUTPUT); // send signal out
pinMode(3,OUTPUT);
digitalWrite(2,LOW); // turn pin off so pin 3 can go high
digitalWrite(3,LOW);

pinMode(2,INPUT); // Input signal to print
pinMode(3,INPUT);

Serial.println(“Pass 1”);
delay(20);

while( digitalRead(2) != HIGH || digitalRead(3) != HIGH ) {
Serial.println(“In the loop”);
delay(50);
}

Serial.println(“Pass 2”);

pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
digitalWrite(2,LOW);
digitalWrite(3,LOW);
delay(100);

pinMode(2,INPUT);
pinMode(3,OUTPUT);
delay(100);

Serial.println(“BLACK”);
delay(5000);
readcolor();
blackRed = red;
blackGreen = grn;
blackBlue = blu;
Serial.println(blackRed);
Serial.println(blackGreen);
Serial.println(blackBlue);
delay(500);

Serial.println(“WHITE”);
delay(5000);
readcolor();
whiteRed = red;
whiteGreen = grn;
whiteBlue = blu;
Serial.println(whiteRed);
Serial.println(whiteGreen);
Serial.println(whiteBlue);
delay(500);

}

// This oscillates back and forth on one wire to turn off led, send signal,
// turn on led, read signal. very fast strobe read – arduino is not capable of
// one wire signal communication over digital ports, so this is a way around
// that over 2 wires communicating with 1 pin on the sensor.
//———————————

void loop()
{
readcolor();
float Cr = (red-blackRed) * 1.0 / ((whiteRed-blackRed) * 1.0);
float Cg = (grn-blackGreen) / ((whiteGreen-blackGreen) * 1.0);
float Cb = (blu-blackBlue) / ((whiteBlue-blackBlue) * 1.0);
Serial.print(“R”);
Serial.print(Cr);
Serial.print(” G”);
Serial.print(Cg);
Serial.print(” B”);
Serial.println(Cb);
if(Cb < 0 && Cg < 0 && Cg < 0){ Serial.println(“black”); } else if(Cb > .9 && Cg > .9 && Cr > .9){
Serial.println(“white”);
} else if(Cg > (Cb + Cr)){
Serial.println(“green”);
} else if (Cb > (Cr + Cg)){
Serial.println(“blue”);
} else if (Cr > (Cb + Cg)){
Serial.println(“red”);
} else if (Cr > Cb && Cg > Cb){
Serial.println(“yellow”);
} else if (Cb > Cr && Cg > Cr){
Serial.println(“cyan”);
} else if (Cr > Cg && Cb > Cg){
Serial.println(“purple”);
} else {
Serial.println(“Unknown”);
}
gotcolor = 0;
delay(5000);

}
void readcolor() { // Reads ColorPAL, putting results in the red,grn,blu variables
char rByte[9];
char dummy[4];

delay(20);
Color90.begin(4800);
Color90.print(“= (00 $ m) !”); // set up loop to continuously send color data
pinMode(3,INPUT);
gotcolor = 0;
while (gotcolor == 0) {
Serial.print(gotcolor);
rByte[0] = Color90.read();
if( rByte[0] == ‘$’ ) {
gotcolor = 1;
for(int i=0; i<9; i++) {
rByte[i] = Color90.read();
Serial.print(rByte[i]);
}
Serial.println(“”);
dummy[0] = rByte[0];
dummy[1] = rByte[1];
dummy[2] = rByte[2];
dummy[3] = 0;

  red = strtol(dummy,NULL,16);

  dummy[0] = rByte[3];
  dummy[1] = rByte[4];
  dummy[2] = rByte[5];

  grn = strtol(dummy,NULL,16);

  dummy[0] = rByte[6];
  dummy[1] = rByte[7];
  dummy[2] = rByte[8];

  blu = strtol(dummy,NULL,16); 
}

}
}

Set Up

Video Results

https://drive.google.com/file/d/1CeIdQExkpIQcp3sQfaidwmCs0gi4XH8O/view?usp=sharing

Conclusion

Lab 3 went pretty smoothly. As you can see from both videos, the outcomes were successful: the ColorPal correctly identified the color of objects placed near it and I was able to use the Arduino and Serial.read() to produce music.