Hi All
I'm new to the arduino and also to i2c, but not to electronics. This is a bit of a long post for a first post, and I kinda get there in the end but am puzzled as to why and how, so please read on.
I have a slave device (a pcb containing a video switch etc) and the documentation says it has an address of 0xba or 0xbb depending on the address A0 select line.
It actually states 'if the A0 line is high (which it is) the device has an address of 0XBA/0xBB where the LSB is the R/W flag
First Question - I'm not totally sure what that means... do I need to read from one Address and Write to the other?
I have some arduino code which is trying to send a couple of basic commands to this board, these commands simply select one or another input and route it to the output, switching every five seconds .
The slave boards API uses something it calles 'alpha commands' on the i2c bus whereby the first byte of data is the 'size' of the command in bytes then follow the actually command.
OK here is my very simple sketch
#include "Wire.h"
#define I2C_ADDRESS 0xba // slave I2C address
int led = 13;
void setup()
{
pinMode(led, OUTPUT);
Wire.begin();
}
void sel1() // select input 1
{
Wire.beginTransmission(I2C_ADDRESS);
Wire.write(0x04); // message size
Wire.write(0x00); //
Wire.write(0xca); // Select Input
Wire.write(0x09); //
Wire.write(0x01); // HDMI 1
Wire.endTransmission();
}
void sel2() // select input 2
{
Wire.beginTransmission(I2C_ADDRESS);
Wire.write(0x04); // message size
Wire.write(0x00); //
Wire.write(0xca); // Select Inout
Wire.write(0x09); //
Wire.write(0x02); // HDMI 2
Wire.endTransmission();
}
void loop()
{
sel1();
digitalWrite(led,HIGH);
delay(10);
sel2();
digitalWrite(led,LOW);
delay(10);
}
The flashing LED is just so I can see something is happening. The video switch does not do anything though, even though I can see it's status is READY to accept commands.
So I had a look what was happening on the i2c bus with my scope and this is what I can see:
blue trace is the clock SCL, yellow trace is the data SDA
Now if I am understanding this correctly then I can see:
a Start condition (SDA goes low while SCL is high)
some data 011101001
a stop condition (SDA goes high while SCL is high)
Now the i2c address is set to 0xBA which is 10111010 but what I see on the scope is 011101001
This kinda correlates to the address
expected 0xBA.........1 0 1 1 1 0 1 0
observed..................0 1 1 1 0 1 0 0 1
This confused me somewhat. I read that i2c uses a 7 bit address. Which is the first part of what I can see on the scope.
Second question then. If i2c uses a 7 bit address how can my device ever have an address of 0xBA ? That needs 8 bits! (anything over 0x7F does). I actually see on the scope 0x7A (first 7 bits) instead of 0xBA
Then there is this '0 1' that I can see after the seven bit address. According to the i2c docs I read, after the seven bit address there is an eigth bit (0 write 1 read) followed by an ACK (1) from the slave
Third Question: Is that what I am seeing here..... address 0x7A..... followed by 0 (write) and then 1 (ack) ?
Now I am WELL confused. The address I sent was supposed to be 0xBA but it looks lke 0x7A on the scope. If I include the read/write bit as part of the address then I am actually sending 0111 0100 (ack) which is 0x74. In that case why do I get an ACK for the wrong address?
Now I really started thinking.....
If....
expected 0xBA.........1 0 1 1 1 0 1 0
gives
observed..................0 1 1 1 0 1 0 0 1
and I want to observe 1 0 1 1 1 0 1 0 (where the last 0 of the address is the 'write' bit)
then in arduino should I address 0xdd (allowing for the additional read/write on the LSB and the loss of the MSB due to 7 bit address)??
because
0xdd is................... 1 1 0 1 1 1 0 1
so observed should be... ...1 0 1 1 1 0 1 0 1 which is 0xBA plus ACK
What I actually saw was 10111010 0 like 0xBA plus an ACK of 0
This is what I see now
After the address I can see the ACK (I think but it is a 0 not a 1 as I thought it would be) followed by the first byte of data 0x04
So something has started working right because my arduino now sends the rest of the sequence!
Bit why am I having to use a completely different address in Arduino to that specified in the documentation for my advice. Seeing as I have never messed with i2c until today I feel quite pleased to have got this far, but I am very confused why it was so difficult and still not sure now if I am doing this right as though my board accepts the command it still does not switch the video (yet!!)
Please someone unconfuse me
Rich
PS I've ordered myself one of these 'bus pirate' devices to help me with this project as decoding i2c on an oscilloscope is do-able it seems but very fiddly