2026-09-30

Wallot inspector

What is fun with a nice UV ink jet printer is on what you can print...

One thing is a bank card.

This is now my Monzo card, oops.


Yeh, I can print on a card and the new non-embossed cards are even easier.

Someone suggested I make a flashy web site offering this as a service just to see how many people will send me their bank cards to print. It really is the 2026 version of "wallet inspector"!

2026-09-28

Elegoo Jupiter 2 3D resin printer

I decided to upgrade my Elegoo Saturn Ultra 16K to an Elegoo Jupiter 2. So this is how it is going...

Resin printer basics

For those that do not know, a resin printer has a tray of goo (resin) in the base, under which is an LCD. The bottom of the tray is a "release film". There is a flat plate suspended above, it lowers in to the tray, a layer of resin is cured, and it lifts off the release film, and then down again for next layer. Eventually the final print hangs from the base plate. There is some messy cleaning and extra curing then to make the final part.

The Saturn had some challenges

I am sure I have griped on this before, but the Saturn had some issues...

The cover was a big top, sides, and front that hinged at the back top. To lift it up you would obviously grab the top sides and push up. The problem is that this motion would easily tip the whole machine back. The trick is grab the bottom sides and pull towards you and then up.

Then the print bed is clamped in placed by a small lever that you push up to release. It is small and stiff, and you push up with palm of your hand. And, you guessed it, this motion would tip the whole machine back. The trick is hold the top back of the machine with one hand while you do this so it does not tip.

However, the print bed is pushed forward when you do this - I never had this happen, but there is a risk it comes off the mount and crashes in to the tray of goo and LCD and smashes it all in a very messy way. So the trick is hold top of machine with left hand, push left elbow to front of print bed, and then lift level with right hand, and hope you do not get covered in resin.

Why does tipping the machine matter? Well, because you have a tray full of goo and if you tip the machine it pours out of the tray in to the machine. This is bad in many ways, not least of which is the machine then leaks goo from the seams for weeks. But also, at the back, directly behind the tray, is the z-axis motor and screw thread, with a big hole around it - so the goo goes right down in to the z-axis motor. This basically burgers that motor. I managed to get working fairly well with a lot of alcohol, lubricant, and running bed up and down for hours. Still not 100% but good enough to be printing again. It needs replacing.

Obviously you have to top up the tray to a level to cover what you are printing, and that makes spills even more easy to happen and more messy when they do.

Finally, changing the release film is a LOT of screws/bolts and very fiddly. Thankfully I realised I rarely need to change if, after a failed print, I use the cleaning cycle which exposes a whole layer you can peel off with any remaining print debris. However, on one occasions it got pierced somehow and I then had to change the LCD screen protector as well as it had resin sealed on to it. Resin printers can be messy.

Also, the print area is not very big, but more than big enough for what I normally print.

Apart from that it is good, and prints well.

An interesting feature is the tray and LCD tip down at the front as part of the release cycle, neatly peeling off the release film from the latest printed layer. Very clever.

The Jupiter

This is different and a bigger machine.

It has a bigger print area, nice.

It has side opening doors, solving the tip back issue.

It has a very long level for release of the bed, which can simply be lifted between thumb and forefinger with no real effort, or risk of tipping the machine.

The z-axis seems to have a cowling to protect from spills.

Even the release film change is a module with a frame and film that simply unclips and a new one clips in place. Costs more, but a lot less effort.

It even has tubing and an auto fill of tray from a bottle at the back, meaning it keeps a low level in the tray - way harder to spill and way less messy when taking off print bed. It can suck that up back in to the bottle for you as well.

I mean that was almost every single gripe I had sorted, well done.

The downside

Sadly there are problems.

It sucks!

That is the main issue. Unlike the Jupiter the print tray and screen do not tilt down to peel off the film from the print, instead the print head just pulls up after the printed layer. It often strains and snaps up. This clearly sucks on the release film, a lot.

After a few small prints I now have creases in the release film which mess up the print.

What is worse is Elegoo's response.

In summary (a) tough, and (b) my fault somehow. I am using all the default settings the app picks knowing printer and resin, and only printing a few small things with which the Saturn had no issues - even so, saying "yes it has a large print area but you can't actually use it" is mental. Where are trading standards when you need them?

2026-09-24

Taxing home internet

There seems to be a proposal to change TV licensing to a tax on home internet! Thanks to this article from ISP review.

I hope it goes nowhere, otherwise I can see myself being an expert witness to parliament, again!

The proposal is "that every home with a broadband connection could automatically help to fund the BBC, even if nobody in the house watches live TV, via a new £11 (monthly) “Home Internet Levy” on their existing ISP bill".

As someone that runs an ISP this immediately rings alarm bells. So let's look at how this could possibly work.

To be clear: I am not covering the merits of the BBC - there is much one could discuss on such things - let's assume the BBC continuing is sensible - let's look at this proposal on that basis.

What they imagine?

My guess is that those proposing this assume that the vast majority of households have a single internet service from a big company ISP, so getting the ISP to add an £11 levy to the bill is simple.

The reality...

The reality is different. There are hundreds of ISPs, large and small, some very small (think a dozen people on a WiFi in a village). The admin is not going to be simple. But there are also a lot of edge cases, and these need to be addressed - even a small minority impacted by, say, paying twice, would cause some uproar.

Multiple lines

Some households have more than one internet service. It could be multiple lines from one ISP, which is not too hard to address at the ISP level. But as an ISP we have no idea if someone has internet at their house from another ISP. If we are to avoid double billing such people (and I really think we should, after all we never double billed people with two TVs) we need a way to sort this. So does a customer tell one ISP they have service from another, send a copy of the bill - that is not difficult to forge, but also impossible for the ISP to validate. Maybe we need a national database of which ISP is the tax collector for each property - that won't be simple.

Business lines

Another small snag is business services. At present a business premises may need a TV licence if they have a TV, but most business premises do not have a TV or need a TV licence, so we need to exclude businesses from this new levy. After all it says home with a broadband connection.

So do we exclude business premises - well this is more admin, and there are databases which identify a premises as commercial. But remember, a lot of people work from home. Indeed, a business service from an employer in addition to a home internet at the same house is one reason you may have two internet services at a house. Mind you, my house, an ex pub, is listed as pub/nightclub on BT's database still, yay, no £11/month for me.

So maybe exclude a business service? Is this down to how the ISP sells it? We sell home and office (business) services. The business ones cost more, but not £11 more - so all our home customers would be mad not to switch to a business service and save money - we'd love that as we charge more for a business service but would not have to send any of it to the BBC.

OK, what if only services sold to a business? Again, people work from home, and there are sole trader businesses. If one can save £11/month by putting down a business name, everyone will.

OK, what if only to limited companies? You know a lot of solicitors offices are a partnership not a limited company - they will love their internet service having an £11/month tax. Of course, it would also be easy to order home internet, and pay for it, but put in the name of a random limited company - hard for ISP to police as companies do this - ordering internet for an employee at home. As long as paid for, not an issue - but when not paid for then the ISP is chasing a random company that has no clue. Putting that fraud encouragement aside, it is less than £11/month to create a limited company and the annual filing!

Shared service

