Page 1 of 7

NXC: I²C drivers for Hitechnic Tetrix motor muxer ?

Posted: 29 Nov 2010, 21:20
by HaWe

Code: Select all

sry, can't reply to the I2C tetrix thread:
@afanofosc:
what do you think, will you have finished your Tetrix drivers in the foreseeable future?
I mean, it doesn't make sence to invent the wheel twice...

regards,
"Ford"

Code: Select all

44H           byte      Motor 1 mode
45H           s/byte    Motor 1 power
46H           s/byte    Motor 2 power
47H           byte      Motor 2 mode 

Re: I2C tetrix drivers?

Posted: 30 Nov 2010, 01:24
by afanofosc
I have been intending to get around to writing API functions for the HiTechnic Tetrix controllers but real work and exhaustion and laziness have all combined to get in the way. I will see what I can do this week or next. Maybe I'll have them ready as a Christmas present for you? Along with a few of the other things I have on my TODO list.

John Hansen

Re: I2C tetrix drivers?

Posted: 30 Nov 2010, 08:10
by HaWe
fine, thank you for this :)
I will try then anyway to get my "run at power-percentage" and "run at constant-speed" ready this week,
a brute-force "go-to-Encoder-Target" is already a little more challenging (without exact + smooth forw/backw approximation),
but what really makes me headaches is synchronizing 2 motors -100...+100% :roll:
and what I really don't comprehend at all is how the PID control works... :?

do you think you can use the syntax sort of I've been suggesting so that it will be more or less compatible what we both are doing?

Code: Select all

// NXTport=(0,1,2,3);  
// TXchannel= (0,1,...7) for a single muxer up to 4*muxer daisy chained

void TXMotorOn(NXTport, TXchannel, power) // power=-100...+100
void TXMotorSpeed(NXTport, TXchannel, percentage) // percentage=-100...+100 for 100%=1000 encoder_ticks/minute
void TXMotorCoast(NXTport, TXchannel) // sets power=-128
void TXMotorBreak(NXTport, TXchannel) // sets power=0

long GetTXEncoder(NXTport, TXchannel)
void ResetTXEncoder(NXTport, TXchannel)
void TXMotorGoTo(NXTport, TXchannel, EncoderTarget_absolute, StopMode) // absolute encoder target (not relative like rotateMotorEx), StopMode: break=true or coast=false

void SetTXMotorSync(NXTport, TXchannel_master, TXchannel_slave,  syncRatio) // only the master will be controlled by the program in future, slave sync-controlled by background task

Re: I2C tetrix drivers?

Posted: 30 Nov 2010, 16:19
by afanofosc
Sadly, I don't think I will be doing anything like what you have proposed. But until I actually start the project I can't say how it will end up. Probably very low level and almost certainly not doing anything like having a turn percentage parameter (unless support for that is built into the device itself). I haven't looked at the docs for quite a while so I don't recall exactly what they can or can't do.

John Hansen

Re: I2C tetrix drivers?

Posted: 30 Nov 2010, 17:08
by HaWe
what's bad with my proposals? I think it's quite intuitivly to be used...?

goto_encoder_target and sync_motors are actually what will be needed.
(in the basic set are just 1 motor mux controller and 2 motors which both normally will be used as chassis driver motors for going synchronized straight ahead or turn synchronized)

the few built-in firmware IIC reg calls you can find here (3rd post): https://sourceforge.net/apps/phpbb/mind ... ?f=2&t=178

Re: I2C tetrix drivers?

Posted: 30 Nov 2010, 18:43
by HaWe
ps:
forgot to mention:
turn speed percentage indeed IS a built-in firmware feature:
mode byte= 0x1 for speed percentage,
0x0=power percentage
0x2=goto encoder target

Re: I2C tetrix drivers?

