Category Archives: Robot

Universal Motor Controller

I designed this universal motor controller capable on driving DC-, Stepper-, BLDC- and even AC – motors earlier. The design parameters was 12-24V at 15A. This is quite a capable controller, but I did a mistake that limit the controller to 12-20V since I connected the Gate Drivers to the Motor PSU directly. To compensate for this I need to modify the design and implement a separate 12V PSU. As I correct this I also want to consider some additional changes.

I am considering is to replace the RS485 with an isolated RS485 due to the amount of energy involved. The 3rd change is Ethernet on a separate adapter board. Basically I want to copy the modules I use on the Universal Adapter as soon as I have tested them.

I am not sure about Ethernet. Ethernet sound nice due to the functionality, but it is a clumsy, 4-wire 1:1 solution. RS485 is slower, but it is a 2-wire network. It actually makes more sense having dual RS485 to be honest. CAN & Ethernet is easier to deal with using an adapter board- RS485 is considered a lower level of communication than CAN because CAN have protocols like CANopen, J1939 etc. The reality is that if we use RS-X that changes.

What I probably should do at some point is to create a “Ethernet” on top of RS-X by using a dual RS-X connection. But, that is fun for later…

So the modified design will be

  • STM32F405RG MCU, 168Mhz, 32bit M4, 1MbFlash, 192KbSRAM
  • 4 x separate half bridge drivers, 30V @15A
  • Current sensors on all
  • BEMF sensors
  • PSU Voltage Sensor
  • Separate 3.3V supercap to sustain MCU in power dips.
  • 3 x hall sensors
  • 2 x temperature sensors.
  • 1 x resolver
  • 2 x end sensors
  • 1-2 x RS485
  • Adapter board for battery/caps
  • Adapter board for CAN/Ethernet/Wifi

Applications

  • Solenoid driver
  • DC Motor driver
  • Stepper Motor Driver
  • Brushless 3-Phase motor driver

PLC Modular System

I have worked far to long with 19″ cabinets and things you mount from front, so what I am thinking is a micro-version of a rack system. We box each electronic module with a backbone plug and custom front connectors. We then plug them in, wire using standard wiring (that we probably have to create) in front – no wiring in the back.

These boxes are simple and can easily be printed on a 3D printer. They will also allow us to mount more electronics tighter to address the total size.

A classic PLC uses 2 wires for a 24V pulse signal – we can typically standardize these so that we apply standard, plug & play cables and avoid as much custom wiring as possible. The top front is after all for wiring to equipment, not for internal wiring that is already done in the back-plane. I think this can work, but I need to talk it through with professional automation engineers – luckily I have access to them in numbers.

One drawback I can see straight away is vibration. I was planning to make this so small that it could fit mobile Equipment, but mobile Equipment vibrate a lot. We will need an outer box and holding mechanism that tolerate very high vibration – or more correctly reduce vibration.

32 x Servo/IO Hat

32xIOHat

New 3D model showing the right angle connectors and the updated “Servo” that now is renamed to 32 x IO Hat. I have done some mechanical changes and added a lot of protection electronics. As mentioned earlier this is my test ground for the VM and each channel have multiple capabilities – hence the “IO” rather than Servo.

  • 32 channel Servo Controller
  • 32 channel digital in
  • 32 channel digital out
  • 32 channel low resolution PWM
  • 2 channel analogue out
  • 12 channel analogue in
  • or any combination of the above

I have three Hat’s that will stack nicely

  • 16/32 channel IO (shown here)
  • 8x H-Bridge + 8 x IO
  • 5 port RS-485/CAN

I do in addition have the 7 x Stepper, but I am not happy with the connectors on that one. The 28BYJ-48 stepper motors comes with a 5-pin connector that is nice and exist as right-angle, but I can only manage 3 of these in stacked position – To be honest I am considering ditching this Hat design.

As we move forward I will add more hat’s and more distributed sensors and controllers to allow larger and more complex systems to be created. I want to create a few robots + I want to automate my home for the fun of it. But, all of this is worthless without an easier way to apply Distributed logic so I will continue to dig into the PLAIN concept for now.

VM Test Ground

