+7-960-0655211 (Билайн)
+7-987-4207734 (МТС)

интернет-магазин
доставка по России и СНГ
работаем с 2010 года

Цветовая сортировка на Arduino с использованием датчика TCS3200

Цветовая сортировка на Arduino с использованием датчика TCS3200


  


01.jpg

Сортировку вещей по цвету легко сделать, но когда вещей для сортировки слишком много и это повторяющаяся задача, тогда автоматические сортировщики очень полезны. У этих устройств есть датчик цвета, чтобы определять цвет любых объектов и после определения цвета вещь помещается в соответствующую ёмкость.
Наиболее популярным датчиком для определения цвета является датчик цвета TCS3200. В этом проекте мы сделаем устройство сортировки с использованием датчика TCS3200, серводвигателей и платы Arduino.

Необходимые компоненты

  • Arduino UNO
  • Датчик цвета TCS3200
  • Сервоприводы
  • Соединительные провода
  • Макетная плата

Создание корпуса сортировщика

Для изготовления корпуса использованы листы Sunboard (вспененный ПВХ) толщиной 2 мм, канцелярский нож для резки и FlexKwik/FeviKwik для склейки деталей. 

Ниже приведены некоторые шаги создания корпуса сортировщика:

1) Берём листы.
02.jpg
2) Размечаем маркером и разрезаем.
03.jpg
04.jpg
05.jpg
3) Наносим FeviKwik и склеиваем части.
06.png
4) После соединения всех частей сортировочная машина будет выглядеть примерно так:
07.jpg

Модуль датчика TCS3200

08.jpg

TCS3200 это программируемый преобразователь "свет в частоту", который объединяет фотодиоды и преобразователь тока в частоту на одной монолитной интегральной схеме CMOS. На выходе датчика прямоугольная волна (коэффициент заполнения 50%) с частотой, прямо пропорциональной интенсивности света (освещенности). Масштабирование частоты на выходе задаётся (выключено, 2%, 20% и 100%) через два управляющих контакта. Датчик состоит из 8*8 массива фотодиодов: 16 с красными фильтрами, 16 с зелёными, 16 с синими и 16 без фильтра. Выводы S2 и S3 датчика используются для выбора, какая группа фотодиодов (красный, зелёный, синий и без фильтра) активна.

09.jpg
09_1.png
09_2.png

Схема подключения

10.png

  Сортировщик с обратной стороны

11.jpg

Программирование

Код для сортировки цветных фишек довольно простой, полный код программы будет в конце. Поскольку используется сервоприводы, библиотека сервоприводов является неотъемлемой частью программы. Здесь мы используем два сервопривода. Первый перемещает цветные фишки из исходной позиции к датчику TCS3200, затем в позицию, из которой фишка скатывается в соответствующую ёмкость. После перемещения фишки к датчику и определения её цвета, второй сервопривод перемещает "горку" к соответствующей ёмкости.
Первым шагом будет включение всех библиотек и определение переменных для сервоприводов.


#include <Servo.h>
Servo pickServo;
Servo dropServo;

Датчик TCS3200 может работать без библиотеки, так как для определения цвета требуется только считывание частоты с вывода датчика. Так что просто зададим номера выводов.

#define S0 4
#define S1 5
#define S2 7
#define S3 6
#define sensorOut 8
int frequency = 0;
int color = 0;

Настраиваем вывод sensorOut как вход, S0-S4 как выходные и устанавливаем им нужный уровень что бы задать датчику масштабирование 20%.

pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
pinMode(sensorOut, INPUT);
digitalWrite(S0, LOW);
digitalWrite(S1, HIGH);

Сервоприводы подключены к выводам 9 и 10. Первый сервопривод (pickServo) подключен к выводу 9, второй (dropServo) к выводу 10.

pickServo.attach (9);
dropServo.attach (10);

Первоначально pickServo установлен в исходное положение, которое в данном случае составляет 115 градусов. Сервопривод с небольшой задержкой перемещает фишку к датчику для определения цвета.

pickServo.write(115);
delay(600);
for (int i = 115; i > 65; i--) {
  pickServo.write(i);
  delay(2);
}
delay(500);

Вызываем функцию определения цвета.

color = detectColor();
delay(1000);

В зависимости от цвета, сервопривод dropServo перемещается "горку" к ёмкости для соответствующего цвета.

switch (color) {
  case 1:
    dropServo.write(50);
  break;
  case 2:
    dropServo.write(80);
  break;
  case 3:
    dropServo.write(110);
  break;
  case 4:
    dropServo.write(140);
  break;
  case 5:
    dropServo.write(170);
  break;
  case 0:
  break;
}
delay(500);

Сервопривод pickServo возвращается в исходное положение.

for(int i = 65; i > 29; i--) {
  pickServo.write(i);
  delay(2);
}
delay(300);
for(int i = 29; i < 115; i++) {
  pickServo.write(i);
  delay(2);
}

Функция detectColor() используется для измерения частоты и сравнения цветовой частоты, чтобы сделать вывод о цвете. Результат выводится в последовательный порт, после чего функция возвращает код цвета.

