2

I am using an ESP8266-12E with a PCF8547. I have managed to turn on and turn off LEDs using these two things. I am using these three commands to do it.

 Wire.begin(SDA_PIN,CLK_PIN);
 Wire.beginTransmission(0x20);
 Wire.write(~((uint8_t)1<<cnt));
 Wire.endTransmission();

The problem I am facing here is: I am using 4 LEDs and I am only able to turn on one LED at a time. When I turn on another, all the LEDs turn off - in short, the LEDs or the PCF8547 do not preserve the state.

I want to toggle on the LEDs without disturbing the other's state. How can I do it?
I think, I need more knowledge about the write function, don't I?

Update:

I have already connected A0, A1, A2 to ground. This is the function I use now to toggle the LEDs.

void enlight(int cnt)
{ 
  if (cnt == 1) 
    value = value | 1<<cnt; 
    if (cnt == 2) 
      value = value | 2<<cnt; 
    if (cnt == 3) 
      value = value | 3<<cnt; 
    if (cnt == 4) 
      value = value | 4<<cnt; 
    value = ~value; 
    Wire.begin(SDA_PIN,CLK_PIN); 
    Wire.beginTransmission(0x20); Wire.write(value);      
    Wire.endTransmission(); 
  }

but when I turn off/on any other LEDs they also toggle, which I don't want.

My Circuit Image

  • Please add circuit description. How have you connected the LEDs? With to low resistors the LEDs will draw to much current. Check the numbers! – Mikael Patel Nov 13 '16 at 13:40
  • Forwarded from the user Pete: Aren't the addresses of the LED's (or devices) given in the datasheet? – zx485 Nov 13 '16 at 16:27
  • @MikaelPatel : i will add the circuit image that is not an issue. what i want to achieve is just like we send HIGH and LOW signals to GPIO pins of ESP8266-12e and turn off/on the led connected to that GPIO , the same i want to do with PCF8547. i want to know technique to access the address or some identification to the I/O pins of PCF8547 so that only one led at a time i can turn on/off without affecting other pins . – KarmaCoding Nov 13 '16 at 16:54
  • Just remember the value you sent last time, and modify only the bits you want to change. Google will tell you how to change a single bit in C (or C++). – Mark Smith Nov 13 '16 at 17:30
  • This might be of some help; github.com/mikaelpatel/Cosa/blob/master/libraries/PCF8574/… – Mikael Patel Nov 13 '16 at 17:45
1

(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<<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<<0;
if (led1) value = value | 1<<0;
if (led2) value = value | 2<<0;
if (led3) value = value | 3<<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<4) {
    // Get a bitmask with a single 1 in the right
    // position for this light
    uint8_t position = 1<<lightNum;

    // Clear (to 0) that bit in the state
    lightsOn &= ~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)
  • totally explainable. i got how it works now. but i am not be able to analyse what address does the pins have. the code you have provided toggles all the other leds too. is it possible to get the addresses of the pins on PCF8547 so that the actual led is toggled by us. – KarmaCoding Nov 13 '16 at 9:49
  • Can you experiment with the values of led0...led3 to find the addresses? They should be the same numbers you were using for cnt. – Mark Smith Nov 13 '16 at 9:56
  • I have been doing experiments, the results are various , but not be able to trigger only one Led , its complicated for the person with non-electronics background, me. i have managed to find what will the value of the variable value but that also not only triggering the particular pin. plus since few days my Serial monitor is not working. so cant predict the output same time. – KarmaCoding Nov 13 '16 at 13:54
  • 1
    Then I think we need a circuit diagram please. – Mark Smith Nov 13 '16 at 14:08
  • I'd also suggest, if your serial monitor is not working, you're making things harder for yourself by working blind. Don't fall into a gumption trap en.wikipedia.org/wiki/Gumption_trap - get that fixed first. – Mark Smith Nov 13 '16 at 14:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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