Over a million developers have joined DZone.

PWM and Shell for a LED

DZone's Guide to

PWM and Shell for a LED

· DevOps Zone
Free Resource

Download the blueprint that can take a company of any maturity level all the way up to enterprise-scale continuous delivery using a combination of Automic Release Automation, Automic’s 20+ years of business automation experience, and the proven tools and practices the company is already leveraging.

Controlling a LED is a great starter for any embedded project: simple and you immediately get feedback if it works :-) . Even better: as driving a LED is not different from working with another digital I/O or controlling a solenoid, the ‘LED’ concept and driver is very universal. I recently have simplified my Processor Expert LED component, so it might be a good time to add some more functionality again ;-) . Let’s add support for PWM, and adding a shell interface on top of it. That way the LED is dimmable, plus I can do everything with a command interface as well:

LED Properties

LED Properties

The LED (or the underlying microprocessor pin) is used either in ‘On/Off’ or ‘PWM’ mode. In On/Off mode I can drive the pin either high or low (normal digital I/O). In PWM mode I use a Pulse Width Modulation (PWM) signal, effectively dimming the LED. An optional Shell interface offers to control the pin using a shell/command line interface (more about this later).

LED Methods

Two new methods have been added: ParseCommand() and SetRatio16(). The first one is used as command line parser, and the second one is to set the duty cycle of the PWM signal.

Shell Command Line Interface

Using a command line interface is something I usually add to all my projects: it is upfront a bit more work, but makes things easier later on. Inspecting the state of the system? yes! Turning a relais on or off? A simple text command will do it! Running automated tests? Sure, just run a batch script!

In the Freedom Shell Project, I have now PWM and the Shell interface enabled:

Freedom Shell Project with LED Command Line Interface
Each LED is ‘addressable’ by it’s component name. To turn the red LED on my  Freedom Board on, I use


The ‘off’ command turns it off again:

LEDR off

To toggle a LED, the ‘neg’ command is used:

LEDR neg

:idea: What is behind the pin does not matter. It can drive anything, even a valve or a DC motor driver :-) .

To change the PWM duty cylce (to dimm a LED), the ‘duty’ command is used. It is using a decimal value between 0 and 0xffff (16bit unsigned).

LEDR duty 0

Sets the pwm duty value to 0, which means the LED is off. And

LEDR duty 0xffff

sets it to the largest value (full duty cycle).

Alternatively, a percent value between 0% and 100% is possible:

LEDR duty 50%

The ‘status’ command tells me details about the current values:

LED status

LED status

Integrating with the FSShell component is simple: I usually use an array of function pointers:

01 static FSSH1_ParseCommandCallback ShellParsers[] =
02 {
04 LEDR_ParseCommand,
05 #endif
07 LEDG_ParseCommand,
08 #endif
10 LEDB_ParseCommand,
11 #endif
13 LED_SD_Green_ParseCommand,
14 #endif
16 LED_SD_Red_ParseCommand,
17 #endif
18 SHELL_ParseCommand
19 };
21 static uint8_t ParseCommand(const unsigned char *cmd, bool *handled, constFSSH1_StdIOType *io) {
22 int i;
24 /* iterate through all parser functions in table */
25 for(i=0;i
26 if (ShellParsers[i](cmd, handled, io)!=ERR_OK) {
27 return ERR_FAILED;
28 }
29 }
30 return ERR_OK;
31 }

:idea: The LED component defines a macro<NAME>_PARSE_COMMAND_ENABLED which can be tested if command line support is present or not.

Example Usage

The Freedom Shell Example project has now PWM and shell support enabled. The PWMsubcomponent automatically creates a PWM_LDD component which is using aTimerUnit_LDD:

PWM Example

PWM Example

Note: because the Kinetis-L TimerUnit only has two channels, there is one TimerUnit_LDD (TU1) for the red and green LED, and another one (TU3) for the blue LED.

Note2: Because the TimerUnit_LDD is referenced from two components, Processor Expert is given warnings like “Warning: Referenced TimerUnit “TU1″ contains another channel that is not used by “Inhr1″. This channel(s) will be affected by component “Inhr1″.” In my view this is a problem of Processor Expert, and I have not found a way to get that warning fixed?

The example project is available here. The updated LED component is available here.

Happy Dimming :-)

Download the ‘Practical Blueprint to Continuous Delivery’ to learn how Automic Release Automation can help you begin or continue your company’s digital transformation.


Published at DZone with permission of Erich Styger, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}