Sunday, 16 September 2018

You had one job

For my ESP8266 mesh project I plan on using ESP-01S modules if I can as I've got at least 16 of them kicking around, maybe more.

Should I need more they're the cheapest way to buy an ESP8266 module, especially with through-hole connections.

They're also very compact. The flipside of this is they only have a couple of conventionally usable GPIO pins and are a pain to work with in other ways. You can't use them in a protoboard because of the double row connector layout. You also need to pull several pins high for them to boot up, change that for programming and so on.

Which is why I've got a load of ESP-01S modules kicking around, I now use WeMos D1 mini boards most of the time I want to use use an ESP8266 in something.

With a view to using this stash of components up I bought these little special purpose USB-Serial "ESP-01S link" adaptors.

Which didn't work.

I was surprised as the stuff I get from Banggood is almost without exception good, I don't think I've ever had anything completely duff from them apart from this.

A bit of poking around showed they don't pull the CH_PD pin high, which is needed for the ESP-01S to boot. So I've soldered a little link on the bottom (see picture) and now they're perfect. With a button and a couple of more links they could be configured for programming the ESP-01S but I'm not fussed about that. I want these as diagnostic tools.

I've written some minimal code that lets you use one as a 'bridge' to painlessMesh over a USB serial port. It prints any incoming packets from the mesh in a simple text format and you can send unicast or broadcast packets. An ESP-01S in one of these adaptors makes for a nice tidy little 'dongle' to work with.

I might cook up a simple UI to get a list of nodes, topology and so on, but this is all I need for now.

Friday, 14 September 2018

Is painlessMesh really painless?

I should blog more, I have been doing stuff, honest.

Anyway I have plans for more mesh networked, location aware stuff. While I am going to try and sort out the Tilda EMF badges I have, the proprietary Ciseco radio tech in them is obsolete. It's great but I can't buy any more so need a new, cheap, way to put things together. Then maybe bridge the two technologies together.

Going back to the time when I was using the Ciseco radios, Wi-Fi on microcontrollers was a pain and expensive. Then the ESP8266 arrived and changed that. It's now cheap as chips and a very mature platform for tinkering with. Wi-Fi has loads of downsides for the sort of things I want to do but it is ubiquitous. So I'm going to do some evaluation of it as a basis for my next project of this sort.

I've settled on using the painlessMesh Arduino library to do the lifting for me and have just built a test node comprising of a WeMos D1 mini Pro with external antenna in a waterproof box along with battery, charging connector and some indicator lights.

You can configure painlessMesh nodes as being 'static' so they are more likely to be a hub in the mesh and my plan is to have a few boxes like this to help keep the wearable nodes in touch.

The painlessMesh API also includes some nice functions for finding out what nodes there are and how they're connected so I aim to build a tool that prints that out allowing me to check how well connected the mesh is and also 'ping' things to check them.

If ESP8266/32 and painlessMesh doesn't stack up I'll try LoRa, which should be better suited in some ways. However LoRaWan means playing nicely with the standard for gateways and this is very limited in bandwidth and talk time etc. Using just dumb broadcast LoRa radios would be antisocial to any nearby LoRaWAN and mean writing my own mesh network code. Again.

Monday, 25 June 2018

Resurrecting the Tilda MKe - part 1

A long time back I bought ten surplus EMF camp badges as they were exactly what I wanted as a platform for a networked handheld gadget I could use in LARP.

Now I'm going through a bit of a phase we're I'm reviewing all the stuff I have accumulated and deciding whether to keep it or not for future projects.

Looking at them now they are still pretty much everything you need for making some kind of small device with a basic UI, except Wi-Fi as they used Ciseco data radios instead. However I've a pot full of ESP-01 modules and also a small stash of Ciseco kit despite them going out of business. Tacking an ESP-01 on to one of the serial ports will give it the best of both worlds.

Wi-Fi might be ubiquitous indoors but for networking low resource microcontroller based things in remote outdoor environments it's actually OTT and the range sucks. Things like the Ciseco radios, or nowadays one of the LORA standards make much more sense but being able to connect to Wi-Fi if available is handy.

Which makes them keepers.

So I've made an attempt to do something with one. This particular one I 'killed' by trying to upload a basic 'blink' sketch to it shortly after I bought them and the whole lot have stayed stashed in a box in my cellar since.

