Wire.write 8bit byte

Hy,
Is Wire.write command capable of sending 8bit byte or only 7bit?
I have i2c device that needs 8bit, because MSB is continuity bit (1-continue, 0-last command).
I'm unsure because I know that wire can only send 7bit address, but what about the messages?

If I use bit with 0 for MSB it works, but I need to use 1 for MSB, because I need to enter more commands before the data.

Thank you

No problem sending full bytes

The byte sent for an address is 8 bit though, with one bit of the address byte acting as the read write signal.

Now I have 2 different anwsers...
Can I use wire.write(0xFF) command for example and Wire will automaticly know it's 8bit or do I need to do something different?

You might want to disclose which device that would be..

PCF8578 and 2 PCF8579 dot matrix display chipset (bmw e39 radio).

Have you tried? The Wire library uses 7 bit addresses and data may be a single 8 bit byte or an array of bytes..

All transfers across the I2C Bus are full bytes. The one that has you wrapped around the axle just happens to consist of 7 Address Information Bits + 1 w/r Control Bit.

Note: An extension to I2C supports 10 Address Information Bits, but that's not germane to this discussion.

Let me clarify the "7-bit address issue of an I2C Slave device" and "8-bit data read/write issue" with the example of the following hardware setup (Fig-1).


Figure-1:

1. The I2C Bus is byte (8-bit) oriented system which means that data transfer/receive takes place one byte at a time.

2. The Slave in Fig-1 has been assigned the 7-bit I2C address as: 010 0011 (0x23).
3. Before wrirting a data byte (Say: 0x83) into the Slave, the Master makes a Roll Call of the Slave by sending its address (0100011).

4. Now, the question is: when the I2C bus handles 8-bit data, then how does it handle 7-bit address of the Slave device?

Ans: In data write mode (data goes from Master to Slave), the I2C Interface automatically places a zero (0) at the right-most position of the 7-bit Slave address to make it 8-bit. Thus, there is:

0100011 ==>  00100011 (0x23)  
==> 01000110 (0x46) //This is what is being transmitted during write mode bus operation

5. The following codes take care of the situation of Step-4:

Wire.beginTransmission(0b0100011);   //==> 01000110 
Wire.write(0x83);    //Master sends 8-bit data (10000011) to Slave
Wire.endTransmission();

6. In read mode (data comes from Slave to Master), the Master makes a Rolll Call of the Slave by putting a one (1) at the right most postion of the 7-bit address to make it 8-bit. Thus there is:

0100011 == 0010 0011 (0x23)
==> 01000111 (0x47)//This is what is being transmitted during read mode bus operation

7. The following codes take care of the situation of Step-6:

Wire.requestFrom(0b0100011, 1); //request to get 1-byte from Slave ; 01000111 = 0x47

8. Test Sketch:
(1) Master Sketch: //sends data 0x83 to Slave; gets 1-byte data (0x53) from Slave

#include<Wire.h>

void setup()
{
    Serial.begin();
    Wire.begin();
    //---------------------------------
   Wire.beginTransmission(0b0100011);   //==> 01000110 
   Wire.write(0x83);    //Master sends 8-bit data (10000011) to Slave
   Wire.endTransmission();
   //-------------------------------------
   Wire.requestFrom(0b0100011, 1);
   byte x = Wire.read()
   Serial.println(x, HEX);  //Serial Monitor -1 of Master shows 53
}

void loop()
{

}

(2) Slave Sketch: //Slave receives 0x83 from Master; Slave sends 0x53 to Master

#include<Wire.h>
volatile byte x;
volatile bool flag = false;

void setup()
{
    Serial.begin();
    Wire.begin(0b010001);  //Slave address 0x23
    //--------------------------------------------------------------
    Wire.onReceive(receiveEvent);  //ISR declaration
    Wire.onRequest(sendEvent);     //ISR declarion
}

void loop()
{
     if(flag == true)
     {
          Serial.println(x, HEX); //Serial Monitor-2 of Slave shows: 83
          flag = false;
      }
}

void receiveEvent(int howMany)
{
     x = Wire.read();   //x = 0x83
    flag = true;
}

void sendEvent()
{
     Wire.write(0x53);
}

