Operácie

Acrob043: Rozdiel medzi revíziami

Zo stránky SensorWiki

Balogh (diskusia | príspevky)
Vytvorená stránka „ == Software for Color Sensors == Demo program: <source lang="c"> /*==================================================== / Connect ColorPAL SIG signal to Arduino pin ...“
 
Balogh (diskusia | príspevky)
 
(18 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 1: Riadok 1:
= Software for Color Sensors =


== Software for Color Sensors ==
== 1. Basic demonstration ==


* TCS230 sensor:  [http://senzor.robotika.sk/sscim/code/TCS230Demo01.bs2  BASIC Stamp II code]
* ColorPAL sensor: http://senzor.robotika.sk/sscim/code/ColorPalDemo01.ino Arduino code]
* TCS3200 sensor:  [http://senzor.robotika.sk/sscim/code/TCS3200demo01.ino  Arduino code]
* TCS2300 description https://www.waveshare.com/wiki/Color_Sensor


Demo program:
Poznamka: ak chceme pri senzore TCS3200 pouzit R,G a B hodnoty v obvyklom rozsahu 0-255, pouzijeme
funkciu map():


<source lang="c">
    //Remaping the value of the frequency to the RGB Model of 0 to 255
/*====================================================
      frequency = map(frequency, 25,70,255,0);
/ Connect ColorPAL SIG signal to Arduino pin 2 and 3
/ Add 2K pullup resistor from pins 2 & 3 to +5v
/ See the result on the serial terminal,  
/ Baud Rate = 115200 kbps 
/ Works with Arduino 0.20, not with 1.00 and above?
/ Source: http://be470merchantuy.blogspot.com/2012/02/lab-3-serialread-and-colorpal.html
/====================================================*/


#include <SoftwareSerial.h>
== 2. Color Matching Demo software ==
SoftwareSerial ColorPAL(2, 3); // rx = 2, tx = 3


int red, grn, blu;
Following Arduino code works with an original Parallax (or PhiPi) ColorDemo.exe program available at
 
the following address: https://www.parallax.com/sites/default/files/downloads/28380-ColorPAL-Color-Matching-Program-BS-Sample-Files.zip
int gotcolor = 0;
int letter;
 
int redBlackRef=8;
int redWhiteRef=234;


int grnBlackRef=3;
int grnWhiteRef=166;