This sort of comes down to small ISPs, but what of blocks of flats with a fibre, paid for by the community or housing association. One £11/month fee? Or does the HA have to collect the tax per home?

There are a lot of WISPs (Wireless ISPs) that do this on such a small scale as well.

Mobile service

This is another huge issue. Mobile internet access would not be included, well we assume not. If it was, you have households paying not just twice, but three or four times over because multiple people have mobile phones.

However, a mobile based home internet is a thing - a 5G router with a SIM and WiFi access points. This is a viable home internet service already - usually in cases of good mobile coverage and poor internet "lines", i.e. where feeding a new fibre is hard. It competes with traditional landline / fibre services already. If mobile services are excluded, that changes the economy here. It will cause people to prefer mobile home internet as cheaper. It skews the market which can impact businesses and infrastructure as well.

Of course, someone will say there are ways to differentiate a 5G router and a mobile service - but how? There are mobile phones and iPads that never leave the house, so not by location. And you can usually put a normal mobile SIM card in a suitable router/WiFi without mentioning it to the mobile company. Even if you cannot, just get an old mobile and suitable SIM in hotspot mode as your cheap home internet.

Auditing ISPs

Another issue is that there are a lot of ISPs, and you won't even know of them all with ease, how do you audit that they are (a) charging all home customers £11/month, and (b) if they are, that they are passing on the full amount? Who is going to do these audits, and who is going to pay for them?

Existing special cases

Of course, TV licensing has special cases for blind people and old people. Scrapping these exceptions in any new scheme would also cause uproar. How the hell can ISPs check these things?

One reason this is all silly

