Adventure #8 – An outdoor adventure

In my latest adventure I am taking on a charity walk which I devised for myself. I am walking the entire length of the Suffolk Coastline which is approx 100km.

The walk itself looks a bit like this

To support my walk I have OS Maps using Viewranger for Android, the Ordnance Survey App itself and some paper maps, but as an absolute backup I took on a small electronics project to repurpose a development board into a GPS.


#1 Display the British National Grid reference from GPS location

#2 Display my location on a map image of some sort


Board selection

I started with what I had lying around, it needed a UART, SD card slot and a screen. So I found my EMF Camp Badge (MK3) from 2016.

SD Card Slot on the back

UART pins exposed across the top

320 x 240 colour display

D Pad and Buttons



Boot from SD card

I copied across the main scripts from the Mk3 Badge master zip file and ensured it was loading the boot and main scripts from the card, this was very easy.


WGS84 to British National Grid

Firstly I decided I should sort out converting the decimal WGS84 to BNG. I found some C code on a forum which I tested on an Arduino, then converted it to python and modified it to produce the BNG in the format i.e “TM123456”

#definitions for geometric conversions
deg2rad = 0.017453292519943295 #(PI / 180)
rad2deg = 57.29577951308232087 #(180/ PI)
a = 6377563.396 # OSGB semi-major axis
bb = 6356256.91 # OSGB semi-minor axis
e0 = 400000 # OSGB easting of false origin
n0 = -100000 # OSGB northing of false origin
f0 = 0.9996012717 # OSGB scale factor on central meridian
e2 = 0.0066705397616 # OSGB eccentricity squared
lam0 = -0.034906585039886591 # OSGB false east
phi0 = 0.85521133347722145 # OSGB false north
af0 = 6375020.48098897069 #(a * f0)
bf0 = 6353722.49048791244 #(b * f0)
n = 0.0016732202503250876 #(af0 - bf0) / (af0 + bf0)
WGS84_AXIS = 6378137 # a
WGS84_ECCENTRIC = 0.00669438037928458 #e
OSGB_AXIS = 6377563.396 #a2
OSGB_ECCENTRIC = 0.0066705397616 #e2
_xp = -446.448 #OSGB/Airy datums/parameters
_yp = 125.157
_zp = -542.06
xrot = -0.000000728190149026 #_xr -0.1502 (_xr / 3600) * deg2rad
yrot = -0.000001197489792340 #_yr -0.247 (_yr / 3600) * deg2rad
zrot = -0.000004082616008623 #_zr -0.8421 (_zr / 3600) * deg2rad
_sf = 0.0000204894 # s=20.4894 ppm
LETTERS = [ [ "V", "W", "X", "Y", "Z" ], [ "Q", "R", "S", "T", "U" ], [ "L", "M", "N", "O", "P" ], [ "F", "G", "H", "J", "K" ], [ "A", "B", "C", "D", "E" ] ]

def right(s, amount):
return s[-amount:]
def left(s, amount):
return s[:amount]

def Marc(phi):
return bf0 * (((1 + n + ((5 / 4) * (n * n)) + ((5 / 4) * (n * n * n))) * (phi - phi0)) - (((3 * n) + (3 * (n * n)) + ((21 / 8) * (n * n * n))) * (sin(phi - phi0)) * (cos(phi + phi0))) + ((((15 / 8) * (n * n)) + ((15 / 8) * (n * n * n))) * (sin(2 * (phi - phi0))) * (cos(2 * (phi + phi0)))) - (((35 / 24) * (n * n * n)) * (sin(3 * (phi - phi0))) * (cos(3 * (phi + phi0)))))

