Date: 07/05/2013
Duration of activity: 16 hours over two days
Group members participating: Ole Rasmussen and Kasper Føns
1. Goal
The goal of this session is to conduct some preliminary investigations on the feasibility of building the envisioned system described in project lab 1.2. Plan
Our plan is to build three machines and experiment with them. We will look at if they are able to function probably and any potential problems or complications that arises underway. The three machines we will try to build are:
We found the TIME_PER_AXLE_LENGTH key parameter by running axles of different lengths through the system and recording the minimum and maximum for each axle length which defines a range for that specific axle length. For example we found that axles of length 12 would be between the sensors from 3495ms to 3614ms. We then calculated an average point inside the range, and in the example, this would be 3555ms. Dividing this number by our axle length of 12, we get 296.25, which would be the perfect TIME_PER_AXLE_LENGTH for length 12 axles.
We created a spreadsheet to see how our system would behave at different TIME_PER_AXLE_LENGTH values and calculated all the metrics described above. We ran axles of length 2, 3, 5, 6, 7, 8, 10 and 12 through the system, each between 10 and 20 times. If a given TIME_PER_AXLE_LENGTH would result in a wrong length being calculated for a given axle, the cell would be marked red in our spreadsheet. Our spreadsheet can be seen in Figure 14. We found a best-fit value of 301 and used that for our program.
We have created the holding bay and the two-step elevator. A video of it can be seen below.
As can be seen, it elevates the items up without bringing too many items at a time. We still need to construct a conveyor belt at the top and somehow divide beams and axles apart. We also need to make sure that only one piece a time is sent on to the sorting machines.
Our elevator system is not very robust and should be redone. Sometimes the elevator gets stuck, stalling the motor. When starting the machine, we also need some way to move the elevator down to the initial position.
Having constructed this small part of the machine, we can estimate that it will take a lot longer to build a robust Feeder. We need to:
- One that is able to count the number of holes in a Lego beam. The BeamCounter.
- One that is able to figure out the length of a Lego axle. The AxleSorter.
- One that is able to feed the other two machines with Lego. The Feeder.
3. BeamCounter
We will try to create a BeamCounter using a conveyor belt to transport beams past a system of two light sensors. We believe the light sensors will be able to detect the number of holes in beams passing by. We begin by constructing the conveyor belt system.
3.1 Conveyor belt system
We wanted to build a conveyor belt to transport the Lego beams. Our first idea was to build the conveyor belt using Lego conveyor belt links [1], also seen on Figure 1. Using belt links would allow us to create one long conveyor belt. However, we quickly discovered that we had a very limited amount of such belt links available. They are not exactly cheap either (~$10 for 36) so we had to find another solution.
![]() |
| Figure 1: Conveyor Belt Links we wanted to build our conveyor system of. |
Instead of using belt links, we wanted to try using Lego tank track threads, as in Figure 2. Since these tracks are of fixed length, we needed to use multiple tracks to construct a longer conveyor belt. We had to make sure that smaller beams were able to cross the conveyor belt intersections.
| Figure 2: Tank Track Threads used in our conveyor belt construction. |
We managed to integrate multiple tank track threads into a longer conveyor belt. The belts were interconnected with gear wheels and could be driven by only one motor. Our design can be seen in Figure 3.
![]() |
| Figure 3: Belt system to move Lego beams forward. |
![]() |
| Figure 4: Rotating Lego axle helps bringing Lego beams of size three over the gap between the tank threads. |
We had problems with smaller Lego beams with a length of two or three. We added rotating Lego axles between the intersections of the tank threads as can be seen in Figure 4. This helped to move beams of length three over the intersection, but length two beams could be stuck and would never move forward. The conveyor belt still needs tinkering to work properly. This will be a problem for a future lab session.
3.2 Counting beam holes
To count the beam holes we added two light sensors. One of the light sensors emits light onto the other. We count the number of holes by counting how many times the light beam is broken by a beam passing by.
Our solution can be seen in Figure 5. Using a simple program we were able to count the number of holes in a beam. If a longer period of time passes where the light beam is not broken, we interpret that as a beam has fully passed the sensors, and then we know the length of it. In rare occasions we could see that our solution would come up with a wrong hole count. We hope to fix this in a future lab by adding walls on the side of the track, only making it one beam wide. This should make sure that the beam is passing the sensor in a straight line and at a set distance from the sensors.
![]() |
| Figure 5: Light sensors counting the number of holes in a Lego beam by sensing if the light beam is broken. |
4. AxleSorter
The AxleSorter should be able to determine the length of a given axle. A key difference from beams is that axles does not have any holes or other easily detectable characteristics for determining its length.
We had two ideas on system that should measure the axle length. The first system would use two wheels through which the axle should pass while the second would use light sensors.
4.1 Car wheel idea
The first idea was to use two wheels connected to two motors. One of the motors should always be powering the first wheel forward. When an axle would hit the wheel, the wheel should drive the axle forward but also push it against the other wheel, which should then rotate for as long as the axle was between the wheels. The second motor would then be connected in float mode to the second wheel and use the tachocounter to register how long the axle was. A prototype can be seen in Figure 6.![]() |
| Figure 6: AxleSorter idea. One of the wheels should be power by a motor while the other should be connected to a motor in float mode, using the tachocounter to measure the length of the axle. |
We had to ditch the two-wheel idea. We found that a single wheel was not able to pull in the axle; we had to push it pretty hard before the wheel had traction with the axle.
4.2 Light sensor idea
Our second idea was to use an LED and a light sensor and move an axle between the two, such that we could register the time it took for an axle to pass by. One could use a tilted smooth surface and let the axle glide down it, past the sensor. Our first design can be seen in Figure 7.
![]() |
| Figure 7: First light sensor AxleSorter design. When an axle passes by, the sensor should be able to register the the light breaking. |
We added a casing around the system to make it robust against light from the environment. It can be seen in Figure 8.
![]() |
| Figure 8: AxleSorter now with casing to protect it from environmental lighting. |
Figure 9 and 10 shows how it looks from the LED side of the system when no axle is there and when an axle is passing by.
![]() |
| Figure 9: AxleSorter where no axle is currently passing by. The light sensor diode is clearly visible. |
![]() |
| Figure 10: AxleSorter where an axle is currently passing by the sensing system. Notice that the light sensor diode is not completely covered by the axle, but this was not a problem in practice. |
A quick program showed that it worked reasonably well. We measured the time it took from the light beam was broken until it was unbroken again while the casing was tilted a bit (See Figure 11).
A major problem with this design is that it is very time sensitive. For example, if we had programmed that it takes 40ms for one axle length unit to pass by the sensor, changing the tilt angle or the speed of which the axles is dropped into the system would result in a wrong axle length detected. This brings us to the next iteration of our prototype.
4.3 Motor + light sensor idea
Our next iteration prototype was a mix of our two initial ideas: driving axles with a motor and sensing the time an axle uses to pass by a light sensor. We rebuilt our design so that a wheel was used to drive the axle past the light sensor at a steady rate (the rate of the motor) and it would therefore be tolerant against slope changes. We could not fit an LED into the new system, as the wheel had to be correctly placed above the light sensors and the LED was a bit too high. We could however use the old RXC light sensors. Our new system can be seen in Figure 12 and a polished version in Figure 13. As can be seen in Figure 12, an axle is passing under the wheel and is being driven forward by it. The two RCX light sensors are the two smaller blue boxes. Figure 13 shows that the motor is geared down from a z16 gearwheel to a z40 gearwheel. This is a gear ratio of 40/16 = 2.5. Since the solution is very sensitive to time, we have geared it down so that axles take longer to move through our sensors. It means there is a larger gap in time between axles of length n and n+1.
![]() |
| Figure 12: Refined system where an axle is currently passing through the system. Axles are driven forward by the wheel at a constant speed. |
![]() |
| Figure 13: Polished version of our AxleSorter. |
Below is the code for our AxleSorter. A specific time of TIME_PER_AXLE_LENGTH specifies how long time passes for a single axle length unit (later explained how we found it to be 301). It uses one motor for driving the wheel and two sensors, one to send out floodlight and one to sense if the light beam is broken.
It then samples the time period it takes for an axle to pass by the sensors and divide this by TIME_PER_AXLE_LENGTH to gain the axle length.
It then samples the time period it takes for an axle to pass by the sensors and divide this by TIME_PER_AXLE_LENGTH to gain the axle length.
package olefoens.axelsorter;
import lejos.nxt.LCD;
import lejos.nxt.NXTRegulatedMotor;
import lejos.nxt.addon.RCXLightSensor;
import lejos.util.Delay;
public class AxelSorter implements Runnable
{
private static final int LIGHT_THRESHOLD = 550;
private static final float TIME_PER_AXLE_LENGTH = 301;
private final NXTRegulatedMotor motor;
private final RCXLightSensor sensor;
private AxelListener listener;
public AxelSorter(NXTRegulatedMotor motor, RCXLightSensor floodLight,
RCXLightSensor sensor)
{
this.motor = motor;
this.sensor = sensor;
floodLight.setFloodlight(true);
sensor.setFloodlight(false);
waitForFloodLightOn();
}
public void setListener(AxelListener listener)
{
this.listener = listener;
}
private void waitForFloodLightOn()
{
LCD.drawString("Waiting for", 3, 5);
LCD.drawString("Floodlight ON", 2, 6);
while(getLightValue() < LIGHT_THRESHOLD)
{
Delay.msDelay(5);
}
LCD.clear();
}
private int getLightValue()
{
return sensor.getNormalizedLightValue();
}
@Override
public void run()
{
motor.forward();
LCD.drawString("Light sensed: ", 0, 5);
LCD.drawString("Dark: ", 0, 7);
try
{
boolean axelDetected = false;
long axelStartTime = 0;
while(true)
{
int lightValue = getLightValue();
LCD.drawInt(lightValue, 3, 3, 6);
if(lightValue < LIGHT_THRESHOLD && !axelDetected)
{
axelDetected = true;
axelStartTime = System.currentTimeMillis();
}
if(lightValue > LIGHT_THRESHOLD && axelDetected)
{
long axelEndTime = System.currentTimeMillis();
long axelTransitionTime = axelEndTime - axelStartTime;
LCD.drawInt((int) axelTransitionTime, 4, 6, 7);
axelDetected = false;
int length = Math.round(axelTransitionTime / TIME_PER_AXLE_LENGTH);
LCD.drawInt(length, 4, 11, 7);
listener.axelDetected(length);
}
Thread.sleep(5);
}
} catch(InterruptedException e)
{
motor.stop();
motor.flt();
}
}
}
We found the TIME_PER_AXLE_LENGTH key parameter by running axles of different lengths through the system and recording the minimum and maximum for each axle length which defines a range for that specific axle length. For example we found that axles of length 12 would be between the sensors from 3495ms to 3614ms. We then calculated an average point inside the range, and in the example, this would be 3555ms. Dividing this number by our axle length of 12, we get 296.25, which would be the perfect TIME_PER_AXLE_LENGTH for length 12 axles.
We created a spreadsheet to see how our system would behave at different TIME_PER_AXLE_LENGTH values and calculated all the metrics described above. We ran axles of length 2, 3, 5, 6, 7, 8, 10 and 12 through the system, each between 10 and 20 times. If a given TIME_PER_AXLE_LENGTH would result in a wrong length being calculated for a given axle, the cell would be marked red in our spreadsheet. Our spreadsheet can be seen in Figure 14. We found a best-fit value of 301 and used that for our program.
![]() |
| Figure 14: Spreadsheet for calculating key parameter TIME_PER_AXEL_LENGTH for our AxleSorter. |
We believe at this point that our AxleSorter is pretty robust, but on rare occasions it still calculates the wrong axle length. This might be tolerable, but should be looked into.
5. Feeder
The feeder machine should be able to hold both Lego axles and beams and feed the sorting machines with only one at a time at a descent rate. We found that the Feeder machine design would be worth copying from akiyuki's Axle sorter [2]. We would create a holding bay, and like [2] we would push beams and axles up using a two-step elevator. This should make sure not too many items are brought up from the bay and like [2] we could make a narrow area where only one item at a time might pass and other items would fall down in the holding tank again.We have created the holding bay and the two-step elevator. A video of it can be seen below.
Our elevator system is not very robust and should be redone. Sometimes the elevator gets stuck, stalling the motor. When starting the machine, we also need some way to move the elevator down to the initial position.
Having constructed this small part of the machine, we can estimate that it will take a lot longer to build a robust Feeder. We need to:
- Redo the elevator.
- Separate beams from axles.
- Somehow make sure beams are laying correctly, the BeamCounter cannot sense how many holes there are if the holes are pointing upwards.
- Only move one piece forward at a time. For example, having two item sent on just after each other, would not allow for our BeamCounter or AxleSorter to distinguish them as two separate bricks.
6. Conclusion
We have constructed three prototypes
- A BeamCounter that works reasonable well, but cannot transport beams of length two.
- A AxleSorter that is nearly complete.
- A Feeder prototype that is not nearlycomplete.
7. Next lab
We need to look at the distributor, the subsystem that should move the sorted Lego bricks into some storage unit. We also need to alter the BeamCounter so that it works more robustly.
8. References
[1] “LEGO Education | Products > Elementary > Conveyor Belt Links.” [Online]. Available: http://www.legoeducation.us/product/details/907. [Accessed: 05-Jun-2013].
[2] “LEGO Axle Sorter AS-L40A - YouTube.” [Online]. Available: http://www.youtube.com/watch?v=fM9qGZCc4DY. [Accessed: 05-Jun-2013].
[2] “LEGO Axle Sorter AS-L40A - YouTube.” [Online]. Available: http://www.youtube.com/watch?v=fM9qGZCc4DY. [Accessed: 05-Jun-2013].