The whole TV licensing thing is odd anyway, it was a Wireless Telegraphy Act thing, a licence to operate radio receiving equipment. That alone is odd, licensing transmission equipment sort of makes sense because of limited spectrum and risk of interference, but no reason to licence receiving equipment (apart from a money making scheme, oh, that's the point).

This got expanded to cover ways to get TV over wires (cable TV, etc), which itself made the whole Wireless Telegraphy thing even dafter. It has moved to, I think a Broadcasting act, and I think now Communications Act, not sure.

Now, remember, whilst this started small, radio equipment licence, it quickly became an All homes in the UK fee - basically everyone had a TV (almost) so everyone had to pay a TV licence.

At that point it would have made sense to move BBC funding to being from general taxation. But that did not happen. Instead, as usage of TV changed the rules have got more and more convoluted over time.

The objective is to try and make it All homes in the UK again, clearly. The idea of taxing home internet is clearly based on the ideal that everyone has home internet.

But why do that - why make it a convoluted tax, which needs huge admin, and a lot of exceptions and special cases which make for loopholes. We have per home taxes already, if they went up by £11/month but no TV licence, a lot of people would be happy as paying slightly less.

This would be a hell of a lot less hassle, and for a lot of people less money and one more thing not to worry about. No more criminal TV licence evasion - problem solved.

Well, that, or make it that people who want BBC services, pay. Bear in mind, when TV receiving licences started, BBC were the only station - actually it started before the BBC were a station even and really was a radio receiving licence. But for some time it was only people accessing BBC services that paid a licence fee.

But either way - public service or paid for service - it should be one or the other not this convoluted legal and administrative nightmare.

Cynical

Let's be cynical for a moment - why now and why this proposal?

The now is kind of down to the existing funding model becoming more and more convoluted and unworkable. That is pretty easy. That said, this is probably just convenient as could be said any time in the last 10 years.

The this is harder - the really obvious answers are either pay for access or public service from general taxation. This proposal is neither. It is creating a new tax, and a means to collect it.

Why would anyone want a new tax - well they are useful - find a way to make a new tax that is (a) justifiable for some public good, and (b) actually less money for 90% of people, and you get away with it.

But what happens when you have a new Home Internet Tax in place - well simple, you can increase it. Boiling frogs. It may be for the BBC now but really is not linked to that even in the existing convoluted ways. So yes, you can increase and extend an Internet access tax as you want, once it is in place.

2026-09-02

Clocks

Some time geeks (should I say Time Lords) checked out my clocks.

Seems they are impressed, saying sub microsecond.

I have spent all day trying to improve on that, and I think I have.

The issues are several - the PPS interrupt that captures the time signal works well, but can randomly have extra latency. The original signal can have jitter, drift, and ever sawtooth (actually have not seen this).

What I did not realise is that there is also noticeable clock drift on the processor, probably temperature related.

I previously assumed clean "on the second" PPS. I have changed it so that is used as a reference on longer term (moving average 5 mins) for frequency, and shorter term phase offset tweaks.

This means my per second reference CPU cycle counts change by 1 at a time as things change, the main change being clock frequency drift. This result is reference ticks varying by 4ns or less.

I need to get the Time Lords to check my latest code and see what they find.

2026-08-31

Dodecahedron

I was shown a dodecahedron with LEDs inside. Looked great, so decided to have a go.

The principle is not that hard - a PCB strip on the inside of each edge with WS2812 style LEDs, and solder pads on the ends, then a triangle corner piece on each vertex soldered to the strips.

The challenge is making it one continuous LED chain for WS2812. As you can guess - 3 way vertices makes that tricky.

After sleeping on it, I realised I need two types of corner.

First off, the strips, I made the ends consistent.


The idea is the strip has two lanes - one goes through all the LEDs (left to right on that image), and the other just connects from one side to the other with no LEDs. So instead of each edge being one way, it is a two lane road. This allows loops around the edges of the dodecahedron.

Now for the corners - after some thought I decided I need two types, I called Y and C.


The Y type feed each lane to its left. The C type link left and top both ways, and loopback the right. I then designed it so it is just one PCB, with Y one side and C the other side.

If you made all vertices Y then it would be a loop around each pentagon.

But the logic is pretty simple. If you put a dodecahedron on a flat base, you have a bottom, middle, and top.


The middle 10 you put Y corners, and top and bottom you put C corners with the C facing sideways to the next edge around. The effect is a loop or Ys around the middle, with each vertex taking a detour up to the top or bottom and then one edge around the top or bottom before looping back to continue around the middle.

You will see two issues with this.

  1. It is two loops, a top hemisphere and a bottom hemisphere, not joined.
  2. It is a loop, but WS2812 is a string.

First issue is solved by changing one of the Y middle pieces to a C, facing the C sideways. This C links the two sides making a loop for the entire thing.

Finally the C has an extra pad, and an area where you see to cut a track. Cutting the track breaks the loop, and the pad is where you inject the WS2812 signal.

The exact mapping will depend which C you tapped in to (the obvious one is the extra one on the middle row), and which way around each LED strip is fitted - either work, just change where it is on the string.

Final step was designing a support as a 3D model, 30 pieces that fit together to hold the PCBs. That involved far too much trigonometry for my liking but I worked it out.

2026-08-14

Tick Tock

I am pleased to say that my new time servers are in the UK NTP pool now.

Dave has done a nice report on how well they are performing, here.


And this is actually on an ADSL line...

(available from my shop obviously)


2026-07-28

Time for something new...

Latest project is a time server.

So why? Well, they exist - you can buy a really nice LeoNTP server, with impressive specs. We see response times of 0.1ms, and it claims 100,000 requests a second. They also have a PPS output, and can do a calibrated 10MHz output apparently (I can't do that).

Can I get close using an ESP32? Well, sort of.

Challenges

It should be simple, in theory - a GPS module, capture CPU cycle count on PPS interrupt and use to get clock rate. Capture NMEA to get time for PPS. Capture cycle count on NTP packet and use reference cycle count, clock rate, and reference time to know exact time of day to fill in NTP reply. yay!

Of course it is never entirely that simple. I did all this and got a working system, but I could do better. My latency as measured on a FireBrick was 2.5ms. I did averaging of the PPS intervals to get a more consistent clock rate, and often the standard deviation on that was below 10ns! But not always. I then did a best of last 5 seconds in terms of a PPS interval to use as a reference - that way the odd delayed interrupt had no impact. That seems to work.

One thing I wanted was PPS interrupt at higher priority than Ethernet, but all GPIOs on an ESP32 are the same interrupt source. Bugger. Do a search and you see plenty of people pissed off about this. I found a fix, make the PPS a PCNT (Pulse count) which has an interrupt (count to 1) which can be set separately to the Ethernet interrupt. There is a trick to remember.

The hardware

The PCB design is not that hard now I have cracked Ethernet. A main PCB, with USB-C, DC input, PoE, and Ethernet.

I have since made an even more compact design.

This then connects to a GPS module, which you can hang out the window (or better, fit in a Stevenson screen). Link with 5 core cable (solid cat5 is ideal), and it can handle a few metres.


Then put both in a nice 3D printed case. See https://shop.revk.uk/ if you want to buy. £60 not £600!

Making it faster

The fact my response times where around 2.5ms was not ideal. I wanted better, but how.

First bodge was hook in to the Ethernet driver receive code and check for NTP packets as they come in, and do a direct reply. I got latency down to 1ms, yay!

But I can do better :-)

Scrap the Ethernet controller altogether. Write my own custom low latency driver. Dedicate CPU1 to PPS and Ethernet only. My custom driver can...

  • Be reactive only - reply immediately to ARP, ND, and NTP.
  • Being reactive, no need for mutex wrap on access to Ethernet chip.
  • Work in interrupt (yes, nasty, but dedicated CPU) so not task switching.
  • Know state of registers to avoid read-modify-write as used a lot in standard driver code.
  • Do read fifo and write fifo with no clean-up between

And guess what - latency down to 0.1ms - bang on what I wanted. Indeed I have seen 0.077ms even.

Now, the logic is fun - it makes the Ethernet no use for anything but NTP. So I have made it (a) optional, and (b) normal Ethernet for first 2 mins so you can access it via Ethernet if needed (assuming you can control power/PoE to reset).

But once switched to low latency NTP only Ethernet, you have to use the WiFi for any access, management, MQTT, and so on.

Bugs

I found bugs in the Ethernet chip (KSZ8851SNL) which does not check IPv6 UDP checksums correctly!

I also found it almost impossible to convince the Ethernet chip to give me unicast, multicast, and broadcast packets - in spite of a lot of reading the data sheet and trial and error. It is now in promiscuous and relying on the switch to protect it. Even that makes no sense - you have to set "Allow any packet" and "Invert the input filter" which to mean means "allow no packets!". I may yet find a working setting. I have already spent a day on this.

I also found it used edge triggered interrupt with a check in task for ISR set as well on timer, I changed to level triggered and that seems to work without hanging.

I also found it nearly impossible to cleanly decommission the Ethernet driver in ESP IDF. I managed to take over interrupts and kill the task, and that was all. Anything more thorough was a nightmare. But that works.

What is it good for?

Well some people are putting in the UK NTP pool, it seems to meet the requirements well and work at a level similar to the rest of the pool.

But it is mainly aimed as being the main server in any business / office. Include with your pool NTP, but being local it will win.

I do not get close to even 10,000 requests a second, more like 5,000, but that is not needed for a typical business, even a large one.

2026-07-14

Shipping to EU from UK

We are selling some stuff to EU, and all over the world now (see shop.revk.uk).

This is all a bit new to us, as we have traditionally only dealt with UK customers. This started with circuit boards stocked at Amazon, and Amazon just sorted the EU VAT (paying us the VAT exclusive amount as an export) for sales in EU - very slick.

Moving on (after Amazon screwed us over) we started selling on Tindie, and Tindie do not do anything special for EU at all. So all our parcels hit customs, and the recipient had to pay VAT (and admin fee). This is the default if you do nothing special when shipping to EU.

However, when Tindie screwed up badly (will they ever recover?) we started selling on Lectronz. I have to say that they have been great. This led us to start to understand how it should be done.

IOSS

The Import One Stop Shop system in EU means we could get an IOSS number for sending small packages (value up to €150) to EU with VAT paid - this means the customer has a much quicker and more seamless delivery with no hassle from customs. We would have to file returns for this, but pay in one go for all EU.

However, it is even easier when using an on-line marketplace like Lectronz, as they handle all the VAT - working out the right rate and charging the customer and paying the VAT. All we have to do is quote their IOSS number as part of shipping.

We integrated the Lectronz API and the Royal Mail Pro Shipping API so staff can just click "print postage" and out pops the postage label and customs label, simple.

The EU has gone to some effort to make this slick and easy for small parcels going in to the EU. Well done EU.

The new €3 duty

As of 1st of July the EU made things difficult - the exact opposite of the slick and easy IOSS process - adding a new €3 import duty on small parcels value up to €150. This is separate from IOSS, so even with IOSS and prepaid VAT, the recipient gets hassled by customs for €3 duty!

Lectronz moved quickly, and added the feature to their systems to work out the €3 duty, and add to the price, to pay us, so we can post "Duty Paid". I updated the API code and set to send duty paid via Royal Mail Pro Shipping API.

Yay, all sorted, all slick again, albeit €3 more expensive for the customer (thanks EU!).

Well no!

This started off OK, with a few parcels, but then we hit an error where Royal Mail will not do Duty Paid to Latvia. Arg, why not? Lectronz were very helpful sorting a refund of €3 so we send not duty paid and explained to customer.

So I decided to check the rate card from Royal Mail. The rates to EU are a mess anyway - they have a base price and per-kg price. The base price ranges from £4.45 to £7.70 which is not too mad, but the per-kg ranges from £0.80 to £10.85 which is mental.

The surprise is that duty paid is not available for Belgium, Bulgaria, Croatia, Czechia, Denmark, Estonia, Finland, Greece, Hungary, Italy, Latvia, Lithuania, Poland, Romania, Slovakia, Slovenia, and even Spain.

This is crazy - with all EU countries charging this new €3 duty - why the hell do Royal Mail not handle this.

The other oddity is that the extra cost for sending duty paid, where possible, varies wildly - from a more reasonable 50p to nearly £5 in one case. It is daft for a customer to pay an extra £5 to handle a €3 duty.

What have I done about it?

I have done a shipping rate for all Europe countries individually. Yes, tedious.

Where duty paid postage is available I have listed that (with the extra cost) so customers have a choice.

It would help if Lectronz allowed me to code a per-kg rate for some countries - I have asked.

We still do IOSS for EU where applicable.

So yes, sorted for now. And it means a sting of countries have the hassle of paying duty on receipt, and a few others make sense to do that anyway as the extra cost is daft.

Update

And today we have...

  • Shipment to Romania saying IOSS not allowed, but we have shipped to Romania with IOSS before, and it is on the rate card.
  • Shipment to Germany with no IOSS and no duty paid, a simple DDU but over €150 and they say NDX not allowed. Well NDX is simple "non document". We tried HV which is "Non documented high value" in case over €150 was the issue, but still says NDX not allowed (yes, I checked the JSON, we set HV).

Arrrrg!

Update

Now seems there is a PDDP with non PDDP service to do the €3 duty and IOSS at once somehow. Trying to make sense of what Royal Mail have sent. If so, it may be simple, but this is mental.

Update

Nope, they sent me a link to a document saying MP7 (DDU normally) with DDP and IOSS is available, but an email saying MPR (DDP but only to some EU countries), but then sent the original PDF again which says MP7 and DDP.

They clearly have no clue!!!

2026-06-28

That CO alarm is giving me a headache

OK, yes that is an old joke, but I do have a slight mystery over the CO alarm.

This first happened last year, and drove me round the bend. A chirp every 49 seconds. This is normally a smoke alarm with low battery.

The problem is that we have 8 alarms in the house, and trying to work out which is chirping is not as easy as it sounds, especially when it is 2am, as it always is with these tings.

I actually ended up replacing every battery and still had a chirp. I then remembered there is a smoke alarm in the loft, and replaced that, only then to realise it was the CO alarm  in the loft! I went to replace that and found it is mains only, and Ei3018 CO alarm. Annoyingly it continued to chirp for some time once removed from the power.

I actually ended up buying a new one, and has been fine for over a year.

Then this week, it happens again. Thankfully I remember the loft this time. What is extra odd is that when I opened the loft hatch, the chirping stopped!

The next night it started again and did not stop. So I removed it, and waited. I put back in place next day.

The next night it started again, so removed, and new one ordered.

But I decided to actually read the manual, and it is odd.

It did not alarm!

Now, a key thing here is, it did not alarm. I would know, I have been in the house all the time, it is linked to all the other alarms, and to a relay input to my alarm/monitoring system as well. It did not do an alarm, honest.

But the manual says it has a memory mode, where, for 24 hours after an alarm, it will chirp. There is however a problem with this.

  1. It had not alarmed!
  2. It stopped chirping when I opened the loft hatch, so was clearly not doing a 24 hour chirp.
  3. It is a single chirp - the manual explains it does 2 or 3 chirps, etc, for different types of alarm.

However, reading further, the manual does have a single chirp every 48 seconds. This is for "AC mains off or low battery backup", or (with green LED) low battery backup. I do not think it had an LED on.

So it does indeed sounds like the backup battery is depleted and the action is "replace alarm".

But this is just over a year for a device that should last over 10 years, arrrg!

I wonder why?

2026-06-25

ESP IDF v6

I do not wish to speak ill of such an awesome project, but, this is head banging against wall stuff.

ESP IDF v6 is out, and there is a migration guide, and a lot of breaking changes. I appreciate these happen, and appreciate a guide to help.

But today I have hit some major stuff with no simple answer.

SHA1

Regardless of security issues, SHA1 is a function needed by some protocols and applications, and generating an SHA1 should be a simple common standard function. ESP32 even has hardware to help AFAIK.

It was in mbedTLS, but no, now it is not, and is some other API, but the ESP IDF does not actually list the functions.

But there is an esp TLS thing with a simple SHA1, except you have to initialise a whole TLS subsystem to use it. I just want to simply do an SHA1 of a buffer. That is all. I do not want to create some huge config object and init a whole subsystem. At this point a local SHA1 coded function may be in order.

This should not be complicated.

I ended up, for this application, changing to esp_rom_md5, which is just stupid. It will be fine for this application, security is not the issue, just a sane hash, but something as basic as a simple SHA1 function should not be this hard.

HTTPS

I have an application that does a lot of https client requests. This used to work well.

Now it breaks it horrid ways - the https client itself may break, or other things break that need memory. Even a simple SPI bus init fails after a few https fetches. My best guess is a memory leak. Long ago https client was not good, and was fixed, but now it seems seriously broken once again. I know this is hard work for an embedded system.

Work around, and I do not like, but files are signed, is use http for now for this application. Will be back to https as soon as this is sorted.

Arrrrg!

I'll keep at it.

2026-06-22

A new UPS scam, it seems.

I think I am seeing a new scam.

Background

When an item is delivered to UK from overseas, we, as recipient, may have to pay VAT, and occasionally duty, as the importer. It is a legal requirement.

Yes, as a business we have "postponed VAT accounting", and even the possibility of a "Duty Deferment Account", and DHL get some credit here for handling both very well, with no admin fees. UPS do not get any credit for this at all.

But as a consumer there are two ways this goes down.

  1. They refuse to deliver unless you pay first, or they demand payment on the doorstep. The scam is they want an admin fee that was not pre-agreed with them, and not part of any contract. And you have no choice if you want the parcel. It is a scam as it breaks pretty much all consumer contract protection laws, and is admin that is normal and so should be part of what they charge the sender, IMHO.
  2. They bill you later, and try and charge the admin fee as well. Usually paying the legally required VAT/Duty and NOT paying the admin fee, can work. They do not like it, but I do not think they have any legally enforceable right to their admin fee. Even so it is time consuming and hassle, and I really need to publish an admin fee I will deduct from such payments and argue that is as valid as theirs.

So yes, un-agreed admin fees to recipient are a scam. That is my view anyway.

Note: Royal Mail have a law allowing them to charge an admin fee, couriers do not. There fact there is a law especially for this - kind of proves it would not be legal without such a law.

A new scam

I am now seeing what I assume is a new scam. This time by UPS. Yes, I believe this is a scam.

This relates to a shipment with Duty/VAT pre-paid by sender. So no charge to recipient. No legally required payment by recipient. Sender PAID to get parcel to recipient duty/VAT pre-paid.

In this case a parcel ordered on Amazon UK (no clue non UK shipper). And Amazon do generally handle everything pre-paid Duty/VAT. They are actually really good at that, and for shipments to EU are "deemed supplier" and handle local VAT and all sorts. Very neat.

The item had zero VAT (condensed milk, but declared as tomato sauce!).

But UPS decided to send an invoice (after delivery) for £6.65+VAT (£7.98) for an "entry prep fee".


Did the recipient ask them to do any entry prep? No, obviously not. That is a normal part of delivery, something they are charging the sender for. So this is a case of charging the admin fee even when there is ZERO VAT or Duty to pay.

It is not a lot, but I bet a lot of people pay, and UPS must handle millions of parcels. This is a big scam, and needs to be reported.

I think this is time to report this fraud to the police.

2026-05-29

PCB designs, Ethernet, and PoE

First off, I am working on adding Ethernet to my ESP32S3 designs. I am going for an KSZ8851SNL SPI Ethernet MAC+PHY, mainly because the ESP IDF has a module for this - so it should be a couple of lines of code (LOL).

I am also going for a Silvertel PoE module.

At this stage I have designed, and ordered, a board to allow me to prove the concept. It is somewhat more expensive than I hoped as I am using a large mag-jack, but I should be able to improved that. At this stage I want to prove it works, both Ethernet and PoE. I should have boards late next week.

But this has led me to thinking of a couple of changes to designs of some of my boards.

Faikout Remote

The Faikout is a small board you fit in a Daikin aircon. It works with Home Assistant, and that is how most people use it, but it also has a simple web control page via WiFi.

The Faikout Remote is designed for situations where this hi tech approach is not ideal, e.g. my guest room, and people without HA. It has a display and joystick button to show temperature, settings and allow control of the aircon via the Faikout. It actually connects to the Faikout over BLE, so can be used when no HA, or even without any WiFi.

Is is USB-C powered so easy to put on a wall with a simple USB lead. It has a temperature sensor, so can work as the temperature reference for Faikout auto mode, but can also work with small battery powered BLE temperature sensors if you want the reference elsewhere, e.g. by a bed.

The problem is I have gone overkill on this. The design also has a load of environmental monitoring sensors, including an expensive CO₂ sensor. This makes it unnecessarily expensive. So I plan to simplify things.

New Faikout Remote

The new Faikout Remote will have the display and joystick (though a more robust joystick), and temperature sensor (but also works with BLE sensors), and an IR receiver, but that is all.

The idea is it is cheaper and just works as a Faikout Remote. The IR is because you can use it with a Daikin IR remote (cover the actual IR receiver in the Daikin aircon).

This is now sold on shop.revk.uk with resin case and display. 

Env monitor board

Having removed all the environmental stuff from the Faikout Remote I would make a new Environment board. It would handle a display, but obviously this is optional as many cases do not need a display. It would include the sensors that were in the Faikout Remote...

  • CO₂
  • Humidity
  • Temperature
  • Pressure
  • Noise
  • Light (including colour)

The temperature uses a built in SHT40 temperature sensor (on thin long track with no ground plane, for some thermal isolation), temperature from SCD41, and from GZP6816D, but also WAGO for DS18B20, and, of course BLE sensors. The DS18B20 are commonly available as a probe on a lead, and one or more can be connected. This is ideal for things like data centre use, for front and back of rack, or home usage for inside and outside temperatures.

I have also made it so the display can be fitted to board, or use the supplied lead and plugged in to board.

It would not have the joystick nor IR receiver.

Connectivity and power

This is where it gets more fun - the plan is Ethernet, so it can work on WiFi or Ethernet, and PoE so it can work on PoE or USB-C or DC 5V-28V. The PoE would be a module (solder in), so optional.

  • Home use would typically be USB-C and WiFi
  • Office use (and well cabled home use) would typically be PoE
  • Data centre use would typically be Ethernet and USB-C, as data centres usually do not have WiFi nor PoE.

This should make it a very flexible environmental monitor, which is increasingly important for things like workplace monitoring for health and safety, as well as home monitoring.

This would be sold on shop.revk.uk with options for PoE, Display, and DS18B20 sensors.

I expect to get started on these soon, but obviously I really need to wait for my proof of concept first - that does not usually stop me :-)

