PIC LED Controller – Stage 2

After completing stage 1 and reviewing it with my friends I decided that it needs the following changes and additions – hence stage 2:

  • Manage 4 LEDs and not only two as in the code of stage 1
  • Allow the app to change the state of each LED to OFF, ON or BLINKING while the app is running. This is a fundamental feature for the full LED controller because the user will be changing the state of the LEDs by the remote control.
  • Allow the app to set the intensity of each LED
  • Change the  LED Controller API functions to start with LC in order to avoid namespace collisions with the client app (although I realise that this is for a tiny PIC and not a desktop).

In short, I wanted my application code (main.c) to look like this:


The file starts with the regular setting of the configuration words and then defines an array of “state” structures:


struct {
  LEDState state;
  short blinkCount;
  short intensity;
} states[] = {
  {LEDON, 0, 10},
  {LEDBLINKING, 1, 5},
  {LEDBLINKING, 3, 15},
  {LEDOFF, 0, 15},
  {LEDON, 0, 15},
  {LEDBLINKING, 4, 10}


Each state consists of an action – Off, On or Blinking. If the state is “blinking” then the second member is the number of blinks and the third member is intensity – a number between 1 and 15 where 15 is brightest and 1 is the least bright.

The array contains six different states and LED 1 (the rightmost LED will cycle through these states.

The main function itself sets up LEDConfig structs, sets the initial states for each LED (note that LED 2 – the second from right) is OFF throughout and enters the main loop. In the main loop LED 2 will remain off. LEDs 3, and 4 will blink at a fixed rate and LED 1 will move through the states above.

This is how it looks like:

The header file now contains some #ifdefs that allow it to compile and run on an iOS device (more about that later). The LEDConfig structure was changed from stage 1 and the functions are prefixed with LC.

Here is the header file.


The LED controller C file is here:


A word on the (free) XC8 compiler

 It seems that the free XC8 compiler is extremely inefficient in transforming the C code to assembly. I noticed that dereferencing a member in a struct requires countless assembly commands. For example, the command (from main.c):

946 ;main.c: 56: short b = states[index].blinkCount;

maps to the following assembly code:

947   02F3   3005   movlw 5
948   02F4   00A2   movwf ??_set_state
949   02F5   0822   movf ??_set_state,w
950   02F6   00F1   movwf ___bmul@multiplicand
951   02F7   0820   movf set_state@index,w
952   02F8   23D5   fcall ___bmul
953   02F9   3E01   addlw 1
954   02FA   3EA0   addlw _states& (0+255)
955   02FB   0086   movwf 6
956   02FC   0187   clrf 7
957   02FD   3F40   moviw [0]fsr1
958   02FE   0020   movlb 0 ; select bank0
959   02FF   00A4   movwf set_state@b
960   0300   3F41   moviw [1]fsr1
961   0301   00A5   movwf set_state@b+1

When the compiler finishes it gives me the following statistics:

Memory Summary:
Program space used      3FEh ( 1022) of 800h words ( 49.9%)
Data space used         7Eh  ( 126) of 80h bytes ( 98.4%)
EEPROM space used       0h   ( 0) of 100h bytes ( 0.0%)
Data stack space used   0h   ( 0) of 1h byte ( 0.0%)
Configuration bits used 2h   ( 2) of 2h words (100.0%)
ID Location space used  0h   ( 0) of 4h bytes ( 0.0%)

This means that not much is left for the rest of my controller code on this chip. The compiler also says that if I’ll buy the PRO version it will shrink the code by 40% and I will save 408 words.

Other areas of inefficiency in my code are the modulo-6 operation (index = (index + 1) % 6) and all the function calls that are an inherent part of the “pseudo object oriented programming” that I use here

Despite of all this inefficiency, I think it is worth writing in C because it it much more readable (to most of us) and allows us to give the program some structure. I think it is possible to overcome the memory capacity problem in several ways:

  1. Use a larger chip – the price difference is probably negligible
  2. Write some parts of the code in efficient assembly (will take me ages)
  3. Buy the PRO version of XC8
  4. Buy another compiler for the PIC processor. I found one for $50.
  5. Check out the GPUTILS – Gnu PIC utilities – I’m going to do this right after I finish this post.

The next steps towards the final LED controller are:

  1. Add a potentiometer that will control the length of the blink of the LEDs
  2. Learn how to receive a PWM signal into the PIC
  3. Revisit the product requirements and modify (I have some ideas for modifications already)
  4. Write a good specification of the init and initial configuration stage. This is not simple as it sounds.
  5. Implement the init and configuration stage
  6. Define the states and update the main function
  7. Test on the breadboard with regular LEDs – add the transistors to the circuit for driving the LEDs
  8. Build the real circuit with the high-power LEDs that I ordered
  9. Build a few more kits and try to sell them

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s