int detectColor() {

Установкой S2 и S3 (низкий, низкий) активируем красные фотодиоды, чтобы получить данные для красного цвета.

digitalWrite(S2, LOW);
digitalWrite(S3, LOW);
frequency = pulseIn(sensorOut, LOW);
int R = frequency;
Serial.print("Red = ");
Serial.print(frequency);//printing RED color frequency
Serial.print("   ");
delay(50);

Установкой S2 и S3 (низкий, высокий) активируем синие фотодиоды, чтобы получить данные для синего цвета.

digitalWrite(S2, LOW);
digitalWrite(S3, HIGH);
frequency = pulseIn(sensorOut, LOW);
int B = frequency;
Serial.print("Blue = ");
Serial.print(frequency);
Serial.println("   ");

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

digitalWrite(S2, HIGH);
digitalWrite(S3, HIGH);
// Reading the output frequency
frequency = pulseIn(sensorOut, LOW);
int G = frequency;
Serial.print("Green = ");
Serial.print(frequency);
Serial.print("   ");
delay(50);

Затем значения сравниваются, чтобы принять решение о коде цвета.

  if (R<22 & R>20 & G<29 & G>27) {
    color = 1; // Red
    Serial.print("Detected Color is = ");
    Serial.println("RED");
  }
  if (G<25 & G>22 & B<22 & B>19) {
    color = 2; // Orange
    Serial.println("Orange  ");
  }
  if (R<21 & R>20 & G<28 & G>25) {
    color = 3; // Green
    Serial.print("Detected Color is = ");
    Serial.println("GREEN");
  }
  if (R<38 & R>24 & G<44 & G>30) {
    color = 4; // Yellow
    Serial.print("Detected Color is = ");
    Serial.println("YELLOW");
  }
  if (G<29 & G>27 & B<22 & B>19) {
    color = 5; // Blue
    Serial.print("Detected Color is = ");
    Serial.println("BLUE");
  }
  return color;
}

Числа нужно подбирать экспериментально, т.к. они зависят от цвета фишек и расстояния от датчика до фишки.

Полный код программы


#include <Servo.h>
Servo pickServo;
Servo dropServo;

#define S0 4
#define S1 5
#define S2 7
#define S3 6
#define sensorOut 8
int frequency = 0;
int color = 0;

int detectColor() {
  // activating red photodiodes to read
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  frequency = pulseIn(sensorOut, LOW);
  int R = frequency;
  Serial.print("Red = ");
  Serial.print(frequency);//printing RED color frequency
  Serial.print("   ");
  delay(50);

  // activating blue photodiodes to read
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  frequency = pulseIn(sensorOut, LOW);
  int B = frequency;
  Serial.print("Blue = ");
  Serial.print(frequency);
  Serial.println("   ");

  // activating green photodiodes to read
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  int G = frequency;
  Serial.print("Green = ");
  Serial.print(frequency);
  Serial.print("   ");
  delay(50);

  delay(50);

  //Readings are different for different setup
  //change the readings according your project and readings detected
  if (R<22 & R>20 & G<29 & G>27) {
    color = 1; // Red
    Serial.print("Detected Color is = ");
    Serial.println("RED");
  }
  if (G<25 & G>22 & B<22 & B>19) {
    color = 2; // Orange
    Serial.println("Orange  ");
  }
  if (R<21 & R>20 & G<28 & G>25) {
    color = 3; // Green
    Serial.print("Detected Color is = ");
    Serial.println("GREEN");
  }
  if (R<38 & R>24 & G<44 & G>30) {
    color = 4; // Yellow
    Serial.print("Detected Color is = ");
    Serial.println("YELLOW");
  }
  if (G<29 & G>27 & B<22 & B>19) {
    color = 5; // Blue
    Serial.print("Detected Color is = ");
    Serial.println("BLUE");
  }
  return color;
}

void setup() {
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);

  //frequency-scaling to 20% selected
  digitalWrite(S0, LOW);
  digitalWrite(S1, HIGH);

  pickServo.attach(9);
  dropServo.attach(10);

  Serial.begin(9600);
}

void loop() {
  //initial position of servo motor
  pickServo.write(115);
  delay(600);

  for (int i = 115; i > 65; i--) {
    pickServo.write(i);
    delay(2);
  }
  delay(500);
  //read color values by calling function. save the values for conclusion in variable
  color = detectColor();
  delay(1000);

  switch (color) {
    case 1:
      dropServo.write(50);

      break;

    case 2:
      dropServo.write(80);
      break;

    case 3:
      dropServo.write(110);
      break;

    case 4:
      dropServo.write(140);
      break;

    case 5:
      dropServo.write(170);
      break;

    case 0:
      break;
  }
  delay(500);

  for (int i = 65; i > 29; i--) {
    pickServo.write(i);
    delay(2);
  }
  delay(300);

  for (int i = 29; i < 115; i++) {
    pickServo.write(i);
    delay(2);
  }
  color = 0;
}

Автор: Abhiemanyu Pandit
Перевод и адаптация для RobotoTehnika.ru: Swarg