Latest render...

2026-05-25

Rendering

I have a simple task, it is auto generating some images for PCB designs.

This all worked, nicely. There are two parts

  • Get KiCAD to render the 3D model of board, and make an image.
  • Get OpenSCAD to render a view of my case design.

In both cases I want a transparent background, anti-aliasing, and cropped around the edges.

KiCAD

KiCAD has a command line that lets you make a nice image render, on a transparent background. However I was not easily able to control which layers show, and it showed stuff I did not want shown. This may have improved since. But also I wanted to change a user layer to an Edge Cut and remove the original Edge Cut to allow me to render a broken out version of the PCB. So I wrote a simple function to edit the KiCAD file before rendering.

I rendered larger and then auto-cropped in gimp.

In panel view

Cut out of panel

OpenSCAD

For the case designs, I have OpenSCAD make STL files ready to print, but I also wanted a render as a PNG. So I asked OpenSCAD to render the STL. STL has no colour so I picked white. But OpenSCAD does not render on to a transparent background.

I got around this by setting white/shades for the object and a very specific light blue background which is not in the object. OpenSCAD did not do anti-aliasing which makes if very easy - render larger - change the blue to transparent, and scale down for anti-aliasing.

I did all that in one imagemagick command. Worked well.

Upgrades

I have since upgraded KiCAD, and OpenSCAD, and gimp.

