Programming x-mas Led strings

We are getting closer to x-mas and I am about to start setting up led strings in my garden. I have a load of 12V and 24V led strings, so I plan using my PWM12 Hat as LED Driver as illustrated below.

The system set up is straight forward – I use a number of PWM12 Hat’s stand-alone to drive the strings. Each channel can drive 5-10 meter of Led’s and I can support both 12V and 24V systems. I need to make a PSU with 5V, 12V and 24V and some kind of waterproof casing for the driver – I will probably just use a plastic bag and mount it on a plate for now.

Programming is easy as I can remote control this through the CAN ports and all we need to do is to output a PWM signal. Most strings are single lights, but I also have a RGB string that need 3 signals to set color. We set intensity by regulating PWM duty, but I have to work out a conversion scale as this is not a linear conversion. Using 32 intensity settings I can get 32,768 different colors on the RGB setting.

Programming with State Diagrams – part 1

A quite like UML State Diagrams as they give a good high level view of what happens in the code on functional levels. I was first introduced to this by a tool that actually let you create embedded code. This overlap a bit with PLD, but it creates a better overview of event-flow and an alternative way of viewing your code. I have tested some tools that attempt creating code, but they are too limiting so I decided to create my own experiment.

I was a bit surprised to find that it is huge variations in how UML State Diagrams are used and since I intend to generate source code I need to define how we will use this.

An UML State Diagram is composed of “States” and “Events”. It has some similarity to a flow diagram like PLD, but the concept is a bit different in the sense that one state can generate several signals or events. Some tools will call it signals, while I prefer the name “events”.

 To define out states we make a rule that input are primarily on left, while output are primarily on right. I also add a round connection point for events where the color will display it’s status. All output events are displayed, while only mandatory input events are displayed by default. To create a new input event you simply grab an event and drag it to the state. This will add the input event and connect the events with a line.

The name of the state will be a function name and the content of that function can be a description representing source code, a PLD diagram or another UML State Diagram.

In the example above I show a full diagram with external input and output. This can be used as a component in other diagrams as follows:

Then used in another you chose what is displayed about the content – you can show the sub-diagram or simply add a text describing what is done.

This last illustration show Fork & Join. Fork will take one event as input and copy it into several events that now process in parallel. Join do the opposite – it takes several Events as input and wait until it has them all.

The experiment is to knock up a tool that does sufficiently of this so I can evaluate if this is a path forward. Is it worth it? At the end it comes down to one single thing – speed of development!


Programming HMI with C#/NET 4.7.2

This demo is a bit in the early stage, but I am using C# and .NET 4.7.2 for a simple test. I developed in C# a few years back and was a bit dissapointed over performance. But, I notice that this have improved dramatically with later .NET versions so I am putting it up for a test. What interest me with C# is that the combination of language, Visual Studio IDE and libraries/framework makes it very productive to work with on the HMI side. What have dissapointed me in the past was performance. I have similar demo using Qt and I have to admit that I have not been convinced about Qt performance either.

What I am experimenting with here is a graphical programming language. In this case I started on UML State diagrams. I am not sure if I want to complete this, but I was using UML State diagrams earlier and know it add some value. I simply want to see if this is a path to pursue if I start using this to generate code. The demo you see above was knocked up in ca 2 days work including scrolling/zooming and a lot of the basic graphichs work.

C# itself is much slower that C++, but C# graphics uses optimized C/C++ libraries and I must admit I like the improvements I see.  What actually convinced me is the plot below. This is done in raster graphics with 10 line plots containing thousands of points and update itself ca 27FPS. This is a stupid test to verify if raster graphics are sufficient for my graphical designers.

The difference between C# and C++ is that .NET (that is C# VM) actually have started using more kernals on HMI. So while it is slower at first it seems to get the upper hand because it can use the entire CPU while C++ libraries are stuck with one kernal. I know I can get a much higher performance using C++, but that will require that I put in a lot of work. This is also why I tend to stick to 2D raster graphics – I lack a framework that can do the same on 3D engines without a lot of work first.

One of the drawbacks with C# used to be that it was Windows only, but both Linux, Android and iOS has since then been integrated into Visual Studio. We will see where this leads.

12 x PWM Hat


I have so many Hat’s by now that I try to make some systematic documentation on them. This drawing is part of what I call “Annotated Schematics” to document the design and collect notes needed for working on the Hat. This example is one of my more powerfully Hat’s as it contains 12 separate PWM ports with current sensors. PWM ports are actually separate Half H-Bridge ports with a GND connector each for maximum flexibility.

  1. Standard CAN port.
  2. 6 x PWM and 6 x GND connectors. Can use different terminals, but is designed for a right angle terminal to allow the Hat to be stacked.
  3. Current sensors. Separate current sensor on each PWM High Side, meaning we measure current out.
  4. Power connector for PWM supporting 60V.
  5. Capacitor Bank.
  6. Leds. One power led and one status led.
  7. USB port.
  8. 5V Power.
  9. Current Sensors.
  10. 6 x PWM and 6 x GND connectors.
  11. PWM Drivers. In this case I use DRV8301 that contains 3 x separate Half H-Bridge drivers. This can be combined to drive 12xindividual PWM signals of 60V/2A, 6xDC Motors, 4×3-Phase Motors, 3xStepper motors or any combination you like. Each of the DRV8301 have power pads connected to back of the PCB and I can actually mount a heatsink on this one if needed.
  12. Standard SWD connector.
  13.  na
  14. STM32F405RG
  15. Raspberry PI Connector with SPI Backbone and 5V. Enables the Hat to be used with Raspberry PI in a stack, stand-alone or together with other Hat’s.

