CraftDuino v2.0
  • - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!

Датчик цвета из RGB-светодиода и фотоэлемента - реальная фотошоповская пипетка

Датчик цвета из RGB-светодиода и фотоэлемента
Про самодельный датчик цвета мы уже писали, так что идея использовать RGB-светодиода (или нескольких цветных светодиодов) для поочерёдного освещения объекта и считывания на фоторезисторе напряжения с последующим выбором наилучшего отклика — не нова.
Однако, попытка сделать реальную «фотошоповскую пипетку» (Eyedropper) продолжает ждать своего воплощения :)

real world eyedropper: color sensing for the arduino


код для Arduino:
// Define colour sensor LED pins
int ledArray[] = {2,3,4};

// boolean to know if the balance has been set
boolean balanceSet = false;

//place holders for colour detected
int red = 0;
int green = 0;
int blue = 0;

//floats to hold colour arrays
float colourArray[] = {0,0,0};
float whiteArray[] = {0,0,0};
float blackArray[] = {0,0,0};


//place holder for average
int avgRead;

void setup(){
 
  //setup the outputs for the colour sensor
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
 
  //begin serial communication
  Serial.begin(9600);
 
}

void loop(){

    checkBalance();
    checkColour();
    printColour();
    }

void checkBalance(){
  //check if the balance has been set, if not, set it
  if(balanceSet == false){
    setBalance();
  }
}

void setBalance(){
  //set white balance
   delay(5000);                              //delay for five seconds, this gives us time to get a white sample in front of our sensor
  //scan the white sample.
  //go through each light, get a reading, set the base reading for each colour red, green, and blue to the white array
  for(int i = 0;i<=2;i++){
     digitalWrite(ledArray[i],HIGH);
     delay(100);
     getReading(5);          //number is the number of scans to take for average, this whole function is redundant, one reading works just as well.
     whiteArray[i] = avgRead;
     digitalWrite(ledArray[i],LOW);
     delay(100);
  }
  //done scanning white, now it will pulse blue to tell you that it is time for the black (or grey) sample.
   //set black balance
    delay(5000);              //wait for five seconds so we can position our black sample 
  //go ahead and scan, sets the colour values for red, green, and blue when exposed to black
  for(int i = 0;i<=2;i++){
     digitalWrite(ledArray[i],HIGH);
     delay(100);
     getReading(5);
     blackArray[i] = avgRead;
     //blackArray[i] = analogRead(2);
     digitalWrite(ledArray[i],LOW);
     delay(100);
  }
   //set boolean value so we know that balance is set
  balanceSet = true;
  //delay another 5 seconds to allow the human to catch up to what is going on
  delay(5000);
  }

void checkColour(){
    for(int i = 0;i<=2;i++){
     digitalWrite(ledArray[i],HIGH);  //turn or the LED, red, green or blue depending which iteration
     delay(100);                      //delay to allow CdS to stabalize, they are slow
     getReading(5);                  //take a reading however many times
     colourArray[i] = avgRead;        //set the current colour in the array to the average reading
     float greyDiff = whiteArray[i] - blackArray[i];                    //the highest possible return minus the lowest returns the area for values in between
     colourArray[i] = (colourArray[i] - blackArray[i])/(greyDiff)*255; //the reading returned minus the lowest value divided by the possible range multiplied by 255 will give us a value roughly between 0-255 representing the value for the current reflectivity(for the colour it is exposed to) of what is being scanned
     digitalWrite(ledArray[i],LOW);   //turn off the current LED
     delay(100);
  }
}
void getReading(int times){
  int reading;
  int tally=0;
  //take the reading however many times was requested and add them up
for(int i = 0;i < times;i++){
   reading = analogRead(0);
   tally = reading + tally;
   delay(10);
}
//calculate the average and set it
avgRead = (tally)/times;
}

//prints the colour in the colour array, in the next step, we will send this to processing to see how good the sensor works.
void printColour(){
Serial.print("R = ");
Serial.println(int(colourArray[0]));
Serial.print("G = ");
Serial.println(int(colourArray[1]));
Serial.print("B = ");
Serial.println(int(colourArray[2]));
//delay(2000);
}


код Processing-а для визуализации:

import processing.serial.*;
import java.awt.datatransfer.*;
import java.awt.Toolkit;

String buff = "";
int val = 0;
int wRed, wGreen, wBlue;
String col = "ffffff";
ClipHelper cp = new ClipHelper();

Serial port;

void setup(){

size(200,200);
 port = new Serial(this, "COM3", 9600); //remember to replace COM20 with the appropriate serial port on your computer
}

void draw(){
 background(wRed,wGreen,wBlue);
 // check for serial, and process
 while (port.available() > 0) {
 serialEvent(port.read());
 }
}

void keyPressed() { cp.copyString(""+col); }
void serialEvent(int serial) {

if(serial != '\n') {
 buff += char(serial);
 }
 else {
 int cRed = buff.indexOf("R");
 int cGreen = buff.indexOf("G");
 int cBlue = buff.indexOf("B");

if(cRed >=0){
 String val = buff.substring(cRed+3);
 wRed = Integer.parseInt(val.trim());
 }
 if(cGreen >=0){
 String val = buff.substring(cGreen+3);
 wGreen = Integer.parseInt(val.trim());
 }
 if(cBlue >=0){
 String val = buff.substring(cBlue+3);
 wBlue = Integer.parseInt(val.trim());
 }
 col = hex(color(wRed, wGreen, wBlue), 6);
 buff = "";
 }

}

// CLIPHELPER OBJECT CLASS:

class ClipHelper {
 Clipboard clipboard;

 ClipHelper() {
 getClipboard();
 }

 void getClipboard () {
 // this is our simple thread that grabs the clipboard
 Thread clipThread = new Thread() {
 public void run() {
 clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
 }
 };

 // start the thread as a daemon thread and wait for it to die
 if (clipboard == null) {
 try {
 clipThread.setDaemon(true);
 clipThread.start();
 clipThread.join();
 }
 catch (Exception e) {}
 }
 }

 void copyString (String data) {
 copyTransferableObject(new StringSelection(data));
 }

 void copyTransferableObject (Transferable contents) {
 getClipboard();
 clipboard.setContents(contents, null);
 }

 String pasteString () {
 String data = null;
 try {
 data = (String)pasteObject(DataFlavor.stringFlavor);
 }
 catch (Exception e) {
 System.err.println("Error getting String from clipboard: " + e);
 }
 return data;
 }

 Object pasteObject (DataFlavor flavor)
 throws UnsupportedFlavorException, IOException
 {
 Object obj = null;
 getClipboard();

 Transferable content = clipboard.getContents(null);
 if (content != null)
 obj = content.getTransferData(flavor);

 return obj;
 }
}


остаётся реализовать это в виде плагина для фотошопа или GIMP-а ;)

Ссылки
Using an RGB LED to Detect Colours
Beginner project: Color Sensing with RGB LEDs and a photocell

По теме
Самодельный датчик цвета
Processing и Arduino
  • +1
  • 6 ноября 2012, 05:40
  • admin

Комментарии (4)

RSS свернуть / развернуть
+
+1
Интересна точность получаемого цвета. И можно ли использовать его в качестве фотоспектрометра для подбора краски, к примеру, в автопокрасочных?
avatar

newstoic

  • 6 ноября 2012, 13:54
+
0
думаю, для этого лучше использовать web-камеру :)
avatar

admin

  • 6 ноября 2012, 18:46
+
+1
Ни в коем случае. Обычные светодиоды не дают нормальных RGB-цветов — можно собрать несложное устройство и сравнить получаемый цвет с его изображением на экране.

Если уж так хочется сделать спектрофотометр своими руками, необходимо использовать датчик из любого недорогого калибратора цвета — цена примерно 3500-5000р (дорогие начинаются от 12-15) и эталонный источник освещения. А описанный девайс сможет только различать принципиально разные цвета, без мельчайших оттенков.
avatar

simon_ru

  • 6 ноября 2012, 20:28
+
0
Может быть датчик можно сделать точнее, если использовать белый светодиод (или лучше какой-либо другой источник с более белым светом) и 3 фоторезистора\транзистора\диода с R,G и B фильтрами соответственно?
avatar

MAFia

  • 29 декабря 2012, 12:03

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.