The development libraries released at the time are now all rather 'legacy' and tied into a complicated framework that uses FreeRTOS to deliver multi-tasking. So while the Tilda is in principle Arduino Due compatible this makes it more of a job than just adding some libraries and getting on with it.

There's an onboard jumper for wiping the flash and after I used this, uploading a simple sketch to it like it was an Arduino Due got it responsive again. I'm not quite sure how I 'killed' it originally as this wasn't at all obscure or hard.

Unable to import all the board information into modern versions of the Arduino IDE I've been fishing in the header files and managed to make all the buttons & LEDs work, plus the Ciseco radio.

Not much luck with the screen yet, apart from turning the backlight on, as despite wading through the docs I haven't been able to work out which pins the screen driver is connected to. Worst case I'll attempt to disentangle the legacy library and shoehorn it into a modern environment.

There's also an MPU-6050 gyro/accelerometer but I'm not desperately fussed about that working.

If I can make a simple example sketch that drives the screen and most of the stuff I'll post it up.

Wednesday, 23 May 2018

I wanna introduce you to a personal friend of mine


Some time back, a friend who was giving up Lasertag LARP was getting rid of a bunch of their old kit. Amongst it was this 'Pulse Ranger' shell, made by some enthusiasts years ago who started up a small business to give people what quite a few wanted at the time: Pulse Rifles.

Because Aliens.

I've wanted a Pulse Rifle ever since I started sci-fi LARP so when he thrust this into my hands I was overjoyed. I had considered taking one of the 3D models there are kicking around and trying to turn it into something 3D printable on a normal hobby printer and with spaces inside to use, but that's a mountain of work.

These shells are very thick blow moulded ABS and tough as hell so it's weathered the years brilliantly. They're not perfect replicas but ape the silhouette very nicely and with a bit of work it should fill the gap I have in my set of Lasertag weapons.


Inside the shell were the remains of an old Lasertag circuit. It was an old board from an original Starlyte and looked a bit sad so I decided to scratch build a new set of electronics inside. This also gave me the chance to make a modern DoT weapon that does multiple hits and the grenade launcher is a nasty thing.

Also back in 1986, having an LED ammo counter on the side was pretty much the definition of cool. So it had to have something like that too. Nowadays we have so much cheap and useful tech around that sticking a little OLED display in is trivial.

With an OLED in there it opens up the option to display more stuff than just the ammo counter and I've been vaguely toying with the idea of having a UI in a 'tag weapon to select different sounds and so on. This will now be my test bed for that.

The shell doesn't have any meaningful mounts inside for the lens unit, so I 3D printed some spacers that hold it in the 'grip' section snugly when you screw the shell together. I epoxied it to one half of the shell, did it all up and left it overnight, making it rock solid. With no datum lines and the shells being somewhat flexible it's impossible to guarantee it's straight so I'll have to adjust the sight rails to suit once everything's together.

Then it just became a case of bashing all the wiring together, I already had one of my scratch built gun boards. Working with it reminded me that I really really should standardise it and get some proper PCBs printed, given how cheap it is, but one gentle weekend of faffing about and I have a Pulse Rifle.

Feel the weight.




Sunday, 4 March 2018

Glow worm upgrade

I'm playing a post-apocalyptic LARP in a month or so and I wanted a torch that didn't rely on batteries. You can get modern dynamo torches but they're usually very cheap plastic things. I saw this vintage Bakelite one and loved the aesthetic.

Sadly it makes an utterly useless torch. The output is akin to a knackered glow worm.
 I had a little look at the bulb assembly and figured I could cannibalise a modern bright LED torch for its LED/heatsink arrangement. There's no way it'd be as good as a modern torch but the massively improved efficiency of an LED should give more light from the dynamo.
Inside it's really nicely constructed. My reasoning for using this in the LARP even though it's set only a little way into the future is that the torch is physically robust and likely to survive the fall of civilisation.

In my experience, cheap plastic stuff from a decade ago has gone all brittle and started to die.
Quickly soldering a couple of wires to the bulb terminals got me about 6-7V AC output from the dynamo. This is in the right region to drive a typical LED torch. The voltage is a little high for the one I'm scavenging from but the current isn't going to be huge so I'm reckoning it'll be fine.

