Programmable PSU Module

PSU Module 2

The concept shown on the Lab PSU earlier is that I can create a battery module as illustrated above. The MCU is simply used to monitor output voltage and current towards preset values that can be controlled by a robot control system if required.

We can also add a charger so we can just connect an external PSU to re-charge the battery. For now I will focus on the PSU module and see if I can get the concept tested.


Returning to the Lab PSU we use the same module as core, but we could also add a programmable, analogue regulator. The later will reduce noise and make the PSU usable on audio applications. The idea is that the Switched PSU regulate the majority of the Power because it is more effective, but we add an analogue regulator on the last 1V or so as a “super filter” as it can deal with ripple and noise better than a switched PSU. As we only regulate the last volt or so the classic power loss will be limited. We can also make this an optional step for high ampere applications (motors etc).

Programmable PSU 3

Looking for Programmable PSU’s on the net I find a few “programmable” priced at 100.- 300.- GBP – I also found this module for ca 30.- GBP on ebay.

PSU Module

This is a 0-30V/5A module from ebay. Quite good spec, but by the time you have added a Box and mains PSU you could as well have bought a standard Lab PSU. You can pre-store 10 volt values With accurate setting from what I can see – which is far from the low frequency function generator with 0-48V/20A out and a build-in logger/Oscilloscope + a wifi Connection I want.

I also want the display/keyboard a bit easier to operate than the one above. But, most important is cost of it all. I have a target to stay under 200.- USD on a finished product. I would like it to be cheaper, but I also need to be realistic as we need to buy a few components like project box and display.

Programmable Lab PSU

Programmable Lab PSU

This is just a draft to play around with ideas. I can use standard switched 12V PSU’s to connect to mains. These cost around 10-20.- USD each for 12V/20A. A programmable switch board can connect these to either deliver higher input voltage or more ampere. I would like to target 48V/20A out – but lets see what we can achieve here. The driver we illustrated earlier in the motor controller can become a Switched Programmable PSU step controlled by a MCU and with a proper output filter stage. With a MCU it is also easy to add a display and a few keys as well as a remote control interface for test automation.

The usage of pre-made PSU’s for mains have to do with CE/FCC approval on equipment connected to mains – we can make these as well, but I don’t want to at this stage –  maybe later.

Going back to my robot I replace the mains step with a battery and ditch the display etc. As I plan this to be small PCB it can also be a module we plug into our lab PSU and we might have a lab PSU with multiple channels out.

As for the lab PSU we can also implement a real-time oscilloscope on the display showing output current and voltage – with a log window this will enable us to see what we put in and how the equipment we supply behave. I need to think about this one a little + I need to test my theories on output filter, but this start to sound like a fun Project – A lab PSU With these capabilities cost far more than I can afford.

Programmable PSU 2


A programmable, switched PSU can also be used as a function generator. The diagram above illustrate how we can change duty cycle of the input PWM to create a DC waveform out. This is actually one of the techniques we use to run 3-phase motors, but it also have the potential to become an awesome lab-PSU with capabilities to simulate spikes/noise or AC PSU’s.

The challenge is however that the frequency out will be ca 1/20 of the PWM frequency in. So using 20Khz PWM we should be able to generate decent waveforms up to 1Khz. This is not much, but it is a OK capability for a lab PSU.

Programmable PSU


I need to address one more electronic designs – I need a 15A PSU for my robot. I did a vero board design earlier using 4 x DC/DC converters due to their low cost. This delivers 12A in peak which is what I need with 12 x servo’s to allow them all to operate simultaneously. But, it is rather big, so I would like to optimize the size a bit if I can.

The concept of a switched PSU is rather easy – you send PWM into a filter consisting of a coil and a capacitor as illustrated above, and you get DC current out. If you have 12V and apply 50% duty you should have 6V in average out.

I designed a 4x half-bridge driver earlier with a very small driver stage, so what I would like to test is to convert this into a programmable, switched PSU. MCU’s are cheap these days and a small STM32F030F4 costing 50 cent could do the job here. It got ADC’s, UART and PWM output needed. It is worth a try to see what we can get out of this.

The fun of electronics

Just realised that I have produced 15 different electronic designs of which 14 contain a MCU the last 6-8 months. I have several other designs in the planned pipeline, but I am holding back a little because I am getting a huge backlog of designs I need to finish coding for.

The challenge is that I find it very easy and relaxing to drop into the lab and do 30 min ++ on electronic schematics, PCB layout or just write a blog article – and actually get something done in 30 minutes. Software work tend to be the larger and more invisible part of the job once the high level design is drafted.

