The TLE94112 multi-half-bridge board allows you, as the name suggests, to control peripherals through a half-bridge. Two of these half-bridges come together to form one H-Bridge. An H-Bridge consists of four switches (most often not actual switches, but transistors) as shown below.
S1 and S3 form a half-bridge, as well as S2 and S4. S1 and S2 are called high-side-switches, S3 and S4 are called low-side-switches.
By closing two of these switches and leaving the other two open, we can control the direction of the current through the motor and thereby the direction of rotation.
The TLE94112 takes care of setting the correct switches so that both switches of one half-bridge are never open simultaneously. This would shorten the power supply and potentially damage it.
If we open all four switches, no current can flow and the motor receives no power.
Further we can control the speed of the motor via PWM (Pulse-Width-Modulation). This works by switching the connection on and off for certain times. The ratio of on- and off-time is called duty-cycle and controls the power that is delivered to the motor. For more information on PWM see this wikipedia article on the topic.
1. Software SetupTo use the TLE shield, we first have to set up some dependencies on the Raspberry Pi. We assume you have a working PI with a Raspian set up. If not, check this page for instructions. Make sure you are using a Raspberry Pi with the 40-pin layout. Any recent model (Pi 2 and onwards) should work.
In the end, we will have installed the following:
- git
- build-essential
- Infineon multi-half-bridge library
- bcm2835 library
The first two are easy and can be installed with one command on the command line through the apt package manager:
sudo apt-get install git build-essential
Next we want to download the multi-half-bridge library directly from the git repository. First, go to a directory, where you wand to develop your application later. Then clone the repository:
git clone
https://github.com/Infineon/multi-half-bridge.git
The library comes with a script to install our last dependency, the bcm2835 library.
cd multi-half-bridge/src/framework/raspberrypi
chmod +x ./install_requirements.sh
./install_requirements.sh
Remember: If possible, take a look at the code you are running to verify that it is in fact doing what you want.
For the following examples we will stay in the multi-half-bridge/src/framework/raspberrypi
directory.
Building your project is done with make:
make example/basicTest
By default, this will build into ../../../build
, as specified in the makefile
in line 14 included in the working directory. Feel free to change it, if you know what you are doing. In the makefile
it is also defined, where the library is located in relation to our working directory. So that we are simply able to include it in our main.c without having to specify a path.
To run your built code, use ../../../build/basicTest
.
When using the shield for our projects, we need to supply the board with power.
This is done via the VBAT and GND screw-terminals of the shield.
Connect between 5.5V and 20V DC to VBAT and the negative Pin/GND of your power supply to GND of the shield. Important notice: The voltage-level you supply is also supplied to the connected DC-motors/stepper-motors/LEDS etc. so be careful not to overvoltage your peripherals.
Next, we connect our peripherals (motor, etc) to the shield, via the other screw-terminals. Each terminal corresponds to one half-bridge terminal and can supply up to 0.9A. An overcurrent event will trigger a safety-shutdown of the bridge (more on that later in the diagnostics section). However, up to 4 bridges can be connected in parallel, each supplying 0.9A, for a total of 3.6A.
3. DC-Motor ControlThe main functionality of the Multi-Half-Bridge is DC-Motor Control. Here we have to be most careful about the maximum current drawn by the motor.
Lets start with including our libraries in our main file:
#include "tle94112-rpi.hpp"
#include "tle94112-motor.hpp"
#include <bcm2835.h>
Next, in order to use our motor, we have to initialize the controller and the motor: Then we need to enable the controller.
int main(int argc, char const *argv[]){
Tle94112Rpi controller; //create the controller
Tle94112Motor motor(controller); /*create the motor and give it the controller*/
controller.begin(); //enable the controller
The next step is important: We need to tell the controller which terminals should be used and which ones are connected in parallel. Remember: Each terminal can carry up to 0.9A, by connecting several in parallel, we can add up these maximum currents to 3.6A.
motor.initConnector(
motor.HIGHSIDE, //indicate, that this is the high-side connection
controller.TLE_NOPWM,//connect PWM to Lowside as higside is active Free wheeling
controller.TLE_HB1, //output 1 is connected to HIGHSIDE
controller.TLE_HB2, //these two outputs are in parallel, to increase max. current
controller.TLE_NOHB, //third and fourth connection options are not connected
controller.TLE_NOHB
);
motor.initConnector(
motor.LOWSIDE,
controller.TLE_PWM1,
controller.TLE_HB3,
controller.TLE_HB4,
controller.TLE_NOHB,
controller.TLE_NOHB
);
motor.connect(motor.LOWSIDE, controller.TLE_HB5);
This concludes the setup of our half-bridge and motor. Now comes the fun part: Controlling the motor.
Let's start with the easiest function: Coasting the motor.
motor.coast();
This function stops current flowing through the motor. In most cases, this means it will slow down and stop rotating due to friction. If an external force is applied to the motor, it might however keep on spinning freely.
Next, we want to spin the motor with full speed in the forward direction:
motor.start(255);
This function can be called with different arguments between -255 and +255 to set the speed. Alternatively we can also use the function
motor.setSpeed(255);
These two are identical and are there to increase readability of your code.
To gradually increase the motor speed over a set amount of time, we have the function
motor.rampSpeed(255, 5000); //target speed, time interval
delay(5000); //wait for the ramp to complete
This one increases/decreases the speed from the current speed to the speed given as the first argument in a time interval (in milliseconds) given as the second argument.
4. LED-ControlIn addition to motor control, the Multi-Half-Bridge can also control LEDs. This is an interesting feature, if the pin output current of the Arduino does not suffice to power up a LED. For the LED control, we will exclusively use terminal 1 and 2 of the board. These two terminals have a special LED-mode, where the threshold for an open-load error is reduced (more on error and diagnostics later).
First, we have to connect our hardware: A LED and a resistor. The value of the resistor depends on your LED and can be calculated by hand or using an online LED calculator. The relevant data should be found in the datasheet of you LED.
Now we can start with the software.
We need to include the library and create a controller. This time however, we don't need a motor.
#include "tle94112-rpi.hpp"
int main(){
Tle94112Rpi controller;
controller.begin();
We enable the LED-Mode for Half-Bridge 1.
controller.setLedMode(controller.TLE_HB1, 1); //to enable LED-Mode
Whereas last time we controlled a motor entity, now we give our commands directly to the controller.
controller.configHB(controller.TLE_HB1, controller.TLE_HIGH, controller.TLE_NOPWM); // tie HB1 HIGH, powering the LED
controller.configHB(controller.TLE_HB1, controller.TLE_FLOATING, controller.TLE_NOPWM); // floating HB1 disables the LED
These lines enable/disable the LED completely. In order to dimm the LED with PWM, we have to configure the PWM source first and then assign it to an output.
controller.configPWM(controller.TLE_PWM1, controller.TLE_FREQ200HZ, 127);
/*
The options for the Frequency are: TLE_FREQOFF, TLE_FREQ80HZ, TLE_FREQ100HZ, TLE_FREQ200HZ We reccomend the fastest mode, otherwise the LEDs starts flickering
*/
controller.configHB(controller.TLE_HB1, controller.TLE_HIGH, controller.TLE_PWM1);
5. Error and DiagnosticsNow we want to have a look at the error detection systems and diagnostic capabilities of the TLE94112 shield.
At first we request the content of the status-register:
uint8_t status = controller.getSysDiagnosis(); //status now contains bit-flags, where a one corresponds to a position-specific error
To check if a specific error was detected we simply do a bitwise comparison between status and a specific bit:
if (status & controller.TLE_SPI_ERROR)
{
Serial.println("SPI error detected!");
// Handle the SPI error here.
}
The following errors and their respective bit-position are checkable. The library provides a shorthand for each error, so you don't have to remember the bit values.
TLE_SPI_ERROR = 0x80, //1000 0000
TLE_LOAD_ERROR = 0x40, //0100 0000
TLE_UNDER_VOLTAGE = 0x20, //0010 0000 etc.
TLE_OVER_VOLTAGE = 0x10,
TLE_POWER_ON_RESET = 0x08,
TLE_TEMP_SHUTDOWN = 0x04,
TLE_TEMP_WARNING = 0x02
All errors except the SPI_ERROR are latched and need to be cleared manually by calling:
controller.clearErrors();
The flag register will be cleared, as long as the error does not persist.
Let's take a look into each error and see, what the presence of that error means:
TLE_SPI_ERROR: This signifies, that the SPI communication to the shield is faulty. Check your cables/connections.
TLE_UNDER_VOLTAGE: The supply voltage to the board is too low (min. 4V). Increase your supply voltage. This error might also show up, if no supply voltage is connected. This error disables all outputs.
TLE_OVER_VOLTAGE: The supply voltage to the board is too high (max. 40V). This error disables all outputs.
TLE_POWER_ON_RESET: This error is thrown, if power on reset is detected. This is probably less important and too complex to be explained here in detail.
TLE_TEMP_WARNING: This error indicates, that the junction temperature of the bridge comes close to its maximum.
TLE_TEMP_SHUTDOWN: This error indicates, that the junction temperature of the bridge exceeds its maximum. This error disables all outputs.
TLE_LOAD_ERROR: This error is a bit more complex, because it signifies an error with one of up to twelve loads. We have to iterate over every HalfBridge and check on the connected load to learn more:
for (uint8_t halfBridge = 1; halfBridge <= 12; halfBridge++)
{
First, we check the load for an overcurrent event:
uint8_t oc = controller.getHBOverCurrent((Tle94112::HalfBridge)halfBridge);
//since the .getHBOverCurrent method expects a HalfBridge datatype we need to cast the uint8_t iterator into that.
This gives us a bit-field that can be checked with bitwise comparision, as before:
if (oc & controller.TLE_LOWSIDE)
{
Serial.print("\tHB");
Serial.print(halfBridge);
Serial.println(":\tOver-current detected in low-side switch.");
}
// Check for an over-current error on the high-side of this half bridge
if (oc & controller.TLE_HIGHSIDE)
{
Serial.print("\tHB");
Serial.print(halfBridge);
Serial.println(":\tOver-current detected in high-side switch.");
}
Next we check for an open load. Here we don't have to do a bitwise comparision, since we only have one relevant bit in the old bit-field
uint8_t ol = controller.getHBOpenLoad((Tle94112::HalfBridge)halfBridge);
if (ol)
{
Serial.print("\tHB");
Serial.print(halfBridge);
Serial.println(":\tOpen load detected.");
}
}
6. Further Reading and more examplesWe hope you were able to follow all the examples and code snippets we provide here. If you are interested in testing out the TLE94112 multi-half-bridge shield you should have a look at the github page with the source code of the library and even more examples explaining how to use it.
If you want to know, how to use the shield together with a raspberry-pi, have a look at our other hackster.io article on that topic.
Comments
Please log in or sign up to comment.