GIMP

GIMP is really good, and I do not want to dis it, honest. But gimp scripting is nightmare.

You would expect something like a simple auto-crop would be a simple command line. It is not. I had to make a script-fu script and put in the right directory (which was version specific). On upgrade I have to move it, but did not work. I have to tell the command line which interpreter to use now.

Even then, the script is a nightmare. I just want to auto-crop and images, so maybe three steps: load image, auto crop image, save image.

If you search you find examples (not for latest gimp) like this!


I managed to make a much smaller script, but still. One annoyance seems to be that there is no one simple place to find documentation of what commands exist and what arguments for scripts. Also, confusingly, some are plugin- and some are gimp-. I got it working but mostly by trusting examples I found not finding clear documentation.

When I upgraded, it did not work. This was difficult. Most commands had changed name, as had some arguments. I eventually got loading the file to work, and setting background colour, and even autocrop. But save file would not work. It seems a path and a string are not the same somehow, but my filename string worked for load, not for save, so inconsistent.

I gave up. I realised that I was doing this for the KiCAD PCB images as well, and in that case I used imagemagick.

In imagemagick it is magick filename -trim filename, so really simple, and worked.

KiCAD

The KiCAD update created something odd where it was showing the User.1 layer I used for V-Cuts, which it did not before. I had to change my tool to strip that layer. And now the images cropped correctly.

OpenSCAD and Background colour

But the OpenSCAD was bugging me - this was not a new issue as such, just I ignored it before. The PNG images seemed to have a black background. Noticeably when I look at a thumbnail on MacOS. This was not happening on the KiCAD based images.

I assumed it was the background setting in the PNG, and that was somewhat confirmed when I used pngcheck which reported the image was a 16-bit greyscale image with a background of 0x00FF. That is nearly black. I found no way to change this. imagemagick seemed to be setting only an 8 bit value for background on a 16 bit greyscale image.

In desperation I coded some C to update a PNG to set the background to a white level, got it all working, but nothing changed! My code was setting to 0x00FF. I tracked down, the image is 8 bit greyscale not 16, so 0x00FF is correct! pngcheck was misreporting as 16 bit (or was counting the 8 bits alpha as part of it, confusingly).

The fix, eventually, was to avoid greyscale as it clearly upset the thumbnails. I forced the original format which was 8 bit RGBA but simply prefixing the output file in imagemagick with PNG00:

This was a lot of yak shaving this morning.

2026-05-21

Tindie

Their communications have been really bad - hiding that there was a take over, not explaining what was happening, blaming planned maintenance with no explanation why not simply rolled back, and then PayPal issues which they claimed were fixed, but clearly are not.

We are well over a month now with Tindie being broken - by which I mean this.

Not paying sellers is not paying sellers. This has to be the end of Tindie as a business, surely?

We threatened legal action and they settled the balance by bank transfer, phew, but we cannot start re-stocking products, even with over $1600 of "waitlist" orders, until Tindie are actually normally and routinely paying sellers. That may never happen now, we'll see. Even if they do get back, we may only list one product there for a long while.