def LLtoNE(latConv,lonConv,heightConv):
latConv*= deg2rad # convert latitude to radians
lonConv*= deg2rad # convert longitude to radians
v = WGS84_AXIS / (sqrt(1 - (WGS84_ECCENTRIC *(sin(latConv) * sin(latConv)))))
x = (v + heightConv) * cos(latConv) * cos(lonConv)
y = (v + heightConv) * cos(latConv) * sin(lonConv)
z = ((1 - WGS84_ECCENTRIC) * v + heightConv) * sin(latConv)
# transform cartesian
hx = x + (x * _sf) - (y * zrot) + (z * yrot) + _xp
hy = (x * zrot) + y + (y * _sf) - (z * xrot) + _yp
hz = (-1 * x * yrot) + (y * xrot) + z + (z * _sf) + _zp
# Convert back to lat, lon
lonConv = atan(hy / hx)
p = sqrt((hx * hx) + (hy * hy))
latConv = atan(hz / (p * (1 - OSGB_ECCENTRIC)))
v = OSGB_AXIS / (sqrt(1 - OSGB_ECCENTRIC * (sin(latConv) * sin(latConv))))
errvalue = 1.0
lat1 = 0
while errvalue > (1/1024):
lat1 = atan((hz + OSGB_ECCENTRIC * v * sin(latConv)) / p)
errvalue = abs(lat1 - latConv)
latConv = lat1
output_airy_elevation = p / cos(latConv) - v
# Convert OSGB36/Airy into OS grid eastings and northings
# easting
slat2 = sin(latConv) * sin(latConv)
nu = af0 / (sqrt(1 - (e2 * (slat2))))
rho = (nu * (1 - e2)) / (1 - (e2 * slat2))
eta2 = (nu / rho) - 1
pp = lonConv - lam0
IV = nu * cos(latConv)
clat3 = pow(cos(latConv), 3)
tlat2 = tan(latConv) * tan(latConv)
V = (nu / 6) * clat3 * ((nu / rho) - tlat2)
clat5 = pow(cos(latConv), 5)
tlat4 = pow(tan(latConv), 4)
VI = (nu / 120) * clat5 * ((5 - (18 * tlat2)) + tlat4 + (14 * eta2) - (58 * tlat2 * eta2))
output_os_eastings = e0 + (pp * IV) + (pow(pp, 3) * V) + (pow(pp, 5) * VI)
# northing
M = Marc(latConv)
I = M + (n0)
II = (nu / 2) * sin(latConv) * cos(latConv)
III = ((nu / 24) * sin(latConv) * pow(cos(latConv), 3)) * (5 - pow(tan(latConv), 2) + (9 * eta2))
IIIA = ((nu / 720) * sin(latConv) * clat5) * (61 - (58 * tlat2) + tlat4)
output_os_northings = I + ((pp * pp) * II) + (pow(pp, 4) * III) + (pow(pp, 6) * IIIA)
xf = output_os_eastings/500000;
yf = output_os_northings/500000;
s1x = (trunc(xf)) + 2;
s1y = (trunc(yf)) + 1;
s1 = LETTERS[s1y][s1x];
xf = (output_os_eastings % 500000)/100000;
yf = (output_os_northings % 500000)/100000;
s2x = trunc(xf);
s2y = trunc(yf);
s2 = LETTERS[s2y][s2x];
output_grid = s1 + s2
output_east = right(str(trunc(output_os_eastings)), 5)
output_north = right(str(trunc(output_os_northings)), 5)
output = [output_os_eastings, output_os_northings, output_airy_elevation, output_grid, output_east, output_north,s1x,s1y,s2x,s2y]
return output

Connect a GPS

The next step was to put a real GPS on it and get a location back. I selected a ublox Neo-6M and mounted it (shoddily) to the back of the Badge. It could have been much more compact, I won’t risk changing it now with 1 week to go to the start of the walk (28/09/20). I 3d printed an antenna mount and glued the antenna to it. It is connected with some header pins, so I could change it in a future revision. I wish all these boards layed out the UART or SPI or I2C pins in the space order and spacing, because it is a bit of a pain.

I tried the default large ceramic active antenna, a small ceramic active antenna, a small passive lcb antenna, and a wifi antenna (cut down to 1/8th wavelength) and found that while they all worked, this large ceramic antenna seemed to perform the best in real world test.

Interfacing GPS

I found a python module online micropyGPS here

I quickly ran out of RAM and had to take an axe to the module code and chop out stuff I wasn’t using (speed calculations & logging)

It was simple to interface the module, in the main loop it just reads characters from the UART and passes them into the module and prints them to the serial port (for testing the GPS)

my_gps = MicropyGPS()
my_gps.coord_format = "dd"
uart = UART(3, 9600, read_buf_len=1000)

while uart.any():
----char = chr(uart.readchar())
----my_gps.update(char) # Note the conversion to to chr, UART outputs ints normally
----output += char
----if (char == "\n"):
--------print (output, end = '')
--------output = ""

The location can be grabbed and converted