I decided to use the 32 x IO (Servo, Analogue, Digital) as my test ground for the VM – the firmware will in this case include easyIPC (SPI in this case) and a 32 channel programmable IO controller. Each of the channels have capabilities like:

  • Servo with a 14 bit pulse resolution.
  • PWM out with 14 bit resolution. This is a bit-banged PWM that can be used on all channels.
  • Digital Signal Input
  • Digital Signal Output

 Some of the channels will have the following:

  • High resolution/frequency PWM signals
  • Analogue Input
  • Analogue output.

This firmware is an excellent test-ground because it includes highly programmable logic and a hard real-time core on the bit-banging part.

Lets draft some PLAIN Assembly code:

Enum uint32 Mode
            Servo=0
            PWM=1
            DigitalIn=2
            DigitalOut=3
            HRPWM=4
            AnalogueIn=5
            Analogueout=6
End

Object Channel 
            Mode chMode = Mode.Servo
            uint32 position=0
            uint32 frequency = 0
            uint32 duty = 0
            uint32 analogueOut = 0
            uint32 analogueIn = 0
End

Channel Ch1
Channel Ch2
Channel Ch3
Channel Ch4
...

Bit digitalIn[32]
Bit digitalOut[32]

This is a draft of how I want PLAIN Assembly to see the easyIPC objects. Ch1.Mode will be located at register 0x8000, but we can also locate data on selected registers as follows

Channel Ch1 at R(0x8010)

In this example I force Ch1 to be located at Register 0x8010.

The more tricky part is the integration with C/C++ code. The challenge is that the module and data we transfer must match what the C/C++ firmware expects. This last mapping is done by the real-time linker in the firmware that receive the above as a “PLAIN Module Specification”. If it fail it will need to reject the module. In theory it should never fail as the assembler should stop us, but it is always the possibility of firmware version mismatch. This part will need to be strict or we will just dig into loads of debug problems.

Map Channel to C(Channel)
Map digitalIn to C(DigIn)
Map digitalOut to C(DigOut)

Assign Ch1.chMode = Mode.Servo
Assign Ch2.chMode = Mode.DigitalIn
Assign Ch3.chMode = Mode.DigitalIn

Event digitalIn[2]
            Assign Ch1.position = 0
End

Event digitalIn[3]
            Assign Ch1.position = 100
End

This example configure Ch1 as a Servo and Ch2, Ch3 as digital input pins. The Map statements link the objects to associated C/C++ code. The Assembler (and real-time linker) will check these exact names and parameters – parameters must match on name and data type.

The Event statement “digitalIn[2]” declare that any change to bit 2 in the digitalIn will cause a call to this bit of logic. This will be called regardless if it is C/C++ or PLAIN assembly that makes the change.

 I think this will work, but I need to let it mature to catch up missing bits and see if I can optimize this. Notice that while this example is ca 40 lines in assembly we would be talking about ca 7 instructions in the resulting code (+ initialization). The initialization will in this case be nothing since 0 is the default value on all registers. The VM will automatically reset this before execution to avoid that we have random, default values. “Event digitalIn[2]” will generate 2 instructions – an Assign and a Return.

But, keep in mind that this draft is work in progress. I will implement this next to see how it actually works out in real life.

PLAIN – Virtual Machine

Languages like Java C# etc all use a virtual machine. This is a software package that need to start and interpret some kind assembly code. Languages like C/C++ compile into native assembly code that is much faster, but also tied to the hardware it run’s on.

A virtual machine have the advantage that we extend the platform with build in features made available in C/C++. This high level code occupy less space than binary code and executes under our control. The drawback is that it executes slower than native code, but I plan to challenge that by introducing very high level assembly instructions.

I would like to create a native assembler at some point, but for now I want to play around with a Virtual Machine design.

VM Block

The diagram above show how we link things together in the firmware. We use easyIPC protocols to communicate, RTOS and HAL + other modules tom access electronics and do complex stuff. The VM executes logic that control what we do.

Instruction Format

Our VM needs it’s own assembly language so we can use a 32 bit design as indicated above. A 8 bit Op-Code + 4 bit Category code leaves 16 pages of 256 instructions. Category 0 is the build in one, but other categories can be used for extended instructions. Length is the added number of 32 bit register, meaning an instruction can be 32 x 16 bits long.

Instruction Move

This show the MOVE R1, R2 that will copy content of R1 into R2. As this is an array of 31 parameters we can extend this to MOVE R1,R2,R3;R4 etc that copies R1 into R2,R3,R4. Op Code 0 is NOP (No Operation).