No use overthinking it.
With the LED soldered on, I instantly got a nice bright light when pumping the torch. As the output is AC the LED is flickering on/off but too fast to notice except when spinning up/down.

Success!
To get a little more even light and not 'waste' half the output from the dynamo I desoldered a bridge rectifier chip from an old PSU board and put it between the output and the LED. Sadly there's no space for a smoothing capacitor. A quick check with a meter showed about 5-6V DC.

I had to file the LED board down a little to squeeze it into the space the old reflector lived in, but nothing drastic.
All done, now the torch gives a very usable output when pumped. It's enough to light a dark room so you can see where you're walking. Outdoors it won't go far, but it's not for that. The lens is a fisheye one designed to make a very broad spread.

It would have been easy to get sucked into trying to make a proper regulated, smoothed PSU fit in the space but this has got me almost all the way there in a few hours of messing around.

Wednesday, 7 February 2018

Up Periscope

Wow, it's been a while.

I think I got intimidated by having to finish off what I was documenting before doing anything new. After a few months passed my enthusiasm about writing up something complicated that was well in the past faded. I may go back to it but don't hold your breath. So here I am with a really quick and dirty tool/prop.
I was away this weekend for a Sci-Fi LARP where I was playing an engineer investigating the return of a mysterious lifepod.

Amongst the players there was a fair chunk of tech kicking around even if it wasn't desperately necessary for the game. I dragged along a mountain of tools including a tablet with endoscope camera.

There were a few hours to kill on the day before the game and I decided to make a 'periscope camera' to complement the endoscope. The ubiquitous cheap USB endoscopes work OK but are fisheye devices focused at a very short distance for working in very small spaces.

This is the guts of a conventional webcam stuck on the end of a cannibalised Poundland selfie stick. It works great for looking over, under or behind things that are a pain in the arse to get over under or behind.

The webcam was one of 'XBox Live Vision' cameras I bought in bulk for a pound each a while back. These are basic but use the standard UVC webcam driver so work with almost anything.

I removed the IR-cut filter and with no casing in front of the board the green LED telltale lights provide some illumination so it's not too terrible in very dark spots. If I feel enthusiastic I'll make another with IR illumination, but this was a quick and dirty, no soldering allowed hack.

I think it will be useful. Tomorrow I'm taking it to work so I can use it inside a congested ceiling space and have a look round for a cable route.

£2 well spent.

Wednesday, 19 April 2017

Using a different tool for each job and linking them together with MQTT - part 3

Things you have to think about when putting a Raspberry Pi inside a prop include things you don't normally have to worry about like graceful startup and shutdown. Also, getting enough power out of a battery for a Pi 3 and a 5" display is not totally inconsequential.

I'll deal with the latter first. I luckily had a 5V/3A Turnigy branded battery eliminator (BEC) kicking around in a parts drawer. These are designed for RC vehicles and nicely self-contained in a shrink-wrapped module with inline inductor to smooth things out. I paired this up with a big chunk of 12 AA NiMH cells wired series/parallel to give me ~7.2V which is about right to run the BEC. The more modern solution would be some LiPo cells but then you need to build a balance charger into the device or expose the connectors so you can charge the cells individually. I've got a bunch of stuff that runs off NiMH cells and a nice high current smart charger that automatically selects voltage/current and this also influenced my decision to go this way.

Then there's the switch. People expect things to just turn on/off at the flick or press of a switch but you can't give them easy direct access to the power or they'll switch things off when they aren't ready. The Raspberry Pi really doesn't like that. There are workarounds you can do with mostly read-only filesystems but at the end of the day the Pi really should be shut down cleanly.

Luckily I had some Polulu solid state power switches lurking from a temporarily shelved project. My house may be overflowing with stuff but sometimes it comes in useful. I wired this so the power switch was connected to the 'on only' contact. That gets everything powered up. When you flick the switch to off, the alternate contact takes a pin on the Arduino low and the Arduino initiates a shutdown sequence. You saw the code for that in part 2. Here's the Python script for the shutdown of the Pi, which is just a variant on the old chestnut about fitting a shutdown switch to the case of a Pi.

