The crane: part three (electronics)
The crane has 10 motors. This lead to TWO big problems:
a) using a speed regulator (like CTI Thor, for example) for each motor is VERY expensive
b) even though I use a 16 channel radio (FrSky Taranis) I had not enough channels for the whole truck
I found a solution that was good for both points: I built myself a 10 motor controller board that used SBus. This way I had to create Outputs just for the four sticks movements (I could not re use steering and throttle because SBus uses the output channel and it includes centering, trimming etc) and a couple of switches (used to multiplex the sticks via software). This way I spared four channel and I was able to keep one radio program (other solution would have been to use the crane as a stand-alone model with its own receiver).
OK, now I had to design the board and make it work. Luckily I am an Electronic and SW designer in the Automation field, so I only had to apply my everyday work
I decided to use an Arduino board coupled with dual H-Bridge ICs (initially I used TI L293D but later I moved to SN754410 which gives a little more power). To read from the SBus I used Arduino
SBUS library, and I inverted the SBUS signal (using a transistor) as indicated in the Readme of the library.
Every single motor needed a lot of wiring:
I had to use an Arduino Mega2560 and I used almost all available pins
Here is the SW I put inside the Arduino:
Code:
#include <SBUS.h>
#include <L293D.h>
#define MOTOR_MAIN_ARM_ENABLE_PIN 2
#define MOTOR_SECONDARY_ARM_ENABLE_PIN 3
#define MOTOR_ROTATION_ENABLE_PIN 4
#define MOTOR_EXTENDER_ENABLE_PIN 5
#define MOTOR_BUCKET_ENABLE_PIN 6
#define MOTOR_BUCKET_ROTATION_ENABLE_PIN 7
#define MOTOR_STABILIZER_LH_EXT_ENABLE_PIN 8
#define MOTOR_STABILIZER_LH_ELEV_ENABLE_PIN 12
#define MOTOR_STABILIZER_RH_EXT_ENABLE_PIN 13
#define MOTOR_STABILIZER_RH_ELEV_ENABLE_PIN 11
#define MOTOR_MAIN_ARM_A_PIN 44
#define MOTOR_MAIN_ARM_B_PIN 45
#define MOTOR_SECONDARY_ARM_A_PIN 34
#define MOTOR_SECONDARY_ARM_B_PIN 35
#define MOTOR_ROTATION_A_PIN 42
#define MOTOR_ROTATION_B_PIN 43
#define MOTOR_EXTENDER_A_PIN 46
#define MOTOR_EXTENDER_B_PIN 47
#define MOTOR_BUCKET_A_PIN 32
#define MOTOR_BUCKET_B_PIN 33
#define MOTOR_BUCKET_ROTATION_A_PIN 36
#define MOTOR_BUCKET_ROTATION_B_PIN 37
#define MOTOR_STABILIZER_LH_EXT_A_PIN 40
#define MOTOR_STABILIZER_LH_EXT_B_PIN 41
#define MOTOR_STABILIZER_LH_ELEV_A_PIN 48
#define MOTOR_STABILIZER_LH_ELEV_B_PIN 49
#define MOTOR_STABILIZER_RH_EXT_A_PIN 30
#define MOTOR_STABILIZER_RH_EXT_B_PIN 31
#define MOTOR_STABILIZER_RH_ELEV_A_PIN 38
#define MOTOR_STABILIZER_RH_ELEV_B_PIN 39
SBUS sbus(Serial3);
L293D motorMainArm(MOTOR_MAIN_ARM_ENABLE_PIN, MOTOR_MAIN_ARM_A_PIN, MOTOR_MAIN_ARM_B_PIN);
L293D motorSecondaryArm(MOTOR_SECONDARY_ARM_ENABLE_PIN, MOTOR_SECONDARY_ARM_A_PIN, MOTOR_SECONDARY_ARM_B_PIN);
L293D motorBucket(MOTOR_BUCKET_ENABLE_PIN, MOTOR_BUCKET_A_PIN, MOTOR_BUCKET_B_PIN);
L293D motorRotation(MOTOR_ROTATION_ENABLE_PIN, MOTOR_ROTATION_A_PIN, MOTOR_ROTATION_B_PIN);
L293D motorExtender(MOTOR_EXTENDER_ENABLE_PIN, MOTOR_EXTENDER_A_PIN, MOTOR_EXTENDER_B_PIN);
L293D motorBucketRotation(MOTOR_BUCKET_ROTATION_ENABLE_P IN, MOTOR_BUCKET_ROTATION_A_PIN, MOTOR_BUCKET_ROTATION_B_PIN);
L293D motorStabilizerLeftExt(MOTOR_STABILIZER_LH_EXT_ENA BLE_PIN, MOTOR_STABILIZER_LH_EXT_A_PIN, MOTOR_STABILIZER_LH_EXT_B_PIN);
L293D motorStabilizerLeftElev(MOTOR_STABILIZER_LH_ELEV_E NABLE_PIN, MOTOR_STABILIZER_LH_ELEV_A_PIN, MOTOR_STABILIZER_LH_ELEV_B_PIN);
L293D motorStabilizerRightExt(MOTOR_STABILIZER_RH_EXT_EN ABLE_PIN, MOTOR_STABILIZER_RH_EXT_A_PIN, MOTOR_STABILIZER_RH_EXT_B_PIN);
L293D motorStabilizerRightElev(MOTOR_STABILIZER_RH_ELEV_ ENABLE_PIN, MOTOR_STABILIZER_RH_ELEV_A_PIN, MOTOR_STABILIZER_RH_ELEV_B_PIN);
int channel09_ModeSel = 0;
int channel11_Tip_BkRot = 0;
int channel12_Ext = 0;
int channel13_LhHr = 0;
int channel14_LhVr = 0;
int channel15_RhVr = 0;
int channel16_RhHr = 0;
static long nextPrintStatusTime = 0;
#define PRINT_STATUS_DELAY 500
void setup()
{
sbus.begin();
//TCCR3B = (TCCR3B & 0xF8) | 0x02 ; //set frequency of pins 2, 3, 5
Serial.begin(115200);
Serial.println("RC Iveco 250 MFU");
}
// this is timer2, which triggers ever 1ms and processes the incoming SBUS datastream
ISR(TIMER2_COMPA_vect)
{
sbus.process();
}
void loop()
{
long currentTime = millis();
channel09_ModeSel = sbus.getNormalizedChannel(9);
channel11_Tip_BkRot = sbus.getNormalizedChannel(11);
channel12_Ext = sbus.getNormalizedChannel(12);
channel13_LhHr = sbus.getNormalizedChannel(13);
channel14_LhVr = sbus.getNormalizedChannel(14);
channel15_RhVr = sbus.getNormalizedChannel(15);
channel16_RhHr = sbus.getNormalizedChannel(16);
if (channel09_ModeSel > 50)
{
motorMainArm.set((channel14_LhVr / 100.0) * 1.2);
motorSecondaryArm.set((channel15_RhVr / 100.0) * 1.2);
motorRotation.set((channel13_LhHr / 100.0) * 1.2);
motorBucket.set((channel16_RhHr / 100.0) * 1.2);
motorExtender.set((channel12_Ext / 100.0) * 1.2);
motorBucketRotation.set((channel11_Tip_BkRot / 100.0) * 1.2);
motorStabilizerLeftExt.set(0);
motorStabilizerLeftElev.set(0);
motorStabilizerRightExt.set(0);
motorStabilizerRightElev.set(0);
}
else if (channel09_ModeSel == 0)
{
motorMainArm.set(0);
motorSecondaryArm.set(0);
motorRotation.set(0);
motorBucket.set(0);
motorExtender.set(0);
motorBucketRotation.set(0);
motorStabilizerLeftExt.set(-(channel13_LhHr / 100.0) * 1.2);
if(motorStabilizerLeftExt.get() == 0)
motorStabilizerLeftElev.set((channel14_LhVr / 100.0) * 1.2);
else
motorStabilizerLeftElev.set(0);
motorStabilizerRightExt.set((channel16_RhHr / 100.0) * 1.2);
if(motorStabilizerRightExt.get() == 0)
motorStabilizerRightElev.set((channel15_RhVr / 100.0) * 1.2);
else
motorStabilizerRightElev.set(0);
}
else if (channel09_ModeSel < -50)
{
motorMainArm.set(0);
motorSecondaryArm.set(0);
motorRotation.set(0);
motorBucket.set(0);
motorExtender.set(0);
motorBucketRotation.set(0);
motorStabilizerLeftExt.set(0);
motorStabilizerLeftElev.set(0);
motorStabilizerRightExt.set(0);
motorStabilizerRightElev.set(0);
}
/*
if(currentTime > nextPrintStatusTime)
{
printStatus();
nextPrintStatusTime = currentTime + PRINT_STATUS_DELAY;
}
*/
}
void printStatus()
{
Serial.print("CH9_ModeSel: "); Serial.println(channel09_ModeSel);
Serial.print("CH11_Tip_BkRot: "); Serial.println(channel11_Tip_BkRot);
Serial.print("CH12_Ext: "); Serial.println(channel12_Ext);
Serial.print("CH13_LhHr: "); Serial.println(channel13_LhHr);
Serial.print("CH14_LhVr: "); Serial.println(channel14_LhVr);
Serial.print("CH14 TRUE: "); Serial.println(sbus.getChannel(14));
Serial.print("CH15_RhVr: "); Serial.println(channel15_RhVr);
Serial.print("CH16_RhHr: "); Serial.println(channel16_RhHr);
Serial.print("Lost Frames: "); Serial.println(sbus.getLostFrames());
}
Here is one of the first tests with wiring still on breadboard (crane was fixed to the table with EXTRA STRONG double stick tape):
The hardest part was the wiring. Initially I planned to use a Arduino Mega 2560 PRO Mini which has a form factor really small compared to standard "Mega". I hoped to put the board inside a fake oil tank beside the crane main arm. But wiring on pre-drilled board turned out a nightmare. All pins of the "Mega 2560 PRO Mini " where on twin rows and soldering so many wires brung to a number of short circuits. After a while I had to give up. It was a no-go... So I had to turn to standard "Mega" and board had to be moved inside the cab
Wiring was all but easy even with the bigger board. I used four ICs as double H-bridge, with two motors attached, and two ICs as double power H-bridge (using two H-b joined together to double the output power) for the main cylinders. I spent a huge amount of time checking every single connection and fixing many short circuits. But at the end I had it working.
Here is the board inside the cab:
To end the "electronic chapter" I have to describe the motors choice. initially I bough cheap N20 gearmotors, but it turned out the were HUGELY under powered for my needs. I had to turn to original POLOLU micro motors in HPCB version. Sadly they are really expensive, something like 15 EURO each. But they are 6V rated, so I hoped to use a single 2S battery for the whole model. Also this turned out wrong, partly because of the H-bridge dropout and partly because main cylinder needed very high strength. So I had to use a 3s LiPo just for the crane and give 12V to the motors (they are rated 3-9V and considering the IC dropout I did not go too much out of specs). This made them very short living especially the main cylinder one. Initially when I still used 1:100 / 1:150 ratio I had to replace it every time I used the crane for long. Then I moved to 1:250 ratio plus trapezoid screw and things got a little better.
This is the actual configuration of the motors
First cylinder: POLOLU 250:1 Micro Metal Gearmotor HPCB 6V
Second cylinder: POLOLU 100:1 Micro Metal Gearmotor HPCB 6V
Extender: POLOLU 50:1 Micro Metal Gearmotor HP 6V
Bucket (both motors): POLOLU 100:1 Micro Metal Gearmotor HP 6V
Stabilizers (all four motors): POLOLU 50:1 Micro Metal Gearmotor HP 6V
Turntable: POLOLU 100:1 Micro Metal Gearmotor HP 6V
Luca