Hardware Posts

Mindstorms ev3 Football

posted in Python, Hardware at 08 September 2017

In my sixth form, I worked as part of a team to make a Mindstorms ev3 robot play football using ev3dev (a loadable Linux OS for the ev3) and Python.

Our Robot (sorry about the image quality, for some reason all of my images of it were missing so all I had was a video of it)

The Robot

DARWIN, our robot, consists of the following components. It has two independent motors and a caster for flexible movement, and a third motor to apply backspin to the ball so that it stays in the robot's grasp. It has a rotation sensor to detect whether it has been pushed off course and a colour sensor to look at the pitch and its lines to make sure it isn't going off the pitch. It also has an ultrasonic sensor to look for a goal and other robots, and an infrared (IR) sensor to look for the ball.

Our Strategy

This robot was designed to score goals rather than just defend, so with that in mind it has a simple plan: find the ball, grab the ball and then score a goal with it. This essentially means it has two states, which we'll get to later. While it doesn't have the ball, it uses the IR sensor to find out what direction the ball is in and moves towards it. If it can't find it at all, it just spins on the spot until it sees it.

The biggest problem we faced was that the IR sensor was unreliable at very short distances, causing it to produce very weird values suggesting that the robot should take a sharp right when the ball is right in front of it. To deal with this, the robot ignores values corresponding to very sharp turns and rather than directly acting on the value it receives keeps calculating the average of the last few readings. We also ignore the IR sensor completely once the robot has the ball, which is done by monitoring the speed of the backspin motor - if it has slowed slightly, we know the ball is likely underneath it so we have it.

To detect the goal, we use both our rotation and ultrasonic sensor. If we have the ball, are facing the right way and detect an object, we assume it is the goal and attempt to score. For collision detection, we turn left or right randomly to avoid the object, and then get back to our original path.

The Code

Because our robot essentially has a few states it can be in, Kirsty cleverly realised that our code could be structured in that way also. So, our main loop in the code is:

functions = {"moveToGoal": moveToGoal, "retreat": retreat, "shoot": shoot, "lookForBall": lookForBall, "realign": realign}
while True:
        state, ro = functions[state](ro)

Where ro is our Robot Object, which contains some key-value pairs of information. Every function returns a state and newly-modified object once done, so we have effortless switching between states.

These stats are organised as follows. Our main state is lookForBall, which in a surprising twist looks for the ball. It reads the IR sensor, keeps track of the average and turns in the relevant direction. This returns its current state unless it turns out it has now got the ball, then it moves to realign. Realign rotates the robot until it is facing the right way, then moves on to moveToGoal (or lookForBall if it loses the ball while rotating). In moveToGoal we move in a straight line and try to score (changing to the state shoot), changing to realign if we get knocked in the wrong direction. The state shoot is self-explanatory.

The final state that we've not covered is retreat, which is when it detects the white line surrounding the outside of the pitch. When it does this, it reverses, makes a quarter turn and then goes back to realign. This can be called while the robot is in moveToGoal. Illustrated, this state system looks like this:

State Diagram

Turns out if you can split a program up like this, it looks really nice.

Work at Tech Will Save Us

posted in Arduino, Web, Hardware at 01 September 2017

For most of the last few summers (2013-2016), I have been at Technology Will Save Us (a London-based tech startup that makes kits to teach children about electronics and programming) for summer work. Spending time there has let me work on some very cool stuff on some of their kits and their website, including:

The DIY Gamer

For the DIY Gamer Kit, I was able to work on part of the library (creating a font for printing words to the display, and working on the beginnings of its IR functionality) and also code the game Snake for it. I also worked on an implementation for the game Simon Says, providing code that was easy for a beginner to read and understand. Multiple versions of the code were provided so that people could work through each version, slowly adding features until they had the complete game. I then combined these games into one program that allows you to switch between these two games, Pong and Breakout.

I also prototyped a scoreboard for the Gamer, which had an IR receiver and three seven-segment displays so it could display the highest score it had received for each game.

Website Work

During one of the summers I worked on elements of the website, helping them shift it over from Wordpress to a Mustache templating system based setup. This involved rewriting pages to suit the new format. I also worked on their (previously live, not sure what happened to it) Meet The Team page, which involved writing Javascript to not load full animated GIFs. In the end I had to load the GIFs via Javascript. Previously I'd tried only loading the GIFs while hovered over, but this required giving users instructions about how to use the page which is a bad sign for something as simple as the Meet The Team page.