Posted: 30 Nov 2010, 22:39
by afanofosc
Sorry, I was not clear. I meant synchronizing two motors turning in different directions or at different speed ratios like the NXT firmware does using the "turn percent" Output module iomap parameter. If motor synchronization at differing speeds/directions is not built into the hardware then there is no chance at all that I will write API functions to support that kind of functionality. You can't do decent motor control via I2C in VM byte code - or at least I don't plan on attempting it.

John Hansen

Re: I2C tetrix drivers?

Posted: 01 Dec 2010, 08:19
by HaWe
ok, I understand, thanks for the clarification!

Re: NXC: I²C Tetrix drivers (motor controller)?

Posted: 29 Dec 2010, 10:42
by HaWe

Code: Select all

44H           byte      Motor 1 mode
45H           s/byte    Motor 1 power
46H           s/byte    Motor 2 power
47H           byte      Motor 2 mode

Tetrix MotorMuxer device 1: I²C addr 0x02/0x03
Tetrix MotorMuxer device 2: I²C addr 0x04/0x05 ...
hi,
I tried the following simplified version (and erased a bug), but the motor1 only runs in forward reverse direction and then the program terminates (motor coast).
Any idea why the motor doesn't start with forward?

Code: Select all

void TXMotorOn(byte NXTport, byte TXmotor, char percentage)
{
  const byte retLen = 0;
  byte modeMsg[];
  byte powerMsg[];
  byte devAddr, modeReg, powerReg;
  char result;

  // constant values for testing
  devAddr = 0x02;
  modeReg = 0x44 ;
  powerReg= 0x45 ;

  // Create the message arrays
  ArrayBuild(modeMsg, devAddr, modeReg, 0);
  ArrayBuild(powerMsg, devAddr, powerReg, percentage);

  // Send the first message as soon as the bus is ready
  while ((I2CCheckStatus(NXTport) == STAT_COMM_PENDING) && (I2CCheckStatus(NXTport) != NO_ERR)) Yield();
  if(I2CWrite(NXTport, retLen, modeMsg) != NO_ERR)    return;

  // Send the second message when the first one is done
  while ((I2CCheckStatus(NXTport) == STAT_COMM_PENDING) && (I2CCheckStatus(NXTport) != NO_ERR)) Yield();
  if(I2CWrite(NXTport, retLen, powerMsg) != NO_ERR)     return;
}

task main(){
  SetSensorType(S1, SENSOR_TYPE_LOWSPEED);
  TXMotorOn(0, 1, 50);
  Wait(2000);

  TXMotorOn(0, 1,  0);
  Wait(1000);

  TXMotorOn(0, 1,-50);
  Wait(2000);

  TXMotorOn(0, 1,  0);
  Wait(2000);

  while (true);
}
ps if I experimentally switch the registers to the motor2 defaults

Code: Select all

  modeReg = 0x47 ;
  powerReg= 0x46 ;
the 2nd motor is running instead - fully as intended - but also only in reverse direction.
:?
[edited]

Re: NXC: I²C Tetrix drivers (motor controller)?

Posted: 29 Dec 2010, 20:13
by HaWe
I meanwhile changed in the source code
byte modeMsg[]; byte powerMsg[];
to
char modeMsg[]; char powerMsg[];
now it displays the direction correctly (50, -50, etc.)

but this is still crazy:
this code lets the motor only go reverse (ignores the first 2 commands) and also displays only the reverse direction (-50)

Code: Select all

#define printf2( _x, _y, _format1, _format2, _value1, _value2) { \
  string sval1 = FormatNum(_format1, _value1); \
  string sval2 = FormatNum(_format2, _value2); \
  string s =sval1+sval2; \
  TextOut(_x, _y, s); \
}