We are far from alone.

Someone has even made a "new Tindie", from scratch, in this time. The site https://smallrun.net/ have managed it, with IOSS, and US tariffs, and all sorts, all working, from scratch, which even Tindie do not manage. This proves that Tindie's delays make zero sense. They could have re-made Tindie from scratch in this time - so why buy Tindie at all in the first place? Nothing about this makes any sense at all. i.e. make a new working platform, then buy Tindie brand and domain, and make a seamless change over - that is what you do, unless you are, well, incompetent. Well, IMHO, they are that.

An existing provider that was smaller, and has now grown a lot as a result of this, is https://lectronz.com/ - they are cheaper and bigger than smallrun, but I wish smallrun all the best.

This is where we have set up shop now - if you found us on Tindie, go to https://shop.revk.uk which I can ensure goes to my shop (Lectronz now).

But Tindie are still not communicating and not actually fixing things. It is a shame, they clearly had a reputation which is now in shatters.

2026-05-18

CE

CE marking is important for ensuring consumers are buying things that are safe and meet their expectations.

However, CE marking has a lot of implications, in terms of costs and tests, and so on. It basically outlaws your average "cottage industry" type set up.

With modern tech, that "cottage industry" can be technological.

But what if it is not "safe". And this is a very good point.

So there are sites like Tindie, and Lectronz, that act as a platform / marketplace to sell loads of tech that is "home grown" and "cottage industry", with a lot of caveats on T&Cs.

My personal view is ...

  • Most consumers need robust consumer protection law
  • Buying something should, by default, be 100% safe
  • If, and only if, the seller is super amazingly clear on what they sell should there be exceptions.

Oddly this ties in to the utter stupidity that is the fact England and Wales allow selling "raw milk". It is crazy, but the laws require (a) higher hygiene standards, and importantly (b) VERY CLEAR warnings that what you are buying is not safe to drink!

So are PCBs the same?

I make a load of PCBs, and sell a load. As it happens, as a company, we also make some serious routers. For those there is a SHIT LOAD of stuff we do to make totally sure it meets all the requirements. I mean, heck, this is stuff using mains voltage inputs, so it matters. And it costs a lot.

But we also make small PCBs, hobbyist stuff, prototype boards. And the cost of CE marking would be mental. Make 10 PCBs and pay £10,000 for testing and certification. No. That does not work, does it?

So can we sell them without a CE?

This gets in to a grey area, as CE mark is needed for most things but not, for example, prototypes. Indeed, you can order a PCB from China for your own use, and no way they CE mark / certify it for you.

And, after all, if one cannot sell without a CE, then the CE mark itself is pointless - if all sold products have to meet the CE marking requirements there is no need for a CE mark to say they meet it. That only makes sense if there can indeed be products not marked CE and hence declaring they do not necessarily meet the requirements, and so keeping consumers informed of that fact.

Interestingly, one of the key aspects of CE for many of my boards is RF compatibility, and for that the ESP32 module I use is CE marked and certified.

But we want to be 100% clear to customers that these board are not certificated or tested beyond that. They are prototype/dev boards, for specialist/hobbyist use only.

So we came up with a new mark... NONCE (Thanks Alex for help making that). Maybe we should trademark that, LOL. [please note, this is a joke]

And to be clear, what we sell is generally PCBs, in a panel, break off excess parts, and so on. And even if we sell a case it is a two part resin 3D print you use to contain the snapped out PCB. The end user does the "final assembly", it is a "kit".

One of our most popular boards is a controller for air-con - you fit it in your air-con - as an end user you are modifying your certified and CE marked air-con by adding a component. So the whole "as modified" air-con would need re-certification as a product - but only if, as an end user, you want to put it on the market. So, it is complicated. We are looking in to testing that can be done on this product as it sells well, but we are not sure it is even possible for us to certify the board as the "environment", i.e. the final product of which it becomes part, varies so much from model to model - some models even have mains voltages on the internal DC power for my board, so it has to go safely inside the air-con case.

At the end of the day we would not want to, in any way whatsoever, mislead a customer as to what they are buying, ever.

P.S. Apparently I need to explain we are not actually marking boards NONCE, that part is a joke!

2026-05-17

Customising PCBs

It is pretty impressive what you can do with "silk screen" printing on PCBs these days. I think JLC even offer full colour now (not tried it). I imagine they have a UV printer.

But for some of my smaller run boards, doing an over print of the assembled PCB could be very useful.

I already have code to make 3D cases from PCB files - I can see me automating making an SVG overprint from the files.

2026-05-16

Cheeky domains

I have a "shop" on Tindie (albeit currently all zero stock until they get working again, if ever) and now one on "Lectronz".

Ages ago I made tindie.uk domain, it web redirects to the shop on Tindie. Was a bit of fun. And a shortcut for me.

Now I have a Lectronz shop, so I made lectronz.uk in a similar way.

But this is a tad naughty maybe. Well maybe.

  • As far as I know neither have a UK trademark so I could even make a legitimate business matching theirs, and even register a UK trademark, if I wanted, using their name.
  • They could dispute with Nominet, but if I then did a UK trademark, I may manage to keep it.
  • The URLs do actually go to their web sites (albeit my "shop" on their web site) so is not, in that respect, a breach of trademark - it references *them* - so just like someone selling Nike shoes can use the word Nike to do so, in an advert for their "shop". I'm selling/referencing their platform.

But yes, it is cheeky, shall we say. And in hindsight maybe a tad childish and not like me...

So now, given that Tindie is a waste of space compared to Lectronz, even when Tindie is working (which they have not been for a month), I now have a much simpler URL:

https://shop.revk.uk/

It goes to Lectronz.

FYI, if Tindie do come back I may list Faikout only, like we do on Amazon. Lectronz is likely to be the main place for any of the other circuit boards (and Faikout). Amazon only continue because they are one of the first places people go, still, so sensible to be on there, and they handle EU VAT, and shipping - but Lectronz do the EU VAT and US tariffs, so Amazon are only there to mop up on their reputation, as it is.

What is funny about Tindie is being off for a month is that someone has made a "new Tindie" from scratch and got on line and working during that month - https://smallrun.net/. To be fair, if I put my mind to it, I am sure I could. They even have tariffs and EU IOSS all sorted (which Tindie do not, still). How Tindie are so slow and so bad at communicating is really quite amazing.

2026-05-05

&

The ampersand used to be consider the 27th letter of the latin alphabet...

i.e. ex, why, zed, "and - per say - and"... I.e. "and" was a letter after zed (Z).

Then came XML and HTML.

As a company with and ampersand in the official actual company name this has been, shall we say, challenging.

We had serious issues with BT XML order integration for some time.

But more lately.

Nominet say things like this...


    Registrar:

        Andrews & Arnold Limited [Tag = AAISP]

        URL: https://aa.net.uk

Yeah, that is NOT our company name.

Other examples, in that past, with bank payee verification showing ANDREWS ARNOLD LIMITED, so I created ANDREWS ARNOLD LIMITED registered (company 12972728) to complain that a different company was being shown than  us.

Now, for Nominet, I decided why not register ANDREWS & ARNOLD LIMITED. Then complain they are using a different company in whois...