VM Tables

This diagram illustrate the internal core of the VM. We have a table holding 32 bit instructions stored in Flash. A Registers table that is located in SRAM for generic use in our logic, and an object table that use address 0x8000 to 0xFFFF to access easyIPC mapped content. Notice that the total register size is 64Kb to make the most of a 16 bit parameter. Stack is located in SRAM at 0x7FFF and up. Each PLAIN Module have it’s own, private stack.

PLAIN contains a set of registers known as easyIPC object registers located between 8000h and FFFFh. These are accessed the same way as stack and generic registers, but are wired to other software or hardware. If these registers are changed events will be generated to allow PLAIN or C/C++ to process changes.

The PLAIN specification allows an application to organize it’s own layout of these objects to guarantee that an application will execute correctly. The issue is that registers for selected hardware need to be located somewhere, and with various hardware/software combinations you end up with far too many registers for the world to be unique. To solve this the Assembler will create a map where all software and hardware is mapped correctly with PLAIN logic. This result in a map that follows the application. The run-time engine will need to map and resolve these calls as the PLAIN application is loaded.

This is work in progress so expect changes as we implement this. The design draft above is based on a proof of concept implementation done about a year ago.

Introducing PLAIN

One of the challenges with a distributed system consisting of multiple Raspberry PI’s, multiple Hat’s and multiple RS-X connected devices is how to control it all. At the end we are running a complex, distributed system and coding logic on this level using a classic programming language like C/C++ is not straight forward. C/C++ is unbeatable dealing with low level electronics, performance and algorithms, but it is a bit clumsy to write higher level logic involving distributed logic. I would like to keep C/C++ to deal with low level things and HOW we do things, but I need something better to describe the logic and WHAT we want done. Having used years with various programming languages, PLC and CNC machinery I basically want to create something new that does things a bit differently.

I decided some time ago to name this PLAINProgramming Language for Automation Industry – basically a language/Logic concept to control robotics on distributed systems. We can evolve this a bit as we move forward, but I have a few key requirements:

  • Generic in nature.
  • Extendable and able to use C/C++ modules.
  • Deal with distributed, high level logic.
  • Support a future graphical CASE tool.
  • State-engine and event based Logic at core.
  • Easy to read top-down text, no cryptic syntax.
  • Easy to learn – read Logic in 5 min – yet powerfully to support Professionals.
  • Embeddable into other solutions.
  • Real-Time Centric.

The previous work on easyIPC fits straight into this work as is establish a plug & play communication network using multiple techniques. What I lack is an Ethernet based protocol, but I will return to this later.

At this point I am planning a language specification, compiler and Virtual Machine. The specification will need to evolve as we move forward on try & fail. Actually I want to start with the Virtual Machine.

32xServo Hat Revision 1.1

32xservehat_1_1Not very exiting, but it has taken me most of the day. This is the revision 1.1 of the 32xServo Hat. Just for the record – the red lanes are actually ground plane so it will all be covered with GND – I just switched it off for the picture.

  • Added optional TVS diode on PSU for better protection.
  • Added 100uF and 100nF capacitor on PSU for spike cutting.
  • Adjusted pin header positions to better fit 3×4 headers.
  • Adjusted the lower 16 channels as they where a bit close to the bottom edge.
  • Added TVS on all 32 channels for protection of the MCU.
  • Changed all LED’s to 0603 package.
  • Added weak pull-up on nRESET.

32xservehat_1_13d

The lower 16 channels can use 3×4 right angle connectors allowing the Hat to be used in a stack. I finally found a good price on 3×4 right angle down to ca 10 cent each – still looking. You can still use classic 2.54 Pitch pin headers that is even cheaper.

Revision 1.0 is actually ok to go, so I will try putting this into production & sales since a lot of people have asked for it. It will be exiting to see what assembly prices I can achieve. PCB & Components are probably ca 10.- USD all together.

20A Stepper Motor Driver

4phasedriver

This is just a concept sketch of the driver step for a 4 phase driver. We add the 4th phase, but I only use one current shunt on this. The width is ca 33 mm using the same trick in mounting a 4 pole 5.08 pitch connector on the back. I need to adjust this and find space for the 6-wire motors so will play around with ideas for now. The size above is ca 33mm x 23 mm , so an actual controller in 35 x 50 mm size might be possible.