2023-04-28

popt

Linux has a really good library called popt. It parses command line arguments.

I use it all the time, and it allows a variety of arguments to be cleanly handled, with different types, default values, help text, and so on.

For a long time it has bugged me, and I assumed it was a bug, that it would leak a small amount of memory. This shows using valgrind. But as it is a one-off leak on a command line I have not bothered too much.

However, following some discussions re memory free tidying on one command recently I thought I would try and get my code 100% leak free - always a good aim.

I have found the problem.

popt malloc's any POPT_ARG_STRING values that it sets!

Now, I was not surprised to find some malloc'd memory, but was surprised at this. I was also surprised that poptFreeContext() does not free all allocated memory, these values are for the user to free.

What concerned me is that I did not know this, and the manual pages are not entirely clear. They do actually explain that poptGetOptArg() returns final arg of poptGetNextOpt(), and "The calling function is responsible for deallocating this string.". It does not seem to make clear that all arguments returned or stored for POPT_ARG_STRING are malloc'd. But that seems to be the case.

Now I know, I can ensure I free all string variables at the end of my program. Or can I?

What of defaults?

Well, damn, this is fun - some variables have defaults (the help text shows them even, if you ask it too), so you can set a default and the use popt, and have a string that is supplier, or the default.

This is useful, until you start freeing all your strings at the end, as these are typically const char assigned, and so not something you can free.

The only way to be clean is assign your defaults using strdup(), so you can always free, whether default or stored by popt.

Why does it do it?

What puzzles me is why it is done in the first place. The arguments are null terminated strings in argv[], so could be referenced directly. Even with a -x or --xname= prefix, an offset in to the argv[] value could be returned.

It is worse!

It seems poptGetArg() also alloc's strings as well, and the manual is totally silent on that point.

Arg! And worse, poptGetArg() is const char*, which is not valid for free() even!

No, No, that does not work

OK, I really tried, honest.

I set my defaults to be strdup() based so they are always safe to free() whether using default or supplied value.

What does that do? Well, if not using the default, the new supplied value is set, and malloc'd, so the free() is still safe. But what of the original default, that is now lost, not free'd, so a bloody leak!

I cannot see any clean way to do this - popt is basically broken.

Arrrg!

2023-04-26

Bulb and Ombudsman

As I mentioned, I had two cases of energy companies with Ombudsman. This is the second one finally sorted.

The other case with So.Energy was about a final bill simply using the wrong meter readings, complicated by the fact that one was an export reading. It was all sorted.

Arguably the Bulb one actually way simpler: 2 years after leaving them, and settling the final bill, they decided, via a new bill, rebelling for my previous usage, that I now owed £7k. The reason this is a "simple" case is that there is an OFGEM rule which bans charging for usage more than a year before the bill. It is a very simple rule.

It is a licence condition, and is also in the terms and conditions (it has to be).

So, a bill, out of the blue, for usage more than 2 years before, is simply not valid. The rule and and terms are simple. So I should have been able to simply point this out to them, and it be the end of the matter.

Which makes no sense really, it sort of says they cannot charge more, but they have charged more.

They even tell the Ombudsman that the back billing rules don't apply, which makes no sense. They told me on Twitter as well that the rule does not apply. This was somewhat stressful to say the least as I thought I was on solid ground here. Oddly they told the ombudsman the new bill was because of new closing readings from the new supplier, which also makes no sense as the new bill had the same closing readings as the previous bills.

So, how did it go with the Ombudsman?

Well, in the end it went well, but it was a hell of a challenge. For a start, it took a long time to get anywhere, as with the other case. I actually ended up making the complaint covering several issues: One was "this latest bill is simply invalid under back billing rules as it all for usage more than a year before", but because Bulb raised this bill I looked back, and spotted they had also previously back billed more than a year, and they had also changed the opening electricity reading to something totally made up, using 09796 not 51485, which is crazy!

The response from the Ombudsman was overly complicated, and hard to understand, instead of simply saying the latest bill is invalid, they go on about a dummy meter exchange and reissuing the bill correctly.

