TReX motor Driver for Disabled power assist

This Article will hold information relating to driving winches in the Access Dinghies with a Pololu TReX motor Driver.

IMG_20151231_121929The TRex from Pololu can drive three motors
Two Bidirectional – ie , forward and reverse ,or attached to main sheet winch, Main in, Main out.
One Single direction but with adjustable speed – suitable for bilge pump or signaling device (LED, HORN)

Brief Update

We found that the Arduino (tho a good idea) was not necessary and added unneeded complexity.
– The Pololu TReX motor driver is connected directly to the winches and the joystick to the TReX.
– Joystick's, originally from Servo City in USA cost quite a lot in postage..$50 from memory…

They are also available via ebay, just search 'potentiometer Joystick' for about $25 inc postage.

I will get a photo of it fitted to one of the Liberty Dinghies and post it up.

– Setting of 28/30 for the winches (with the TReX software from Pololu) gives max pulling power on the sheets with out breaking anything.

Postage from USA is quite expensive but here is a link to Pololu which has all of the documentation, its quite extensive and there is also an Arduino Sketch there i did up for this Motor Controller (gcebiker is my web name)…..the documentation on the Arduino sketch needs tweaking as i found their math for the settings to not quite add up (but its a very good starting point), 28/30 works for us but we are also using a modified 'electric window winder motor' from a car to drive the Jib Winch after the original was over driven.

I now get the Pololu Parts and many of my other parts from Little Bird Electronics in Australia.

Pololu TReX Dual Motor Controller DMC01

Older pages than this i have on this site also list other drivers we trialed.

This Driver was also covered in liquid Tape to delay corrosion, the clear top is necessary to see the LED indicators on the board for trouble shooting/seeing if it has armed itself.


 

 

 

Wiring

Arduino

Joystick to A0 and A1
Switch for pump/horn D4 – and ground if using independent (of joystick) switch.
Digital Pin 8 (TX in this sketch) to TRex 'SI' (Serial Input)
Digital Pin 7(RX in this sketch) to TReX 'SO' (Serial Output)
Ground Arduino to TReX ground Serial pin Headers
+ 5v to TReX BEC (battery eliminator)

 

Below are pictures as it is assembled, tight fit may need a bigger water proof enclosure.

IMG_20151230_144749IMG_20151230_144958 IMG_20151230_144800 IMG_20151230_144819 IMG_20151230_144834 IMG_20151230_144845 IMG_20151230_144909 IMG_20151231_121942 

 

 

TReX
As per diagram below from Pololu Website.

0J294.1200

 

0J290.1200

 

0J95.1200

Copy of Current Arduino Code, Revisions may not be up to date as code is changing quite quickly as i am building it.

/* written by Tony Matthews for the purpose of
Disabled assist sail winch control
in 303 and liberty Class Access dinghy's

One brushed bidirectional motor drives a main sheet winch,
One brushed bidirectional motor drives a jib sheet (liberty) or rudder (303's, 2.3's)
One brushed motor is a bilge pump, to empty any water that splashes in
Or operate signaling device, horn/light.

Code here in is written by Tony Matthews, whom has TBI.
TBI – Traumatic Brain Injury …Use at your own risk.
For the benefit of Sailability Gold Coast, Queensland, Australia.

Serial.print is for testing.
tRexSerial.write is the software serial UART to communicate with the TReX.


Notes from Pololu's documentation.
–Motor Current codes —
Code needs one of each ie, current and current limit
0x13: motor 1 current limit (default: 0 – no motor 1 current limit)
0x14: motor 2 current limit (default: 0 – no motor 2 current limit)
0x15: motor 1 current limit proportionality constant P (default: 0x0A)
0x16: motor 2 current limit proportionality constant P (default: 0x0A)

–Acceleration Codes–
Acceleration used over 'set direction' as TReX has in built soft start/stop
Less wear on the winches to have soft starts.
Motor 1 – BiDirectional
0xC4 – Brake Low M1
0xC5 – Reverse M1
0xC6 – Forward M1
0xC7 – Brake low M1

Motor 2 – BiDirectional
0xCC – Brake Low M2
0xCD – Reverse M2
0xCE – Forward M2
0xCF – Brake Low M2

Motor 3 – Single direction only
0xF1 – Accelerate Motor M3

— Motor speed settings —
May be represented as an integer as the Arduino converts it to HEX automatically (TReX reads HEX)
Must be positive number between 0-127
0 being stopped, 127 full speed
(Actual speed depends on acceleration logic and current draw V current limit)
eg M3 to full speed would be
tRexSerial.write(0xF1);  //M3
tRexSerial.write(127);  // full speed

All motor speed/direction/stopped need a speed value to go with them , eg stopped + 0 , forward + 127
*/


//Software serial settings
#include <SoftwareSerial.h>
const int rx = 7; // rx pin of Arduino, SO(serial out)of TRex.
const int tx = 8; // tx pin of Arduino, SI(serial in)of TRex.

SoftwareSerial tRexSerial (rx, tx); // RX to SO of Trex, TX to SI of Trex

// Pot inputs
// Main sheet M1
int mainPin = A0;  //input A0 for mainsheet
int mainVal = 511;  // int to hold main Input value,  start up in neutral 511
int mainValmapin;
int mainValmapout;

// Jib sheet M2
int jibPin = A1;
int jibVal = 511;
int jibValmapin;
int jibValmapout;