void TXMotorOn(byte NXTport, byte TXmotor, char percentage)
{
  const byte retLen = 0;
  int i, j;
  char modeMsg[];
  char powerMsg[];
  byte devAddr, modeReg, powerReg;
  char result;

  // constant values for testing
  devAddr = 0x02;
  modeReg = 0x44 ;
  powerReg= 0x45 ;
  
    // Create the message arrays
  ArrayBuild(modeMsg, devAddr, modeReg, 0);
  ArrayBuild(powerMsg, devAddr, powerReg, percentage);

  // Send the first message as soon as the bus is ready
  while ((I2CCheckStatus(NXTport) == STAT_COMM_PENDING) && (I2CCheckStatus(NXTport) != NO_ERR)) Yield();
  if(I2CWrite(NXTport, retLen, modeMsg) != NO_ERR)    return;

  printf2(0,56,"mReg=%3d","mVal=%3d",modeMsg[1],modeMsg[2]);
  
  // Send the second message when the first one is done
  while ((I2CCheckStatus(NXTport) == STAT_COMM_PENDING) && (I2CCheckStatus(NXTport) != NO_ERR)) Yield();
  if(I2CWrite(NXTport, retLen, powerMsg) != NO_ERR)     return;
  
  printf2(0,48,"pReg=%3d","pVal=%3d",powerMsg[1],j=powerMsg[2]);
}

task main(){

  SetSensorType(S1, SENSOR_TYPE_LOWSPEED);


  TXMotorOn(0, 1, 50);
  Wait(2000);


  TXMotorOn(0, 1,  0);
  Wait(1000);


  TXMotorOn(0, 1,-50);
  Wait(2000);


  TXMotorOn(0, 1,  0);
  Wait(2000);
  while (true);
}
But if I insert sound commands (PlaySound(SOUND_UP)a.s.o.), everything's fine - first forward, then stop, then reverse, then stop, indicated by the sound beeps and the correct display output:

Code: Select all

#define printf2( _x, _y, _format1, _format2, _value1, _value2) { \
  string sval1 = FormatNum(_format1, _value1); \
  string sval2 = FormatNum(_format2, _value2); \
  string s =sval1+sval2; \
  TextOut(_x, _y, s); \
}

void TXMotorOn(byte NXTport, byte TXmotor, char percentage)
{
  const byte retLen = 0;
  int i, j;
  char modeMsg[];
  char powerMsg[];
  byte devAddr, modeReg, powerReg;
  char result;

  // constant values for testing
  devAddr = 0x02;
  modeReg = 0x44 ;
  powerReg= 0x45 ;
  
    // Create the message arrays
  ArrayBuild(modeMsg, devAddr, modeReg, 0);
  ArrayBuild(powerMsg, devAddr, powerReg, percentage);

  // Send the first message as soon as the bus is ready
  while ((I2CCheckStatus(NXTport) == STAT_COMM_PENDING) && (I2CCheckStatus(NXTport) != NO_ERR)) Yield();
  if(I2CWrite(NXTport, retLen, modeMsg) != NO_ERR)    return;

  printf2(0,56,"mReg=%3d","mVal=%3d",modeMsg[1],modeMsg[2]);
  
  // Send the second message when the first one is done
  while ((I2CCheckStatus(NXTport) == STAT_COMM_PENDING) && (I2CCheckStatus(NXTport) != NO_ERR)) Yield();
  if(I2CWrite(NXTport, retLen, powerMsg) != NO_ERR)     return;
  
  printf2(0,48,"pReg=%3d","pVal=%3d",powerMsg[1],j=powerMsg[2]);
}

task main(){

  SetSensorType(S1, SENSOR_TYPE_LOWSPEED);

  PlaySound(SOUND_UP);
  TXMotorOn(0, 1, 50);
  Wait(2000);

  PlaySound(SOUND_LOW_BEEP);
  TXMotorOn(0, 1,  0);
  Wait(1000);

  PlaySound(SOUND_DOWN);
  TXMotorOn(0, 1,-50);
  Wait(2000);

  PlaySound(SOUND_LOW_BEEP);
  TXMotorOn(0, 1,  0);
  Wait(2000);
  while (true);
}
what the hell is going on???