📜 ⬆️ ⬇️

What will happen if you mix nuts, Arduino, OpenCV and Delphi. Part 1

Hi, habrovchanin.

The writer from me is not very, the teachers at school repeatedly pointed out to me after reading my writings. Not that the essence was not stated, I was reproached for the dryness and brevity of the story. Then it seemed to me nagging, because conciseness is wonderful. But not for the writer. This time I will try to correct it, because since that time, tons of saifai have been read. Such is the preamble, and it is possible that the person who has mastered this text will cry up to the end with a bloody tear, but I warned.

It bothered me to live happily in a small town in central Ukraine. The reasons for this are not known to me, but every autumn the collective farm market turns into a walnut exchange market, it is brought in from the whole region. Everyone buys and sells both dressed and stripped nuts. The excitement affects both professional dealers and retirees, for some reason I remember Dutch tulips. But the story began in the summer.
')
With my godfather we own a small computer store where he sells, and I do minor repairs and programming. Once again, having arrived from a week-long rest with tents on the river bank, I had been sunburned and rybivshitsya and had something to solder in my office, which I affectionately called the "crypt" because of the abundance of dead iron and a constant ambient temperature.

- They came to you.

I came out of the crypt and met a little older boy named Andrei. In the palm of his hand he had halves of walnut kernels, one dark brown, almost black, the other - light, almost beige. Andrei offered a job, it was necessary to separate the first from the second programmatically. This was the first mistake. No, do not think badly, the error is not that he contacted me, but in the fact that he brought me so different examples. I was given complete freedom in terms of platforms and implementations. Although it was proposed to use cameras, I discarded them, in view of how it seemed to me then, the complexity of implementation and the resource intensity of such an approach. The sensor tcs3200 was chosen as a sensor - a color- > frequency converter, which is often used in DIY projects for sorting something colored. According to the datasheet, the sensor had good characteristics: it had 16 photodiodes of each color (R / G / B) plus 16 photodiodes for white color separately. The depth of sensitivity of each channel was significantly higher than 8 bits per channel, which is offered by a household webcam. The first version of the device was a cardboard tube of food foil with a cut out window for the sensor and the backlight. Data with the highest possible speed was transferred to the Windows application. It turned out about 600 measurements per second.

imageimage
Photos are not mine, taken from the network, photos of the first prototype, alas, no more. The very same prototype was torn by children when they (and the prototype and children) were left unattended.


In the screenshot of the application, graphics on a black background had to be drawn in Photoshop from memory. Further, all the illustrations will be real.

Nuts slid by the piece on a pipe inclined by 45 degrees, and if the data from the sensor differed from the background (pre-calibrated), the nut and its weighted average color were recorded. The nuts were sorted by this value, I admit, a rather primitive algorithm, however, it worked perfectly.
Sketch for 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); } 


imageimage
Photos, where you can see the difference between the first and second nuts.

With those samples that Andrey gave me everything worked perfectly and separated the dark from the light nuts with an accuracy of 95%. What was the epic file when the next time nuts were brought with less contrasting differences. The craft refused to distinguish between nuts, because their weighted average color was almost the same. An attempt was made to analyze the nuts according to the time / color saturation graphs, but this did not give the desired results; the sensor at such speeds was noisy. As a result, it was decided to move to the camera.

But this will be more interesting in the second and final part, I promise.



PS: Added sketch

The promised second part.

Source: https://habr.com/ru/post/238629/


All Articles