Our EV3DEV / C++ Daisy Chain unlocks additional functionality

In our current layout, we have two Lego constructions that require more than 4 motors and we use the daisy chain function for that. In case you don’t know: the daisy chain functionality offers you the possibility to connect up to 4 EV3 bricks, one master and 1, 2 or 3 slave bricks. You program the master brick as usual, but you can also access the motors and sensors as if they were connected to the master brick. So you can access a maximum of 16 motors and the same number of sensors. That is the theory, in practice this is unfortunately not the case. The Lego software is very buggy. Most of the time, the sensors of the slave brick(s) are not seen by the master brick, motors are ok-ish. If you only use motors connected to the slave, it works most of the time. Of course we checked with our Mindstorms friends if there was a solution for this. Their answer: Lego knows about the problem, they are not fixing this. The solution: don’t use daisy chain ….

Anyway, while moving from the standard Mindstorms EV3 programming environment to the EV3DEV / C++ environment, we noticed that EV3DEV doesn’t support the daisy chain option. We searched the internet if somebody else had already implemented the daisy chain functionality in EV3DEV / C++, but that was not the case. So, we had the choice either to split the software and change the PC application (so we don’t need daisy chain), or to implement the daisy chain function in our EV3DEV software. We choose the last option. Of course, it is an additional challenge.

The principle that we want to follow, is basically the same as in the EV3 programming environment: you have one master brick running the application software and one or more slave bricks. The software running on the master brick should be able to access the sensors and motors on the slave brick(s) as if they would be connected to the master.

In order to achieve this, we needed to extend our motor and sensor library with additional methods. For example, you can create a motor like this for the master brick:

// Create a large motor at port C at the local brick (master)
EV3MotorLarge MasterMotorC = EV3MotorLarge(OUTPUT_C);

And we added the option to create a motor for the second, slave brick:

// Create a virtual brick, accessible at the specified IP address
// And create a large motor at port A at the virtual brick (slave)
slaveBrick remoteBrick("192.168.137.4");  
EV3MotorLarge SlaveMotorA = EV3MotorLarge(OUTPUT_A, std::make_shared<RemoteBrick>(slaveBrick));

Once the motors have been created, you can use a master or slave motor in the same way, e.g.

MasterMotorC.OnDegrees(100, 360, Backward);
SlaveMotorA.OnDegrees(100, 360, Forward);

So far, so good and nothing special yet. But as you can see, the creation of the virtual brick is based on an IP address. That implies, that you can also have a slave brick that is not physically connected by an USB cable. If it is connected via Bluetooth or WiFi, it also works! And the number of slave bricks is NOT restricted to a total of 4 (1 master + 3 slaves). In theory, you could have an infinite number of slave bricks. Of course, there is a limit and that will have to do with the performance. I don’t have enough free bricks available to test the performance with 4+ bricks. Something for my backlog ;-).

Apart from the extended number of slave bricks, we have also added the option to access (from the master program) the LED lights on the slave bricks, the sound and the LCD display. In fact, everything we can do on the master brick, we can do on the slave brick(s).

How did we manage to do this? When the remoteBrick class is created, a TCP connection is setup between the master brick and the slave brick. On each slave brick, a generic ‘server’ program is running that accepts commands from the master brick. All commands that need to be executed on the slave brick, are send via a simple protocol by serializing the command into a string (e.g. “CreateLargeMotor,Output_A” or “MotorOnDegrees,100,360,OutputA,Forward”). On the slave side, the string is de-serialized and then executed.

In the current implementation, the server program needs to be started on the slave brick(s) manually. This will also be automated: when the remoteBrick class is created, it will start the server program automatically. Just work in progress ;-).

(Almost) Final version of the new container loader

In the video, you see the (almost) final version of the container loader. The only thing that is missing, is the power cable carrier.

What is new in this version (apart from finishing the build)? First of all, it has been added to the ‘real’ conveyor belt (you can see the enormous length ;-). This conveyor belt moves the containers from the warehouse to the wagons.

