According to the documentation:
"Each motor has its encoder count stored in an array of four bytes, together the bytes form a signed 32 bit number, the encoder count is captured on a read of the highest byte (registers 2, 6) and the subsequent lower bytes will be held until another read of the highest byte takes place. The count is stored with the highest byte in the lowest numbered register. The registers can be zeroed at any time by writing 32 (0x20) to the command register."
I understand that:
1. The encoder count can be represented by a signed long int variable (-2147483648 to 2147483647).
2. For the motor turning in one direction the count is a positive number and in the other direction is a negative number.
3. Registers 2,3,4,5 are used for encoder1 and 6,7,8,9 for encoder2.
4. The four bytes (32bits) of a signed long int variable correspond to registers 2,3,4,5 of encoder1 count from the MSB to the LSB.
5. The four bytes (32bits) of a signed long int variable correspond to registers 6,7,8,9 of encoder2 count from the MSB to the LSB.
Using C (CVAVR), I can do this to calculate the encoder count:
1. Read the four registers as unsigned char variables.
2. Cast the unsigned char variables to unsigned long int variables and shift left 24,16,8,0 bits each one in correspondence to the 2,3,4,5 or 6,7,8,9 registers.
3. Compose an unsigned long int variable by adding the four unsigned long int variables or ORing them.
4. Cast the unsigned long int variable obtained to a signed long int variable.
So, I write this code:
long int read_encoder1_count(void)
{
unsigned long int data;
data = 0;
i2c_start();
i2c_write(0xB0);
i2c_write(2);
i2c_start();
i2c_write(0xB1);
data |= (unsigned long int)i2c_read(0) << 24;
i2c_stop();
i2c_start();
i2c_write(0xB0);
i2c_write(3);
i2c_start();
i2c_write(0xB1);
data |= (unsigned long int)i2c_read(0) << 16;
i2c_stop();
i2c_start();
i2c_write(0xB0);
i2c_write(4);
i2c_start();
i2c_write(0xB1);
data |= (unsigned long int)i2c_read(0) << 8;
i2c_stop();
i2c_start();
i2c_write(0xB0);
i2c_write(5);
i2c_start();
i2c_write(0xB1);
data |= (unsigned long int)i2c_read(0);
i2c_stop();
return (long int)data;
}
long int read_encoder2_count(void)
{
unsigned long int data;
data = 0;
i2c_start();
i2c_write(0xB0);
i2c_write(6);
i2c_start();
i2c_write(0xB1);
data |= (unsigned long int)i2c_read(0) << 24;
i2c_stop();
i2c_start();
i2c_write(0xB0);
i2c_write(7);
i2c_start();
i2c_write(0xB1);
data |= (unsigned long int)i2c_read(0) << 16;
i2c_stop();
i2c_start();
i2c_write(0xB0);
i2c_write(8);
i2c_start();
i2c_write(0xB1);
data |= (unsigned long int)i2c_read(0) << 8;
i2c_stop();
i2c_start();
i2c_write(0xB0);
i2c_write(9);
i2c_start();
i2c_write(0xB1);
data |= (unsigned long int)i2c_read(0);
i2c_stop();
return (long int)data;
}
I made a bench test run (the wheels not touching the floor) using mode 3 with turn 0 (speed regulation enabled and resetting the encoders count at start) in a two-wheel robot at speed1 60 and the physical result was OK. But the reading (every 5 seconds) of the encoders count is strange:
1. One reading is positive and the other is negative. OK, the two motors run in opposite directions.
2. The two readings start from zero and increase continuosly in absolute value. OK.
2. The two readings differ in absolute value something as some dozens.
3. At some time (with the count greater than 30000 (maybe 32767 ???)) the encoders count change sign and start to decrease in absolute value (???).
In conclusion, there must be a mistake at some point. I welcome your help. thank you.
