Подключение датчика цвета TCS230/TCS3200 к Arduino

Подключение датчика цвета TCS230/TCS3200 к Arduino

Датчики цвета предоставляют более надёжные решения для сложных задач автоматизации. Они используются в различных отраслях, включая пищевую, автомобильную и производственную промышленность, для таких целей, как обнаружение материалов, определение цветных меток на деталях, проверка этапов производственного процесса и так далее.

В то время как дорогие датчики цвета используются в промышленных приложениях, недорогие датчики, такие как TCS230, можно использовать для менее требовательных задач.

Датчик цвета TCS230 (также выпускаемый под маркой TCS3200) довольно популярен, недорог и прост в использовании. Прежде чем использовать этот датчик цвета в нашем проекте на Arduino, давайте разберёмся, как вообще работает датчик цвета.

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

Белый свет состоит из трёх основных цветов (красного, зелёного и синего), которые имеют различные длины волн. Эти цвета комбинируются друг с другом, образуя различные оттенки.

Когда белый свет падает на любую поверхность, некоторые длины волн поглощаются, а некоторые отражаются, в зависимости от свойств материала поверхности. Цвет, который мы видим, является результатом того, какие длины волн отражаются обратно в наши глаза.

Подключение датчика цвета TCS230/TCS3200 к Arduino

Теперь вернёмся к датчику. Типичный датчик цвета содержит яркий белый светодиод, который проецирует модулированный свет на объект. Для определения цвета отражённого света почти все датчики цвета состоят из сетки цветочувствительных фильтров, также известных как «фильтр Байера», и массива фотодиодов под ними, как показано на рисунке ниже.

Подключение датчика цвета TCS230/TCS3200 к Arduino

Один пиксель состоит из 4 фильтров: одного красного, одного синего, одного зелёного и одного прозрачного (без фильтра). Этот шаблон также известен как «шаблон Байера». Каждый фильтр пропускает свет только одного цвета к фотодиоду под ним, а прозрачный фильтр пропускает свет как есть, как показано ниже. Этот дополнительный свет, проходящий через прозрачный фильтр, является большим преимуществом в условиях низкой освещённости.

Подключение датчика цвета TCS230/TCS3200 к Arduino

Обрабатывающий чип затем обращается к каждому фотодиоду (по одному цвету за раз) и измеряет интенсивность света. Поскольку существует массив фотодиодов, результаты сначала усредняются, а затем отправляются на обработку. Путём измерения относительного уровня красного, зелёного и синего света определяется цвет объекта.

Модуль датчика цвета TCS230

В основе модуля лежит недорогой RGB-сенсорный чип от Texas Advanced Optoelectronic Solutions — TCS230. Датчик цвета TCS230 представляет собой полноценный детектор цвета, способный обнаруживать и измерять практически бесконечный диапазон видимых цветов.

Подключение датчика цвета TCS230/TCS3200 к Arduino

Сам датчик расположен в центре модуля и окружён четырьмя белыми светодиодами. Светодиоды загораются при подаче питания на модуль и используются для освещения объекта. Благодаря этим светодиодам датчик может работать даже в полной темноте для определения цвета или яркости объекта.

TCS230 работает от напряжения питания от 2.7 до 5.5 вольт и обеспечивает выходные сигналы TTL-уровня.

Принцип работы TCS230

TCS230 определяет цвет с помощью массива из 8 x 8 фотодиодов, из которых 16 фотодиодов имеют красные фильтры, 16 — зелёные, 16 — синие, а оставшиеся 16 — прозрачные (без фильтров).

Если вы внимательно посмотрите на датчик, то сможете увидеть эти фильтры.

Подключение датчика цвета TCS230/TCS3200 к Arduino

Каждые 16 фотодиодов соединены параллельно, поэтому с помощью двух управляющих выводов S2 и S3 вы можете выбрать, какие из них считывать. Например, если вы хотите определить только красный цвет, вы можете выбрать 16 фотодиодов с красными фильтрами, установив оба вывода в LOW, согласно таблице.

Аналогично, вы можете выбрать различные типы фотодиодов с помощью различных комбинаций S2 и S3.

S2

S3

Тип фотодиода

LOW

LOW

Красный

LOW

HIGH

Синий

HIGH

LOW

Прозрачный (без фильтра)

HIGH

HIGH

Зелёный

Встроенный преобразователь тока в частоту преобразует показания фотодиодов в прямоугольный сигнал, частота которого пропорциональна интенсивности выбранного цвета. Диапазон типичной выходной частоты составляет 2Гц~500КГц.

