Hi - this is probably a lot to ask but I've spent the better part of 2 full days trying to just get an I2C connection going with the Gamoto motor controller. I must be missing something really basic but am now reduced to poking at code without a clue.
The problem is with the slave address you're using for the motor controller. Assuming you have the 3 address dip switches set to 0 (the default), the slave address you need to use is 0x48.
I know it looks like it should be 0x90, but the Wire library only wants the 7-bit address of the device. The low bit is the R/W bit and that is set automatically by the library depending on the action.
A common way to simplify this is to do something like:
int slaveAddress = 0x90;
Wire.beginTransmission(slaveAddress >> 1);
...
Wire.endTransmission();
If you do the binary math, 0x90 shifted right one bit is 0x48.
Also make sure you have pull-up resistors on the SDA and SCL signal lines.
According to the data sheet you only need to send a single register address. Also, there doesn't appear to be a register with address 0x90. There is a register at decimal 90 (Raw R/C pulse counts). Maybe this is what you mean?
So if you were trying to read that register, you would want code like this:
Wire.beginTransmission(0x48);
Wire.send(0x5A); // Decimal 90
Wire.endTransmission()
Wire.requestFrom(0x48, 2); // request 2 bytes from slave device #0
byte b1;
int registerValue=0;
while(Wire.available()){
b1 = Wire.receive(); // receive a byte
Serial.println(b1, HEX); // print the character
registerValue=(registerValue << 8) + b1;
}
Oops, a correction. I didn't realize the registers are in LSB then MSB order. In that case the code should be (the previous would work for MSB then LSB order):
byte b1;
int registerValue=0;
byte byteCount=0
while(Wire.available()){
b1 = Wire.receive(); // receive a byte
Serial.println(b1, HEX); // print the character
registerValue+=(b1 << (byteCount * 8));
byteCount++;
}
I can explain (really! why I tried the stuff I was trying - first, the addresses, from the Gamoto docs I couldn't tell what the slave address should be:
I was confused if with 'beginTransmission' it should be the R or W or just some base address (like 0)
Then I was trying to follow a read register I2C PIC example from the manual where is looks like there is first a write then the register., then another write, then a read, then a write... very confusing.
All I could think was the purpose was to tell the Gamoto to write a register to some read buffer before a read was possible.
So from there it's just been a muddle and a lot of Googling for Arduino I2C/TWI examples. etc. The examples have either been too simple or too technical (or not relevant).
So...
--beginTransmission() should use the Write address
--the register sent
--then the Read address
--then receive
I'll tinker with this today to see if I can make sense of it.
So...
--beginTransmission() should use the Write address
--the register sent
--then the Read address
--then receive
I'll tinker with this today to see if I can make sense of it.
No, not exactly. Don't worry about read vs. write address. The Wire library only gets supplied the slave address which is the 7 bit address (0x48 in this case) in all situations. The library takes care of setting the R/W bit appropriately while communicating with the device.
So to read register you:
Wire.beginTransmission(0x48);
Position the address pointer at the register you want: Wire.send(??);
Wire.endTransmission();
Wire.requestFrom(0x48,2);
Loop while Wire.available() doing Wire.receive()
To write a register:
Wire.beginTransmission(0x48);
Position the address pointer at the register you want: Wire.send(??);
Send the LSB: Wire.send(LSB);
Send the MSB: Wire.send(MSB);
Wire.endTransmission();
Also be wary of any delays that the device might need. For example, some devices specify a minimum delay after a write before the next command. Also some devices need a minimum amout of time between the request and when data will be available. If you try to read the data too quickly after the Wire.requestFrom you might not receive any data because the device couldn'e respond yet (and the Wire.available() will be zero causing the while-loop to exit). These timings depend on the device and should be specified in the datasheet.
Thanks again for your help - still no joy here though. With the code below reading from register 0x22, the example in the docs indicate that I should be receiving 0x1234 (4660). I'm getting 500.
Everything looks right except for the code I gave you to convert the two bytes into the integer value (which was totally wrong!). That'll teach me for writing code late a night!