Can't get simultaneous output out of A4, A5 and A7 on Photon

I'm just trying to put an RGB LED on my Particle Photon. Pins D0 and D1 are already occupied for an I2C device, and pins RX and TX are already occupied for a serial device.

According to the docs, I should have 3 more PWM pins:

Particle Photon boards have 9 PWM pins: D0, D1, D2, D3, A4, A5, WKP, RX, TX. However there’s a note: PWM timer peripheral is duplicated on two pins (A5/D2) and (A4/D3) for 7 total independent PWM outputs. For example: PWM may be used on A5 while D2 is used as a GPIO, or D2 as a PWM while A5 is used as an analog input. However A5 and D2 cannot be used as independently controlled PWM outputs at the same time. See: https://docs.particle.io/datasheets/photon-datasheet/

Technically 5, but since two of them are shared, this brings it down to 3. 3 is all I need for an RGB LED, so I hooked it up to A4, A5 and A7/WKP.

I am able to get each individual color to light up, red green and blue, by analogWrite-ing each pin as 255 one at a time.

I am NOT able to combine two or three pins at the same time. If I analogWrite all three pins 255 at the same time, only red (A7/WKP) shows up.
Same for just two pins at a time. Same if I replace analogWrite with digitalWrite (which is really weird, that's not even PWM!). Same if I try swapping A4 and A5 for D2 and D3. Same if I try swapping out a new RGB LED (I have a hundred, and can confirm they all work fine and can make white light on other devices).

Even if I do all this in void setup, before the i2c and serial devices have begun doing anything, this happens. Although in theory, according to the docs, they shouldn't interfere.

Here is my code, although it's pretty long and complex, the relevant routine is the ledcycle():

I did find this thread from 8 years ago with someone who had the exact same issue on the exact same pins, and it appears it was never resolved. The last few commenters confused the author's attempts on A4/A5/A7 for his earlier attempt on A4/A5/A6, which of course won't work because A6 is a DAC, but never explained why he couldn't get it to work on A4/A5/A7.

I don't see any obvious reason why those pins should not work. The important thing is that all of the pins must be assigned to different TIM and TIM_Channel, and that is true of A4, A5, and A7. The definitive source of this is the Device OS source code, which is here:

I was able to get A4, A5, and A7 to work properly on the Photon with PWM. I used this code:

#include "Particle.h"

SYSTEM_THREAD(ENABLED);

const pin_t pins[3] = {
    A4,     // red
    A5,     // green
    A7      // blue
};
const size_t numPins = sizeof(pins) / sizeof(pins[0]);

const uint32_t testColors[] = {
    0x000000,
    0x800000,
    0x008000,
    0x000080,
    0x808000,
    0x008080,
    0x800080,
    0x808080,
    0xffffff
};
const size_t numColors = sizeof(testColors) / sizeof(testColors[0]);
unsigned long lastChange = 0;
size_t nextColor = 0;

void setup() {
    for(size_t ii = 0; ii < numPins; ii++) {
        pinMode(pins[ii], OUTPUT);
    }

}

void loop() {
    if (millis() - lastChange >= 2000) {
        lastChange = millis();

        for(size_t ii = 0; ii < numPins; ii++) {
            // LED is common anode (LOW = on, HIGH = off) so reverse that here by using the 255 - factor
            analogWrite(pins[ii], 255 - (testColors[nextColor] >> (ii * 8) & 0xff));
        }

        if (++nextColor >= numColors) {
            nextColor = 0;
        }
               
    }
}

1 Like

Hey thanks man, really appreciate you testing this. And just to confirm you were able to get white (all 3 pins on at the same time) without issue? I can get individual colors red, green, and blue to come out of the LED, I just can't combine two or more of them at max (255) analogwrite value.

So either something else in my code is somehow blocking these 3 pins from working simultaneously, or my old Photon is old and not working properly.

This code works, and flashes the RGB LED red, then green, then blue:

int LEDApin1 = A4;
int LEDApin2 = A5;
int LEDApin3 = A7;

analogWrite(LEDApin1, 255);
delay(leddelay);
analogWrite(LEDApin1, 0);

analogWrite(LEDApin2, 255);
delay(leddelay);
analogWrite(LEDApin2, 0);

analogWrite(LEDApin3, 255);
delay(leddelay);
analogWrite(LEDApin3, 0);

But this code, that should produce white, only produces red:

analogWrite(LEDApin1, 255);
analogWrite(LEDApin2, 255);
analogWrite(LEDApin3, 255);
delay(leddelay);
analogWrite(LEDApin1, 0);
analogWrite(LEDApin2, 0);
analogWrite(LEDApin3, 0);

However if I combine them at much smaller values, IE analogwrite-ing with a value of 100 instead of 255, then I am able to make combined colors. It seems to snap to red when the analogwrite value gets too high. I tried a different, more powerful power supply to see if that was the issue, but it made no difference.

And I've tried different RGB LEDs (even a completely different one - an SMD one made by a different company), they all have this same problem. I can't imagine how any of my code could prevent these 3 pins from operating simultaneously at max pwm output, but my code does include some very advanced libraries (the BSEC library is actually a precompiled .a file written for generic Cortex M3 processor and is untested on Photon, but seems to work fine for me).

Yes, my code tests all combinations. You should just try running it on your board and see what happens.

I used a common anode RGB LED. Each of the R, G, and B have independent current limiting resistors to the GPIO. The common leg connects to 3V3.

If you have a common cathode LED, which also requires individual current limiting resistors, but the common leg connects to GND, remove the 255 - factor from the analogWrite command.

1 Like

If you have a common cathode LED, which also requires individual current limiting resistors,

So that'll do it, huh. I could have SWORN I had gotten these things working with just a single resistor on the common cathode pin. I thought the only difference was that some colors end up being slightly brighter than others, not red taking over the entire thing. Apparently this is because the red anode operates at a slightly lower voltage than the other two anodes, and hogs all the current sometimes.

Sorry for wasting everyone's time, but thank you for the simple solution!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.