PCF8547 Wire.write explanations
(I haven't used this library, but this looks like a general C(++) question...)

The important part of what you're doing is this:

Wire.write(~((uint8_t)1&lt;&lt;cnt));


Let's break it down.

It calculates a value by taking the number 1 and shifting it left cnt times. Then it takes the complement of that number - changes 0s to 1s and 1s to 0s.  This number is sent to Wire.write() and lights up light number cnt.

Example: Let's say you start with cnt==2, to light LED 2.  It will shift the number 1 left by two digits, giving you the binary number 00000100.  Then it will invert this, giving you 11111011.  This is given to Wire.write().

We can see from this that to light an LED, we need to put a '0' in the right place.

How can you make several numbers light up?  We need to put several zeros in, at the right places.

Here's an example of how you might like to do this - which isn't the prettiest code but I hope it shows you what's going on.

// How we would like the LEDs to appear
boolean led0 = true;    // LED 0 ON
boolean led1 = false;   // LED 1 OFF
boolean led2 = true;    // LED 2 ON
boolean led3 = false;   // LED 3 OFF

// Start with all LEDs off
uint8_t value = 0;

// Put a 1 in place for each LED we want to be ON
// The | symbol means "logical OR" (Google it)
if (led0) value = value | 1&lt;&lt;0;
if (led1) value = value | 1&lt;&lt;0;
if (led2) value = value | 2&lt;&lt;0;
if (led3) value = value | 3&lt;&lt;0;

// Invert this value
value = ~value;

// Write it to Wire
Wire.begin(SDA_PIN,CLK_PIN);
Wire.beginTransmission(0x20);
Wire.write(value);
Wire.endTransmission();


Since it appears you have to send values for all the lights every time, you need to remember the value you sent last time, and modify only the bits you want to change.  Here's a way you can do that:

void setLight(int lightNum, boolean lightOn) {
  // Remember the last state of the lights.
  // Start with all lights OFF.
  static uint8_t lightsOn = 0;

  // We only have four lights (0-3).  Only respond for lights
  // we we have.
  if (lightNum&lt;4) {
    // Get a bitmask with a single 1 in the right
    // position for this light
    uint8_t position = 1&lt;&lt;lightNum;

    // Clear (to 0) that bit in the state
    lightsOn &amp;= ~position;

    // Set (to 1) the bit if we want the light on
    if(lightOn) lightsOn |= position;

    // Write out the value of all lights
    Wire.begin(SDA_PIN,CLK_PIN);
    Wire.beginTransmission(0x20);
    Wire.write(~lightsOn);
    Wire.endTransmission();
  }
}


Call it with something like

setLight(0, true);    // Switch the first light ON
setLight(3, true);    // Switch the fourth light ON (first stays on)
setLight(0, false);   // Switch the first light OFF (fourth stays on)