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.

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 insi...