Page 1 of 2

I²C commands for Tetrix motor muxers?

Posted: 02 Nov 2010, 15:11
by HaWe
hi,
in the nxtasy forum someone posted the I²C commands for the Tetrix motor muxers (by Hitechnic).
Maybe I'll find one to write a NXC driver for them - but I can't find the commands anymore.
Can someone pls post the codes again?

Re: I²C commands for Tetrix motor muxers?

Posted: 03 Nov 2010, 19:39
by HaWe
hi, meanwhile HT replied to my driver request.
If anyone else is interested, here is a servo driver sample:

Code: Select all

#include "NXCDefs.h"

#define IO_PORT IN_1

int err=0;
int err0=0;
int err1=0;
int err2=0;
int err3=0;
int err4=0;
int err5=0;
int err6=0;
int err7=0;

int status;

int count;
byte inI2Ccmd[];                // buffer for outbound I2C data
byte outbuf[];

void setservos(int timer, int servo1,int servo2,int servo3, int servo4, int servo5, int servo6)
{
  ArrayInit(inI2Ccmd, 0, 10);
  inI2Ccmd[0] = 0x02;
  inI2Ccmd[1] = 0x41;
  inI2Ccmd[2] = timer;
  inI2Ccmd[3] = servo1;
  inI2Ccmd[4] = servo2;
  inI2Ccmd[5] = servo3;
  inI2Ccmd[6] = servo4;
  inI2Ccmd[7] = servo5;
  inI2Ccmd[8] = servo6;
  inI2Ccmd[9] = 0;
  count=0;
  I2CBytes(IO_PORT, inI2Ccmd, count, outbuf);
  Wait(20);
  ArrayInit(inI2Ccmd, 0, 2);
  inI2Ccmd[0] = 0x02;
  inI2Ccmd[1] = 0x41;
  count=8;
  I2CBytes(IO_PORT, inI2Ccmd, count, outbuf);
  Wait(20);
  if (ArrayLen(outbuf)==8)
    {
    if (outbuf[0]!=timer) err0+=1;
    if (outbuf[1]!=servo1) err1+=1;
    if (outbuf[2]!=servo2) err2+=1;
    if (outbuf[3]!=servo3) err3+=1;
    if (outbuf[4]!=servo4) err4+=1;
    if (outbuf[5]!=servo5) err5+=1;
    if (outbuf[6]!=servo6) err6+=1;
    if (outbuf[7]!=0) err7+=1;
    }
    if (ArrayLen(outbuf)!=8) err+=1;
  ClearScreen();
  NumOut(20,LCD_LINE1,err);
  NumOut(20,LCD_LINE2,err0);
  NumOut(60,LCD_LINE2,err1);
  NumOut(20,LCD_LINE3,err2);
  NumOut(60,LCD_LINE3,err3);
  NumOut(20,LCD_LINE4,err4);
  NumOut(60,LCD_LINE4,err5);
  NumOut(20,LCD_LINE5,err6);
  NumOut(60,LCD_LINE5,err7);
}

void waitservos()
{
  status=1;
  while(status!=0)
    {
    ArrayInit(inI2Ccmd, 0, 2);
    inI2Ccmd[0] = 0x02;
    inI2Ccmd[1] = 0x40;
    count=1;
    I2CBytes(IO_PORT, inI2Ccmd, count, outbuf);
    Wait(20);
    if (ArrayLen(outbuf)==1) status=outbuf[0];
    NumOut(20,LCD_LINE6,status);
    }
}



task main()
{
  SetSensorLowspeed(IO_PORT);                // port 1 servo controller
  SetSensorType(IO_PORT,SENSOR_TYPE_LOWSPEED);
  while(TRUE)
    {
    setservos(1,0,22,44,66,88,110);
    waitservos();
    setservos(1,255,233,211,189,167,145);
    waitservos();
    }
  
}

Unfortunately a encoder motor sample is still missing, maybe to someone the pdfs are helpful.
Functions like these would be needed:

Code: Select all

// NXTport=(0,1,2);  TXchannel= TetrixMuxChanell(0,1)...(0,1,2,3,4,5,6,7) 
single up to 4*daisy chained

void TXMotorOn(NXTport, TXchannel, percentage)
void TXMotorCoast(NXTport, TXchannel)
void TXMotorBreak(NXTport, TXchannel)
long TXEncoderValue(NXTport, TXchannel)
Synchronizing would be fine of course even not necessarily already now from
the start

Code: Select all

void TXMotorSync(NXTport, TXchannelA, TXchannelB)

Re: I²C commands for Tetrix motor muxers?

Posted: 18 Nov 2010, 20:52
by HaWe
can anyone explain, how to build NXC I2C commands out of this table to use it for motor control?

Code: Select all

Address 	Type 	Contents 

