Photon pwm alocation

Hi Everyone,
I am using the following pin allocations for my Photon project
int PWM1 = TX; // pwm out for chanel 1 pin 3
int PWM2 = WKP; // pwm out for chanel 2 pin 5
int PWM3 = A5; // pwm out for chanel 3 pin 7
int PWM4 = A4; // pwm out for chanel 4 pin 8
int Button = D5; // interrupt button
int FULBR1 = D1; // pin 14 Digital out
int FULBR2 = D7; // pin 20, Digital out
int FULBR3 = A6; // pin 6,Digital out
int FULBR4 = RX; // pin 4,Digital out

int CH1 = D2; //digital out for relays 1 pin 15 D6
int CH2 = D3; //digital out for relays 2 pin 16 D4
int CH3 = D4; //digital out for relays 3 pin 17 D3
int CH4 = D6; //digital out for relays 4 pin 19 D2

int CH1IN = A0; //Digital in for PWM1 for short ckt checking pin 12
int CH2IN = A1; //Digital in for PWM2 for short ckt checking pin 11
int CH3IN = A2; //Digital in for PWM3 for short ckt checking pin 10
int CH4IN = A3; //Digital in for PWM4 for short ckt checking pin 9
Is there a conflict between PWM1 to 4 pin allocations?
I am using a web App to control the PWMs. I have built a few boards for this project. On some boards, PWM2 is not always responding and on other boards, PWM4 is not always responding
Would somebody please help? Thanks in advance

PS: I have no problems controlling relays 1 to 4

Hi, it might be that you are getting impacted by this:

  • On the Photon, P1 and Electron, this function works on pins D0, D1, D2, D3, A4, A5, WKP, RX and TX with a caveat: 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.

source here and screenshot here:

Note: I read the above very very quick, please verify if it is the case :wink:


Thanks Gus, I am using Photon with header which is the same as P0,
The board was working fine in year 2020. Is it possible that API has changed since then.

Sorry, I wouldn’t know.
If you changed the Device OS, perhaps. But if it stayed the same then I would look elsewhere.

Also, if you posted the code maybe someone in the community could spot an issue.

Sure Gus here is the code
Hops, It is an 1100-line file, I can not copy past the whole file
How else can I send it
Regards Kazem

if you are using the particle web Build interface, you can share your project and post the link IF NOTHING in that firmware should remain SECRET :slight_smile:

Sorry I can not share the hole file.
If I can find a way to send a cutdown version of it I will
Thanks again Gus


Hello Gus,
I found the problem with PWM4 connected to A4,
I have a hardware interrupt activated by overloaded on any PWM outputs. When I removed the code within the interrupt routine the PWM4 started to work fine. I do not understand the relationship between the 2. Would you explain it to me, please?

void SHORT(){
   detachInterrupt(Button); // disable short ckt interrupt
   if (digitalRead(CH1IN) == LOW) {
       FLshort1 =1; 
        digitalWrite(PWM1, LOW); digitalWrite(FULBR1, LOW);
        if (digitalRead(CH2IN) == LOW){
        FLshort2 =1; 
        digitalWrite(PWM2, LOW); digitalWrite(FULBR2, LOW);
        if (digitalRead(CH3IN) == LOW) {
       FLshort3 =1;
        digitalWrite(PWM3, LOW); digitalWrite(FULBR3, LOW);
        if (digitalRead(CH4IN) == LOW) {
        FLshort4 =1;
        digitalWrite(PWM4, LOW); digitalWrite(FULBR4, LOW);

    attachInterrupt(Button, SHORT, FALLING, 11);  

If I remove the code within void short(), PWM4 work fine??
I need to have this function. What is the way around it
Thanks in advance

I do not know. What are you trying to achieve with that function?

It is for detecting which PWM is overloaded then it will shut it off and set a flag
another timer will enable all PWM’s. every 8 seconds If there is still an overload on it or any other PWM it will shut it off and set the corresponding flag so it can not be turned on for 8 seconds.
The shorted PWM has to be turned off in the interrupt routine as fast as possible to protect the output transistors I hope I have answered your question. Regards Kazem

when you say that (above), could it be that this function deactivated PWM4?
Could it be that CH4IN is detected LOW sometimes?

I’m not sure if this is your problem, but you should not detach the interrupt and reattach it in the ISR.

The attachInterrupt() call is not ISR-safe as it allocates memory using new. I’m kind of surprised it didn’t cause a SOS panic. Actually, detachInterrupt() isn’t either because it calls delete.

Thank you, gentlemen. Short ISR is called only under short circuit conditions. rickkas7 I implemented your idea, but it did not help. I even commented //attachInterrupt(Button, SHORT, FALLING,11); in the setup loop When a short circuit takes place a hardware interrupt will call short ISR and relevant PWM will be turned off within that ISR. Relevant CH1IN to 4 will remain active until the corresponding PWM is turned off within the short ISR. If short circuit ISR is not called in under normal conditions why is it making PWM4 not respond? I have doubts about my PWM allocations being TX, WKP, A5, and A4. Are you sure that this allocation is OK?

This is the source of truth for timer assignments from the Device OS source.

Timers on the same timer number (TIM1, TIM3, etc.) must share the same frequency, but can have different duty cycles. If two pins share the same timer and channel, only one can be used for PWM.

  • TX - TIM1, TIM_Channel_2
  • WKP - TIM1, TIM_Channel_3
  • A5 - TIM3, TIM_Channel_1
  • A4 - TIM3, TIM_Channel_2

That looks safe, and it matches the documentation.

1 Like

Thank you, Sir. Now I am starting to look elsewhere.
I moved the short circuit checking to the main loop. I still had the same problem, then it turned out that reading CH4IN connected to PWM4 is the source of the problem, but I do not know why.
once I found out I will let you know if you like me to
Thanks again

1 Like