У датчика есть ещё два управляющих вывода, S0 и S1, которые используются для масштабирования выходной частоты. Частота может быть масштабирована до трёх различных предустановленных значений: 2%, 20% или 100%. Эта функция масштабирования частоты позволяет использовать датчик с различными микроконтроллерами и другими устройствами.

S0

S1

Масштабирование выходной частоты

LOW

LOW

Выключение

LOW

HIGH

2%

HIGH

LOW

20%

HIGH

HIGH

100%

Вы можете получить различные коэффициенты масштабирования различными комбинациями S0 и S1. Для Arduino в большинстве приложений используется масштабирование 20%.

Распиновка модуля датчика цвета TCS230

На следующей схеме показана распиновка типичного модуля TCS230.

Подключение датчика цвета TCS230/TCS3200 к Arduino

GND — вывод заземления.

OE — вывод разрешения выхода (Output Enable). Этот вывод используется редко, и на большинстве модулей он постоянно включён. Если он не включён, подтяните его к LOW.

S0 и S1 — выводы для выбора масштабирования частоты.

S2 и S3 — выводы для выбора массива цветных фильтров.

OUT — прямоугольный сигнал TTL-уровня.

VCC — вывод питания модуля. Подключите его к источнику питания от 2.7В до 5.5В.

Подключение датчика цвета TCS230 к Arduino UNO

Подключить TCS230 к Arduino очень просто. Используются все выводы, кроме вывода разрешения выхода (OE), а модуль безопасно питается от 5-вольтового выхода Arduino.

Ниже приведена схема подключения для экспериментов с TCS230:

Подключение датчика цвета TCS230/TCS3200 к Arduino

Ни один из используемых пинов Arduino не является критически важным, поскольку модуль не требует каких-либо специфических функций пинов, поэтому при желании вы можете использовать другие пины. Просто не забудьте изменить номера пинов в коде, если вы измените схему подключения.

После подключения датчика к Arduino пора писать код!

Калибровка датчика

На самом деле мы будем использовать два скетча для работы с датчиком цвета TCS230.

  1. Первый скетч (калибровочный) поможет нам получить необработанные данные с датчика.

  2. Второй скетч (основной скетч Arduino) будет использовать ранее полученные данные для отображения значений RGB для определяемого цвета.

Обратите внимание, что оба скетча используют одну и ту же схему подключения.

Ниже приведён калибровочный скетч. Этот скетч обращается к датчику TCS230 по одному цвету за раз и считывает длительность импульса на выходном выводе. Результат затем отображается в мониторе последовательного порта.

Загрузите скетч в Arduino и установите датчик так, чтобы он был направлен на объекты. Начните с поиска эталонных объектов белого и чёрного цвета. Эти эталонные объекты дадут показания при максимальных и минимальных значениях для всех трёх цветов.

// Define color sensor pins
#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define sensorOut 8

// Variables for Color Pulse Width Measurements
int redPW = 0;
int greenPW = 0;
int bluePW = 0;

void setup() {
     // Set S0 - S3 as outputs
     pinMode(S0, OUTPUT);
     pinMode(S1, OUTPUT);
     pinMode(S2, OUTPUT);
     pinMode(S3, OUTPUT);

     // Set Pulse Width scaling to 20%
     digitalWrite(S0,HIGH);
     digitalWrite(S1,LOW);

     // Set Sensor output as input
     pinMode(sensorOut, INPUT);

     // Setup Serial Monitor
     Serial.begin(9600);
}

void loop() {
     // Read Red Pulse Width
     redPW = getRedPW();
     // Delay to stabilize sensor
     delay(200);

     // Read Green Pulse Width
     greenPW = getGreenPW();
     // Delay to stabilize sensor
     delay(200);

     // Read Blue Pulse Width
     bluePW = getBluePW();
     // Delay to stabilize sensor
     delay(200);

     // Print output to Serial Monitor
     Serial.print("Red PW = ");
     Serial.print(redPW);
     Serial.print(" - Green PW = ");
     Serial.print(greenPW);
     Serial.print(" - Blue PW = ");
     Serial.println(bluePW);
}


// Function to read Red Pulse Widths
int getRedPW() {
     // Set sensor to read Red only
     digitalWrite(S2,LOW);
     digitalWrite(S3,LOW);
     // Define integer to represent Pulse Width
     int PW;
     // Read the output Pulse Width
     PW = pulseIn(sensorOut, LOW);
     // Return the value
     return PW;
}