I basically said I could not "accept" the decision if I could not understand the decision or what it could mean financially, and they basically said until I accept the decision they cannot order Bulb to action it, and only then would they know the financial implication.

The other issue is that the response and several exchanges with the ombudsman said things like "So if Bulb revise the bill and there are unforeseen charges it needs to apply backbilling. Backbilling does not apply if you are in credit or the charges have decreased upon billing you accurately."

Obviously the idea that if there are unforeseen charges they would apply back billing was a concern. It seemed to suggest that I would be back billed for unforeseen charges.

At one point I said: "To be 100% crystal clear, accepting this decision cannot result in me owing Bulb any money at this point, as the only money they are currently asking me for is for an invalid backbilled charge two years after leaving, and any additional charges they find are too late and so cannot be backbilled now." and got the reply "Backbilling will apply if there there are unforeseen charges (increased debt)."

I exchanged dozens of messages and finally got to the bottom of it. When they say "backbilling" what they mean is "the OFGEM anti-back billing rule / licence condition". So they mean "...there are unforeseen charges it needs to apply the anti-back billing rule and not back bill you". That is essentially the exact opposite of what was actually said.

Then they suggested there could be some additional charges if the new bill to replace the £14k bill they had raised was lower, but still left me owning money (there had been a £7k credit first, hence balance being £7k now). This turned out to be because she misunderstood how long ago it was and thought some of the (revised) usage was within a year still.

It took a long time to get a clear answer to "So the worst that can happen, from my point of view, is that I still owe nothing. The best is that they owe me some." - at which point I accepted the decision.

What did Bulb do?

They harassed me by calls, emails, and in writing all the time, even after saying they would wait for the outcome of the ombudsman case they then harassed me again. It is ridiculous.

Eventually, on the last day allowed, they issued a new bill, it showed me in credit (by several thousand in fact).

I advised bank details and they sent the £150 compensation they were ordered to. Not the credit balance.

I queried, and they say any credit would be sent once the final bill was raised (which web site said would be 31st May).

I finally said I would advise the Ombudsman that the matter was not resolved unless they confirmed either no additional bill (how could there be) and paid me the balance, or confirmed the extra final bill (which I would then dispute via the Ombudsman). I was not going to wait a month.

To my surprise, and as 10 separate smaller payments all at once, they have sent me the balance.

