This project was supposed to participate in the Machine Bouilder Competition. I ran out of time, so I publish this as a Work In Progress instead.
A ballot counterFill the head with red, yellow and green beads. Push the button. The head starts counting all beads, spits them out in different jugs according to their colour, and updates the colour count on a small display.
In our working community, we use a balloting system to tell how our week was.
People pick one bead and place it in a jar. Green for "I had a good week", yellow for "The week was quite ok" and red for "Bad week". Someone counts all the colours and makes a report. I made this ballot counter to take care of the counting process.
The designI made a model using play-doh. I did a 3D scan and did further editing in Tinkercad. To be able to do the final design and print in colours (not necessarily original colours), I need to use Autodesk Fusion, which can handle the original 80 MB scanned model in full colour.
PrincipleThe head of the elf has a funnel shaped hole, which is to be filled with the beads. The beads fall one by one through a pipe and stops at the bottom of the pipe. A colour sensor reads the colour. The whole head rotates accordingly and the bead continues, rolling out from the mouth and along the tongue of the elf, into a jar, while the colour count is updated. The whole process is controlled with a smartphone.
Detaileddescription
The head rotates over a thrust bearing consisting of a ring gear bolted to a base plate. The ring gear has a groove for 8 bearing balls. The bottom of the head has a similar groove, which allows the head to rotate over the balls. A planetary gear system is powered by a continuous servo motor attached to the head, spinning the sun gear. Two planet gears attached to the head transfer the power to the ring gear. One of the planet gears has markings for a pulse detector, which measures the amount of movement.
When a bead falls into the tube of the funnel, it stops at the flipper, a quadrant shaped part. When the flipper is in its farmost position, the bead falls into a hole in the flipper. The flipper moves a bit, placing the bead under a colour sensor. When the colour is determined, the head is rotated so that the tongue points to the right jar. The flipper rotates further and the bead falls into the next tube, letting the bead roll out of the mouth of the head. At that time, the next bead has fallen into the tube of the funnel and has stopped against the flipper.
A bead has fallen onto the flipper.
The flipper rotates so that the bead falls down to the hole in the flipper. The height of the flipper will fit only one bead in the hole.
The flipper rotates so that the bead is placed on the LDR/RGB LED unit (the colour sensor). Now the colour is determined. A black top plate and the black bottom plate isolates the colour detection unit from ambient light. Also the flipper needs to be black. At this point, the whole head needs to be rotated for the bead to drop into the right jar.
Finally the flipper rotates to its initial position, which lets the bead fall into the throat tube and further out of the mouth to roll down along the tongue. The next bead will hopefully rest on the flipper.
The LDR/RGB LED unitWith this design, extremely little ambient light should get into the chamber created for the colour recognition process. Still, before lighting the red, blue and green led lights consecutively, the complete darkness can also be measured and be used as a reference value. That value can be subtracted from each colour value.
It's also important to get the response from an empty chamber. The ambient light and the response from red, green and blue light.
If the ambient light appears to be of no importance (the LDR gives the same response no matter what the room lighting is or whether there is a bead in the chamber or not), I will happily leave out everything dealing with the ambient light. In that case, I can simply get the RGB prophiles for four different cases. Using 10 bit AD pins, the RGB triplet values could be something like:
- red bead (600, 150, 170)
- green bead (120, 850, 130)
- yellow bead (580, 730, 140)
- no bead (100, 130, 70)
Each RGB triplet is a point in a 3D colour space. When a new bead is examined, its colour profile form a point in the space. Using 3D Pythagorean, the distance to each known colour (or no bead case) is calculated to find out which is the most likely colour. If no obvious colour can be detected, we either have a new colour or the bead is in an unfortunate position in the chamber. The bottom plate in the chamber should guide the bead to one position. In ambiguous cases, the flipper can rotate back and forth to get the bead in a better position.
Things to consider
If the LDR/RGB LED method appears to be unreliable, the RGB triples could be converted into another colour space like HSV, where more empasis could be given to the H channel.
The effect of the RGB LED could be lowered using PWM, if the glossy surface of the bead reflects too much of any colour. We'd like to create a situation, where only the true colour of the bead is reflected and caught up by the LDR.
Because of the elf design, the whole structure rotates according to the determined colour. The head lies on top of a fixed ring form base, which has a circular groove acting as an axial or thrust ball bearing. The inner rim of the ring works as the ring gear in a planetary gear.
To complete the thrust bearing, the bottom of the head part has a similar groove, allowing the head to rotate with low friction. A continuous servo motor is attached to the sun gear. Two planet gears on opposite sides of the sun gear transfer the motion to the ring gear. Well, the ring gear is stationery, making the planets and sun rotate. And the whole head rotates with the planets, the axes of which are firmly in the head basement.
All parts except the steel bearing balls are 3D printed PLA. The coder gear (one of the planet gears) is printed in black PLA, with a white pattern on the top layer to create a pattern for the IR sensor. The ring gear has 84 teeth. The planets have 35 teeth each and the sun has 14 teeth. The coder wheel pattern has 8 white sectors. I will count only 8 sectors, not 16 transitions.
When 35 teeth of the coder wheel have passed, it has made one revolution. And travelled 35 teeth of the 84 tooth ring gear. 35/84 of 360 degrees is 150 degrees. I'm tempted to increase the number of sectors on the encoder gear. With 10 sectors, one sector would corresponding to 15 degrees, which is a nice angle to use to reach say 30, 45, 60, 90, 120 or any other simple fraction of 360 degrees.
If I stick to 8 sectors, one sector is 18.75 degrees. If I need a better resolution, I could count not only 8 sectors of one colour, but 16 transitions from one colour to another.
The IR sensor works with an analog input pin. I'll be using only an IR LED/photoresistor unit without its own AD circuit.
The photoresistor will create a measureable voltage depending on the amount of infrared light it receives. The coder wheel has white and black segments. So there will be a maximum and minimum reading while the wheel turns. The transition from white to black and vice versa in both directions must be calibrated for the system to be able to control the rotation in both directions and to be able to count not 8 transitions, but 16 transitions, giving a resolution of 9.375 degrees. Further improvement would require more sectors on the coder gear or timed control of the continuous servo motor: measure the time between transitions. Divide that time into smaller units and stop the motor at exact time to reach the desired position.
But before testing, I can't be sure of the sectors being of equal size. And with a single sensor, I can't determin the direction of the rotation. I have to depend on my program knowing in which direction it rotates the head.
The weight of the head with all moving parts lies on 8 bearing steel balls, which roll along the groove in the stationery ring gear. The ball ring holds all 8 balls in place. The balls are easily pushed into place in the ring due to the flexible plastic. There's no force acting on the ring when the balls are rolling, just a slight friction. All forces act on the balls and the grooves in the gear ring and the base of the head.
The head has a rather complex bottom part, which attaches to a ring gear fixed on a table top, and holds the servo with the sun gear and the two planet gears with ball bearings and the TCRT5000 module for the coder gear (one of the planet gears). So I did a test print to see if it works. Here is it in action:
I had a steady rotation spead and measured the output from the TCRT5000:
I'm pretty confident that I can get very accurate readings from the coder wheel. In my test print, the TCRE5000 is only 1 mm from the coder wheel gear, when it should be 5 mm. For the final print, I'll add some millimeters.
The wave pattern revealed that the coder wheel 3D print wasn't very accurate. The wheel was 3D printed in black PLA. On the top layer, I placed a pattern for the coder. The pattern was printed in white PLA, but because it was only one layer, the result was a bit greyish and not very even. I might laser cut a thin white adhesive plastic sheet with same pattern and add it, to get a more even and more reflective surface.
A detailed description of the encoder wheel
As seen in the image, the signal from the IR phototransistor follows roughly a sine wave. The values of the wave tops vary, as well as the values of the bottoms. The minimum wave top is somewhere around 595. The maximum wave bottom is around 220. We can say for sure that a value of 410 is far from a top or a bottom.
Now we're ready to actually count 8 white sectors and 8 black sectors of the wheel, having a rough accuracy of 9 degrees per sector (see earlier chapter). We can find the middle of a sector by checking the amount of change. First we might need some filtering. Say we take the average of last three readings from the IR phototransistor. We compare the value with previous reading (which was the average of three consecutive readings). If the change rate changes sign, we are at a wave top or bottom. We check whether the actual reading is above or below 410 to determine which it is. This way we can detect each of the 16 sectors. We might get unwanted sign changes, if there's a lot of noise, like ambient IR light.
If there are too many wrong sign changes of the change rate due to noise, we need a better filter. Anyway, if the wave tops are 18 degrees apart, and one top is 9 degrees apart from the previous bottom, if, due to noise, we get two tops, these tops are maybe only 1 or 2 degrees apart from each other and either of them is as good as it needs to be. When the head is rotating, the logics of the encoder must at each time know the direction of the change and whether we are at the bottom half or the top half of a full wave. The accuracy comes from the fact that when we are not quite sure whether we are on the top or bottom half of the wave, we have a very clear reading of the change rate. It's near the maximum positive rate or the minimum negative rate. And when we are at a zero change rate, the change rate itself can't tell whether we are at the top or at the bottom. But the absolute value of the phototransistor will definitely tell us if we are at the top or at the bottom.
This way we will reach a resolution of about 9 degrees of the rotating head. Extending the resolution further to 4.5 degrees, would require that we detect a "sign change" of the absolute value of the IR phototransistor reading. If we set the mean value of 415 to mean zero. But as the wave pattern showed us, the mean of 415 doesn't work for each of the 8 wave lengths.
When the encoder wheel rotates, the change of rate is of course dependent on the rotating speed.
Yes, we are talking about a sine wave and its first derivative, which is a cosine wave. Only this is a real world scenario with a lot of noise and a skewed wheel and whatnot. But looking at a sine and a cosine wave:
Work flow for the encoder
1. Detect the nearest top or bottom. Make it your zero point.
2. To move n steps (each being 9 degrees) in one direction, start moving until there's a sign change in the reading.
3. Continue to move until there's a sign change in the first derivative. Count this as a step and continue, until you have n steps.
4. At each stop, remember if the stop is at the bottom or at the top of a wave. Know what sign change at the reading you are looking for. Know what sign change at the 1st derivative you are looking for to count as a step.
When starting at the first step, the nearest top or bottom can be found as follows:
Check the initial reading. If above 405, we are looking for a top. Rotate in one direction and calculate the rate of change. If it is positive, continue until it becomes negative, stop there, you are at the top. If it is negative, change direction and rotate until it becomes negative, stop there, you are at the top.
If the initial reading is below 405, do the opposite of what described above.
Work flowWhen the power turns on, the machine waits for a bead to fall into the funnel tube. When that happens, it waits another 10 s, just in case the user still adds beads.
If no bead falls into the tube, the machine asks the user to fill the head with beads and to stir.
When the sorting starts 10 s afer the first bead has fallen into the tube, the following program flow is executed:
1. read the colour of the bead 2. if this is the first bead of one colour, sing a song3. rotate to the corresponding jar4. rotate the stopper back and forth to release the beadand to let the next bead fall down to the colour sensor5. if the colour sensor sees a new bead, jump to 1 5.1 if no new bead can be seen, rotate head back and forth and jump to 5 5.2 after several attempts at 5.1, say "I guess that was all. Or should you stir the beads?" 5.3 if a new bead can be seen, jump to 56. read out loud the result and ask the user to shut down the power
The colour sensorI have an Adafruit TSL2591 light sensor. That is a bit overkill, I'll save it for more important things. I also have a real colour sensor somewhere, but since this project only needs to detect three colours, I won't waste it on this project. Besides, it doesn't add interesting and complex challenges. So I go for an RGB LED and a light dependent resistor (LDR).
When the bead falls into the funnel tube and stops at the stopper, an RGB LED shines consecutive red, green and blue light on the bead. An LDR measures how much light is reflected from the bead. Each colour will form its own recognisable "spectrum". A lot of measurements will be done to get an average, "3 band spectrum" of each colour.
The circuit- 4*aa batteries
- 2 servo motors
- 1 speaker
- switch
Due to delays in the competition, I had no time to order a PCB from PCBWay, once I had received all other hardware, so I made my own using a CNC router. I describe the procedure in this project.
Here's the PCB, as designed in EasyEDA. Once again, due to the delays, my subscription to Autodesk ended before I got the hardware.
The upper part has all the pins I need in this project. I also include ten pins at the lower part, mainly for stability. I solder headers to each hole having a copper trace running through. The copper traces at the lower part will provide access to extra pins, if I want to add features later to the Ballothar.
In short, I export the design to an SVG file, where I have the copper traces and the holes. I read it into Inkscape, where I turn everything into G-code. All holes will be a task for a 1 mm drill bit, all copper traces will be another task for a router bit grinding into the copper surface.
Here's the result:
I did a bad job positioning the piece before the routing began. One of the top traces wasn't as wide as it should have been. Luckily, it's only a digital signal line, not a power line. The other one is the ground, but it only grounds the Arduino board at that point, so no big currents there!
Magnified:
It's important to clean the surface and remove all lose flakes.
One important feature of the PCB is that it sits on the backside pins of the Arduino Giga. Too bad, the backside pins don't include any analog in pins, therefore I need two wires to go from the PCB, through a screw hole in the Giga, to two analog pins on the front side of the Giga.
The casingsI cut two holes in the back of the head to fit in the Arduino Giga and the battery pack.
The Arduino cover got four pegs to hold it in place. Due to a faulty measurement, the battery slot got to be too narrow, so I needed to add some details to the cover to match the surface of the head.
Instead of pegs, this cover simply fits into the slot snuggly.
Late add-onsWhen the head was ready printed, I discovered that the funnel I intended to use was a bit too high. So I added a "crown" to the head to raise it a bit. And because the Arduino Giga has zillions of pins, I could as well add some blinking leds.









_t9PF3orMPd.png?auto=compress%2Cformat&w=40&h=40&fit=fillmax&bg=fff&dpr=2)


Comments