DevOps Zone is brought to you in partnership with:

Erich is Professor at Lucerne University of Applied Sciences and Arts and Distinguished Member of Technical Staff at Freescale Semiconductor. Erich has a MsCS degree and 18+ years of experience in the embedded software and tools world. He created many embedded cross C/C++ compilers and debuggers. Additionally he is researching in the domain of programming languages, real time and mechatronic systems. Erich is a DZone MVB and is not an employee of DZone and has posted 98 posts at DZone. You can read more from them at their website. View Full User Profile

PWM and Shell for a LED

01.03.2013
| 2677 views |
  • submit to reddit

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 InterfaceEach LED is ‘addressable’ by it’s component name. To turn the red LED on my Freedom Board on, I use

LEDR on

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 {
03 #if defined(LEDR_PARSE_COMMAND_ENABLED) && LEDR_PARSE_COMMAND_ENABLED
04 LEDR_ParseCommand,
05 #endif
06 #if defined(LEDG_PARSE_COMMAND_ENABLED) && LEDG_PARSE_COMMAND_ENABLED
07 LEDG_ParseCommand,
08 #endif
09 #if defined(LEDB_PARSE_COMMAND_ENABLED) && LEDB_PARSE_COMMAND_ENABLED
10 LEDB_ParseCommand,
11 #endif
12 #if defined(LED_SD_Green_PARSE_COMMAND_ENABLED) && LED_SD_Green_PARSE_COMMAND_ENABLED
13 LED_SD_Green_ParseCommand,
14 #endif
15 #if defined(LED_SD_Red_PARSE_COMMAND_ENABLED) && LED_SD_Red_PARSE_COMMAND_ENABLED
16 LED_SD_Red_ParseCommand,
17 #endif
18 SHELL_ParseCommand
19 };
20
21 static uint8_t ParseCommand(const unsigned char *cmd, bool *handled, constFSSH1_StdIOType *io) {
22 int i;
23
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 :-)

Published at DZone with permission of Erich Styger, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)