It is known that address of OLED SSD1306 is 3C. The frame format is as follows: enter image description here

The figure implies that the binary pattern should be 01111000 for the first frame (considering write mode and the second last bit is a dont care).
So I was trying to send the first frame using Wire.h library. The following is a code Wire.beginTransmission(0b01111001); But i receive a nack (return value of 2)

However, If I send 00111100, i receive a ack(return value of 0). What is wrong in my interpretation?

  • You should scan the bus, maybe the display has a different address. You can use this sketch: playground.arduino.cc/Main/I2cScanner
    – Sim Son
    Commented Apr 7, 2020 at 10:50
  • I referred to this link. It shows the address is 3c but that should not be the case because the above pic is of ssd1306 datasheet
    – shivamag00
    Commented Apr 7, 2020 at 10:55

2 Answers 2


You misinterpret how the Wire library is used. Though the first byte in the transmission is called the address byte, the actual address consists only of the 7 higher bits in that byte. The direction bit is not in the address.

So the Wire.beginTransmission() method wants the address as parameter, without the direction bit. That bit is set corresponding to the used function (0 for Wire.beginTransmission() and 1 for Wire.requestFrom()).

0b0111100 is the real address (when connnecting the address pin to ground)(note, that there are only 7 bits, since the address only has 7 bits). The write operation address byte will then be 0b01111000, though the library is hiding that way from you. You need to provide the 7 bit address to the function.

the second last bit is a dont care

As mentioned above, that is not correct. This bit (the least significant bit of the address) is set by the address pin SA0. It seems, that you have it tied to ground, which sets the corresponding bit in the address to zero. If you would tie it to Vcc, it would be 1.

  • I understand where I was wrong. Thank you. However, I have one more question. How do I send the read/write bit??
    – shivamag00
    Commented Apr 7, 2020 at 11:30
  • @shivamag000 as chrisl wrote you don't manually send it. The read/write bit is automatically handled by Wire.startTransmission() (clears the bit to address the slave in write mode) and Wire.requestFrom() (sets the bit to address the slave in read mode). It's important to only use the 7-bit address, preferably in another format than binary, which can be a bit confusing
    – Sim Son
    Commented Apr 7, 2020 at 11:36
  • Yes, the data direction bit is handled by the library. When you use the write functions (Wire.beginTransmission() and Wire.endTransmission()) it will use zero for the direction bit. If you use the read function Wire.requestFrom(), it will use 1 for the direction bit.
    – chrisl
    Commented Apr 7, 2020 at 11:42
  • Also keep in mind, that the actual transmission is done in Wire.endTransmission(). Before that no data will be transmitted.
    – chrisl
    Commented Apr 7, 2020 at 11:43
  • Thank you @chrisl
    – shivamag00
    Commented Apr 7, 2020 at 11:54

I2C has a 7-bit address space. The device's actual address is 0b0111100 (=0x3c). The sequences 0b01111001 and 0b01111000 address the same slave while the first one (least significant bit is 1) starts a read transmission, the second one starts a write transmission.

Those least significant bits are nothing you need to care about when using Wire.h: the mode of operation is automatically set when using Wire.startTransmission(addr) (returns 0 when slave ACK'ed write command) and Wire.requestFrom(addr) (returns 0 when slave ACK'ed read command).

  • Even if I send 0b01111000, a nack is received
    – shivamag00
    Commented Apr 7, 2020 at 11:15
  • @shivamag000 that's not what you wrote in your question ("However, If I send 00111100, i receive a ack") and a return value of 0 means that the slave ACK'ed
    – Sim Son
    Commented Apr 7, 2020 at 11:17
  • @shivamag000 also, 0b01111000 is not what you are supposed to pass to Wire.beginTransmission(). It takes the 7-bit address. You better don't mess with binary format, simply do Wire.beginTransmission(0x3c)...
    – Sim Son
    Commented Apr 7, 2020 at 11:20
  • can you please show the reference where it says that wire.begin takes seven bit addresses
    – shivamag00
    Commented Apr 7, 2020 at 11:22
  • @shivamag000 arduino.cc/en/Reference/WireBeginTransmission
    – Sim Son
    Commented Apr 7, 2020 at 11:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.