To be honest I should have just renamed 12972728, but have done it now as separate company.

Firstly Companies House did not consider an 05555 phone number valid. Hmmm. But I did a different number, and applied for the company.

Now I get an email. An email to my x@x.xx format email address to tell me that my email address is invalid...

Yes, read that again. It is a kind of SPECIAL!

I called them, and well, the person I spoke to kind of appreciated the irony here. Emailing me to tell me my email is invalid, is, well, special.

She said the system was fine but a person, an examiner, rejected based on the email address. She has sent a memo to not reject that email. We'll see.

Why can people not simple follow standards, for email addresses, for phone numbers, for everything.

I have applied again. Once I have new company I can then complain to Nominet over whois.

And again rejected. Another weird one is when logging in to gov gateway using x@x.xx format address they say they are emailed a code to xx@x.xx !!! They actually email x@x.xx address, but why double the first letter when shown on screen... Hang on, I get the show first...last letter and a one letter address confuses the hell out of that. That makes more sense, but is still stupid.

Oh, there is more! The email from Companies house was wrong. It stripped & to &. Wow. How is this hard in this day and age?!

2026-05-03

Lectronz and IOSS

We sell lots in the UK (services and goods), and handle UK VAT, obviously.

Some of you may be surprised that A&A sell all over the world as well - development circuit boards. I have mentioned it, I am sure.

For now, we have used Amazon and Tindie.

Both are a problem...

Amazon

Two good aspects of Amazon, one is they will do fulfilment, so we send stock and they ship to customers. and secondly they handle selling to EU, etc, and the VAT and so on. We do not have to worry about it, and for these exports we are paid the VAT exclusive price.

Amazon have been arseholes, they unlisted the most popular product on a mere accusation, took months to sort with frozen stock, and finally returned after I threatened to sue. We lost all the reputation and reviews, and new listing of same item is selling 20% of the rate.

We now only list this one popular(ish) product on Amazon, as they do sell some, and sell to EU easily. But they did screw us over for no reason.

Tindie

Tindie are useless at tax and VAT. We have to do the shipping. However, we have integrated their API such that staff can see a list of orders, click and get postage via Royal Mail (with all the customs declaration stuff). They put in a jiffy bag, stick on label, and postman collects with the rest of the days postage.

Tindie were selling pretty well, close to Amazon rates, and sometimes more. But we had to ship. The much more slick postage integration I recently did makes it a lot easier and my staff can take over many of the products we sell without any hassle.

Tindie then shut down with no warning for maintenance, lied about it for two weeks, finally said new owners, made site live but with the one important feature of "paying us" (or anyone else) missing. We shipped some more orders, but have now zeroed all stock until sorted. They claim to have sent balance, but we will not know for sure for a day or two.

Lectronz

So we have signed up with Lectronz. They are tiny compared to Tindie, but that seems to be changing (I wonder why!).

They work the same as Tindie, free to list, charge a fee for sales, and card processing charges too (stripe). They even have Tindie API integration to import products (they then need a little work, and Tindie may be blocking some of it).

But they have a lot of extra bits...

Better shipping rates

The shipping is saner, it is all linked to sets of countries, but is all weight based. You set the shipping for a weight range, and you can also set a tariff rate for US as a percentage! This is lacking in Tindie.

They don't have a shipping rate that is price + price per kg (I have asked) as that would be even better as that is how we pay Royal Mail for international shipping.

Tariffs for US

But this means sales to US show (and charge) a specific tariff fee - very clear, and we link in to doing PDDP shipping with Royal Mail.

VAT for UK

We can, and have, told them we are VAT registered and selling to UK has 20% VAT. They shows this and add it at point of sale. Simple.

VAT for EU

This is where it gets fun. For orders shipped to EU, under (I think) €150, they will automatically work out the EU VAT based on target country, and add to the price.

They deduct this from what they pay us, and settle with EU VAT authorities for us.

They then tell us an IOSS code to use with Royal Mail to record as a pre-paid VAT. The customer then has no hassle with paying VAT on import.

This is really hassle free for us and the customer.

Other countries still have VAT on import and so is any order to EU over €150, but they managed to make that all very clear on the checkout page.

Do buy some stuff, here. I will be adding more and more soon.

2026-04-28

Spectre

A "Spectre" is a new shape.

Yes, I did say new shape! It is pretty incredible that there can be any such things as new shape, I mean, how do we not know all the shapes already? Also, to be fair, it is a reasonable bet that the ancient Greek's knew of this and forgot to write anything down. But certainly in my life time - this is indeed a new shape. Discovered in 2023!

So what makes it special? There is, of course, a whole wikipedia article on what is called The Einstein Problem, but I'll try and explain it simply.

This shape tessellates. Basically that means you can tile your bathroom wall with it - the shape fits together with itself to cover a surface with no gaps. Lots of shapes do this, squares, triangles, hexagons, and so on. You can rotate the tiles if needed (e.g. for triangle you have to). There are many that do not, such as pentagons, and circles, etc. You cannot tile a wall with circles without leaving gaps.

So what? Well, most tessellating shapes create a repeating pattern. Hexagons make a familiar honeycomb pattern for example. But with the Spectre you can make a pattern that does not repeat. In fact, you cannot make a repeating pattern with it at all, no matter how hard you try. Yes, some groups of tiles may appear the same in other places but even then these do not form a regular pattern, at any level.

There is some debate over the rules - this was, it seems, a competition. The rules allowed you to turn a tile over. The researchers created a shape called the "Hat" which worked but some of the tiles had to be turned over. People, quite reasonably, said "If I want to tile my bathroom wall I have to buy two sets of tiles". So the researchers came out with the "Spectre" a year later, and that works without turning over tiles. In fact if you can turn over titles, you can make a repeating pattern with it.

But basically, until this was discovered, nobody even knew if a forced aperiodic tessellating monotile shape even existed. That is what makes it a new shape.

You can now tile your bathroom wall with one type of tile and it is a non repeating pattern.

But how?

Well, you could just try placing randomly where they fit, but you quickly end up with gaps that are not Spectre shaped, and have to back track and try again.

However, there is an agorithm, published by Simon Tatham, here. I'd like to thank him for his work, but I have a word of caution if you want to use his paper. I also appreciate, as a coder, the counting from 0 all the way through.

It just so happens I had an idea how to use this shape, for reasons which will become apparent later this year I hope. So I wanted to code generating a surface covered with these tiles. Long story short - here it is, open source on Codeberg.

But this took me a couple of days, which is a long time for me, so let me explain the issues.

The principle is simple, a recursive set of meta tiles are groups of tiles in a pattern (represented has hexagons in the paper).

You can start at the top, pick a meta tile from a set of 9 different types, and that tells you how to place 7 or 8 subtitles in a honeycomb pattern, and their types (from the set of 9) and orientation. You repeat as far as you want and the last level you actually have Spectre tiles not hexagons.

You can also start at the bottom with a Spectre, and decide which of the meta tile types it shall be at random. You can then find a meta tile which includes that type, and it tells you the neighbouring Spectre tiles to place. This is then a meta tile which you can again decide is part of a higher level meta tile randomly, and that tells you what meta tiles to place for its neighbours and work down to Spectre tiles below. So you have one upward process in a loop, and at each point have a recursive downward process placing 6 or 7 neighbours at each level down. This is the approach I took.