lat = float(my_gps.latitude[0])
long = float(my_gps.longitude[0])
location = LLtoNE(lat,long,0)

Interfacing the screen

Working with the screen is simple with ugfx, here are some examples I used

ugfx.text(3, 0, str(location[3] + "_" + location[4] + "_" + location[5]) + " ", ugfx.BLACK)

Loading maps

To meet objective #2, I loaded the SD cards with some gif files that represent each 1km square for example TM1941.gif, TM2041.gif etc and loaded up the current tile.

ugfx.display_image(0, 0, strimage)
ugfx.display_image(240, 0, strimage_east)

strimage is the path to the current 1km tile, and strimage_east, is the tile to the east of that. this is because the tiles are 240×240 pixels, but the screen is 320 wide, so I get 80 pixels of the next tile displayed as well to use the screen real estate.

Final result

Once I put some logic around all the examples above to take input from the buttons and added code to draw the battery voltage and cursor. Here is a video demo.

These maps bear some similarity to the Ordnance Surveys maps, but they are of course not, these few maps tiles shown here were digitally recreated by myself using mspaint 😀

Consumer Advice #1 – Samsung C27HG70 setup for Win10 gaming

Hey. In this quick blog I outline the settings I used to make the most out of my new monitor. It took a while to get right, but once its right the C27HG70 makes for an all round decent display.


Some key technical details about the display

  • Aspect Ratio 16:9
  • Display Type QLED monitor / TFT active matrix
  • Features Black eQualizer, 92% Adobe RGB colour gamut, FPS Mode, Flicker Free technology, RTS Mode, Eco Saving Plus, Eye Saver Mode, Low Input Lag, Quantum Dot Technology, 125% sRGB colour gamut, Super Arena Gaming UX, 88% (NTSC 1976) colour gamut, HDR (high dynamic range), Screen Size Optimizer, Refresh Rate Optimizer, Game Color Mode, Custom Key
  • Energy Class Class D
  • Energy Consumption per Year 91 kWh
  • Power Consumption (On mode) 62 W
  • Diagonal Size 27″
  • Viewable Size 26.9″
  • Curved Screen Yes (1800R)
  • Adaptive-Sync Technology AMD FreeSync
  • Built-in Devices USB 3.0 hub
  • Panel Type VA
  • Native Resolution Ultra WQHD 2560 x 1440 at 144 Hz
  • Brightness 600 cd/m²
  • Contrast Ratio 3000:1
  • Colour Support 1.07 billion colours
  • Response Time 1 ms
  • Horizontal Viewing Angle 178
  • Vertical Viewing Angle 178
  • Backlight Technology LED backlight
  • Colour Matte dark blue grey
  • Dimensions (WxDxH) 62.48 cm x 39.07 cm x 55.67 cm – with stand
  • Weight 6.3 kg


A setup for flexible gaming and casual desktop use.

  • Windows 10 Pro
  • Intel i7 8086K
  • nVidia RTX2080 Super

Displayport cable

The first thing I needed to do to set this up is take the Samsung Display Port cable that came with the display, open a window and throw it out towards the garbage. It was useless, the screen would continually flicker horribly. Even a Belkin cable I bought from Poundland 8 years ago did a better job !

I recommend getting a Displayport certified cable or even raiding the local poundland it seems.

Resolution and colour depth

Set the native resolution for the screen. 2560 x 1440 @ 144Hz and enable 10 bits per channel colour depth and full dynamic range.

Adaptive Sync

Don’t forget to turn on nVidia Gsync

Colour profile

It is useful to tell your operating system what colours the display can output. Samsung provide a .icc profile file for this.

Screen setup

Use the on-screen controls (little d-pad button to the rear right of the screen)

I set it as the following :

I found the contrast and sharpness to be particularly important to reduce “VA glow”. For a few weeks I would notice that in the darker parts of some games, when the screen is changing (walking forwards) some objects would emit a glowly edge. I came to found that this is known as “VA glow”. Due to the panel technology this is a common problem. Some users attributed it to the freesync technology. I was able to tune the settings to avoid the glow. Setting the sharpness below 60 really seemed to exacerbate it the problem!


Don’t be tempted to turn HDR on for the desktop for general use, it seems to reduce the tonal depth of the desktop and give it a high brightness, low contrast glimmer look. However, if you consuming HDR content full-screen from either Youtube, VLC or a Bluray player, then do turn it on for that session, it really does make HDR content look impressive. Not something I can really show you here !

