11 years, 8 months ago.

Need Help: Reading VEX Integrated Encoder with mbed

Hi,

I purchased for my robot project the VEX Robotics Motor 393 with Integrated Encoder Module and am trying to read the velocity and position data with the mbed. All my attempts so far to get useful data out did not work. Following the description in http://www.vexforum.com/showthread.php?p=255691 and a template given for the Arduino (https://github.com/alexhenning/I2CEncoder) I managed to initialize the right encoder (LED light is blinking green), to disable the terminator to the left encoder and to initialize the left encoder (LED light is solid green) with:

// Assign address for right encoder:
    char ChangeAddressCommand[2];
    char Unterminate[2];
    ChangeAddressCommand[0] = I2CENCODER_ADDRESS_CHANGE;   //..=0x4D 
    ChangeAddressCommand[1] = RIGHT_NEW_ADDRESS;     //New address (= 0x20) ...
    //change the i2c address (I2CENCODER_DEFAULT_ADDRESS=0x60) :
    i2c.write(I2CENCODER_DEFAULT_ADDRESS, ChangeAddressCommand,2); // Send command string
// Zero it on initialization
  zero();
  wait(0.5);
  //...Unterminate the first encoder so can speak to second encoder...
  Unterminate[0] = I2CENCODER_UNTERMINATE_REGISTER;   //...=0x4B
  Unterminate[1] = I2CENCODER_TERMINATE_REGISTER;       //...=0x4C
  i2c.write(RIGHT_NEW_ADDRESS, Unterminate, 2);

  //Assign address for left encoder:
  ChangeAddressCommand[0] = I2CENCODER_ADDRESS_CHANGE;
  ChangeAddressCommand[1] = LEFT_NEW_ADDRESS;     //New address (= 0x22)...
  //change the i2c address (after this write the :
  i2c.write(I2CENCODER_DEFAULT_ADDRESS, ChangeAddressCommand,2); // Send command string
  // Zero it on initialization
  zero();  

After this initialization I try to read the velocity registers with:

  char cmd[2];
  cmd[0] = I2CENCODER_VELOCITY_REGISTER;   //...= 0x44...
  ack = i2c.read(RIGHT_NEW_ADDRESS, cmd, 2);
  float echo1 = ((cmd[0] << 8) + cmd[1]); //R

As a result I get FFFF in echo1 which results in 0 speed. What am I doing wrong?

Thank you very much for any help.

Arasch

Please use <<code>> and <</code>> around your code for better readability.

posted by Erik - 02 May 2013

2 Answers

11 years, 7 months ago.

Thank you for the answer Erik.

I tried that like this:

char regloc = I2CENCODER_POSITION_REGISTER;
    i2c.write(RIGHT_NEW_ADDRESS, &regloc, 1);

    char cmd[2];
    cmd[0] = I2CENCODER_VELOCITY_REGISTER;
 
  ack = i2c.read(RIGHT_NEW_ADDRESS, cmd, 2);


  float echo1 = ((cmd[0] << 8) + cmd[1]); //R
  
  return echo1;

Now the velocity I get with

  unsigned int vb = getVelocityBits();
  pc.printf("vb == %X \n\r " , vb);
  if (vb == 0xFFFF) return 0;
  return rotation_factor / (double(vb) * time_delta);

is starting at 59.41 feet per second and is counting down. It doesn't seem to be the velocity value (no changes when I stop the wheel manually)... I seem to be missing something basic...

Thanks again for your help.

Arasch

Accepted Answer

Whoops you required the velocity, then make regloc equal to I2CENCODER_VELOCITY_REGISTER. Your assignment to cmd[0] doesn't actually do anything, the data is read into that register. The register location you want to read is set by first writing that register via the I2C bus. Then you do the I2C read and you read that register (and generally if you do two reads you also read the next register).

posted by Erik - 03 May 2013

Great, thank so much. With

char regloc = I2CENCODER_VELOCITY_REGISTER;
    i2c.write(RIGHT_NEW_ADDRESS, &regloc, 1);
  char cmd[2]
  ack = i2c.read(RIGHT_NEW_ADDRESS, cmd, 2);

  float echo1 = ((cmd[0] << 8) + cmd[1]); //R
  
  return echo1;

it works now.

Arasch

posted by Arasch Lagies 03 May 2013
11 years, 7 months ago.

I think you forgot to write to the sensor which register you want to read, something like:

char regloc = I2CENCODER_POSITION_REGISTER;
i2c.write(RIGHT_NEW_ADDRESS, &regloc, 1);