If I started at the top I would pick one of 9 meta tiles, and maybe one of 12 orientations, and that would be it, the Spectres under that are determined by the algorithm and not any more random. By starting at the bottom, I pick one of 12 orientations and place the first tile, and pick one of 9 meta tiles, but at each level as I go up I get to pick which higher meta tile it is in, and in some cases which of two sub tiles it is. This is random at each level and makes for a much more randomised final output.

So what was confusing me?

The distraction that took me most of the time trying to get this working is the rather excellent graphic representations in Simon's paper. They show a hexagon meta tile substituted with 7 or 8 joined hexagon meta tiles, and shows a hexagon meta tile substituted with a Spectre tile. These diagrams have specific orientation, and rotation, so one is lulled in to a sense of simplicity that you are literally replacing one hexagon with a set of them, each with specific orientation.

Looks pretty, and simple, but this is NOT the case!

The diagrams are actually simply a mapping, a look up table for what gets joined to what and what side. The hexagon has 6 sides, basically at the lowest level each Spectre is joined to exactly 6 other Spectre tiles (there is a special case for that G meta tile where it is two Spectre tiles, the others are all one, just to add to the fun). So you have each Spectre tiles as having 6 connection sets of edges - but these are not simple, as each of the 9 types of meta tile is a Spectre with a specific set of edges for each of the 6 sides.

The numbering is the key - on the yellow tile there is a side 0, which is actually the three edges 8, 7, and 6 (marked 0.0, 1.0, and 2.0). On the purple, there is a side 4, which is edges 13, 12, and 11 (marked 0.4, 1.4, and 2.4). But side 4 on the yellow tile is only sides 12 and 11 (marked 0.4 and 1.4). But you a see yellow side 0 and purple side 4 would fit together. Some of these 6 sides are one edge (see purple side 3), but can be as many as 6 edges in some cases. Each of the 9 meta tiles has a specific set of edges making up the 6 joint points to other tiles. Each similarly has a set of edges on the hexagon pattern, which is different for each type.

So in practice you connect the defined edges, and they end up nothing like hexagonal tiles. In fact they twist and distort all over the place. The graphical representations are really not helpful in my view, sorry. Also, I would have numbered side.subedge so 1.0, 1.1, 1.2, not 0.1, 1.1, 2.1, personally.

Once I grasped that logic, the code became simple. As I say, you start with one Spectre, and connect neighbours. You only need to know the specific 6 sets of edges for that tile. Then when you use the meta tile rules you know which set of edges that connects to on the neighbouring Spectre. It is pretty simple to then align the new Spectre connected on that edge. Having placed the 7 or 8 Spectres to make a meta tile, you then just need to know the 6 joining points on that meta tile, which are themselves 6 sets of specific Spectre tile edges within the meta tile.

One issues is these connecting sides are several edges, so I actually picked one end, e.g. for yellow it would be 8, 5, 2, 0, 13, 12, 10, and for purple it would be 8, 5, 3, 0, 13, 10 as the 6 outgoing edges. These are the first edge of each side (numbered 0.x). When placing a Spectre next to one of these, you pick the other ends, so 6, 3, 1, 13, 11, 9 for yellow and 6, 4, 1, 0, 11, 9 for purple, the last edge for each side.

So connecting yellow side 0 to purple side 4 you connect yellow edge 8 to purple edge 11. The 11 being the incoming edge. This means you don't have to think of the sets of edges, just one edge on one Spectre tile for each of the 6 outgoings sides of your meta tile, at any level. This is quite a small amount of data to hold in a simple recursive algorithm

Another thing I got wrong is I stored a list of tiles, and referenced them as the 6 sides. Each tile with a starting point and rotation so I could plot it, and align new attached tiles. But this really is not necessary, and ends up using memory. I can plot the tiles (output a path to SVG) as I go, and I just need the 6 sides of a meta tile to be the 6 sets of position, rotation, and outgoing edge number. The only memory usage is a small set of data for the level of recursion. You quickly cover a very large number of tiles in each level (multiple by 8 or 9 each time), so need very few levels of recursion.

Co-ordinates

One issue is coordinates. Ultimately the output uses pixels or millimetres to several decimal places, and indeed I allow a final output rotation. But internally all lines on the Sprectre tiles are at multiples of 30 degrees. Even so you do not want to use floating point - rounding errors will accumulate as you recurse and lead to tiles not quite aligning, and also it is not possible to test two points are the same (why you need this is explained below). So the solution is to use coordinates that are integers! How do you do that with 30 degree angles, well simple - each distances is an integer multiple of sin60 plus an integer multiple of cos60 - at the final stage you multiple out and add these. You can also make a simple table of one unit distance integers for each 30 degree angle. And a table of the relative integer offsets for each point on a Spectre at each angle. This means no floating point maths, nor sin/cos, until you actually output to SVG.

Finishing

One problem which I don't think Simon's paper covers, and was unexpected, is knowing when to stop! I am trying to cover a rectangular area. How do I know I have got there?! I could just set a maximum level, but using random choices for meta tiles at each level one can find the whole things quickly gets to way bigger than the area but ends up one sided leaving gaps in your rectangle. If I had gone top down, or always picked the current tile being in the middle of the meta tile, I could maybe work out a max level, but that is not what I am doing.

After a bit of head scratching I finally worked out a way. I wanted to make a grout line on top of the final tile output so I decided to keep track of all the edges I placed. A simple start/end for each unit length edge in a list. This can be made as I go along, and the integers mean I can always match to an existing edge to plot the grout efficiently as a series of lines.

This also meant I could actually keep two lists - one a list of first use of an edge, and then moving over to another list of second use of an edge, when a tile is attached the other side.

I could also check each edge I added to a list to see if it falls (even one end) within my target rectangle, and so only keep edges I need.

But this has the side effect that as soon as my list of single used edges, within rectangle, is empty, I must have 100% covered the rectangle, as no edges that don't have a tile on one side are in the target area. I can then immediately abort the whole placement process at every level just by checking the list of single use edges is now empty.

Cropping

The final challenge was the edge of rectangle. Firstly the SVG has a viewBox, and so I can simply plot tiles that fall even slightly within the rectangle, and the same for grout lines. These go off the edge, but you cannot see when looking at the final SVG.

This has a problem, if you want to use the SVG in another design, as I did, the embedding does not inherently crop the edges. But SVG has an answer for this, clipPath. It allows me to clip an object to a path, a rectangle in this case. Perfect.

The snag is support of clipPath is not that good. I don't know why, but lots of things mess up, ignoring it, or barfing in some other way. One was my resin printer, which simply ignored the whole block of tiles if it has a clipPath.

So I ended up making a whole path generation set of functions which understood cropping the path to the edge of the rectangle. I could not sleep, and ended up coding this at 2am.

The final result is I can now make an SVG of a randomised set of tessellating aperiodic Spectre monotiles, with loads of options. I even added a sort of bevel edge to the tiles with a lighting based shade.

This is shaded per level, showing how the tiles actually join up at a meta level.

Wallot inspector

What is fun with a nice UV ink jet printer is on what you can print... One thing is a bank card. This is now my Monzo card, oops. Yeh, I can...