Technically I think I could argue for more - the re-bill covers the whole period I had service, but there was a period of time in the middle of service where I did not have a bill within 12 months of usage, so they should not now be billing me for that period of time in the middle. But the whole experience of dealing with Bulb and the Ombudsman has been so much hassle, pursuing that extra bit is not worth it (I'm clearly getting old).

Irony?

The irony here is I left Bulb a couple of years ago and had paid in full. I did not realise they had overcharged me, nor by how much. Had they not decided to bill me for an extra £7k, they would have got away with it.

In my defence, until Bulb, I had not had experience of such inept energy companies, and did not expect to have to check every bill in detail to look for such mistakes.

Update: Bulb then later sent a standard email saying they are compensating people an extra 20% of refunded amount, which was a nice bonus. Yes, it arrived!

2023-04-14

Industry standards

There are many industries that have various industry standards. These are often relevant to the internal workings of the industry, not something customers see, and help then industry work smoothly as a whole. This is particularly important when various parts of the industry need to interact with a range of suppliers and clients. Sometimes the standards are based on standards bodies or even a regulator, sometimes industry bodies, sometimes simply the de facto standard of the major player.

But sometimes when you get under the hood you can be shocked to find a lack of industry standard where clearly one would be both obvious and simple.

Now, when I explain this latest craziness, I know, for sure, someone will come out of the woodwork and say "but there is standard X". The problem is that whatever standard here may be it is clearly not widely used in the industry as yet.

Also, when I explain this latest craziness, someone will say, "Why not just make a standard then?". Well, see xkcd/927. Obviously I could propose a standard - this is a very simple matter, but there is no way I could get it adopted. I'd go for all in one JSON file to be honest.

PCB Assembly files

The issue is PCB assembly files. I am (personally) quite new to this, and discussing with my colleagues that do this for a living they are "Oh, yeh, it is crap, there is no standard".

What is needed...

When making a printed circuit board, and adding components (assembled PCB), you need a few things.

  • The actual artwork for the printed circuit board - several bits, such as the copper layers, the solder resist, solder paste, the silk screen, the edge cuts, the drill file.
  • The details of the components you need placing on the board
  • The details of exactly where those components are to go on the board

There are actually a load of other things, some of which are fabricator specific, like PCB thickness (and number of layers, and material), solder resist colour, silk screen colour, copper thickness and finish, and various production options. If an extensible standard existed (e.g. JSON or even XML) it could include a load of "common" attributes and allow for custom attributes, and so allow ordering a PCB to be literally loading one file. I have been caught out forgetting one of the many options before now and managed to get a board the wrong thickness. My PCB package knows the thickness but has no way to include that in the production files.

Artwork

The first part does seem to be pretty standard, though it sort of evolved, but now is quite good - GERBER files and drill files all in a zip file. There are several options and versions, but in general these really "just work". Even details like whether coordinates are based on inches of millimetres are standard headers in the file now. It seems a variety of de facto / proprietary standards have congealed in to something pretty common at last.

Picking components

Picking the components is the area I would expect to be complicated, but I was quite surprised. My experience here is of two PCB fabrication companies, one in UK and one in China. To my surprise, in both cases, they were able to track down components quite easily.

The basic parameters of "Manufacturer name" and "Manufacturer part number" seem to cover it very well, but even without these - even something simple like calling a component "5k1" and stating a package of "0603" will get you a standard tolerance 0603 package 5.1 kΩ resistor. Indeed, on one occasion whilst trying to find the part for an inductor, I totally failed to find it on the parts site, but it turned out that simply putting the value and package "4x4" found one that I failed to find.

Comma Separated Value

One of the issues is the file format, something obvious for standardisation, seems totally arbitrary. The only common factor seems to be the use of CSV files.

In one case the web site allowed me to load the CSVs from the PCB drawing package, display it spreadsheet style, and then let me select which rows are which things (Bill of Materials, and Positions), and then select which columns in those rows are things like "Manufacturer name", "Part number", and so on, with some level of pre-guessing in place. This is a total faff as every time you load the files you have to go through this process.

In another case the fabricator specify the exact set of columns to use for each file. This has the advantage that if you can make a script to make the files, you don't have to fettle them when using them. But the exact layout is unique to that fabricator, not standard.

Position

This is the one that really gets me. The Bill of Materials has the details for what parts you have, as I explain, but then you need to say where they go. There are not many details for each component.

  • Side (top/bottom)
  • X / Y position on the PCB
  • Rotation

The side is usually text "top" / "bottom", so simple enough.

The position is, it seems, usually, "as viewed from top", but could be in millimetres or based on inches, and will have an origin somewhere. It could also be Y going up or Y going down, even! It seems obvious it should actually use the same origin and units and direction as the GERBER file, but does it?

The good news is that this does generally seem to work, the actual position does not seem to go wrong, though there have been cases where negative values break things. It also seems that fabricators can work out your origin and units based on how components hit solder paste / pads. But if there was a proper standard this would a be lot simpler.

It seems rotation is more complex, and whilst it seems "degrees" are a standard I found that whether it is "as viewed from top", or "as viewed from above the component" is a thing. I use a plug-in for KiCad (PCB design package) to make the files for JLCPCB. The fact a plug-in is needed just highlights the problem - why is there not a simple common standard for this! The problem is, I have now found, that the plug-in uses rotation "as viewed from top", which is what KiCad uses, but JLCPCB seem to need it to be "as viewed from above the component". I have had to fix the plug-in.

You may wonder how this could happen? Surely it would be noticed. Well actually it is not that simple. A rotation of 0 or 180 will be correct on the bottom layer anyway. A rotation of 90 or 270 will simply reverse the component, which, for many, does not matter. Other rotations are less common. The ones that do matter, like diodes, and ICs with a pin 1, have to be manually fettled anyway, so it is not obvious they should not have needed this just because they are on the bottom. This is such a common issue that JLCPCB even have a standard service to check pin 1 is correct and propose corrections.

A good example is something so simple it needs no adjustment, a resistor. This is two resistors at 10 degrees rotation (as viewed from top), and sent to JLDPCB with a value of "10" in the rotation.




No standard within components

You may wonder why you may have to fettle the positions anyway, hence not noticing the bug. Well the reason is that there is, apparently, no standard for how components are "placed". Even though data sheets for components normally have detailed technical drawings showing the exact dimensions and outline, and even 3D models these days, there is no convention for component manufacturers providing an "origin" on their drawings, or even a "mid point", though "mid point" is at least something you may be able to work out on many. There is also no standard for which way is the "un-rotated" orientation of the component.

What is even more fun is that a component usually has three possible origins for its positioning, and some fabricators use different basis. Some may even use Mid and Pin 1 to define orientation, which is fine until pin 1 is in the centre of the device?

  • Origin - some point on the technical drawing as a reference point, e.g. bottom left.
  • Mid point - this at least is likely to be something you can work out for most components
  • Pin 1 location - this is less simple - is it the mid point of the recommended SMD pad for pin 1 maybe? Or maybe the centre of the dot on the package marking pin 1?

This means that each fabricator makes up their own rules, on a per component basis. So you need a way to mark an offset X/Y and rotation on each component to match the fabricators rules. They are not even consistent - you would think a standard package, such as a small 8 pin IC, would always be the same orientation, but even that is not the case, even within one fabricator, it seems.

The big clue that the plug-in was wrong was that moving a correctly adjusted component from top to bottom broke it. By correcting the rotation on the bottom, it is now possible to make these "adjustments" part of the footprint for the component, so that whenever you use it, it will be placed correctly.

P.S. Don't get me started on poor quality technical drawings - i.e. those that are dimensioned with just slightly too few dimensions to work out all necessary points.

P.P.S. Don't get me started on poor quality 3D models. They look good, and many are stunningly accurate, and very useful, but they have an origin and orientation - this too is arbitrary, and often does not even have Z axis as "in/out of PCB when placed" - using these means manual fettling every damn time. If all components had a defined reference origin and orientation it could use that for the 3D model as well. Oh, and I have seen lovely detailed 3D models that actually do not match the footprint so look wrong!

2023-04-08

Which came first, the chicken or the egg?

I only post this because I know people will argue...

The classic question is phrased: "Which came first, the chicken or the egg?"

It comes from the observation the chickens come from eggs, and eggs come from chickens, in a seemingly infinite cycle. I simple naive question.

There were eggs long before there were chickens.

The problem is, of course simple, without any more qualification. Eggs have existed long before chickens. So for this question to be even remotely controversial, it needs some qualification. So let's rephrase:

"Which came first, the chicken, or the chicken egg?"

What does "chicken egg" mean?

This is, of course, obvious, isn't it... I can point to such an egg and show you. Well, I could if any shops had any chicken eggs in them - it is all chocolate eggs at the moment!

But there are two possible variations - "An egg that came from a chicken" or "An egg that hatches in to a chicken".

And this is where the solution lies. At some point in history a proto-chicken, something you would not define (by whatever criteria you are using) as a chicken, laid an egg, and from that egg came something you would define as a chicken. That is evolution. Whatever definition you use for "chicken", wherever you draw the line, that is what happened at some point.

So which came first depends on which of those two definitions of "chicken egg" you are using.

So the question is answered by defining the question. Not a dilemma at all.

Or it is defined by qsort?

2023-04-04

Phœnix Contact connectors

For some time I have "standardised" on my connectors for my small PCBs as the molex mini SPOX 2.5mm connectors.

They have a number of features that make them useful - higher density than screw connectors (unless tiny tiny screws), and being pluggable makes it possible to simply unplug one PCB and plug in a replacement. They need a crimp tool, and being molex it is not cheap, but they are easy enough to make up. Even with screw terminals I would always use bootlace ferrels, which makes this no more hassle really. The other advantage of plugs is you can crimp / wire the plug more easily away from where the plug has to connect to the board (which may be in a tight space), and then just plug in.

However, feedback from a customer of the alarm system is they do not like them - the main issue is the expensive crimp tool. They worked around by getting pre-crimped wires. But also it means I cannot sensibly ship a board of any sort with these that can just be used.

The alternative I am trying now is Phœnix Contact connectors (e.g. these).

  • They are also 2.5mm spacing. This means existing boards can use these new connectors with no change. In practice they are a fraction longer so hang over the edge of the board very slightly, so the PCB is being changed to accommodate on next version, but that is not enough to be a problem on existing boards.
  • They are slightly narrower which allows some boards with lots of connectors to save a few mm width.
  • Like the mini SPOX, the 2.5mm spacing is close enough that one could fit 0.1" square pin headers instead if needed.
  • The plugs are "push in" wire contacts, no crimps, meaning I can supply plugs with the boards and they can be used right away.
  • Available with locating pegs, useful especially for smaller sockets, PCBs space permitting.
  • Available in black or white, and surface mount, and right angle and straight, and socket on PCB or plug on PCB, which is really flexible.
  • They are close enough spacing that the plugs can fit a standard 0.1" square pin header too.
A small downside is cost - the plug and socket is slightly more, and if supplying the plug with the board that adds to the cost of the board (but the customer would have had to get plugs for SPOX, making it better overall). The lack of cost and hassle of a special crimp tool is a good saving for customer. Also, when considering cost, the fact the crimps themselves are approx 10p each makes the SPOX much closer to the cost of the Phœnix Contact solution.

Another small downside is the plugs are longer, which means at least one board (the keypad module) will stay as SPOX, but be supplied with a plug and crimped leads as they solder on to the back of the keypad. The other cases look like they will still work in the back of an exit button box, etc.

Testing

Finally, today, after a week of UPS being stupid, I have the first of these to play with. They are as expected.

One simple test was can a Phœnix Contact plug fit a SPOX socket, and the answer is, sort of, with a bit of force, not ideal, and it is the other way up so a plug made for Phœnix Contact will not just work in SPOX even if you force it as wired backwards.

Here we have the mini SPOX (white) and the Phœnix Contact (black). You can see what happens trying to plug on in to the other. And no, the SPOX don't even slightly fit in the Phœnix Contact socket.

Wires

The wires that work are a factor. The crimps on mini SPOX can handle a range of wires, stranded and solid. But these push in are a tad more picky. The first test was confirming that the really very nice heavy duty Belden 0.75 mm² black/red stranded wires just work. They are probably the biggest it would handle, but really nice for power wires.

The next test was that solid cat5/6 cable works, and yes, that seems a perfect fit for signal wires.

The one wire that does not work is a finer stranded wire - it does not have the solidity to push in to the plug. And, sadly, my smallest bootlace ferrules are also too big it seems. This could be a slight issue for some existing wiring as "alarm cable" is often the fine stranded wire, though solid cat5 cable seems to be more common now. That said, it may be that the same technique for removing wires (pin/screwdriver) could be used to lift the lever and allow the thinner stranded wires, albeit slightly more fiddly.

In case you are wondering how it works, they have very nice data sheets.

To remove the wire you need a pin, or, as in this case, a very small screwdriver.

The plugs will fit on 0.1" square pins if needed.

2023-04-01

Talking to an AI would be easier than Amazon

I have rarely had to deal with Amazon seller support, and every time has been a challenge. And don't have a go at me for even using Amazon - they have proved useful, sadly.

They seem to work by the message you send being picked up by a person at random, and replied to, hours later. But the replies seem to only consist of stock paragraphs. They seem unable to to answer basic questions in simple English.

So my challenge this week was simple - we (A&A) sell a few PCBs, and I wanted to mark them with the brand "AJK" rather than "Generic". When you make a listing, they ask the brand, and will not accept "AJK".

Just to explain, "AJK" is a brand I have, a registered trademark even, for PCBs, and is in gold plated metal actually on some of the PCBs (space permitting). I think that makes it a "brand", which I own. Obviously I have authorised A&A to make and sell PCBs using that brand.

The process starts simply - you try and type AJK, and it directs you to create an application to use a brand, and that has some moderately sane requests - pictures of product showing the brand, letter authorising manufacturer to use the brand, simple things I was able to easily provide.

I thought this would be easy. It is deceptive. This started a 4 day journey that was driving me round the bend to the extent that I was replying to one message at 2am even.

The biggest problem is they would ask for things like :-

Well, that is all pretty easy. I supplied all of that at the start though. And every time they ask this, I supply the image they want. This issue is that if they (new person each time) perceive I have failed in some aspect of that list, they won't say what, they just repeat that whole request. I never found out what was missing/wrong.

On two separate occasions when they requested something over and over again I added arrows and labels to the picture I was sending covering every thing they asked for.

At one point is was an issue that Andrews & Arnold Ltd were not "related" to the brand. This is crazy as step 1 was including a letter, from me personally as holder of the trademark, to Andrews & Arnold Ltd, authorising Andrews & Arnold Ltd to make and sell products using the brand. That took a lot of replies. One oddity is they say they will not accept a GS1 certificate - which makes no sense, what is the point of such certificate if they won't accept it. It seems they did however accept that Andrews & Arnold Ltd were allowed to use the GTIN/EAN we were using but they did not see how it related to AJK brand. Well, FFS, the letter, at the start, linking the two. Arrrg!

It got to the point they complained I was sending the same image. Well they kept asking for the same stuff. This was the request for the packaging image.

They also asked for all of the details of the product listing. This is an annoying thing as they could maybe have not stopped me making the listing at the "brand" stage and I could have sorted them all. But again, I answered all of those questions - several times.

Somehow, eventually, after I took 20 images of me holding the package, opening it, removing the PCB, and zooming in on the "AJK" logo on the PCB, they accepted we could list items using the "AJK" brand. I did not send a video, that would have been the next step I think.

So, next was the brand on the listing. In desperation I made a listing as "Generic" brand (I should register that as a trademark now). It may be partly what got the whole thing approved, I don't know. But now I have two PCBs listed as "Generic" and want changed to "AJK". One of these has the AJK logo clearly shown in the listing in gold plated metal on the PCB itself. Both have it on the packaging image.

At this point, I can make a new listing and use AJK, just typing in the brand box, but changing an existing listing, even just made the day before, is complicated, it seems.

This is the same list they sent the first time, and I said "we are the manufacturer and I am telling you this is the brand". But no, it is "policy". Thankfully I only need one of these, and web site was easiest. So I added to the web site on circuit boards that they were branded AJK. Simples.

Nope.

So apparently they don't just need the site to confirm the requested change (brand name, which I did) they want more. Why not say that in the first place, FFS. And somehow the "About us" page needed to be involved, that was new too, and crazy.

So this is where we are now. The A&A "About us" page has this...

Will it work? - no idea, but I can change that wording to be whatever they want, if only they will actually say what they want. If all else fails, when stock is sold, I delete the listing and make new ones with the AJK brand. That or I try and register a trademark for "Generic" (perhaps in some stylised text) and cause them havoc by saying "why are so many things listed using my brand/trademark?" - he he.

Failed! [They know I am brand owner and the UPC (actually GTIN/EAN) owner too]

So why ask me for the web page, etc, if they are not then going to do it...

P.S. They have now circled back to asking for web site / manual showing the brand, it is crazy.

Having circled back to that, I tried again, similar (less sarcastic) item on A&A page, and got this.

My reply: "I am the brand owner, so you can make the changes now, yes?". We'll see. No chance is there?!

They finally accepted that, and then said "you can't change the brand". So why the fuck string me along in the first (sorry, second, or third) place. Arrrrg!

So now I have got to the detailed explanation of how to delete and re-create my listings (why the fuck?), and my reply asking how that impacts the FBA stock, and, well, silence.

Fencing

Bit of fun... We usually put up some Christmas lights on the house - some fairy lights on the metal fencing at the front, but a pain as mean...