This Hat is so powerfully that it replaced a lot of other Hat’s I planned. I was considering a separate Stepper Motor Hat or DC Motor Hat etc, but I don’t see the point. This is one of the most flexible motor drivers I have made. If you go back on this blog you will also see my notes on how many attempts I made on routing this before I succeeded. So far it is only minor comments on what needs to change.

This show another part of my “standard” documentation, the functional block diagram. This is basically just a visual content list.

I have done PWM signals before, but I am looking forward to experiment with the current sensors. If I use current sensors on a Stepper I should be able to sense torque and automatically detect edges etc.

The reason I started assembling this now (it has been around for a while) is however x-mas coming up – powering multi-colored led string.



PWM12 – Current Sensor

I have started assembling the first PWM12 board and this is the current sensor I use. It will probably work ok, but the circuit lack two important components. One a small capacitor between CSense and ground and secondly a TVS between the same. The reason is I could have needed those to protect the MCU against pulses, but I had no space for them. Hopefully INA193 will absorb the pulses if we have any.

Buck Converter working

Soldered up a new board just to realize that DRV8301 was bust as well, so replaced DRV8301 and Buck converter is actually working. I am getting 3.4V just enouth for SPX3819 to give 3.2 out and the MCU ticks at 168Mhz. Looking at datasheet I also see that I have done correctlt – EN_BUCK should be floating.

I suspect that I busted the MCU partly by giving it 15V on the ADC by mistake – who knows – I still have components to solder on, but it’s a good start on my 2nd board.

Had to scrap yet another MCU as well. I soldered a new MCU, but it did not tivk properly. This one is from a different batch, so I hope to be out of the bad batch scheme – I am buying these MCU’s from proper distributors next. Talking about MCU’s checking pricing through Arrow I realize that STM32H753Vx is not much more expensive that STM32F405RG – I think the V version with it’s 100 pins is a bit large for most of my projects thought. I am also a bit dissapointed over IDE support on H743 yet, but I get it working.

Expression Parser

One key component of any Parser is the Expression Parser. This one is used to parse mathematical or logical expressions into a list of micro-statements. Plain have a separate instruction to execute math, but the parser need to build the list correct.

Example : 4 + 5 * 3

If we add 4+5 we get 9 and if we multiply that with 3 we get 27 which is wrong because * (multiplication) have higher priority than +. So the correct processing is:

5*3 gives us 15 and adding 4 gives us 19.

I have a preference for using tables to compute expressions. I need one temp table, a operator priority table and an output table for micro-instructions. The algorithm is quite simple as we parse a value and a operator before we evaluate the tree.

First is 4 +. As this is the first we can’t do any temp calculations.

Second is 5 *. Since * have higher priority than + we just add it to out temp table and parse 3 =. Our table will now look like this:

  1. 4 +
  2. 5 *
  3. 3 =

=is the highest priority so we now output a micro statement:

  1. t1 = 5 * 3

And we modify our table to the following:

  1. 4 +
  2. t1 =

Next we output t1 = 4+t1. t1 is our result leading to a small math script as follows:

  1. t1= 5 * 3
  2. t1 = t1 + 4

What we now lack is parenthesis, variables and function calls and we have an algebraic expression parser. Many language parsers will build the language on this, but my preference have always been to handle the language and expressions separately.

Dealing with this in plain was a challenge because a normal language would implement assembly instructions like Add, Sub, Mul, Div etc. At this point I decided to implement a math instruction that take the parsed tree as input to enable math to be done as close to C as possible. This keeps the instruction set small + it preserves execution speed.

Plain Syntax Alternatives

One of the challenges I have with Worldpress is to be able to show source code in here, so I apologize for the bad quality on the examples above.

The examples show one of my Plain test examples in 2 different syntax styles. the one to left is the currently chosen one and the one to right is the more C++ alike version and decided to leave for now.  My rationale is that some of the syntax is more difficult to express using CPP style and since Plain and C++ will co-exist it would create too much confusion.

Plain Assembler

The Assembler itself will read Plain source code and generate a RTL file that is downloaded to the device. RTL (Real Time Linker) is located on the target device and will convert RTL format to executable Plain VM instructions.

Most modern Assemblers are very similar to Compilers. The main difference is that the Assembler have a syntax that is close to the native assembly or in this case VM instructions. That said Plain is actually a high level language, so the technique used is a classic Descent Recursive Parser assisted by tables.

Any Assembler (or Compiler) will consist of 3 components; a Parser, a Repository and a Code Generator. The Parser read Plain code and convert it to a repository (database) over the code. Once done it call the code generator that in this case generate RTL Code. One of the differences with Plain is that the Repository is exposed and can be imported and exported as well as accessed through other applications.

The Repository need a XML repository file that define the target platform and available libraries/modules on that platform. This together with the Plain source code form the final applications.

While the assembler “PASM” is one application we will also have several other command line utilities and file formats. One is the output reports from the repository that can be used for IDE integration or libraries. Another is the download utility, but I will return to those in due time.

Plain has been a long coming system since I needed to create HW supporting Plain, FW supporting Plain, VM Engine, RTL as well as the assembler itself. It will still be on-going for a while, but I am not that far off demonstrating the first Plain applications.