00 – 07H 	chars 	Sensor version number 
08 – 0FH 	chars 	Manufacturer 
10 – 17H 	chars 	Sensor type 
18 – 3DH 	bytes 	Not used 
3E, 3FH 	chars 	Reserved 

40H – 43H 	 s/long 	Motor 1 target encoder value, high byte first 
44H           byte      Motor 1 mode 
45H           s/byte    Motor 1 power 
46H           s/byte    Motor 2 power 
47H           byte      Motor 2 mode 
48 – 4BH 	 s/long     Motor 2 target encoder value, high byte first 
4C – 4FH 	 s/long     Motor 1 current encoder value, high byte first 
50 – 53H 	 s/long     Motor 2 current encoder value, high byte first 
54, 55H      word       Battery voltage 54H high byte, 55H low byte 
56H           S/byte    Motor 1 gear ratio 
57H           byte      Motor 1 P coefficient* 
58H           byte      Motor 1 I coefficient* 
59H           byte      Motor 1 D coefficient* 
5AH           s/byte    Motor 2 gear ratio 
5BH           byte      Motor 2 P coefficient* 
5CH           byte      Motor 2 I coefficient* 
5DH           byte      Motor 2 D coefficient* 
The Motor 1/2 mode fields select the operating mode for each channel.
The Motor 1/2 power fields set the operating power level for each channel. This value is a signed byte.
The Motor 1/2 target encoder value fields will accept a 32 bit target position setting for use in position setting mode. This value is a signed 32 bit value.
The Motor 1/2 current encoder value fields will return the 32 bits current encoder value. This value is a signed 32 bit value.
The Motor 1/2 gear ratio fields have not been implemented in the current version of the firmware.
The Motor 1/2 P coefficient fields specify the differential control loop P coefficient. This value is an unsigned byte.*
The Motor 1/2 I coefficient fields specify the differential control loop I coefficient. This value is an unsigned byte.*
The Motor 1/2 D coefficient fields specify the differential control loop D coefficient. This value is an unsigned byte.*
The Battery voltage field will return the current battery voltage. The high byte is the upper 8 bits of a 10 bit value. It may be used as an 8 bit representation of the battery voltage in units of 80mV. This provides a measurement range of 0 – 20.4 volts. The low byte has the lower 2 bits at bit locations 0 and 1 in the byte. This increases the measurement resolution to 20mV.
*Note: the preset PID coefficient values in the firmware have been tuned for the motors being used and it is recommended they not be changed. Any changes to these values will be lost at power down.

3.3. Channel mode
The motor controller has one mode control byte per channel to control and monitor its operation.
D7.... D6.... D5.... D4.... D3.... D2.... D1.... D0
Busy Error... - ...NTO . Rev .Lock .Sel 1 .Sel 0

Sel Action
00 Run with power control only
01 Run with constant speed
10 Run to position
11 Reset current encoder

The Run with constant speed command will cause the firmware to adjust the motor power to compensate for changing loads in order to maintain a constant motor speed.
The Run to position command will cause the firmware to run the motor to make the current encoder value to become equal to the target encoder value. It will do this using a maximum rotation rate as defined by the motor power byte. It will hold this position in a servo like mode until the Run to position command is changed or the target encoder value is changed. While the Run to position command is executing, the Busy bit will be set. Once the target position is achieved, the Busy bit will be cleared. There may be a delay of up to 50mS after a Run to position command is initiated before the Busy bit will be set.
The Reset current encoder will reset the current encoder value to 0 and then clear the command resulting in Off-braked state to be engaged.
The Lock bit is reserved and not implemented at this time.
The Rev bit may be used to alter the forward/reverse direction mapping for both the motor output and the encoder inputs. This function is primarily intended to harmonize the forward and reverse directions for motors on opposite sides of a skid-steer chassis.
The Error bit will be set if the motor controller has shut down due to a fault condition such as an output short circuit, output over-current or internal overheating has been detected. It will be cleared automatically after a one minute cool down period followed by a controller restart. The shut down function includes placing both motor channels into float mode.
The NTO or No Time Out bit may be set to stop the controller timing out if no I2C communication is received within 2½ seconds. In order to set the No Time Out state, the NTO bit must be set in both motor channel mode registers.

3.4. Channel power
The motor controller electronics is capable of operating each channel independently in PWM mode. This field may be set in the range of -100 to +100. 0 is used to set Off/Brake. Any value above 100 will be treated as 100, except –128 which is used to set Off/Float. Negative values run the motor in the reverse direction. The power should be set positive when being used as a parameter for the Run to position command. This field sets the rotation rate in Run with constant speed and maximum rotation rate in Run to position in the range of -1000 – +1000 degrees per second represented by the range -100 – +100. As with PWM mode, 0 is used to set Off/Brake while –128 is used to set Off/Float.
HiTechnic FIRST Motor Controller Specification

