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 ;-).

How to? EV3’s in Daisy Chain mode plus WiFi

If you have two or more Lego Mindstorms EV3’s in daisy chain mode, it is not possible to use a Wifi connection with the EV3 as well. For our project, we need this functionality. Two embedded software engineers in our team are now updating the firmware to make this work. But are we going to be in time….? From a project management perspective, it is always wise to have a fallback scenario. But is there one….?

Continue reading “How to? EV3’s in Daisy Chain mode plus WiFi”

Connecting the two daisy-chained EV3 bricks to our PC application…

Candy Rotating StockContext

The new developed Candy Rotation Stock (CRS) is controlled by two EV3 bricks in daisy chain modus. The CRS uses a total of three large EV3 motors for the major movement, one medium motor for the conveyer belt that is part of the conveyer system and two medium motors for the movement of the branch. Four sensor ports are needed, so that could be handled with one brick. The three large motors are always switch on or off simultaneously. If a motor multiplexer would exist, the CRS could be controlled by one EV3 brick.

Problem

So, what is the problem? By using the daisy chain modus, you can extend the number of ports by serializing the bricks which makes one  virtuel EV3 with 16 motor ports and 16 sensor ports. True, writing the EV3 program to control the CRS is no problem. In the Youtube video is shown that this works (see the previous article).

The problem that we have, is that the CRS is part of a larger picture. When the visitor chooses a color, this color needs to be  passed to the CRS, the CRS moves a candy in  the chosen color to the crane pickup position, the crane needs to get a signal that the candy is available, etc. So, we need communication with the CRS brick. And here starts the problem: if you connect two EV3 bricks in daisy chain modus, the USB port where you also need to put the WiFi dongle, is now occupied by the USB cable to the second brick. The same problem occurred at the Candy crane, which is also controlled by two EV3’s. The solution that we used there, was to move the intelligence of the crane movement to the PC. We could do this again, but that would mean a change in our software architecture. And next: let’s find another solution since the goal of our group is to learn from these type of problems and find (new) ways to solve these.

Solution(s)

The best solution is (of course) the availability of a firmware that supports WiFi and daisy chain modus. See the article about the plans that we had for 2015, among of them was the new firmware. But I don’t think we will have this before Lego World 2015 …

So, another plan was needed and we came up with the following: the CRS bricks will not be connected by WiFi to the PC application. No, the communication is completely done locally:

  1. The chosen color at the PUI is send to the Buffer Control (BC) brick. This EV3 brick is connected by WiFi to the PC application.
  2. Then, the BC brick sends a message (I will come to the ‘how’ later) to the CRS brick which color needs to be picked.
  3. The CRS brick makes sure that the right candy is transported to the Crane Pickup location.
  4. When ready, the CRS brick communicates back to the BC brick that the candy is available for the crane. The BC brick sends a message to the PC, so the rest of the flow can continue (crane movement, etc).

Brick 2 Brick communcation

So, the question is: how do the BC brick and the CRS bricks communicate? The answer is: by using two motors that are physically connected, see the sketch below. An additional advantage is, that it also works between an NXT and EV3, EV3 and EV3 or NXT and NXT. So, if WiFi is not possible (daisy chain, NXT) and bluetooth not possible (NXT to EV3), then this may be do the trick:Lego Motor Protocol

In this example, pressing the button on the Ev3 starts a short rotation of the EV3 motor. Since the EV3 motor is connected to the large EV3 motor, the rotation is the trigger and starts an action. For example, run the medium motor for 20 seconds. When the action is done (= medium motor stops), the large EV3 motor is rotated backwards. This results in a rotation of the NXT motor, and this is the trigger for the NXT program. The basis of this communication protocol is that the large motors (both at the NXT and the EV3) can either be used as activator (motor movement) and as sensor (rotation).

Ok, I admit: the communication protocol is rather slow. But it works. And you don’t need a PC. You can extend the protocol in two triggers: clockwise rotation is trigger 1 and counterclockwise rotation is trigger 2. I am now debugging the NXT and EV3 code. When I have this finished, I will upload a video to our Youtube channel.