#!/usr/bin/python
import time
import os
while 1:
  time.sleep(1)
  if os.path.isfile('/tmp/reboot'):
    time.sleep(5)
    os.system("sudo reboot")
  elif os.path.isfile('/tmp/poweroff'):
    time.sleep(5)
    os.system("sudo poweroff")
Not much to say about this, it just looks for files in '/tmp/' and reboots or shuts down depending on which file it sees. Stick it in /etc/rc.local again and the job's a goodun.

Things I didn't get right are I used a latching switch for on/off and I should have fitted a way to both charge the batteries and power the device externally.

The batteries lasted a couple of hours but then it had to be charged before it could be used again. We had mains power in the end so being able to use a PSU would have been good. Connecting the smart charger with it powered up made the charger shut down, otherwise that would have been an option.

The latching switch prevented me from making the box shut down when inactive. It would try to shut down (the Pi would shut down) but if the switch was physically in the 'on' position the power would stay on until you flicked the switch. I picked this up in time to fix it but couldn't find a nice momentary switch without resorting to mail order. Which would have come too late. It's a lesson learned for next time.

Tuesday, 18 April 2017

Using a different tool for each job and linking them together with MQTT - part 2

Now we have a working MQTT server, it's time to start making use of it.

As I was planning to use MQTT to broker messages between Web server CGI scripts, Javascript in Chrome web browser and an Arduino the obvious way to do this is push data at the USB serial port of the Arduino.

Normally this port is used for uploading the Arduino sketch to the board and sometimes people end up filling it with debug/status messages once the sketch is running. However there's a long history of it being used as an actual way to control stuff.

So I threw together a piece of 'middleware' that shuffles data between some MQTT topics and the USB serial port.

#!/usr/bin/python
import time
import os
import mosquitto
import serial
# commands to the arduino are as follow...
# R red LEDs
# G green LEDs
# B blue LEDs
# N no LEDs
# O open/go
# P power off
arduinoBootupTime = 5
arduinoIsBooted = 0
debug = True
# Define the various MQTT callback functions as this is an event driven model
def on_connect(mosq, obj, rc):
if debug:
print("rc: "+str(rc))
return
def on_message(mosq, obj, msg):
if debug:
print(msg.topic+" "+str(msg.payload))
arduino.write(str(msg.payload))
return
def on_publish(mosq, obj, mid):
if debug:
print("mid: "+str(mid))
return
def on_subscribe(mosq, obj, mid, granted_qos):
if debug:
print("Subscribed: "+str(mid)+" "+str(granted_qos))
return
def on_log(mosq, obj, level, string):
if debug:
print(string)
return
#
time.sleep(arduinoBootupTime)
# Connect to the local MQTT server to pass stuff to/from a browser
mqttc = mosquitto.Mosquitto()
mqttc.connect("localhost", 1883, 60)
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe
# Subscribe to the topic that sends commands TO the Arduino
mqttc.subscribe("arduino/in", 0)
while 1:
if debug:
print "Trying to connect to Arduino\n"
arduino = serial.Serial('/dev/ttyUSB0',115200,timeout=1)
while arduino.isOpen():
if arduinoIsBooted == 0:
if debug:
print(arduino.name) + " connected - Giving " + str(arduinoBootupTime) + "s for it to bootstrap"
time.sleep(arduinoBootupTime)
arduinoIsBooted = 1
mqttc.loop()
arduinoOut = arduino.readline()
if len(arduinoOut) > 0:
if debug:
print "Received " + arduinoOut.rstrip() + " from the Arduino"
if arduinoOut.rstrip() == 'powerDown':
powerOffFile = open('/tmp/poweroff', 'a')
powerOffFile.close()
else:
mqttc.publish("arduino/out", arduinoOut.rstrip())
arduino.close()
time.sleep(10)

This is about as simple as things can be and mostly cribbed from example scripts. It waits a while to give the Arduino time to boot as the USB port attaching to Raspberry Pi will cause it to reset. Then it tries to connect and loops round forever passing messages back and forth.

The meat of this is in two functions, the first of which gets triggered as a callback when an MQTT message arrives...

