Lab 3: ColorPAL





Use Serial.read() to control the Arduino


We learned we needed to enter or "send" the data to the serial monitor each time we input new data.

Play Notes on the Arduino

int inputChar;

void setup () {
pinMode(12,OUTPUT);
Serial.begin(9600);
}
// this code will play the A major scale which has 3 sharps, C#, F#, and G#
void loop(){
if (Serial.available() > 0) {
inputChar = Serial.read();
if (inputChar == 'a'){
tone(12,1760);

}
if(inputChar == 'b'){
tone(12,1976);

}
if(inputChar == 'c'){
tone(12,2216);

}
if(inputChar == 'd'){
  tone(12,2348);

}
if(inputChar == 'e'){
  tone(12,2636);

}
if(inputChar == 'f'){
  tone(12, 2960);

}
if(inputChar == 'g'){
  tone(12, 3324, 400);

}
}

}

Above is the code we used to play different tones corresponding to an A major scale.

We used a Piezo buzzer and had the same circuit set-up as in previous labs.

Create some LED flashing routines and trigger them with different letter commands






In this lab, we learned how to use to ColorPAL sensor and coded for discrepancies since the ColorPAL sensor is not perfect and also has internal reflectance.

Thus, we first calibrated our sensor by using a "white reference" and a "black reference" - we used the white cover of my notebook and then a black USB cord to then develop a color correction formula.

*Important note: To power the ColorPAL resistor, we must use Ground on the Analog side of the Arduino board.


ColorPAL Color Sensor

When we first measured our white reference, the following values appeared: R177, G132, B254. We used a white piece of paper as our reference.
Then with black reference, where the colors should all be 0 (since black is the absence of color), we read values of B7 G3 R8. For this, we used a black lid from a coffee mug.

Thus, we found our values that needed to be adjusted for.

The values from the black reference indicate Kr, Kg, and Kb.
Thus, in conjunction with the measured values, Ur, Ug, and Ub, we can find the intensity of the reflected light.
Actual reading: (Ur – Kr), (Ug – Kg), and (Ub – Ug).
U = the uncorrected measurement

The values from the white reference are labeled as Wr, Wg, and Wb.
Thus, in conjunction with the measures values, we can find the maximum range of red, green, and blue.
Range: (Wr – Kr), (Wg – Kg), and (Wb – Kb)

Thus, the corrected color measurements would be:

Cr = (Ur – Kr) / (Wr – Kr)
Cg = (Ug – Kg) / (Wg – Kg)
Cb = (Ub – Kb) / (Wb – Kb)

The corrected values range between 0 and 1. 0 would indicate a black (based on our black target) and 1 would indicate white based on our white target.

From here, we began coding so that the ColorPAL could read different colors and return the color based on a combination of R, G, and B values.

Circuit with the 3-pronged ColorPAL sensor.

Here is a series of videos showing the ColorPAL working with various colors:






Below is our code including the corrected colors:

#include <OldSoftwareSerial.h>
OldSoftwareSerial Color90(2, 3);  // rx = 2, tx = 3

float red;
float grn;
float blu;
int Cr = 0.0;
int Cg = 0.0;
int Cb = 0.0;
float Kr = 7.0;
float Kg = 3.0;
float Kb = 8.0;
float Wr = 177.0;
float Wg = 132.0;
float Wb = 254.0;

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);     // spec is 80, but not all ColorPAL units work with 80

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

}

// 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();

  Serial.println(Rainbow(red,grn,blu));
// readcolor();
// Serial.print("R");
// Serial.print(red);
// Serial.print("  G");
// Serial.print(grn);
// Serial.print("  B");
// Serial.println(blu); 
  gotcolor = 0;
  delay(1000);

}
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) {
    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;

      Cr = strtol(dummy,NULL,16);
      red = (Cr-Kr)/(Wr-Kr); //corrected red
     
      dummy[0] = rByte[3];
      dummy[1] = rByte[4];
      dummy[2] = rByte[5];

      Cg = strtol(dummy,NULL,16);
      grn= (Cg-Kg)/(Wg-Kg); //corrected green
     
      dummy[0] = rByte[6];
      dummy[1] = rByte[7];
      dummy[2] = rByte[8];

      Cb = strtol(dummy,NULL,16); 
      blu = (Cb-Kb)/(Wb-Kb); //corrected blue
    }
  }
}

String Rainbow(double red, double green, double blue){
if(red>=0.45){
  if ((green <=0.1) && (blue <= 0.1)){
    return "red";
  }
  else if((green >= 0.5) && (green > blue)){
    return "yellow";
  }
  else{
    return "color";
  }

}
  else if((blue > green) && (blue > red)){
    return "blue"; 

  }
  else if((green > blue) && (green > red)){
    return "green";
  }
  else{
    return "color";
  }
}


Comments

Popular posts from this blog

Lab #3: ColorPAL

Lab #4: Non-volatile memory, Servo Motors and MATLAB

Lab #5: Bio-Signals