Thursday, March 31, 2011

Lab 3: Serial.read and ColorPal

The first part of this lab was to learn how to use the serial.read command. We simply wanted to plug in a command ("a" for instance) and have the arduino output a result in the serial monitor using the following code:

 void setup() {
Serial.begin(9600);
}

void loop() {
int inputChar;
if (Serial.available() > 0){
  inputChar = Serial.read();
 
    if (inputChar == 'a')
    {
        Serial.println("This is a");
    }
    if (inputChar == 'b') {
        Serial.println("This is b");
  }
}
}

The second thing we wanted to do was for the Arduino to read a number from the serial monitor. However, since the Arduino works in a way where certain numbers and letters are coded in addition to the fact that the inputs must be multiplied by 10 to shift to the right, we had to use an altered code. This is because instead of the number 23, the arduino would read 5 because it adds the 2 numbers together. We wanted to shift the 3 to the right before adding the 2 so that we can get the output 23, rather than 5:

void setup() {
Serial.begin(9600);
}

void loop() {
 
int inputChar;
int inputNumber;
inputNumber = 0;

if (Serial.available() > 0) {
      delay(5);
      while (Serial.available() > 0) {
        inputChar = Serial.read();
        inputNumber = inputNumber * 10 + (inputChar-48) ;
        Serial.println(inputNumber);
       
      }
    }
}


Another thing we did was to use the input from the keyboard in addition to the tone function to use the keyboard commands to produce different notes on the Arduino. This essentially turned the computer keyboard into a musical keyboard:

 void setup() {
Serial.begin(9600);
}

void loop() {
int inputChar;
if (Serial.available() > 0){
  inputChar = Serial.read();
 
    if (inputChar == 'a')
    {
        Serial.println("A");
        tone(3,440,1000);
    }
    if (inputChar == 'b') {
        Serial.println("B");
        tone(3,494,1000);
  }
  if (inputChar == 'c') {
        Serial.println("C");
        tone(3,523,1000);
  }
}
}


ColorPal

The ColorPal is a color measuring module that when connected to the Arduino, can be placed to any surface and measure the red, green and blue components of the color of that surface. For our intensive purposes, we first wanted to connect the ColorPal and get it working. Afterwards, we wanted to be able to have the ColorPal detect the color of a surface and output that color in the serial monitor after analyzing the RGB values. We first had to measure the black and white color levels to essentially "zero" the device:




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

int red;
int grn;
int blu;

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");

  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(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.print("R");
  Serial.print((red - 23)*0.96226);
  Serial.print("   G");
  Serial.print((grn - 26)*0.78704);
  Serial.print("   B");
  Serial.print((blu - 31)*0.63591);
  Serial.print("   Color: ");
 
  int sum = (((red - 23)*0.9622) + ((grn - 26)*0.78704) + ((blu - 31)*0.63591));
 
  if (sum <=-50)
  Serial.print("Blank");
  if (sum >250)
  Serial.print("White");
  if (sum >-50 && sum <=4)
  Serial.print("Black"); 
  if (sum >4 && sum <=250 && red > blu && red > grn)
  Serial.print("Red");
  if (sum >4 && sum <=250 && grn > blu && grn > red)
  Serial.print("Green");
  if (sum >4 && sum <=250 && blu > red && blu > grn)
  Serial.print("Blue");
 
  gotcolor = 0;
  delay(100);

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

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


 

1 comment:

  1. Hello! I've been trying to figure out how to use a ColorPAL with an Arduino, and yours is the only actual successful example of the two working together that I've found. I'm curious about the correction factors that you apply to the RGB values at the beginning of the loop statement-- did you arrive at those values by trial and error, or was there some other reason? Are you pleased with the ColorPAL in general?

    ReplyDelete