The LEGO MINDSTOMS EV3 has a very small display, dificult to use for complex tasks.
Most of the time I use it through SSH so the display doesn’t bother me but sometimes, when autonomy is needed, I find myself thinking how great would be if I could use something like like a large TV or a video projector.
Yes, we can do it with something like a laptop or a Raspberry Pi as a “proxy”. But now we can also do it with a Google Chromecast:
I installed lighttpd (a light web server) on the EV3 and configured it to listen to port 3000. Then I used pychromecast to make my Chromecast “play” JPEG files present on the EV3 web server – a JPEG file for each value or message that I want to show on TV.
Here the script I used in the video:
#!/usr/bin/python3 from ev3dev.ev3 import * from time import sleep import pychromecast us = UltrasonicSensor() bt = Button() DELAY = 0.01 DELAY_PLAY = 1.75 # 1.5 NOT OK chromecasts = pychromecast.get_chromecasts() cast = next(cc for cc in chromecasts if cc.device.friendly_name == "NOMAD") cast.wait() mc = cast.media_controller print("Blacking chromecast...") mc.play_media('http://192.168.43.104:3000/black.png', 'image/png') sleep(5) mc.stop() mc.play_media('http://192.168.43.104:3000/pressanykey.png', 'image/png') while bt.any() == False: sleep(DELAY) mc.stop() last_dist=-1 while True: dist = us.distance_centimeters/10 if dist != last_dist: mc.play_media('http://192.168.43.104:3000/'+str(round(dist))+'.png', 'image/png') sleep(DELAY_PLAY) mc.stop() last_dist = dist
“NOMAD” is the name I gave to my Chromecast on setup, the script finds it by name so I don’t have to bother with the IP address when I take it to another place or event.
“192.168.43.104” is the IP address of my EV3. A better script will find it by itself.
The JPEG files that contain the numbers were generated with another script:
#!/usr/bin/python3 from time import sleep from PIL import Image, ImageDraw, ImageFont txt = Image.new('RGB', (320,240) ) fnt = ImageFont.truetype(font="/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf", size=75) d = ImageDraw.Draw(txt) for x in range(0,256): # fill image with black txt.paste((0,0,0) , [0,0,320,240] ) # (x,y) from top left , text , font, (R,G,B) color d.text( (90,80), str(x).zfill(3) , font=fnt, fill=(255,255,255) ) txt.save('/var/www/html/'+str(x)+'.png')
This last script needs to be run with sudo because it writes to the webserver content folder (“/var/www/html/”) and since I let the default permissions unchanged the default (‘robot’) account cannot write on it.
This method is far from perfect – the Chromecast is good for streamed content but not so good for static content. I cannot switch from an image to another in less than 1.75 seconds (and not sure if even 1.75 doesn’t get me in troubles) and when doing it the image flikers. And the Chromecast caches the files so when I change anything (say the “press any key” image) I have to reboot the Chromecast to clear the cache.
So this script is also very useful (and boy, how I hate rebooting something)
#!/usr/bin/python3 from time import sleep import pychromecast chromecasts = pychromecast.get_chromecasts() cast = next(cc for cc in chromecasts if cc.device.friendly_name == "NOMAD") cast.wait() cast.reboot()