Lego Mindstorms EV3 with an image with 4 different shades of gray

As mentioned in the previous post, any EV3 is capable of displaying 4 different shades of gray. However, this functionality is not available in the standard Lego programming environment.

When using EV3DEV in combination with C++, there are no libraries available (or I can’t find them πŸ˜‰ ) to upload easily an image to the LCD screen. You need to write the right values to a screen buffer in order to display an image. But if you do it right, you can get an image like this on the EV3:

A standard Lego Mindstorms EV3 can display four different shades of gray (click on the picture for a short video)

I wrote a simple C# program that scans the complete image, pixel by pixel from left to right and from top to bottom. The image pixel values are converted into a array with the EV3 pixel values.


  const int MaxDisplayX = 178;
  const int MaxDisplayY = 128;

  Bitmap myBitmap = new Bitmap("Example picture.png");
  Color pixelColor;

  // Start of the array initialization
  System.Console.WriteLine("unsigned short int imageArray[] = {" + Environment.NewLine);

  // Get the color of a pixel within myBitmap.
  for (int y = 0; y < MaxDisplayY; y++)
    for (int x = 0; x < MaxDisplayX; x++)
      pixelColor = myBitmap.GetPixel(x, y);

      // RGB values are always the same, so doesn't matter if I read R, G or B
      switch (pixelColor.R)
        case 0: // Black
        case 85: // Dark Gray
        case 170: // Light Gray
        case 255: // White

      // No ; at the end of the last array element
      if (!((x == (MaxDisplayX - 1)) && (y == (MaxDisplayY - 1))))
        System.Console.Write(", ");

  // End of the array initialization
  System.Console.WriteLine("};" + Environment.NewLine);

Note: the C# program can only convert 4 different values to the pixel array, so the input should be an image that has already been converted into a 4 grayscale image. The image should also have the exact size of the screen, i.e. 178 x 128 pixels. I have only tested it on one grayscale image, so I don’t know if the four grayscale values (0, 85, 170, 255) are always the same four.

The output of the C# program looks like this …

unsigned short int imageArray[] = {

  0x4949, 0x4949, 0x4949, 0x4949, 0x4949, ... etc


… and is written to the file “imagearray.h”. That file used in the C++ program that runs on the EV3:

#include "imagearray.h"
  int fbfd = 0;
  char* fbp = 0;

  long int screensize = 0;
  struct fb_var_screeninfo vinfo;
  struct fb_fix_screeninfo finfo;

  fbfd = open("/dev/fb0", O_RDWR);
  if (fbfd == -1)

  if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo))

  /* Get variable screen information */
  if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo))

  /* Figure out the size of the screen in bytes */
  screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

  fbp = (char*)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
  if ((int)fbp == -1)

  // Iterate over the number of array elements
  // Note: sizeof gives the total number of bytes, therefore we
  //       have to divide by the size of one array element
  for (int i = 0; i < sizeof(imageArray) / sizeof(imageArray[0]); i++)
    // one pixel = 4 bytes in the screen buffer 
    *((unsigned short int*)(fbp + i * 4)) = imageArray[i];
  munmap(fbp, screensize);


That’s all. Simple as that.


Mindstorms EV3 without modification has 4 level grayscale display

Until now, we have programmed the EV3 bricks with the standard Lego programming software. Using messages to send commands from the PC and to retrieve status information from the EV3’s (this was not trivial, see this article

Programming the EV3’s with the standard programming language has as anything pros and cons. A major drawback, is that you can not do complex math. So we decided to convert all EV3 programs to EV3DEV and the C++ language.

I started this weekend with learning the EV3DEV environment and wrote my first, small test programming (pressing a touch sensor = motor rotates). Reading the manuals, learned me that you can do much more with the EV3 than with the standard programming environment.

For example, you can address the two LED’s on the brick separately. And it can also display four different grayscales on the display:

And this is all standard available!

Watch the short video on Youtube to see these features in action (click on the photo above).

Some useful links to get started:

Delta Crane will be replaced by Container Loading Station

For our layout in 2020, we will replace the Delta Crane, the module that was responsible for loading the containers from the conveyor belt to the wagons. You can see the Delta Crane in action in the following video (start at time frame 3:09):

One of the biggest disadvantages of the crane, is its speed. Or its slowness, that is a better description. In order to decrease the total running time (from color selection to candy delivery), loading of the wagons is now one of the bottlenecks.

So, I started to think about a new way of loading the train. How do I get the containers from the belt, to the wagons ….?

Another conveyor belt? No, to straight forward.

A push mechanism (kind of reverse of the delivery station)? No, been there, done that.

A robot arm? Yeah, that could work but is that special enough?

(quite some time passing by …)

And then I came with something completely new, as you can see in the following video:

At the left, you can see (a simplified part of) the conveyor belt, on the right you see the (simplified) train. The superstructure in the middle is able to move back and forth, so it can reach the four wagons without moving the train. In this first prototype, I can only move the superstructure by hand. But of course, this will be automated as well using sensors to detect the 4 wagon positions.

You can find renders of the final result at our Flickr page (click on the photo below).

Lego Monorail EV3 – Automated Switch

A monorail without a switch track is not a real monorail πŸ˜‰

I have been working on an automatic switch for the Lego Mindstorms EV3 monorail. The idea is that there will be a monorail track on our layout with two reverse loops. The loops will each have a switch and the train will need to set the switch in the right position. One reverse loop will be at the delivery station, where the empty containers can be loaded onto the monorail. And the second reverse loop will be at the Candy warehouse, where the empty containers will be dropped. For this year, the (un)loading of the empty containers will be manually. It just saves time to walk between the two locations with the empty containers. Yes, I know this sounds lazy and yes, it is.

In the video below, you see version 1.0 of the automated switch. Currently, the switch is powered by a PF motor. The train was simply programmed to run and switch direction when it noticed a the green tile (on the left, not visible in the video), a red or a yelow tile. Meanwhile, I was operating the switch with a PF remote control.

The next update will be a finished reverse loop, including a second EV3 that controls the switch. The train-EV3 will communicate with the Switch-EV3 to set it in the right position.


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: and videos are available at Youtube:

Enjoy reading,


Pneumatic compressor for the 6-axis robot arm with auto start/stop

The grabber of the robot arm is opened and closed by pneumatic pressure. Therefore, I needed an air compressor that can generate a pressure of approx. 20 – 30 Psi. But how do you manage this air pressure? If the motor keeps running, the air pressure becomes too high. If you switch the motor on and off manually, you need to stay alert and watch the manometer if the air pressure doesn’t become too low. The solution: build an automatic start/stop system. In this article you can read how I achieved this.

Continue reading “Pneumatic compressor for the 6-axis robot arm with auto start/stop”

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”

How to? Synchronizing two threads

In the EV3 programming environment, it is possible to start multiple threads. For example, you want two motors to run simultaneously and when both motors are finished, you want to play a sound. But there is no default mechanism in the programming environment to continue with the main thread when the second has also finished. InΒ  the example below, the “Ready” sound is played too early if motor A finishes before motor B is finished.

Continue reading “How to? Synchronizing two threads”

Loading the train with the 6-axis DOF robot arm

I wrote a small test program for the robot arm to load the train with two containers. Loading the two wagons was done in one minute, so much faster than the candy crane.

Have a look at the video and please share with me what you think of it.