3.5. Channel current encoder value
The motor controller maintains a current encoder value for each motor channel. It is initialized to zero at power up and tracks all subsequent motor movement. It may be reset to zero using the Reset current encoder function. The encoder has a resolution of 1440 counts per revolution of the motor shaft or ¼ degrees per count.
3.6. Channel target encoder value
The motor controller uses this value to drive the motor to the target position when executing a Run to position command.

The goal is sth like this

Code: Select all

// NXTport=(0,1,2,3);  TXchannel= TetrixMuxChanell (0,1,2,3,4,5,6,7) 1*2 single motors up to 4*2 daisy chained

void TXMotorOn(NXTport, TXchannel, percentage)
void TxMotorTurn(NXTport, TXchannel, percentage, target)
void TXMotorCoast(NXTport, TXchannel)
void TXMotorBreak(NXTport, TXchannel)
long GetTXEncoderValue(NXTport, TXchannel)

and maybe this for synchronizing

Code: Select all

void SetTXMotorSync(NXTport, TXchannel_master, TXchannel_slave, syncRatio)

Re: I²C commands for Tetrix motor muxers?

Posted: 26 Nov 2010, 08:55
by HaWe
hasn't anybody got any idea?
apart from this specific driver problem it would be also a good example to learn how to use those numbers for IIC generally!

Re: I²C commands for Tetrix motor muxers?

Posted: 26 Nov 2010, 19:56
by mattallen37
Sure, I am positive I could get the NXT to control the motors and servos, but I don't have the hardware to test functions on. You should be able to just read/write to the I2C registers to make the motors work. Perhaps you should try learning some low level I2C stuff. There are some commands that are seemingly fairly new.

Code: Select all

ReadI2CRegister(Port, address, reg, out);
WriteI2CRegister(Port, address, reg, value);
They should simplify things for you.

Re: I²C commands for Tetrix motor muxers?

Posted: 26 Nov 2010, 20:53
by HaWe
thx, matt.
so I assume
TXmotor_1 OnFwd 50%
is sth like

Code: Select all

void TXMotor1On(NXTport,  percentage){
  while (I2CCheckStatus(NXTport)!= STAT_COMM_PENDING){Wait(1)};
  WriteI2CRegister(NXTport, 0x44,  0);  // 44H byte Motor_1 mode: 0=power control mode
  while (I2CCheckStatus(NXTport)!= STAT_COMM_PENDING){Wait(1)};
  WriteI2CRegister(NXTport, 0x45, percentage); // 45H s/byte  Motor_1 power: 50 =50%
}
//...
TXMotor1On(0,50);
but if I compile this I get
# Error: Preprocessor macro function does not match instance (asm { __MSWriteToRegister(_port, _i2caddr, _reg, _val, __RETVAL__) })
File "c:\Temp\temp.nxc" ; line 3

(Bricxc 3.3.8.9)
:?:

Re: I²C commands for Tetrix motor muxers?

Posted: 26 Nov 2010, 21:10
by mightor
You are not supplying the correct number of arguments to the WriteI2CRegister() function. Read the previous post by Matt again and then look at yours.

- Xander

Re: I²C commands for Tetrix motor muxers?

Posted: 26 Nov 2010, 21:21
by HaWe
oh yes, you're right!
but now I don't know what is address and reg? I only have reg=register= 0x44 or 0x45...?

aaahm: maybe address=0x02 for the device/motor1?
The first motor controller in the daisy chain will use an I2C address of 02/03
and 0x03 for motor2?

Re: I²C commands for Tetrix motor muxers?

Posted: 26 Nov 2010, 22:01
by mattallen37
The address is the address for the multiplexer, not the port. The address is a constant. I just looked at the documentation to find out what the address is. Here is what it says.
The first motor controller in the daisy chain will use an I2C address of 02/03. Subsequent controllers will obtain addresses of 04/05, 06/07 and 08/09. Only four controllers may be daisy chained.
So whatever one is closest to the NXT has the address of 0x02, then the next controller (on the daisy chain) has the address of 0x04.

The register is the place where you set the values, it looks like 0x44-0x47 are the main registers needed to run the two motors.
Edit, actually 0x45-0x46 are probably the only ones needed for simple speed-only control.

Re: I²C commands for Tetrix motor muxers?

Posted: 26 Nov 2010, 22:13
by mattallen37
Try using something like this for simple motor speed control.

Code: Select all

#define HTMMUXPort S1
#define HTMMUXaddr 0x02

byte MotorControlArray[2];
byte motor_1_speed;//The variable that contains the desired motor 1 speed.
byte motor_2_speed;//The variable that contains the desired motor 2 speed.

task main()
{
  SetSensorLowspeed(HTMMUXPort);
  while(true)
  {
    MotorControlArray[0]=motor_1_speed;
    MotorControlArray[1]=motor_2_speed;
    WriteI2CRegister(HTMMUXPort, HTMMUXaddr, 0x45, MotorControlArray); //Port, address, the register to start the write, the value(s in this case)
  }
}