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.
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.
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.
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.
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.
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.
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
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.
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
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.
Event C OnCommand(Motor lm, Motor rm)
const Forward = 0
const Reverse = 1
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.
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.
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:
||A single bit data-type that can be used to create bit-fields. Used in math it is treated as an unsigned integer.
||A byte is 8 bits.
||An unsigned 16 bit integer.
||A signed 16 bit integer.
||An unsigned 32 bit integer.
||A signed 32 bit integer.
||A 32 bit floating point.
||A text string.
||A boolean value that can be true or false.
||Data structure used to create data-types based on existing data-types.
||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.
I just realized that I probably can optimize the assembly a little by introducing “End” as a single entry instruction. The reason is because we now use goto that are 2 entries. I can avoid the 2. entry by using the stack.
for x=1 to 10
As “for” is an instruction it can create a ix to itself on the stack and as we reach “end” we treat that as a “goto ix”. The upside of this is that we suddenly have a 1:1 between assembly and actual instructions. I also believe this will be faster than using a goto – not that it matters.
if A = 1
In this example we introduce “end” to replace the goto’s we only need to insert the ix for the next instruction located after “end”. in this case we would save 3 entries and be down to 10 + 3. The rule here need to be that we insert the ix if we execute the true block. The irony in this example is that we insert “end” before elsif and else, but not at the end statement.
So in short assembly that require a end will insert a ix on the stack that is removed by end as it jump to this location.