If I understand correctly I just need to convert my slave address 0x3c to binary and add 0b infront of it.
Then 8bit addresses will be sent.

Slave address is: 0x3C = 0111100
During data write operation, the I2C Interface of Master automatically puts a zero (0) at the right most position of the given 7-bit Slave address. As a result, the following 8-bit is formaed which is transmitted to Slave over the I2C Bus.

0111100
==> 01111000 = 0x78

I got this address (0x3c) with i2c analyzer on arduino. However it works, I can use set-mode command if I put 0 in front except of 1.

I'm so confused about what is wrong... does wire.write automaticly send write bit? Because that could be the problem also, datasheet shows that write bit must be sent only before first command...
This is the actual pattern of what I want to do:

Good luck!

You're over-thinking this. Just use the 7-bit address as given. The library / hardware takes care of the required left shift and setting the r/w bit correctly.

I tought that might be the problem... I don't know what is wrong, first thing that I must send is set-mode command that would be 11010101 = 0xD5 first bit is continue bit to define if next byte would be 1= command or 0= data...

This command works, but nothing after that command works...

If I use 01010101 = 0x55 (c bit = 0 = last command, data will follow) data will be displayed on the screen, but I need to use 2 or 3 more command bytes after set-mode command and before data bytes to set location -data pointer.

0x55 is basicly 7bits, because of the zero in the front.... data bytes are also 7bits and they work.... problem starts when I want to send 8bit byte.

I think that this is my problem:


I would need to prevent wire.write to send write bit.

Wire.write does not alter the data in any way. The I2C address and associated read/write bit is handled by Wire.begin, and as long as you use the correct I2C address you do not have to be concerned with that.

Your code will need to handle the correct formatting of the date being sent with Wire.write.

As its name indicates, Wire.beginTransmission(address) will get ready for a transmission to the I2C slave device with the given address.

Subsequently, all the bytes you send with the write() function are queued for transmission (stored in a temporary buffer) and the queue is actually transmitted only when calling endTransmission().

So you don’t need to worry about the writes, they do not trigger individual transactions. Just build the right frame and let the library /hardware handle the rest.

As an example here is some routines from one of my libraries to write a single byte to an I2C FRAM. The FRAM is 8Kbyte so the address in the FRAM to access is sent as two bytes, high and low, the data, then follows;


void writeMemoryUint8(uint16_t addr, uint8_t data)
{
  uint8_t msb_addr = highByte(addr);
  uint8_t lsb_addr = lowByte(addr);

  Wire.beginTransmission(Memory_I2C_Addr);
  Wire.write(msb_addr);
  Wire.write(lsb_addr);
  Wire.write(data);
  Wire.endTransmission();
}

And here is the routine to read a byte 'data' ;

uint8_t readMemoryUint8(uint16_t addr)
{
  uint8_t data;
  uint8_t msb_addr = highByte(addr);
  uint8_t lsb_addr = lowByte(addr);

  Wire.beginTransmission(Memory_I2C_Addr);
  Wire.write(msb_addr);
  Wire.write(lsb_addr);
  Wire.endTransmission();
  Wire.requestFrom((Memory_I2C_Addr), 1);
  data = Wire.read();
  return data;
}

The I2C address of the FRAM is 0x50, specified in constant 'Memory_I2C_Addr'

Thank you all for anwsers. I made it work by putting Wire.beginTranmission before and Wire.endTransmission after every command.

For example:
1. Slave's I2C 7-bit address tag : 0100011
2. Then Slave's I2C 8-bit "write-mode address": 01000110 = 0x46
3. Then Slave's I2C 8-bit "read-mode address": 01000111 = 0x47

4. The I2C Interface never sends the 7-bit address tag; rather, it sends 8-bit write- or read-mode address to check the presence of the Slave and to inform it the mode of "data direction" -- read (from Slave to Master) or write (from Master to Slave). The LSBit of Step-2/3 (above0) is called "Read/Write Control Bit" (Fig-1).

I2CAddressControlBit
Figure-1:

5, After the transmission of the 8-bit write- or read-mode address, the next transactions are pure 8-bit data which do not contain any "control bit".