PWM with Restful API

A project log for Restful IO

A developer friendly way of analog digital io via restful web services & usb

GorkyGorky 02/28/2016 at 07:050 Comments

reLet's start with a bit of story and put a few letters together to convey the bigger picture of what I am trying to do with an acronym.

PIAAS - for Peripheral Interface As A Service.

Not sure if this will sound like a good idea to people working on other acronyms like IOT, SOA and SAAS as this whole concept is abstracting very low level interfaces with very high level architecture. Also makes it appealing to a few people who can understand both concepts but personally I am quite happy with the results and hope that it will drastically increase the productivity of makers and inventors with a variety of skill sets and trades.

So here in the scope of this project I am trying to extract and expose as many peripherals as possible from a single MCU as restful web services. PWM happened to be the next one in line after digital io and analog input as I have some ideas around controlling servos and a few more fancy things which needs PWM to be controlled. Came up with three different services so far and thinking they are flexible enough for a number of applications.

Hardware PWM Service

There are 2 hardware pwm modules on PIC16F1455. I needed to draw the boundry here to make things a bit more straightforward and simple. Came up with two services. These services provide PWM with 10bit duty in 4 different frequencies 732 Hz, 2.9 kHz, 11.7 khz and 46.8 kHz. MCU allows a lot more options here in terms of frequency, less pwm bits but I am trying to build a flexible device here while not over engineering it. Service calls as below.


Starts hardware PWM at first attached RestIO device on port C5 with a duty cycle of 25%. Last parameter is for 10bit duty which is 256 in the example above, 1023 will result in 100% duty as you might have guessed.


Sets the hardware pwm frequency to 46.8 kHz, http://restioServer/0/pwmFreq/1 sets it to 11.7 kHz. Last parameter is the frequency divider where 2 and 3 results to 2.9kHz and 732 Hz respectively..

Well long story short we have a nice and stable PWM service with a couple of common frequencies. No jitter. Not effected by other service calls or USB communication. As accurate as your USB data clock (means very accurate).

Software PWM

There are 7 digital output ports on Rest IO board and all can output pw modulated signals now. Good things first there are seven of them compared to 2 hardware alternatives, they have simpler services and period (frequency) of each port can be configured separately. Bad things, precision is definitely not something you can rely on, lower duty cycles higher frequencies are quite impossible and USB communication interrupts the modulation so more jitter for free. But still many applications can forgive and live with the jitter like controlling brightness of LEDs or speed of a fan etc... And this service is made exactly to meet all sorts of dirty analog output needs.

I implemented a tight software PWM loop abusing a timer on PIC16f1455 that is controlled from Rest IO Server. Again some limitations there but quite good results.

So here are 2 service calls to give you an idea of how flexible and easy it is.

  1. http://restioServer:8080/0/softPWM/c0/5000/10000
  2. http://restioServer:8080/0/softPWM/c1/200/2000

Service call as usual starts with device id and command being softPWM in the above calls followed by port. Next 2 values first one is duty length in microseconds, second one period length in microseconds. First call will output PWM at 100Hz with 50% duty cycle from port c0 and second call will start another PWM from port c1 at 500Hz with 10% duty cycle and both will live nicely together. At these frequencies jitter amount will also be quite ignorable and signal will also be surprisingly precise even if you start all 7 ports at the same time. Of course you need to be easy on the other services as USB communication is priority and will block the PWM loop.

The frequency can go up to 5Khz with 50 microseconds of duty length as minimum. I will add more images from scope and results of the tests I did with a bunch of leds and servos.

Different software PWM signals' phases are completely arbitrary based on when they have started. Voltages on channels are not 5V and differ as they have different debug LEDs attached.

Pulse Shot

This service provides a guaranteed length pulse from any digital output port. It blocks until complete, meaning it will block other service requests and software PWM. I came up with this as an alternative to software PWM mainly for servo control as many servo motors only bother about the length of the high signal and they can wait 20 milliseconds for the next signal to arrive. Guess this can be used for servo like communication with other devices. But like it's name it can only guarantee a single pulse for the given duration in microseconds which can go as long as 65536 μs. Consecutive calls to service will definitely result in high pulses for exactly given time but time between them is a complete matter of luck depending on many things like network, usb etc...

Here's a rest call for single pulse shot


which causes port c3 to get high and and stay high exactly 1500 μs.

Still testing a few things, cleaning up software both server and the demo control client web but mostly it's done. Also a new revision of RestIO board is on its way, not necessarily for these services but next version of RestIO will be slightly better hardware and PWM capable software.