int bluBlackRef=6;
* TCS230 sensor: [http://senzor.robotika.sk/sscim/code/TCS230Demo02.bs2  BASIC Stamp II code]
int bluWhiteRef=285;
* ColorPAL sensor [http://senzor.robotika.sk/sscim/code/ColorPalDemo02.ino Arduino code]
* 2014: [http://learn.parallax.com/colorpal-arduino-demo Arduino demo + code]
* 2014: [http://parallax.com/downloads/colorpal-color-matching-program-and-basic-stamp-sample-files Demo pre BS2]




void setup(){
[[Obrázok:ColorMatchDemoExe.png|center]]


Serial.begin(115200); // Start communication with serial port read value
== 4. Calculations ==
ColorPAL.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
=== TCS230 ===
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");
Because even the completely black surface reflex some light under white LED illumination, the light response from a completely black subject will be non-zero. For this reason, the black response for each color component has to be determined experimentally, so that it, too, can be subtracted from the overall response. The three components thus measured (with an ambient reference subtracted), Kr, Kg, and Kb, are known as the “black reference”. A black reference is typically obtained only once before each measurement session.
delay(20);


while( digitalRead(2) != HIGH || digitalRead(3) != HIGH ) {
The TCS230 light sensor colored photodiodes does not respond equally to the red, green, and blue wavelengths. So, in addition to the ambient reference and black reference, it is also necessary to take a “white reference”, wherein the TCS230 is presented with a completely white surface. Again, after subtracting the ambient lighting, the red, green, and blue components of this reference will be called, Wr, Wg, and Wb. Now we have a way of determining a subject’s actual color as a percentage of the difference between the white and black references. This percentage can be expressed as a value between 0 (0%) and 255 (100%), as follows for red, say:
Serial.println("In the loop");
Cr = 255 . (Ur – Kr) / (Wr – Kr),
delay(50);
where Ur is the uncorrected (except for ambient) reading, and Cr is the corrected reading.
}


Serial.println("Pass 2");


pinMode(2,OUTPUT);
=== ColorPAL ===
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);
The sensor outputs a voltage proportional to all the light that it sees, weighted by the above curve. Therefore, when a subject is illuminated with a red LED only, it will respond with a voltage proportional to the red component of the subject’s color, and similarly with blue and green. When there is ambient light mixed in with the LED’s illumination, its effect can be eliminated by sampling first without any LEDs turned on, then subtracting this reading, in turn, from each of the red, green, and blue components. This reference measurement should be taken before each color measurement to eliminate any effects from varying ambient conditions. In the paragraphs that follow, it will be assumed that an ambient reference is taken and subtracted from each measurement discussed.
pinMode(3,OUTPUT);
delay(100);


}
Because the LED and sensor sit next to each other on the ColorPAL’s circuit board, and because the plastic snorkel itself reflects some light back (primarily from its threads), the light response from a completely black subject will be non-zero. For this reason, the black response for each color component has to be determined experimentally, so that it, too, can be subtracted from the overall response. The three components thus measured (with an ambient reference subtracted), Kr, Kg, and Kb, are known as the “black reference”. A black reference is typically obtained only once before each measurement session. The TSL13T light sensor does not respond equally to the red, green, and blue LEDs, and those LEDs don’t put out equal amounts of light at the red, green, and blue wavelengths. So, in addition to the ambient reference and black reference, it is also necessary to take a “white reference”, wherein the ColorPAL is presented with a completely white surface. Again, after subtracting the ambient lighting, the red, green, and blue components of this reference will be called, Wr, Wg, and Wb. Now we have a way of determining a subject’s actual color as a percentage of the difference between the white and black references. This percentage can be expressed as a value between 0 (0%) and 255 (100%), as follows for red, say:
Cr = 255 . (Ur – Kr) / (Wr – Kr),
where Ur is the uncorrected (except for ambient) reading, and Cr is the corrected reading.


// 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()
=== Color Matching ===
{
  readColor();


  int redCorrect = (255*(red-redBlackRef))/(redWhiteRef-redBlackRef);
'''Color matching''' is done using a "minimax" approach in the RGB color space. In this method, the distance between two colors is the absolute value of the difference between the RGB component that differs most:
  int bluCorrect = (255*(blu-bluBlackRef))/(bluWhiteRef-bluBlackRef);
  int grnCorrect = (255*(grn-grnBlackRef))/(grnWhiteRef-grnBlackRef);


Di = max{|R - Ri|, |G - Gi|, |B - Bi|}


  Serial.print("R");
where R, G and B are the red, green, and blue coordinates of the color being scanned; and Ri, Gi and Bi are the coordinates of stored color. The color with the closest match is taken to be the one whose is the smallest, i.e. minimizing the maximum difference. Hence the term "minimax".
  Serial.print(redCorrect);
  Serial.print(" ");
  Serial.print(red);
  Serial.print(" G");
  Serial.print(grnCorrect);
  Serial.print(" ");
  Serial.print(grn);
  Serial.print(" B");
  Serial.print(bluCorrect);
  Serial.print(" ");
  Serial.println(blu);


  //int redCorrect = red;
== 3. Processing software ==
  //int bluCorrect = grn;
  //int grnCorrect = blu;


  if (redCorrect > 240 && redCorrect <=255 && grnCorrect >240 && grnCorrect <=255 && bluCorrect >240 && bluCorrect <= 255)
* PC software: [http://ap.urpi.fei.stuba.sk/sscim/code/ColorSensorDemo03.pde  Processing code]
  {
* TCS230 sensor: [http://ap.urpi.fei.stuba.sk/sscim/code/TCS230Demo03.bs2  BASIC Stamp II code]
    Serial.print("White");
* ColorPAL sensor [http://ap.urpi.fei.stuba.sk/sscim/code/ColorPalDemo03.ino Arduino code]
    delay(100);
  }


[[Obrázok:ColorProcessingDemo.png|center]]


  if (redCorrect > 0 && redCorrect <= 40 && grnCorrect >0 && grnCorrect <=40 && bluCorrect >0 && bluCorrect <= 40){
<source lang="c">
    Serial.print("Black");
// Demonstration program for Color Sensors
    delay(100);
// TCS 230 sensor requires TCS230_Demo03_SS_CIM.bs2
  }
// ColorPAL sensor requires ColorPAL_Demo03_SS_CIM.ino with line 78 uncommented
 
//
  if (redCorrect > 140 && redCorrect <= 255 && grnCorrect >0 && grnCorrect <=80 && bluCorrect >0 && bluCorrect <= 130){
// SS_CIM 2013
    Serial.print("Red");
// Richard Balogh
    delay(100);
  }
 
  if (redCorrect > 200 && redCorrect <= 255 && grnCorrect >0 && grnCorrect <=200 && bluCorrect >130 && bluCorrect <= 255){
    Serial.print("Pink");
    delay(100);
  }
 
  if (redCorrect > 200 && redCorrect <= 255 && grnCorrect >80 && grnCorrect <=160 && bluCorrect >0 && bluCorrect <= 120){
    Serial.print("Orange");
    delay(100);
  }
 
  if (redCorrect > 180 && redCorrect <= 255 && grnCorrect >200 && grnCorrect <=255 && bluCorrect >0 && bluCorrect <= 255){
      Serial.print("Yellow");
      delay(100);
    }
 
  if (redCorrect > 120 && redCorrect <= 200 && grnCorrect >0 && grnCorrect <=230 && bluCorrect >120 && bluCorrect <= 255){
      Serial.print("Purple");
      delay(100);
    }
 
  if (redCorrect > 0 && redCorrect <= 180 && grnCorrect >100 && grnCorrect <=255 && bluCorrect >0 && bluCorrect <= 170){
      Serial.print("Green");
      delay(100);
  }


  if (redCorrect > 0 && redCorrect <= 180 && grnCorrect >0 && grnCorrect <=255 && bluCorrect >170 && bluCorrect <= 255){
import processing.serial.*;
      Serial.print("Blue");
      delay(100);
  }


  gotcolor = 0;
int lf = 10;   // Line Feed in ASCII
  delay(100);
int cr = 13;   // Carriage Returin in ASCII


/* End of loop()  */
int val = 0;    // To store data from serial port, used to color background
int r,g,b,c;    // Used to color background
Serial port;    // The serial port object


/* ***************************************** */
void setup() {
/* Function readColor()                     */
  size(200,200);             // Size of canvas
/* Reads ColorPAL, putting results in the    */
/*      red, grn, blu variables             */
/* ***************************************** */
void readColor()
{
  char rByte[9];
  char dummy[4];
    
    
  delay(20);
println(Serial.list());     // List of available ports
  ColorPAL.begin(4800);
  ColorPAL.print("= (00 $ m) !"); // set up loop to continuously send color data
  pinMode(3,INPUT);
  gotcolor = 0;
  while (gotcolor == 0)
  {
    rByte[0] = ColorPAL.read();
    if( rByte[0] == '$' )
      {
      gotcolor = 1;
      for (int i=0; i<9; i++)
          {
          rByte[i] = ColorPAL.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);
                            // Use the port (CHANGE THIS according YOUR PC!)
 
  port = new Serial(this, Serial.list()[3], 9600);  
    dummy[0] = rByte[6];
    dummy[1] = rByte[7];
    dummy[2] = rByte[8];
 
    blu = strtol(dummy,NULL,16);
    }
  }
}  /* End of function readColor() */
 
</source>
 
If the program works correctly, it will send to the serial port (115 200 Bd) following data:
 
 
  R27 32 G106 71 B40 50
Green
R37 41 G134 89 B50 61
Green
R34 39 G126 84 B46 57
Green
 
R19 25 G84 57 B27 36
R18 24 G78 53 B26 35
R15 22 G65 45 B23 32
R15 22 G68 47 B22 31
R14 21 G68 47 B21 30
 
R16 23 G31 23 B26 35
Black
R16 23 G32 24 B30 39
Black
R15 22 G26 20 B21 30
Black
R10 17 G21 17 B19 27
 
 
 
 
 
 
== Demo software ==
 
 
Following Arduino code works with an original Parallax (or PhiPi) ColorDemo.exe program available at
the following address: http://www.parallax.com/Portals/0/Downloads/docs/prod/sens/ColorPAL_programs.zip
 
[[Obrázok:ColorPAL_demo.png|center]]
 
<source lang="c">
/*====================================================
/ Connect ColorPAL SIG signal to Arduino pin 2 and 3
/ Baud Rate = 9600 kbps
/ Works with Arduino 0.20, not with 1.00 and above?
/====================================================*/
 
#include <SoftwareSerial.h>
 
SoftwareSerial ColorPAL(2, 3); // rx = 2, tx = 3
 
int red, grn, blu;
 
int gotcolor = 0;
int letter;
 
char colorByte[9];
 
void setup(){
 
  // for colordemo 9600,
Serial.begin(9600); // Start communication with serial port read value
ColorPAL.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);
 
delay(20);
 
while( digitalRead(2) != HIGH || digitalRead(3) != HIGH ) {
delay(50);
}
}


 
void draw() {
pinMode(2,OUTPUT);
        // The serial data is used to color the background.   
pinMode(3,OUTPUT);
background(r,g,b);  
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);
 
 
  delay(20);
  ColorPAL.begin(4800);
   ColorPAL.print("= (00 $ m) !"); // set up loop to continuously send color data
  pinMode(3,INPUT);
 
 
}
}


// 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();
  gotcolor = 0;
  delay(100);


/* End of loop()  */
// Called whenever there is something available to read


void serialEvent(Serial port) {


/* ***************************************** */
  // Data from the Serial port is read in serialEvent()  
/* Function readColor()                     */
  // using the readStringUntil() function with LF as
/* Reads ColorPAL, putting results in the   */
   // the end character.
/*      red, grn, blu variables            */
/* ***************************************** */
void readColor()
{
   char rByte[9];
  char dummy[4];


// delay(20);
  String input = port.readStringUntil(lf);
// ColorPAL.begin(4800);
 
// ColorPAL.print("= (00 $ m) !"); // set up loop to continuously send color data
  if (input != null) {
    // Print message received
    println( "Receiving:" + input);
   
  // The data is split into an array of Strings with
  // a comma as a delimiter and converted into an
  // array of integers.
  int[] vals = int(splitTokens(input, ","));  
   
    // Fill r,g,b variables
    r = vals[0];
    g = vals[1];
    b = vals[2];
    c = vals[3];
 
    /* ************************************* */
    /*                                      */
    /*    Here is place for Your code!!!    */
    /*                                      */
    /* ************************************* */
   
    println( "R:" + r);
    println( "G:" + g);
    println( "B:" + b);
    println( "C:" + c);


   pinMode(3,INPUT);
   }
  gotcolor = 0;
}  
  while (gotcolor == 0)
  {
    rByte[0] = ColorPAL.read();
    if( rByte[0] == '$' )
      {
      gotcolor = 1;
      for (int i=0; i<9; i++)
          {
          rByte[i] = ColorPAL.read();
          }
 
    Serial.print("R0");
    Serial.print(rByte[0]);
    Serial.print(rByte[1]);
    Serial.print(rByte[2]);
    Serial.print(" G0");
    Serial.print(rByte[3]);
    Serial.print(rByte[4]);
    Serial.print(rByte[5]);
    Serial.print(" B0");
    Serial.print(rByte[6]);
    Serial.print(rByte[7]);
    Serial.print(rByte[8]);
    Serial.println();   
 
    }
  }
} /* End of function readColor() */
</source>
</source>

Aktuálna revízia z 22:23, 23. marec 2019

Software for Color Sensors

1. Basic demonstration

Poznamka: ak chceme pri senzore TCS3200 pouzit R,G a B hodnoty v obvyklom rozsahu 0-255, pouzijeme funkciu map():

    //Remaping the value of the frequency to the RGB Model of 0 to 255
     frequency = map(frequency, 25,70,255,0);

2. Color Matching Demo software

Following Arduino code works with an original Parallax (or PhiPi) ColorDemo.exe program available at the following address: https://www.parallax.com/sites/default/files/downloads/28380-ColorPAL-Color-Matching-Program-BS-Sample-Files.zip



4. Calculations

TCS230

Because even the completely black surface reflex some light under white LED illumination, the light response from a completely black subject will be non-zero. For this reason, the black response for each color component has to be determined experimentally, so that it, too, can be subtracted from the overall response. The three components thus measured (with an ambient reference subtracted), Kr, Kg, and Kb, are known as the “black reference”. A black reference is typically obtained only once before each measurement session.

The TCS230 light sensor colored photodiodes does not respond equally to the red, green, and blue wavelengths. So, in addition to the ambient reference and black reference, it is also necessary to take a “white reference”, wherein the TCS230 is presented with a completely white surface. Again, after subtracting the ambient lighting, the red, green, and blue components of this reference will be called, Wr, Wg, and Wb. Now we have a way of determining a subject’s actual color as a percentage of the difference between the white and black references. This percentage can be expressed as a value between 0 (0%) and 255 (100%), as follows for red, say:

Cr = 255 . (Ur – Kr) / (Wr – Kr), 

where Ur is the uncorrected (except for ambient) reading, and Cr is the corrected reading.


ColorPAL

The sensor outputs a voltage proportional to all the light that it sees, weighted by the above curve. Therefore, when a subject is illuminated with a red LED only, it will respond with a voltage proportional to the red component of the subject’s color, and similarly with blue and green. When there is ambient light mixed in with the LED’s illumination, its effect can be eliminated by sampling first without any LEDs turned on, then subtracting this reading, in turn, from each of the red, green, and blue components. This reference measurement should be taken before each color measurement to eliminate any effects from varying ambient conditions. In the paragraphs that follow, it will be assumed that an ambient reference is taken and subtracted from each measurement discussed.

Because the LED and sensor sit next to each other on the ColorPAL’s circuit board, and because the plastic snorkel itself reflects some light back (primarily from its threads), the light response from a completely black subject will be non-zero. For this reason, the black response for each color component has to be determined experimentally, so that it, too, can be subtracted from the overall response. The three components thus measured (with an ambient reference subtracted), Kr, Kg, and Kb, are known as the “black reference”. A black reference is typically obtained only once before each measurement session. The TSL13T light sensor does not respond equally to the red, green, and blue LEDs, and those LEDs don’t put out equal amounts of light at the red, green, and blue wavelengths. So, in addition to the ambient reference and black reference, it is also necessary to take a “white reference”, wherein the ColorPAL is presented with a completely white surface. Again, after subtracting the ambient lighting, the red, green, and blue components of this reference will be called, Wr, Wg, and Wb. Now we have a way of determining a subject’s actual color as a percentage of the difference between the white and black references. This percentage can be expressed as a value between 0 (0%) and 255 (100%), as follows for red, say:

Cr = 255 . (Ur – Kr) / (Wr – Kr), 

where Ur is the uncorrected (except for ambient) reading, and Cr is the corrected reading.


Color Matching

Color matching is done using a "minimax" approach in the RGB color space. In this method, the distance between two colors is the absolute value of the difference between the RGB component that differs most:

Di = max{|R - Ri|, |G - Gi|, |B - Bi|}

where R, G and B are the red, green, and blue coordinates of the color being scanned; and Ri, Gi and Bi are the coordinates of stored color. The color with the closest match is taken to be the one whose is the smallest, i.e. minimizing the maximum difference. Hence the term "minimax".

3. Processing software

// Demonstration program for Color Sensors
// TCS 230 sensor requires TCS230_Demo03_SS_CIM.bs2
// ColorPAL sensor requires ColorPAL_Demo03_SS_CIM.ino with line 78 uncommented
//
// SS_CIM 2013
// Richard Balogh

import processing.serial.*;

int lf = 10;    // Line Feed in ASCII
int cr = 13;    // Carriage Returin in ASCII

int val = 0;    // To store data from serial port, used to color background
int r,g,b,c;    // Used to color background
Serial port;    // The serial port object

void setup() {
  size(200,200);             // Size of canvas
  
 println(Serial.list());     // List of available ports
  
                             // Use the port (CHANGE THIS according YOUR PC!)
 port = new Serial(this, Serial.list()[3], 9600); 
}

void draw() {
        // The serial data is used to color the background.   
 background(r,g,b); 
}




// Called whenever there is something available to read

void serialEvent(Serial port) {

  // Data from the Serial port is read in serialEvent() 
  // using the readStringUntil() function with LF as 
  // the end character.

  String input = port.readStringUntil(lf); 
  
  if (input != null) {
    // Print message received
    println( "Receiving:" + input);
    
   // The data is split into an array of Strings with 
   // a comma as a delimiter and converted into an 
   // array of integers.
   int[] vals = int(splitTokens(input, ",")); 
    
    // Fill r,g,b variables
    r = vals[0];
    g = vals[1];
    b = vals[2];
    c = vals[3];
  
    /* ************************************* */
    /*                                       */
    /*    Here is place for Your code!!!     */
    /*                                       */
    /* ************************************* */
    
     println( "R:" + r);
     println( "G:" + g);
     println( "B:" + b);
     println( "C:" + c);

  }
}