Game tuning

Some games let you set the max FPS the game will run at, this will help reduce heat from the graphics cards for games that would usually run at the max refresh rate of the display (144fps). In Witcher 3, I have to set it to unlimited as it only has an option for 30 or 60 (probably being an older game).

With the adaptive sync technology enabled, I can get 90 fps in Witcher 3 and it looks really smooth, again I can’t show you but it is impressive looking.

Hope this has been helpful.



Coronavirus Update

In line with the latest government advice we are cancelling our regular meetings, effective immediately. As the situation changes we will keep you updated. If you need access to the space to collect personal items, tools, projects etc please let us know and we will arrange a date and time.

Adventure #6 – CNC PCB

In this adventure I attempt to get the Roland Camm-2 2300/A CNC machine to mill a PCB into some copper board. This is what the temporary setup looks like. I have the CNC machine, laptop, and an old XP machine.

We have procured a set of tools for the Roland specifically for milling and drilling PCBs. I started by testing on some polystyrene (as in the above), which seemed to go OK so I thought I would move to my PCB project. I took the Copper layer and converted it to a bitmap such that Dr Engrave can import it. It was at this point I knew I was in too deep and it could only go wrong.

I stuck down the copper board with some double sided tape. After some fiddling with the tool settings and trying to position the tool itself correctly on the Z-axis, I pressed the “print” button and closed my eyes! There was not too much I could do at this point, it was either going to start neatly cutting out the tracks or crash into the end and start eating itself. My polystyrene test did not fill me with any more confidence, but my hand was positioned over the emergency stop button.

After a few minutes of whirring and buzzing, I was presented with this (below)  🙁

It’s not what I expected, but for my first attempt I suppose it could have been worse. Let me take you through it.

  • Its not cut evenly at all, there must be some severe levelling problems with the bed and/or the material
  • The tracks are very thin and pretty wobbly looking
  • The tool hasn’t lifted off properly and has wiped a skid mark across it
  • The pads are very small and wont take drilling without disappearing entirely
  • The “toothed” button pads are a mess, one is just a gaping hole

Next steps are to:

  • Get a fatter tool to mill the wooden bed flat
  • Make a jig and/or test sticking down the copper much flatter
  • Redesign the layout with fatter tracks that are father apart
  • Test cutting out the edge cuts
  • Test drilling to through holes
  • Try again

Thats all for today, I will keep you updated on the progress.

Adventure #4 – SNES Controller Distraction

Instead of trying to finish off one project at a time, I got distracted with dissecting a SNES controller. In this brief project I am converting it into an XINPUT compatible controller by way of a custom PCB and Teensy LC.

Firstly I cracked open the case a got a good look at its innards. Its made up of the PCB, buttons and rubber parts with conductive pads.

The challenge is to fit a Teensy-LC into the case, in roughly the same size PCB. As with my other XINPUT Teensy project, each button needs wiring to GND and a GPIO. I decided to upgrade the controller a bit by adding a Neopixel.

The schematic shown below uses:

1 Teensy-LC component for Kicad
10 push switches for the top buttons
pin headers for shoulder buttons and grounds
1 x Neopixel plus is resistor and capacitor

The layout took a few iterations and much measuring before finalising it. My first challenge was to create a footprint for the button contacts.

In order to make pads of custom shape, I needed to upgrade to Kicad 5. To make the custom shape, one had to create a pad, then draw the rest of the irregular shapes using “graphic lines”. Once done, select them all, RMB and use “Create Pad from selected shapes”. The gaps between pads are 0.5mm.

I found a 3d render of a teensy-lc and modified it a bit to suit the project. This enabled me to visualise the fit. The teensy reset button made need poking out of the back of the case (or removing)

click to embiggen

The code is this time based on MSF Flightstick, which is a very easy way to make an XINPUT compatible device. I should really have done something cool like put an accelerometer in it. I think the next one might be wireless. I have found some sweet looking 433MHz modules “HC-12”, which I will mess around with in another blog. Here is it printed out and placed in the case, if only I could laser print copper.. It isn’t as badly aligned as it looks, that is just the parallax effect. It is that filthy though!