// Function to read Green Pulse Widths
int getGreenPW() {
     // Set sensor to read Green only
     digitalWrite(S2,HIGH);
     digitalWrite(S3,HIGH);
     // Define integer to represent Pulse Width
     int PW;
     // Read the output Pulse Width
     PW = pulseIn(sensorOut, LOW);
     // Return the value
     return PW;
}

// Function to read Blue Pulse Widths
int getBluePW() {
     // Set sensor to read Blue only
     digitalWrite(S2,LOW);
     digitalWrite(S3,HIGH);
     // Define integer to represent Pulse Width
     int PW;
     // Read the output Pulse Width
     PW = pulseIn(sensorOut, LOW);
     // Return the value
     return PW;
}

После загрузки скетча вы получите подобные показания. Запишите показания, полученные при обоих крайних значениях.

Подключение датчика цвета TCS230/TCS3200 к Arduino

Объяснение кода:

Скетч начинается с определения выводов, используемых для подключения TCS230. Также определяются переменные для хранения длительности импульсов красного, зелёного и синего массивов фильтров.

#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define sensorOut 8

int redPW = 0;
int greenPW = 0;
int bluePW = 0;

В функции setup мы определяем выводы S0-S3 как выходы. Эти выводы будут использоваться для выбора масштабирования частоты и цвета, который мы хотим считать. Выводы S0 и S1 используются для установки масштабирования частоты на 20%, что является стандартным значением при использовании этого датчика цвета с Arduino. Далее выходной вывод датчика определяется как вход Arduino — именно здесь мы будем получать прямоугольный сигнал. Наконец, мы настраиваем монитор последовательного порта.

void setup() {
     // Set S0 - S3 as outputs
     pinMode(S0, OUTPUT);
     pinMode(S1, OUTPUT);
     pinMode(S2, OUTPUT);
     pinMode(S3, OUTPUT);

     // Set Pulse Width scaling to 20%
     digitalWrite(S0,HIGH);
     digitalWrite(S1,LOW);

     // Set Sensor output as input
     pinMode(sensorOut, INPUT);

     // Setup Serial Monitor
     Serial.begin(9600);
}

В секции loop мы вызываем три функции getRedPW(), getGreenPW() и getBluePW() для получения длительности импульса. Рассмотрим getRedPW() в качестве примера.

Функция getRedPW() получает длительность импульса красного цвета. Она начинает с установки выводов S2 и S3 для выбора красного фильтра. Это единственный шаг, в котором эта функция отличается от аналогичных функций для зелёного и синего цветов.

Затем определяется целочисленная переменная для хранения длительности импульса. Длительность импульса определяется с помощью функции Arduino pulseIn(). Эта функция измеряет длительность импульса — обратите внимание, что мы настроили её на измерение длительности LOW-части импульса. Результат — время в миллисекундах. Это значение затем возвращается, и функция завершается.

int getRedPW() {
     // Set sensor to read Red only
     digitalWrite(S2,LOW);
     digitalWrite(S3,LOW);
     // Define integer to represent Pulse Width
     int PW;
     // Read the output Pulse Width
     PW = pulseIn(sensorOut, LOW);
     // Return the value
     return PW;
}

Возвращаясь к основному циклу, мы вызываем три функции для считывания длительности цветовых импульсов с задержкой 200мс между ними для стабилизации датчика. Затем мы выводим значения в монитор последовательного порта и повторяем цикл.

void loop() {
     // Read Red Pulse Width
     redPW = getRedPW();
     // Delay to stabilize sensor
     delay(200);

     // Read Green Pulse Width
     greenPW = getGreenPW();
     // Delay to stabilize sensor
     delay(200);

     // Read Blue Pulse Width
     bluePW = getBluePW();
     // Delay to stabilize sensor
     delay(200);

     // Print output to Serial Monitor
     Serial.print("Red PW = ");
     Serial.print(redPW);
     Serial.print(" - Green PW = ");
     Serial.print(greenPW);
     Serial.print(" - Blue PW = ");
     Serial.println(bluePW);
}

Код Arduino — чтение значений RGB с TCS230

После получения показаний вы можете загрузить следующий скетч, в котором мы будем считывать значения RGB с датчика цвета TCS230.

Перед загрузкой скетча введите шесть калибровочных значений, полученных из калибровочного скетча, в начало скетча. Замените «0» на ваши реальные значения.

