Software Servo for Photon - Getting Software PWM to work

I have a servo connected to the A7 pin on my photon. I mistakenly looked at the outputs for the Spark prior to building my PCB (Spark has hardware PWM support on pin A7, but the Photon does not).

My mistake aside, software PWM is useful tool in our collective Photon chest.

I attempted to use the Arduino SoftwareServo code (http://playground.arduino.cc/ComponentLib/Servo) on my Photon. I feel it would be a useful addition to Photon users, but I am struggling to get it to work.

First I included Softwareservo.h and SoftwareServo.cpp.

I replaced “#include <WProgram.h>” with “#include<applcation.h>”, which got past the first compile error.

Now it is giving me the following two compile errors and I am completely stuck:

SoftwareServo.cpp:51:51: error: 'clockCyclesPerMicrosecond' was not declared in this scope
     pulse0 = (min16*16L*clockCyclesPerMicrosecond() + (max16-min16)*(16L*clockCyclesPerMicrosecond())*angle/180L)/64L;

and

SoftwareServo.cpp:108:21: error: 'TCNT0' was not declared in this scope
     uint8_t start = TCNT0;

Any help getting this working or, or a pointer to a working Software PWM library would be greatly appreciated.

The Photon does have PWM support on A7/WKP!

See here
https://docs.particle.io/reference/firmware/photon/#analogwrite-pwm-

And for SoftPWM, have you tried the respective contributed library?
https://build.particle.io/libs/560fd8c66ca615e7790027cd

TCNT0 is a hardware counter on AVR chips which is not present on ARM Cortex like the STM32F2xx used in Photons.

And the equivalent for clockCyclesPerMicrosecond would be SYSTEM_US_TICKS which is defined like this

#define SYSTEM_US_TICKS		(SystemCoreClock / 1000000)//cycles per microsecond

@alexg, as (the omnipresent) @ScruffR pointed out, I adapted an arduino software PWM library to use the Core/Photon/Electron hardware timers. The port was made for the old Spark Core but it will work for the Photon. :wink:

1 Like

Thank you both for the clarification and the library.

I made a mistake in the first post: the servo is connected to the A6/DAC pin, not A7, and it is A6 that does not seem to support hardware PWM. With this in mind I think software PWM is the best option.

I tried the SoftPWM library and got it up and running. Nice library, tested with the D7 LED example. Duty cycle works fine. It did allow me to move the servos, but servos need a specific pulse width rather than a PWM duty cycle.

Turns out servos need a pulse width between 1ms and 2ms (ie. 1ms is 0deg, 1.5ms is 90deg and 2ms is 180deg). These pulses should occur 50 times a second (every 20ms), but most servos are fairly flexible as to the frequency. Thus I need to modify the library to get accurate servo control. Using the existing PWM library, the servos move full cycle with values of 10 to 40.

Any ideas on the easiest path from here?

Many thanks, Alex

1 Like