As I can get away with not plating the through holes I am tempted to use the recently renovated CNC milling machine in the makerspace to make the board. OSHPark nicely gives me the various layers, top and bottom copper, soldier mask and silk screen and drills. I guess I would have to figure out how to generate those layers myself from Kicad and make sure the dodgy Roland software running on Windows XP can understand it. I will also need to research if I can add soldier mask myself and how I can mask the pads. Yet another blog I think! I will do a seperate blog on my attempts to resurrect the Roland PNC-2300A!

Once I have produced a board and tested it, I will link to that blog from here 🙂 That is all, until our next adventure.


Coderus Sponsorship

Software design engineering company Coderus, based at Martlesham, has announced a sponsorship deal with the Ipswich Makerspace which will see staff from the firm get involved with the community tech and making hub. In return for their support, employees from Coderus will be invited to make use of the equipment and facilities available at the Makerspace’s Dove Street facility.

Coderus has a long-standing commitment to engaging with its community and feels that it shares the same core values and passion about technology as the Ipswich Makerspace. Pillar drills, laser cutters, CNC machine and 3D printers are some of the equipment that the members can use among a wide variety of tools for any type of craft or project. Tech enthusiasts will also have the opportunity to work on either individual or group projects, with free soldering consultation as an option. Each Coderus member will have the opportunity to visit the Makerspace and work on projects, as well as attending the regular meetups and in-house projects.

“From modern hardware to traditional crafts, Ipswich Makerspace fits perfectly the interests of our team”, said Mark Thomas, Director of Coderus. “It has been really nice seeing some of the guys using the laser cutter and the 3D printers for their own projects already. Stephen Chalkley has welcomed us all.”

Stephen Chalkley of the Ipswich Makerspace said: “We’ve grown from a small group meeting in a draughty church hall to having our own building in just a few years. Our members have an enormous range of experience and skills and they are very generous about sharing them. Being sponsored by Coderus is a great validation of our efforts and we’re looking forward to working with them.”

“There’s a great synergy between Coderus and the Ipswich Makerspace as they both provide fertile ground for innovative ideas.”

Adventure #3 – If I could chuck wood….

Merry Christmas adventurers. In this adventure I am building the frame for my arcade machine. It is built of Wickes’ finest 12mm MDF. It is held together with pine and prayer. My brother and I used the tablesaw to cut the front, sides and back. In this image it is waiting for its face.

I have stripped down an LCD monitor and mounted it in the frame.

After getting the frame together and standing in front of it, it only really seemed big enough for 2 players. I have tested mounting the joysticks.

Kindly Ipswich Makerspace’s own superhero Adam helped laser out the screen surround on “Helios” the big laser.

It me

Outstanding jobs

  • Build replacement button PCB to control the LCD
  • Procure PC parts and mounting system
  • Install IEC C14 connector and power button
  • Vinyl wrap
  • Finish and polish the turd game in Unity
  • Unleash it on people

Look out for my other adventures where I go off down rabbits holes, such as:

  • Write a new game! and build its artwork
  • Convert a SNES controller to XINPUT compatible
  • Build my own gaming mechanical keyboard
  • Hack a Boilermate 200 PCB into a “Smart” Boiler
  • Macro photography
  • Learning Finnish and the Piano
  • Something to do with my day job, I forget what it is now, probably Internet or phones or something.

Adventure #2 – Lathing away

Afternoon adventurers. As part of my project to build an arcade case for Laser Defender game, this weekend with my good friend Matt G, he has been instructing me in the ways of the metal worker.

To test out the analog axis of my Teensy USB gamepad, I needed some potentiometers, which needed finishing with same handles. I found some old kitchen drawer handles and put them to work on Matt’s lathe.




Input Device #1 : Thottle control

A 10K slide pot with kitchen drawer handle

This works great as a throttle control in “Simple Planes”, next step is to build a housing for it, or maybe integrate it into a custom keyboard project.

Input Device #2: Turny handle thing

Yeah I dunno what this is really for, but its a turny handle thing. Im sure I’ll want a turny handle thing at some point.

Arcade stick

Actually all of the lathing was really for helping make some metal adapters for mounting rumble pack motors to my XINPUT arcade sticks, which look a bit like this. These are 2 separate parts “smushed” together (technical term).

When mounted on the stick, look a bit like this (rumble motor up underneath).

That’s it for now. Hoping to get my circuit boards next week!