I2C begginer with I/O expander with mega328p C code
OK the answer is that I didn't send the correct address!

Because if the I2C starting command with the slave is successful, then you should get successful sending ACK according reading the value of transmission status from the status register TWSR and ANDing this value with 0xF8. Then by reading the datasheet you know the value of transmission status. I developed a function to determine the status of transmission with Arduino Serial library which is I2C_TWSR_Check();.

I did this code for Master transmitter and receiver only.

So the trick is that you have to fix the address according to the AVR's TW address command format, which is the first bit is for read/write command and the remaining 7-bits are for the address, so you have to shift the real address which I got by "I2C address scanner" I got from one of AVRfreaks members.

For example, if the address is 0x20, then after shifting it 1-bit to the left, the new address is 0x40 for write operation and 0x41 for read operation.

void I2C_init(void);
void I2C_start(uint8_t address);
void I2C_stop(void);
void I2C_tx(uint8_t data);
uint8_t I2C_rx(void);
void I2C_TWSR_Check(void);

uint8_t bitmask;

/////////// I2C modules addresses ////////////
// 8-bit I/O expander 0x20 
#define IOEXP_WR  0x40    // I/O 8-bits expander address
#define IOEXP_RD  0x41

// LCD1602 adapter
#define LCD1602_WR  0x4E  // LCD1602 I2C adapter address
#define LCD1602_RD  0x4F

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  I2C_init();
}

void loop() {


  I2C_start(LCD1602_WR);
  I2C_TWSR_Check();
  I2C_tx(0xff);
  I2C_TWSR_Check();
  I2C_stop();
  _delay_ms(500);

  I2C_start(LCD1602_WR);
  I2C_tx(0x00);
  I2C_stop();
  _delay_ms(500);
}

void I2C_init(void)
{
  //set SCL to 100kHz
  TWSR = 0x00;
  TWBR = 0x48;
  //enable TWI
  TWCR = (1&lt;&lt;TWEN);
}

void I2C_start(uint8_t address)
{
  TWCR = (1&lt;&lt;TWINT)|(1&lt;&lt;TWSTA)|(1&lt;&lt;TWEN);
  while (!(TWCR &amp; (1&lt;&lt;TWINT)));
  //I2C_TWSR_Check();
  TWDR = address;
  TWCR = (1&lt;&lt;TWINT)|(1&lt;&lt;TWEN)|(1&lt;&lt;TWEA);
  while (!(TWCR &amp; (1&lt;&lt;TWINT)));
  //I2C_TWSR_Check();  
}

void I2C_stop(void)
{
  TWCR = (1&lt;&lt;TWINT)|(1&lt;&lt;TWSTO)|(1&lt;&lt;TWEN);
}

void I2C_tx(uint8_t data)
{
  TWDR = data;
  TWCR = (1&lt;&lt;TWINT)|(1&lt;&lt;TWEN)|(1&lt;&lt;TWEA);
  while (!(TWCR &amp; (1&lt;&lt;TWINT)));
  //I2C_TWSR_Check();
}

uint8_t I2C_rx(void)
{
  TWCR = (1&lt;&lt;TWINT)|(1&lt;&lt;TWEN)|(1&lt;&lt;TWEA);
  while (!(TWCR &amp; (1&lt;&lt;TWINT))); 
  return TWDR;
}

void I2C_TWSR_Check(void)
{
  uint8_t Status;
  Status = TWSR &amp; 0xF8;
  switch(Status)
  {
    /////////////// MASTER TRANSMITTER //////////////
    case 0x08: 
    Serial.println("Start is OK");
     break; 
    case 0x10:
    Serial.println("Re start");    
     break;    
    case 0x18:    
    Serial.println("SLA+W OK ACK");    
     break;    
    case 0x20:  
    Serial.println("SLA+W no ACK");    
     break;      
    case 0x28:  
    Serial.println("data TX OK ACK");    
     break;    
    case 0x30:       
    Serial.println("data TX OK no ACK");   
     break;       
    case 0x38:        // arbitration lost in SLA+W or data TX
    Serial.println("arbitration lost in SLA+W or data TX");    
     break;

    /////////////// MASTER RECEIVER //////////////  
    case 0x40:
    Serial.println("SLA+R OK ACK");    
     break;    
    case 0x48:    
    Serial.println("SLA+R OK NO ACK");   
     break;       
    case 0x50:  
    Serial.println("data RX OK ACK");   
     break;  
    case 0x58: 
    Serial.println("data RX OK NO ACK");   
     break;  

     default:
     Serial.println("Error");
    break;
  }
}