def on_message(mosq, obj, msg):
arduino.write(str(msg.payload))
return
This simply sends the message straight to the Arduino. Coming the other way is almost an exact reverse except we're using newlines to mark the end of messages so we can read them with 'readline'. This means we need to strip them off before publishing to MQTT. Python has a handy function for this in 'rstrip'.

arduinoOut = arduino.readline()
if len(arduinoOut) > 0:
if arduinoOut.rstrip() == 'powerDown':
powerOffFile = open('/tmp/poweroff', 'a')
powerOffFile.close()
else:
mqttc.publish("arduino/out", arduinoOut.rstrip())
There's another little if/else in here to handle the shutdown sequence. I used the VERY simple method of writing a file to /tmp/ if the Raspberry Pi needs to shut down, which is controlled by the Arduino. I could have had a second script subscribed to the topic for this, but this keeps all the MQTT code in one place. Because the Pi uses memory for /tmp/ instead of saving to its SD card, this safely disappears once the machine is shut down.

That's about it, things coming out of the Arduino USB serial port end up in the topic '/arduino/out/' and stuff in the topic '/arduino/in/' get sent to the serial port. The test for the existence of the Arduino serial port '/dev/ttyUSB0' means it loops round forever trying to reconnect if the Arduino get unplugged or resets.

To make this run at startup I put it into /etc/rc.local which is another quick and dirty 'make it work' solution. It works. This is not a server it's a prop, so I'm being cavalier with scalable/secure ways of doing things.

Wednesday, 12 April 2017

Using a different tool for each job and linking them together with MQTT - part 1

I've recently finished a quite complicated prop that needed to have a 'user interface' and thought I'd put down my thoughts on how I built it.

At a high level what we've got is a Raspberry Pi doing the user interface using Chromium web browser in kiosk mode, an Arduino Nano doing the 'physical computing' and a Teensy microcontroller acting as a custom keyboard for interaction with the Raspberry Pi.

What I've done is in principle inefficient as I could have done it all with the Raspberry Pi. However using different technologies like this is a way to compartmentalise bits of the project and use the technology you're most comfortable with for each part.

I've already used MQTT to tie things together before so it was an obvious thing to use again. It is implemented with a very simple protocol that many things are capable of understanding, including diminutive memory-constrained microcontrollers like an Arduino or ESP8266. Also, the idea of bringing data into MQTT from a hodgepodge of sources to tie things together is not a foreign concept at all, it's pretty much designed for this.

What is MQTT?

In principle the MQTT Wiki is a good point to start but like a lot of documentation in the open source community assumes a chunk of pre-knowledge and is full of gaps. So I'm going to re-invent the wheel here and describe it again in fairly plain language...

MQTT is just a way to send and receive messages. These messages can be pretty much anything you want, text, images, sounds, any arbitrary binary data. In principle they can be as large as you like but if something listening on the other end doesn't have enough memory to receive it then it'll definitely fail and probably crash or lock up.

For MQTT to work it needs a server (called a broker) that everything connects to. The broker makes sure that messages get where they need to go. A commonly used server is Mosquitto and it's what I've used. Be aware that the version which installs by default on a Raspberry Pi (probably other Linux distributions too) is old and compiled without Websockets support. You should use the current version from the Mosquitto developers or you will be limited in which clients you can use. More on that in a bit.

Topics, subscribe, publish, LWT and QoS

There are a load of clients available, Python, Javascript, Arduino, NodeMCU/Lua etc. etc. and they all use the same terminology when you want to do something with them.

Topic

A topic is a 'channel' for messages. There can be an aribtrary number of these on a broker. Unless you do specific configuration on the broker to lock things down you can create/destroy these arbitrarily by sending to or listening for data on a topic. In my application I've got topics called 'arduino/in' and 'arduino/out' for sending to and receiving from the Arduino respectively. All topics can be 'bidirectional' ie. you send and receive on the same topic from a client, but that can complicate your code as you need to process your own messages coming back at you. Which is why I'm using topics in a 'unidirectional' manner.

The broker normally handles creating topics and tidying up afterwards automatically, again unless you want to control this.

Subscribe

When you want to receive messages from a topic, you 'subscribe' to it. Depending on the programming language you use it is likely this happens as a 'callback'. This means that when you subscribe you create a function that gets run every time a message comes in on the topic. Your code needs to be able to deal with being arbitrarily interrupted when this happens.