Plain Assembly – parameters

Developers of C/C++ will probably be a little confused over the lack of pointers. I use syntax like:

Func MyFunc(MyObject ob)

What is “ob”? Am I sending the full object, a reference or a pointer?

Func MyFunc(MyObject ob, uint32 i)
            ob.myParameter = 1

MyObject foo
uint32 var
Call MyFunc(foo, var)

 In C/C++ this would create a copy on the stack, so any changes would remain local. This is very clear in C/C++ because we control pointers. In other languages “MyObject” would become a hidden pointer with the consequence that the assign inside the function would alter “foo” while the 2nd assign will only change the local copy if “i”.

The idea (for now) is that objects always are passed as a pointer by default, while build in data-types always create a local stack entry.

Func MyFunc(copy MyObject ob, Reference uint32 i)
            ob.myParameter = 1

This one add a option parameter “copy” to force the object to become a local stack copy in case we need that option. I also add the keyword “Reference” to force i to become a pointer so that changing I will change the oroginal variable. Using “Reference” will generate an error if we try calling this with a constant value.

Plain Assembly – Event triggers

I need to evolve my Event trigger mechanism.

Lets assume we want to control a robot with 2 electric motors – one left and one right. We are currently running forward with 1000 RPM and want to reverse with 10RPM.

Assign leftMotor.direction = reverse
Assign rightMotor.direction = reverse
Assign leftMotor.speed = 10
Assign rightMotor.speed=10

The issue is that as we make the first assign we also raise the event. This will cause the left motor to reverse at 1000RPM. The result is behaviour we did not intend during the update, so we need a mechanism that allow us to Control the event.

Object Motor
            uint32 direction
            uint32 speed

Event C OnCommand(Motor lm, Motor rm)

const Forward = 0
const Reverse = 1

Motor leftMotor,rightMotor

leftMotor.direction = forward
rightMotor.direction = forward
leftMotor.speed = 1000

Raise OnCommand(leftMotor, rightMotor)
leftMotor.direction = reverse
rightMotor.direction = reverse
leftMotor.speed = 10

Raise OnCommand(leftMotor, rightMotor

“Event C” does in this example declare a C code event named “OnCommand” with 2 x Motor Objects as parameters. Rather than having event’s triggered automatically we raise them controlled. I have tried different syntax to do the same automatically, but I believe controlling this manually actually is a must.

The syntax is a draft – the usage of raise is in this example inconsistent With earlier examples, so I will need to work on that. I also notice that I forgot Assign on the assign statements – this was accidental, but I decided to leave it because I am considering dropping the need for Assign, Call and Raise in the Assembly syntax.

Plain VM – Distributed Processing

One of the key objectives with Plain is to support distributed systems. The mechanism to do so is at the core of the VM and this is one of the areas where the VM really makes sence.

We have already described objects – data structures that map into C code with Events. We have briefly mentioned that the same mechanism can be used to communicate with a different module – meaning that if you write to a register in one VM instance that becomes an event in a second VM instance – and the two modules communicate.

The beauty of this is that we can do that with easyIPC in the middle communicating between two Plain applications running on different devices – or even better between a C/C++, Java, C#, Python or any application with a easyIPC SDK and any Plain application.

The beauty about it is that it requires close to no extra coding except mapping up events. I need to work on adding syntax to support this, but it will work.

Plain Assembly – Data types

The VM is designed to control logic so everything is mapped into a 32 bit virtual register for simplicity. The assembly language support a large range of data types, but the VM will by default treat everything as a 32 bit register to keep it simple and fast.

The assembly language do however support a range of data-types:

Bit A single bit data-type that can be used to create bit-fields. Used in math it is treated as an unsigned integer.
Byte A byte is 8 bits.
Uint16 An unsigned 16 bit integer.
Int16 A signed 16 bit integer.
Uint32 An unsigned 32 bit integer.
Int32 A signed 32 bit integer.
Float32 A 32 bit floating point.
String A text string.
bool A boolean value that can be true or false.
Object Data structure used to create data-types based on existing data-types.
Enum A data-type that only allow a of constant values.

Arrays are supported for all data-types by adding [] after the variable name. Operations can use ranges as a[0..9].

Adding “packed” to a Object will force it to be bit-packed. This is designed to allow the VM to encode/decode bit-packed Messages etc.

As for other data-types we could also support double64, uint64 etc.