Furthermore, an ultrasonic sensor has been added at the top of the super structure. This ultrasonic sensor detects if a container has passed under it, so it ‘knows’ that after 1 second it can set its state to ‘container delivered’. Without this sensor, the only way to ‘ensure’ if the container has been loaded, was to use a predefined time frame. A predefined time frame has two major drawbacks: you need a very long time to make sure that the container has arrived. And you can not guarantee that the container will be delivered, no matter how long you define the time frame. You can see the ultrasonic sensor detection in close up around time frame 0:45.

Delta robot (flex picker) for Lego World 2017

A completely new delta robot has been build for Lego World 2017. The robot is based on the ABB FlexPicker Robot. You can read more about building the Lego Version at Eurobricks.

More photos are available at our Flickr page: Flickr.com/user/siouxnetontrack/deltarobot and videos are available at Youtube: youtu.be/user/siouxnetontrack.

Enjoy reading,

Hans

Ticket Dispenser Unit (complete), version 2017

As you can read in the first article about the Ticket Dispenser Unit (click here for the article), the version for Lego World 2016 a ‘fast build’. Nevertheless, it worked almost flawless. Almost … sometimes the card was not transported to the end. With just some small modifications, it works even better now.
Ticket Dispenser Unit (LDD)

Continue reading “Ticket Dispenser Unit (complete), version 2017”

Engineering the new delivery station for Lego World 2016

For Lego World 2016, we are engineering a new delivery station. Some background information: in the 2015 version, the candy crane grabbed the candy directly. Unfortunately, too often the candy fell out of the grabber during the movement of the crane. Therefore, we decided to update the crane that it would pick up the complete container (with the candy, of course :-)). The crane update is already finished as you can read in our previous article. In this article, you can read about the ideas of the new delivery station.

Sketch Delivery Station for Lego World 2016

Continue reading “Engineering the new delivery station for Lego World 2016”

Lego vacuum grabber for picking up the candy tickets

For Lego World 2016, we have planned to pickup and hand over the candy tickets using a vacuum grabber.

Posted Image

Continue reading “Lego vacuum grabber for picking up the candy tickets”

Building a power chain system (for the candy crane)

When building the candy crane, I was able to test it without using the power transformer (art 45517). At Lego World, because of the power consumption, it was needed that we hooked up both EV’3 to a power transformer. The cables of the transformer sometimes got into the running wheels, causing the system to fail. So, we needed to add a power chain system like this:

Power Chain System

Continue reading “Building a power chain system (for the candy crane)”

Updated crane hoist positioning

As described in the previous post (“Plans for Lego World 2016”), the updated crane uses two touch sensors for the positioning of the hoist. In  this article, I explain this in more detail.

Sioux.NET on Track - Candy Crane - Hoist

The two sensors slide over two rails that makes sure that they are pressed or released. By this means, we can distinguish four positions that are shown in the picture below:

Sioux.NET on Track - Positioning Hoist system

The numbers 1 to 3 are ‘defined’ positions:
1. Pickup position where the container is picked up from the conveyor belt.
2. Loading position #1 where the container is loaded into the train at track 1
3. Same as previous, but then for track 2.

Position 4 defines ‘the rest’, that is any position between the defined numbers and left from position 3. But note that there is no position 4 at the right from position 1. This is important for determining the starting position: when starting up the EV3 of the hoist, the EV3 can determine if it is on position 1, 2, 3 or 4 based on the state of the two touch sensors. In case of position 4, it is not exactly defined. But one thing is certain: if the hoist moves to the right, it will eventually find position 1. That is the reason that there is no position 4 at the right of position 1. Otherwise we wouldn’t know at startup in what direction the hoist should move to one of the defined positions.

So, the first thing to do when starting up: move the hoist to position 1 by moving to the right until it finds that sensor 1 is pressed and sensor 2 is released. From that moment, it is easy: if the hoist has to move to one of the three defined locations:

  1. if the new position > current position: move to the left
  2. if the new position < current position: move to the right.

And keep on moving, until the touch sensors indicate that you have reached the desired position:

  1. Touch sensor 1 = pressed  and Touch sensor 2 = released
  2. Touch sensor 1 = released  and Touch sensor 2 = pressed
  3. Touch sensor 1 = released and Touch sensor 2 = released

A demo program that randomly chooses the new position, has proven that the touch sensor readings are very accurate and that it never failed to miss a location. If you are interested in the EV3 program, please drop me a note.