MicroBit Compiler

In the summer of 2016, I worked on a preliminary web-based compiler for the MicroBit kit for TWSU's online interface for programming it. This involved researching what compilers are available and discussing what language to translate the online interface into (the online programming environment is block-based, so would be translated into code before compilation). This also involved writing some Node.js to actually build this.

In the end I built two compilers, one which compiles Arduino code and one which attaches an interpreter to Python code.

Other Work

I did some work attempting to get a desktop application for programming Arduino boards from the web working on Windows, my favourite (read: not favourite) operating system. This involved working with formatting system paths and various options to get the Arduino npm module to even consider working.

I also got to experiment with compilation over audio and while I didn't get very far with it, I learned a lot about how Arduino code is compiled and controlling audio using the Web Audio API.

I also helped out at a few of their workshops helping people program and use some of TWSU's kits.

Only Connect

posted in Love2d, Hardware at 01 September 2017

Some backstory: one of my teachers at sixth form was an Only Connect contestant who thought that running our own Only Connect would be cool. So, I wrote software and created buzzers for our own version! This was made in February 2015, although at the time of writing this post I'm rewriting some of the code to prove I have improved and do know how to use a for loop.

Only Connect Software

The Software

The application is written LÖVE 2d, a library for making games in Lua, and also the only thing I knew how to make graphical applications in at the time. Whoops. Needless to say, for making GUIs, this is a mistake. But anyway, a few nice things came out of it. This application can run an entire Only Connect show including tiebreakers and can be controlled with just your keyboard rather than fancy special hardware (more on that later). It features nice animations, a way to read sets of questions from file and a host console that tells the host what the scores are and who should go next (which is just a bunch of print statements to console, nothing special there).


The animations are done by defining linear tweens that can be used throughout the code. A tween is stored as a Lua table containing its start value, end value, length and how much time has elapsed. When updated with updateTween(tween), this internal count of how much time has elapsed is updated. When getting the current value of the tween with val(tween), it just does start + (end-start)*(time/total_time), as you would expect from a linear transition.

These are used throughout the program to make things glide across the screen rather than teleport. It is also used to fade between colours, for example when a hieroglyph is selected, it fades to and from the new colour with three tweens - red, green and blue value.

Reading Questions from File

| round 2
Toy Story Movies~Toy Story;Toy Story 2;Toy Story 3;Toy Story 4 (Coming Soon!)
Composite Numbers~20;21;22;24
*Grades In Some Rythmn Games~C (about 60%);B (about 70%);A (about 80%);S (about 90%+)
Noble Gases~Argon;Krypton;Xenon;Radon
Note Lengths~Crotchet;Minim;Semibreve;Breve
| round 3 #1
Types of Netrunner Card~Operation;Hardware;Program;Resource
Synonyms for Situation~Problem;Predic -ament;Situation;Event
| round 3 #2
Programming Languages~Go;C;Python;Java
Action Words~Stop;Wait;Run;Hop

Here is part of an Only Connect question file. In importer.lua, we import this as the questions by putting them in the relevant Lua tables and splitting up the clues. The format is pretty simple: | starts a comment, ~ splits a question and answer and ; separates answers. We also have * and $ prefixes which mark the picture and music rounds respectively, which look for the pictures and music files present in the folder shared with this questions file. The code for converting these is mostly just multiple applications of string.gmatch, so is uninteresting. But the format itself is quite nice.

Actually Displaying Things

This isn't very special, and mostly just involves drawing things at certain positions on screen. It does account for changing the size of the screen, however: a scale variable is defined based on the height of the window, and everything is multiplied by that scale. This meant that everything could be tested at one screen size and would automatically work for others. A second scale variable is also defined that works out how much wider it is, so that even if you just change the width and not the height, the elements will move to centre, such as on a particularly wide screen.

The Hardware

Only Connect Hardware

The hardware, despite looking like a mess of wires, is relatively simple. We have some arcade buttons attached to a MakeyMakey, which converts electrical input into keypresses. There are four total boxes - two with just a single button that acts as a buzzer for each team, one to house the MakeyMakey and one for the host. The host box has three buttons - one to say the team was correct, one to say the team was incorrect and one to move the question on (reveal new clues, move to the next question etc). The MakeyMakey could easily be replaced by an Arduino, but that would require an Arduino capable of simulating keypresses.