// dead band settings
int deadVal = 300;    // will change to pot values , one for each axis
int midVal = 511;
int fwdVal = (midVal + deadVal);
int revVal = (midVal – deadVal);

int zero = 0;    // integer for serial data '0' as 0 is ambiguous as used in a 'serial.write(0)'

// Power/speed variables
// Current limit (desired current limit in milliamp's / 150ma / 2 = ( )value)
// (rounded up) 2amps=7 , 10amps=33
int maxAmps = 2;//Current limit (desired current limit in milliamp's / 150ma / 2 = ( )value)
int overAmpbeh = 0; // over Amp limit behaviour 0=turn motor off
// data packet settings
unsigned char data[4];
unsigned long timer = 0;

void setup()
{
  delay (1000);
  tRexSerial.begin(19200);
  delay (400) ;    // wait for serial to start.

  // Write TReX Motor Settings/Behavior.


  // build M1 data packet for current limit and proportionally constant
  // build M1 current limit packet
  {
    data[0] = (0x80);   // set parameter bit instruction
    data[1] = (0x07);   // TReX id number (if i had more than one, still necessary with only one)
    data[2] = (0x13);   // Parameter id, 0x13 for M1 Current Limit
    data[3] = (maxAmps);     // Current limit (desired current limit in milliamps / 150ma / 2 = ( )value)
    // eg, desired current limit 2amps, ergo 2000/150/2=6.66, rounded up to 7
    for (unsigned char i = 0; i < 4; i++)
      tRexSerial.write(data[i]);
  }
  delay(10);
  // build M1 Proportionally constant settings packet
  {
    data[0] = (0x80);   // set parameter bit instruction
    data[1] = (0x07);   // TReX id number (if i had more than one, still necessary with only one)
    data[2] = (0x15);   // Parameter id, 0x15 for M1 Proportionally constant current Limit (pccl)
    data[3] = (overAmpbeh);      // Behavior of PCCL current limit // Proportionally constant 0 (turn motors off if over current)

    for (unsigned char i = 0; i < 4; i++)
      tRexSerial.write(data[i]);
  }
  delay(10);
  //Build M2 Parameter settings packets

  //M2 data packet for current limit
  {
    data[0] = (0x80);   // set parameter bit instruction
    data[1] = (0x07);   // TReX id number (if i had more than one, still necessary with only one)
    data[2] = (0x14);   // Parameter id, 0x14 for M2 Current Limit
    data[3] = (maxAmps);      // Current limit (desired current limit in milliamps / 150ma / 2 = ( )value)
    // eg, desired current limit 2amps, ergo 2000/150/2=6.66, rounded up to 7
    for (unsigned char i = 0; i < 4; i++)
      tRexSerial.write(data[i]);
  }
  delay(10);
  // Build M2 Proportionally constant settings packet
  {
    data[0] = (0x80);   // set parameter bit instruction
    data[1] = (0x07);   // TReX id number (if i had more than one, still necessary with only one)
    data[2] = (0x16);   // Parameter id, 0x15 for M1 Proportionally constant current Limit
    data[3] = (overAmpbeh);      // Behavior of PCCL  Proportionally constant 0 (turn motors off if over current)

    for (unsigned char i = 0; i < 4; i++)
      tRexSerial.write(data[i]);
  }
  delay (10); // give tRex time to apply settings.

}
void loop () {
  // Main sheet control (M1)
  {
    mainVal = analogRead(mainPin);
    delay(10);

    if (mainVal > fwdVal)   // Forward M1
    {
      mainValmapout = map(mainVal, fwdVal, 1023, 0 , 127); // map speed to return int 0-127
      data [0] = (0xC6); // accelerate motor 1
      data [1] = (mainValmapout);   // Analog read val ,mapped.
      for (unsigned char i = 0; i < 2; i++)
        tRexSerial.write(data[i]);
    }
    else if (mainVal < revVal )  // Reverse M1
    {
      mainValmapin = map(mainVal, 0, revVal, 127 , 0); // map reverse speed to return int 0-127
      data [0] = (0xC5); //reverse accelerate motor 1
      data [1] = (mainValmapin); // Analog read val ,mapped.
      for (unsigned char i = 0; i < 4; i++)
        tRexSerial.write(data[i]);
    }
    else       // stop M1
      tRexSerial.write(0xC7);   // brake low
    tRexSerial.write(zero);   // zero integer value
  }

  //Jib sheet control (M2)
  {
    jibVal = analogRead(jibPin);
    delay(10);

    if (jibVal >= fwdVal)    // Forward M2
    {
      jibValmapout = map(jibVal, fwdVal, 1023, 0, 127); // map speed to return positive int 0-127
      data [0] = (0xCE); // accelerate motor 2 forward
      data [1] = (jibValmapout); // Analog read val, mapped.
      for (unsigned char i = 0; i < 2; i++)
        tRexSerial.write(data[i]);
    }

    else if (jibVal <= revVal )    // Reverse M2
    {
      jibValmapin = map(jibVal, 0, revVal, 127 , 0); // map reverse speed to return positive int 0-127
      data [0] = (0xCD); //reverse accelerate motor 2
      data [1] = (jibValmapin); // Analog read val ,mapped.
      for (unsigned char i = 0; i < 2; i++)
        tRexSerial.write(data[i]);
    }

    else   // brake M2
      tRexSerial.write(0xCF); // brake low
    tRexSerial.write(zero); // zero integer value

  }

}