// Define color sensor pins
#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define sensorOut 8

// Calibration Values
// *Get these from Calibration Sketch
int redMin = 0; // Red minimum value
int redMax = 0; // Red maximum value
int greenMin = 0; // Green minimum value
int greenMax = 0; // Green maximum value
int blueMin = 0; // Blue minimum value
int blueMax = 0; // Blue maximum value

// Variables for Color Pulse Width Measurements
int redPW = 0;
int greenPW = 0;
int bluePW = 0;

// Variables for final Color values
int redValue;
int greenValue;
int blueValue;

void setup() {
     // Set S0 - S3 as outputs
     pinMode(S0, OUTPUT);
     pinMode(S1, OUTPUT);
     pinMode(S2, OUTPUT);
     pinMode(S3, OUTPUT);

     // Set Sensor output as input
     pinMode(sensorOut, INPUT);

     // Set Frequency scaling to 20%
     digitalWrite(S0,HIGH);
     digitalWrite(S1,LOW);

     // Setup Serial Monitor
     Serial.begin(9600);
}

void loop() {
     // Read Red value
     redPW = getRedPW();
     // Map to value from 0-255
     redValue = map(redPW, redMin,redMax,255,0);
     // Delay to stabilize sensor
     delay(200);

     // Read Green value
     greenPW = getGreenPW();
     // Map to value from 0-255
     greenValue = map(greenPW, greenMin,greenMax,255,0);
     // Delay to stabilize sensor
     delay(200);

     // Read Blue value
     bluePW = getBluePW();
     // Map to value from 0-255
     blueValue = map(bluePW, blueMin,blueMax,255,0);
     // Delay to stabilize sensor
     delay(200);

     // Print output to Serial Monitor
     Serial.print("Red = ");
     Serial.print(redValue);
     Serial.print(" - Green = ");
     Serial.print(greenValue);
     Serial.print(" - Blue = ");
     Serial.println(blueValue);
}


// Function to read Red Pulse Widths
int getRedPW() {
     // Set sensor to read Red only
     digitalWrite(S2,LOW);
     digitalWrite(S3,LOW);
     // Define integer to represent Pulse Width
     int PW;
     // Read the output Pulse Width
     PW = pulseIn(sensorOut, LOW);
     // Return the value
     return PW;
}

// Function to read Green Pulse Widths
int getGreenPW() {
     // Set sensor to read Green only
     digitalWrite(S2,HIGH);
     digitalWrite(S3,HIGH);
     // Define integer to represent Pulse Width
     int PW;
     // Read the output Pulse Width
     PW = pulseIn(sensorOut, LOW);
     // Return the value
     return PW;
}

// Function to read Blue Pulse Widths
int getBluePW() {
     // Set sensor to read Blue only
     digitalWrite(S2,LOW);
     digitalWrite(S3,HIGH);
     // Define integer to represent Pulse Width
     int PW;
     // Read the output Pulse Width
     PW = pulseIn(sensorOut, LOW);
     // Return the value
     return PW;
}

Загрузите скетч и наблюдайте за результатами с образцами различных цветов. При необходимости вы можете внести небольшие корректировки в калибровочные значения.

Объяснение кода

Вы заметите, что большая часть этого скетча полностью совпадает с предыдущим, за исключением следующего:

Шесть калибровочных значений, полученных из калибровочного скетча, вводятся в начале скетча.

// Calibration Values
int redMin = 0; // Red minimum value
int redMax = 0; // Red maximum value
int greenMin = 0; // Green minimum value
int greenMax = 0; // Green maximum value
int blueMin = 0; // Blue minimum value
int blueMax = 0; // Blue maximum value

Определяются три новые переменные для значений RGB, которые мы хотим выводить.

int redValue;
int greenValue;
int blueValue;

В секции loop мы считываем каждое из значений с помощью той же функции, что и в предыдущем скетче. Затем мы используем функцию Arduino map() для преобразования этих значений в значения RGB, используя наши калибровочные значения в качестве ориентира.

Обратите внимание, что мы инвертировали диапазон (минимальное значение маппится на 255, а максимальное — на 0), потому что наши функции возвращают длительность импульса, а не частоту.

// Read Red value
redPW = getRedPW();
// Map to value from 0-255
redValue = map(redPW, redMin,redMax,255,0);
// Delay to stabilize sensor
delay(200);

Наконец, мы выводим значения в монитор последовательного порта. Эти итоговые показания будут соответствовать значениям RGB сканируемого объекта.