Publish

When you want to send a message to a topic you 'publish' it. There's very little more to be said, you publish and it appears.

LWT

The broker periodically checks to make sure any clients it has are contactable. You can optionally set a 'Last Will and Testament' when you connect the client, which publishes a message to the topic of your choice if the client is no longer contactable. This is a very simple way to check if a particular client is online. I did not use this in my application.

QoS

When you publish or subscribe to a topic you can specify the 'quality of service' on the connection. This comes as...
  • QoS 0: At most once, which is unreliable and the client should receive it but this is not guaranteed
  • QoS 1: At least once, which is reliable. However the client may receive duplicates
  • QoS 2: Exactly once, which is reliable.
Given I was dealing with two clients running on the same device as the broker I left things as QoS 0 for my application. Some clients such as the NodeMCU one only support QoS 0.

Installing Mosquitto on a Raspberry Pi

Do not be tempted to install it from the standard Raspbian repository with 'apt-get install mosquitto'. This will work but some clients will fail with unhelpful errors, particularly the NodeMCU and Javascript ones. The Javascript client requires Websockets support and NodeMCU needs MQTT v3.1.1 both of which are missing in the standard build.

There's a handy guide to installing a newer version with Websockets support here, but in case this goes away here's the potted recipe for the current version of Raspbian (Jessie) at time of writing.

wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
sudo apt-key add mosquitto-repo.gpg.key
cd /etc/apt/sources.list.d/
sudo wget http://repo.mosquitto.org/debian/mosquitto-jessie.list
sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install mosquitto
Once this is installed, have a look in the file  /etc/mosquitto/mosquitto.conf and add the following line below the default 'listener'. We don't need Websockets yet, but we will later.
listener 1883

listener 9001
protocol websockets
Then restart the service with...
 sudo service mosquitto restart

Testing Mosquitto works

This is fairly easy, but first you need to install some Mosquitto clients...
sudo apt-get install mosquitto-clients
Start one session to your server and run the following command. It'll sit there waiting for messages to come in on the topic called "test".
mosquitto_sub -t 'test'
In another session, run the following command to send a message to the same topic.
mosquitto_pub -t "test" -m "Hello world!"
You should get "Hello world!" come up in the first window. It really is that simple to send messages back and forth, the client defaults to connecting to the local machine.

There was a lot of work to achieve this, but now you've done this you could have two wirelessly connected NodeMCU microcontrollers sending messages to each other via the broker and make things happen remotely. Or as we'll see in the next part, by clicking a button on a web page you can make things move that aren't directly connected to the web server.

This is all without having to create your own protocol to do this because MQTT is widely supported. I've done that kind of thing in the past and it was significantly time consuming.

Sunday, 19 March 2017

Rapid prototyping

 Another piece of making for College of Wizardry. I was asked if I could make some badges from the logo on the IC website.

This neatly demonstrates how good a 3D printer is for 'rapid prototyping' even with a simple thing like this.

The first step was to take the source logo and put some spacing between the various element with a bitmap editor. This was so they would come out as separate objects once traced.

Then I used Inkscape to trace it into a series of paths. There are several ways to do it but I got the best results from choosing to trace on two different levels of brightness then selected the resulting objects one by one and tidied up/removed them manually.

Do not underestimate how long this takes, I spent something like four hours doing this. Then I turned this into an OpenScad file using an export filter I found on Thingiverse.

With an OpenScad file I was then free to hack the design around, altering which bits got printed or not, relative heights and so on. This is where the fast prototyping came in, as I could print it quickly and have a look at the result as a physical object. Although with hand editing of the OpenScad file it was still a slow process.

Eventually we settled on just the lion's head part of the logo and played with the size a bit.

Even with a decent looking design, it was still always going to look a bit plastic, but a quick dab of coloured varnish sorted them out. I wiped it off the highlights to create some basic shading and bring through the base colour. Then it was a case of sticking badge pins on the back of each one with hot glue and they're done.

The design process took a while but then I could batch produce them easily. So we ended up with one each for most of one of the player factions, limited only by running out of filament after one of the print runs went bad. Which still happens very occasionally, my 3D printer is definitely an enthusiast/hobby device rather than a consumer item.