Ардуино: датчик цвета

В одном из предыдущих уроков — Ардуино: трехцветный светодиод — RGB — мы разобрали, что такое RGB и научились работать с трёхцветным светодиодом. В этом уроке мы разберёмся, как работать с датчиком цвета, научим нашу Ардуино распознавать красный, синий и зелёный и выведем полученные данные при помощи RGB-светодиода!

Как работает датчик цвета

Датчик TCS230, расположенный в центре платы, состоит из фотодиодов четырёх типов: 16 фотодиодов с красным фильтром, 16 фотодиодов с зелёным фильтром, 16 фотодиодов с синим фильтром и 16 фотодиодов без светофильтра . К датчику подносят образец одного из трёх цветов — красного, зелёного или синего. Образец освещается светодиодами на плате вокруг датчика. Датчик имеет преобразователь тока в частоту, он преобразует показания фотодиодов в квадратную волну с частотой, пропорциональной интенсивности света выбранного цвета. Эта частота затем считывается Arduino.

Распиновка на плате с датчиком TCS230 имеет следующее значение:

  • GND – земля;
  • OE – контакт включения;
  • S1, S0 – настройка масштабирования частоты импульсов.
  • S3, S2 – входной сигнал настройки фильтра;
  • OUT – выходная частота;
  • VCC – напряжение питания.

Для определения цвета, который будет считываться фотодиодами, датчик TCS230 оснащен контактами S2 и S3. Поскольку фотодиоды подключены параллельно, разные типы фотодиодов можно выбирать, переключая контакты S2 и S3 в разные комбинации состояний HIGH и LOW.  Правила выбора этих комбинаций для нужных нам цветов следующие:

Тип фотодиода S2 S3
Красный LOW LOW
Синий LOW HIGH
Без фильтра (чистый) HIGH LOW
Зеленый HIGH HIGH

Контакты S0 и S1 используются для масштабирования выходной частоты. Ее можно масштабировать до трех заранее заданных значений: 100%, 20% и 2%. Масштабирование частоты используется для разных микроконтроллеров, чтобы оптимизировать данные, считанные датчиком.

Масштабирование частоты S0 S1
Отключение LOW LOW
2% LOW HIGH
20% HIGH LOW
100% HIGH HIGH

Для Ардуино мы будем использовать масштабирование 20%.

Подключение датчика к Ардуино

Для визуального отображения определяемого цвета мы воспользуемся RGB-светодиодом. Схема должна работать следующим образом: к датчику подносят образец выбранного цвета и на светодиоде загорается тот же цвет.

TCS230 GND VCC OUT S0 S1 S2 S3
Arduino Uno GND +5V 8 4 5 6 7

Принципиальная схема:

Внешний вид макета:

Программа:

// контакты TCS230 для подключения к Arduino
#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define sensorOut 8
     
// для хранения частоты, считанной фотодиодами
int redFrequency = 0;
int greenFrequency = 0;
int blueFrequency = 0;
     
// для хранения данных о красном, зеленом и синем цветах
int redColor = 0;
int greenColor = 0;
int blueColor = 0;

// подключение к контактам rgb-светодиода
const byte rPin = 9;
const byte gPin = 10;
const byte bPin = 11;
     
void setup() {
      pinMode(S0, OUTPUT);
      pinMode(S1, OUTPUT);
      pinMode(S2, OUTPUT);
      pinMode(S3, OUTPUT);
      pinMode(rPin, OUTPUT);
      pinMode(gPin, OUTPUT);
      pinMode(bPin, OUTPUT);
     
      pinMode(sensorOut, INPUT);
     
      digitalWrite(S0,HIGH);
      digitalWrite(S1,LOW);
     
      Serial.begin(9600);
}
     
void loop() {
      // считывание данных с фотодиодов с красным фильтром
      digitalWrite(S2,LOW);
      digitalWrite(S3,LOW);
     
      redFrequency = pulseIn(sensorOut, LOW);   // считываем выходную частоту
      redColor = map(redFrequency, 70, 120, 255,0);
     
      Serial.print("R = ");
      Serial.print(redColor);
      delay(100);
     
      // считывание данных с фотодиодов с зеленым фильтром
      digitalWrite(S2,HIGH);
      digitalWrite(S3,HIGH);
    
      greenFrequency = pulseIn(sensorOut, LOW); // считываем выходную частоту
      greenColor = map(greenFrequency, 100, 199, 255, 0);
     
      Serial.print(" G = ");
      Serial.print(greenColor);
      delay(100);
     
      // считывание данных с фотодиодов с синим фильтром
      digitalWrite(S2,LOW);
      digitalWrite(S3,HIGH);
     
      blueFrequency = pulseIn(sensorOut, LOW);  // считываем выходную частоту
      blueColor = map(blueFrequency, 38, 84, 255, 0);
     
      Serial.print(" B = ");
      Serial.print(blueColor);
      delay(100);
     
      // вывод на светодиод распознанный цвет
      // вывод в монитор порта сообщение, какой цвет распознан
      if(redColor > greenColor && redColor > blueColor){
          digitalWrite( bPin, LOW );
          digitalWrite( gPin, LOW );
          digitalWrite( rPin, HIGH );
          Serial.println(" - RED detected!"); 
      }
      if(greenColor > redColor && greenColor > blueColor){
        digitalWrite( rPin, LOW );
        digitalWrite( bPin, LOW );
        digitalWrite( gPin, HIGH );
        Serial.println(" - GREEN detected!");  
      }
      if(blueColor > redColor && blueColor > greenColor){
        digitalWrite( gPin, LOW );
        digitalWrite( rPin, LOW );
        digitalWrite( bPin, HIGH );
        Serial.println(" - BLUE detected!"); 
      }
}

Когда мы запустим программу и откроем монитор порта на скорости 9600 бод, то при поднесении к датчику образца мы увидим значения для каждого из трёх цветов и сообщение о том, какой цвет выбран. Следует заметить, что в случае, если сообщение о цвете не соответствует реальному цвету, то необходимо подредактировать значения частот в программе, подстраивая их по значениям R, G и B в мониторе порта:

redColor = map(redFrequency, 70, 120, 255,0);
greenColor = map(greenFrequency, 100, 199, 255, 0);
blueColor = map(blueFrequency, 38, 84, 255, 0);

Демонстрация работы датчика

Внешний вид нашего макета:

Определение цветов в действии:

1+

Изменено: