Привет, хабровчанин.
Писатель из меня не очень, на это неоднократно указывали мне учителя в школе после прочтения моих сочинений. Не то что что-бы суть не была изложена, меня упрекали в сухости и лаконичности повествования. Тогда мне это казалось придирками, ведь лаконичность — это замечательно. Но не для писателя. В этот раз я попытаюсь исправится, ведь с того времени прочитаны тонны сайфая. Такова преамбула, и не исключено, что осиливший этот текст до конца всплакнет кровавой слезой, но я предупредил.
Удосужилось мне счастливо жить в небольшом городке в центральной Украине. Причины сего мне не известны, но каждую осень колхозный рынок превращается в биржу по торговле грецким орехом, его везут со всей округи. Все покупают и продают как одетый так и раздетый орех. Ажиотаж затрагивает как профессиональных перекупщиков, так и пенсионеров, мне при этом почему-то вспоминаются голландские тюльпаны. Но история началась летом.
С моим кумом мы владеем небольшим компьютерным магазинчиком, где он продает, а я занимаюсь мелким ремонтом и программированием. В очередной раз приехав с недельного отдыха с палатками на берегу реки, загоревший и нарыбачившийся вдоволь я сидел и что-то паял в своем кабинете, который я лаского зову «склеп» по причине обилия мертвого железа и постоянной температуры окружающей среды.
— К тебе пришли.
Я вышел из склепа и познакомился с парнем немного старше меня по имени Андрей. На ладони у него были половинки ядер грецкого ореха, одно темно-коричневое, почти черное, другое — светлое, практически бежевое. Андрей предложил работу, нужно было программно отделять первые от вторых. Это была первая ошибка. Нет, не подумайте плохо, ошибка не в том, что он связался со мной, а в том что принес мне настолько разные примеры. Мне была дана полная свобода в плане платформ и реализаций. Хоть и было предложено использовать камеры, я их отбросил, ввиду, как мне тогда показалось, сложности реализации и ресурсоемкости такого подхода. В качестве сенсора был выбран датчик tcs3200 — преобразователь цвет->частота, такие часто используют в DIY проектах по сортировке чего-нибудь цветного. По даташиту датчик имел хорошие характеристики: имел по 16 фотодиодов каждого цвета(R/G/B) плюс отдельно 16 фотодиодов для белого цвета. Глубина чувствительности каждого канала была заметно выше 8 бит на канал, которые предлагает бытовая вебкамера. Первая версия устройства представляла собой картонную трубу от пищевой фольги с вырезанным окошком для датчика и подсветки. Данные с максимально-возможной скоростью передавались в виндовое приложение. Получалось около 600 замеров в секунду.

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

На скриншоте приложения графики на черном фоне пришлось нарисовать в фотошопе по памяти. Далее все иллюстрации будут реальными.
Орехи скользили поштучно по трубе, наклоненной на 45 градусов, и если данные с датчика отличались от фона (предварительно калиброванного) — фиксировался орех и его средневзвешенный цвет. По этому значению и сортировались орехи, признаю, довольно примитивный алгоритм, тем не менее он отменно работал.

Фотографии, где видно разницу между первыми и вторыми орехами.
С теми сэмплами что дал мне Андрей работало все прекрасно и отделяло темные от светлых орехов с точностью в 95%. Какой же был эпик фэйл когда в следующий раз были принесены орехи с менее контрастными различиями. Поделка отказывалась различать орехи, ведь их средневзвешенный цвет был практически одинаков. Была предпринята попытка анализировать орехи по графикам время/насыщенность цвета, но это не дало желаемых результатов, датчик на таких скоростях прилично шумел. В результате чего было принято решение переходить на камеры.
Но об этом во второй, заключительной части, будет интересней, обещаю.
PS: Добавил скетч
Обещанная вторая часть.
Писатель из меня не очень, на это неоднократно указывали мне учителя в школе после прочтения моих сочинений. Не то что что-бы суть не была изложена, меня упрекали в сухости и лаконичности повествования. Тогда мне это казалось придирками, ведь лаконичность — это замечательно. Но не для писателя. В этот раз я попытаюсь исправится, ведь с того времени прочитаны тонны сайфая. Такова преамбула, и не исключено, что осиливший этот текст до конца всплакнет кровавой слезой, но я предупредил.
Удосужилось мне счастливо жить в небольшом городке в центральной Украине. Причины сего мне не известны, но каждую осень колхозный рынок превращается в биржу по торговле грецким орехом, его везут со всей округи. Все покупают и продают как одетый так и раздетый орех. Ажиотаж затрагивает как профессиональных перекупщиков, так и пенсионеров, мне при этом почему-то вспоминаются голландские тюльпаны. Но история началась летом.
С моим кумом мы владеем небольшим компьютерным магазинчиком, где он продает, а я занимаюсь мелким ремонтом и программированием. В очередной раз приехав с недельного отдыха с палатками на берегу реки, загоревший и нарыбачившийся вдоволь я сидел и что-то паял в своем кабинете, который я лаского зову «склеп» по причине обилия мертвого железа и постоянной температуры окружающей среды.
— К тебе пришли.
Я вышел из склепа и познакомился с парнем немного старше меня по имени Андрей. На ладони у него были половинки ядер грецкого ореха, одно темно-коричневое, почти черное, другое — светлое, практически бежевое. Андрей предложил работу, нужно было программно отделять первые от вторых. Это была первая ошибка. Нет, не подумайте плохо, ошибка не в том, что он связался со мной, а в том что принес мне настолько разные примеры. Мне была дана полная свобода в плане платформ и реализаций. Хоть и было предложено использовать камеры, я их отбросил, ввиду, как мне тогда показалось, сложности реализации и ресурсоемкости такого подхода. В качестве сенсора был выбран датчик tcs3200 — преобразователь цвет->частота, такие часто используют в DIY проектах по сортировке чего-нибудь цветного. По даташиту датчик имел хорошие характеристики: имел по 16 фотодиодов каждого цвета(R/G/B) плюс отдельно 16 фотодиодов для белого цвета. Глубина чувствительности каждого канала была заметно выше 8 бит на канал, которые предлагает бытовая вебкамера. Первая версия устройства представляла собой картонную трубу от пищевой фольги с вырезанным окошком для датчика и подсветки. Данные с максимально-возможной скоростью передавались в виндовое приложение. Получалось около 600 замеров в секунду.

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

На скриншоте приложения графики на черном фоне пришлось нарисовать в фотошопе по памяти. Далее все иллюстрации будут реальными.
Орехи скользили поштучно по трубе, наклоненной на 45 градусов, и если данные с датчика отличались от фона (предварительно калиброванного) — фиксировался орех и его средневзвешенный цвет. По этому значению и сортировались орехи, признаю, довольно примитивный алгоритм, тем не менее он отменно работал.
Скетч для Leonardo
const int s0 = 12; // sensor pins const int s1 = 13; const int s2 = 11; const int s3 = 10; const int out = 9; // TCS230 output const int ejector = 7; int red = 0; int green = 0; int blue = 0; int white = 0; int comm = 0; void setup() { pinMode(s0, OUTPUT); pinMode(s1, OUTPUT); pinMode(s2, OUTPUT); pinMode(s3, OUTPUT); pinMode(out, INPUT); pinMode(ejector, OUTPUT); Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } digitalWrite(s0, HIGH); digitalWrite(s1, HIGH); //l } void loop() { if (Serial.available() > 0) { comm = Serial.read(); } if (comm == 65) { getColor(); Serial.write(lowByte(red)); Serial.write(highByte(red)); Serial.write(lowByte(green)); Serial.write(highByte(green)); Serial.write(lowByte(blue)); Serial.write(highByte(blue)); Serial.write(lowByte(white)); Serial.write(highByte(white)); delayMicroseconds(25); } if (comm == 66) { digitalWrite(ejector, HIGH); delayMicroseconds(10000); digitalWrite(ejector, LOW); } if (comm == 67) { Serial.end(); Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } } } void getColor() { digitalWrite(s2, LOW); digitalWrite(s3, LOW); red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); digitalWrite(s3, HIGH); blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); digitalWrite(s2, HIGH); green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); digitalWrite(s3, LOW); white = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); }

Фотографии, где видно разницу между первыми и вторыми орехами.
С теми сэмплами что дал мне Андрей работало все прекрасно и отделяло темные от светлых орехов с точностью в 95%. Какой же был эпик фэйл когда в следующий раз были принесены орехи с менее контрастными различиями. Поделка отказывалась различать орехи, ведь их средневзвешенный цвет был практически одинаков. Была предпринята попытка анализировать орехи по графикам время/насыщенность цвета, но это не дало желаемых результатов, датчик на таких скоростях прилично шумел. В результате чего было принято решение переходить на камеры.
Но об этом во второй, заключительной части, будет интересней, обещаю.
PS: Добавил скетч
Обещанная вторая часть.