Radio Controlled Timer, Step G


Adding buttons to manually switch lamp on/off, connected to the remote transmitter

The buttons don’t need any debouching as the remote transmitter already must be handling this. The MCU just lets this signal through. As the “transmit” part of the program will be used both with buttons and “schedule” this is in a separate source file, “transmitter_1829_RadioControlledTimer.asm”.

Button functions included in “buttons_1829_RadioControlledTimer.asm”.

To verify buttons-transmitter functionality the transmitter, and the receiver, are used. As this does not require any unit test, just manually pushing the button.

main_R1829_RadioControlledTimer.asm” was modified with the scanning code.

The program built with “Final” configuration to manually test.

Code on Github


Radio Controlled Timer, Step F


To determine if a time is matched. The current time in the RTC is compared to

  • the sunrise/sunset (per month)
  • the good morning /good night (for daylight saving or not)

If a match is found the function returns one of these events.


If no match found NOTHING is returned.

Source file “OnOff_1829_RadioControlledTimer” (.inc and .asm) created. (OK it is not the best name for the source file but …)

The definition of the events (GOOD_MORNING, …) are defined in the “OnOff_…inc file.

These definitions are also used in the “OnOff_…asm” file and I don’t want to duplicate the definitions.

To be able to include the “OnOff_…inc” file in the “OnOff_…asm” file the extern definition of “OnOff_Check” has to be excluded when include in the .asm file.

(Otherwise the assembler will see both

  • extern  OnOffCheck
  • global OnOffCheck

end get very confused.)

A “INCLUDED_IN_ASM” definition and an ifndef solves this.

To verify this, a unit test “OnOff_unittest_1829_RadioControlledTimer” (.inc and .asm) is used.

No schema change.

Code on Github.

Radio Controlled Timer, Step E

  • Set up a table for sunrise/sunset per month
  • Set up good morning/good night.
  • Save/read from 1829 EEPROM

For every month set up a table with sunrise / sunset.

Use good morning at 06:00 and good night at 23:00 for all months.

A day in Jan

  • 06:00 turn on (Good morning)
  • 09:16 turn off (Sunrise)
  • 15:04 turn on (Sunset)
  • 23:00 turn off (Good night)

09:16 and 15:04 = sunrise / sunset 15 Jan where I live.

And in June with sunrise at 02:51 and sunset in 23:51, always off.

One problem with good morning / good night is daylight saving. As the RTC will run on non-daylight-saving time all year the 06:00 an 23:00 has to be adjusted one hour during daylight-saving months.

A table for this is also needed.

All these times (sunrise / sunset / good morning, good night) will be possible to change from a PC program communicating with the 1829 via UART in a later part. But initial values defined in the source code as EEPROM data.

Unit testing of EEPROM requires 2 memory buffers for EEPROM data.

  • A save area for EEPROM during unit testing as EEPROM unit testing writes to EEPROM and “destroys” the data from the source code. After EEPROM unit tests this has to be restored as future unit tests may depend on the data in the source files.
  • A buffer for writing/reading of unit test data. This buffer specific for unit tests.

One buffer = 63 bytes so two buffers cant’t be fit in a 80 byte RAM page. Two RAM pages needed.

Also some restructuring of unit test code.

No change in schema from step D.

Code on Github

Radio Controlled Timer, Step D

  • Setting and reading date/time in the RTC (Real Time Clock) DS1302.
  • Using a super cap for DS1302 backup

No need to read individual bytes in the RTC, only burst mode needed.

Reading the DS1302 datasheet, the minimum clock low or high time is 1 µs. As the 1829 runs at 4MHz, the minimum instruction execution time is 1 µs. No need for delays in program, except for the CE signal requiring a 4µs delay before and after clocking data.

As functions in other source files will read/write the RTC registers a common definition of the RTC clock registers are needed. Created “” file.

“RTC_1829_RadioControlledTimer.asm” (and “.inc”) implements the burst read/write functions.


Previously parts where simple to test.

A. If MPLAB X signalled “Running”
B. LED light
C. Character received in Realterm

But this part needs some sort of unit tests and these tests should not be included in the final application.

(OK, integration test may be more adequate term to use, but I’ll stick to the term unit test for all automatic tests.)

Used the MPLAB X possibility to use different configurations

Renamed the default configuration to “Final” and created “Unit_testing” by duplicating “Final” configuration.

Final : no change, the same as default

Unit_testing : defined the Preprocessor macro “UNIT_TEST” for mpasm.

Now there are 2 configurations to select between.

And in the source code an “ifdef UNIT_TEST” or “ifndef UNIT_TEST” directive can be used to select different code blocks.

To start the unit tests another main program is needed. Ok it is possible to use the “main_1829_RadioControlledTimer.asm” file with ifdef’s but the unit test will clobber up this file.

Better to use a separate main file for unit tests.

Created a new .asm file “main_unittest_1829_RadioControlledTimer.asm”.

In MPLAB X there is a possible to exclude some files for a configuration. So the Final configuration excludes “main_unittest_1829_RadioControlledTimer.asm” and the Unit_testing configuration excludes the “main_1829_RadioControlledTimer.asm


Assuming there will be a need for more unit tests later on, created an .asm  file containing only the unit test for the RTC module, “RTC_unitest_1829_RadioControlledTimer.asm” and a corresponding .inc file.

Some other files also added to make the structure easier to follow.

  • main_unittest_1829_RadioControlledTimer.asm” contains a routine that unittests jumps to if any error detected. An “.inc“file added.
  • Unit testing uses some common routines/macros, added “UnitTest_common_1829_RadioControlledTimer.asm” and its “.inc” file.

This is what the project file structure looks like now when Final configuration selected. The excluded files showN as “grey”.

To be able to see the result from the unit tests, output to UART where include and the LED’s was also used.

When starting RTC unit tests “RTC” is written to the UART. As every (ok only 1 yet) unit test is assigned a number this number is printed to the UART after success.

If all unit tests pass, the green LED is lit.

If any test fails the red LED is lit. And with the help of the UART printout the failing test can be pinpointed.

When you run the tests for a number of times the RealTerm screen becomes a bit messy to read. But RealTerm can emulate an ANSI terminal and it is possible to “clear screen” by sending a specific character sequence, beginning with an Escape character (ESC). Every time the unit testing starts a “clear screen” sequence is sent. (Sorry, if you use the Arduino serial monitor you will get a number of junk characters, as this monitor don’t understand ANSI character sequences.)

The supercap charging can be observed, after power has been applied some time, by disconnecting programmer and any battery/power. Wait some minute and measure the supercap voltage. It should be above 2V.


Code on Github

EDIT: 2018-10-15
  • Of course, 1829 ICSPDAT and ICSPCLK = pin 19 and pin 18
  • Green LED still connected to RC3, pin 7
  • 1302 CE = pin 5, SCLK = pin 7

Schema changed!

Radio Controlled Timer, Step C

  • Send characters to a PC using the 1829 UART

Only transmit, receive will be done later. Sending to PC will help in testing the RTC 1302 added in next step.

Added a 10nF decoupling capacitor to the 1829 as we are using a higher clock frequency.

TX pin changed from default pin RB7 to alternate pin RC4.

A 1k resistor in series with TX prevents any problems with shorts when inserting/removing the 3,5mm plug.

A simple “FTDI”, converts from 3V serial to USB, is used. In this case a Microchip MCP2221 break out box.

Using a terminal program on the PC. I used Realterm.

Communication uses 9600, 8, N, 1.

If you have an Arduino (with serial communication, like Uno) you can use it instead of the MCP2221 break out box. Just make sure you have a sketch downloaded to the Arduino that don’t use the serial communication. The Arduino serial monitor can be used instead of Realterm.

Checking the 1829 datasheet and baud rate tables shows that the 512kHz default clock is way to slow so this has to be changed to at least 4MHz.

Created a subroutine to set clock speed in main and modified the Delay_1s routine to use 3 counters instead.

UART functions in separate .asm and .inc files

Code on Github

Note: When you reprogam the StepC code a number of “SA” appears in terminal with no delay of 1s. This is known Microchip tools behaviour. MPLAB X / Curiosity resets the 1829 a number of times before the programming is done. During these resets 1829  manages to send “SA” before next reset.

EDIT: 2018-10-15
  • Of course, 1829 ICSPDAT and ICSPCLK = pin 19 and pin 18
  • Green LED still connected to RC3, pin 7

Schema changed!

Radio Controlled Timer, Step B

  • Add LEDs for debugging
  • Split source into  several source files

The 1829 configuration moved to a separate file “”

As there will be more .asm files added later, common parts moved to a separate file. As of Step A only the line #include “”.

Added file and moved the include directive here

Also added radix dec to the file. Dec (decimal) is more natural to use than hex (hexadecimal), if a hex number is needed, I will use the H’xx’ notion. And the errorlevel -302 as MPASM throws a lot of messages about banking when using SFR registers.


LED’s can be very helpful when debugging. Adding a RGB led will give, at least, 3 colors to use.

But now a pin usage list has to be created.

For every LED pin there will be 3 registers involved

  • ANSELx to select analogue/digital
  • TRISx to select input/output
  • LATx for output state

This means four definitions for every LED. It may seem a lot of definitions for just one LED but in the long run it simplifies a lot. Much easier to remember and if a LED has to be moved to another pin, only a few changes in one place needed.

LED handling created in a separate .asm file and a corresponding .inc file.

To verify LED handling a Delay routine added to main. The delay counters placed in common RAM.

From the logic analyser.

Code on Github

EDIT: 2018-10-15

Of course, 1829 ICSPDAT and ICSPCLK = pin 19 and pin 18

Schema changed!


A PIC 16F1829 Radio Controlled Timer


In this series I will build a remote-controlled timer using a PIC16F1829. The remote-controlled timer will be built in a series of steps, A, B, C, …

A simple prototype board used to build and program the remote-switch.

Source code can be found at Github.

1) The problem

In our house we have a number of timers controlling lamps.

Turned on in the morning, off during daytime, on in the evening and then off during the night.

But as the sunrise-sunset in the winter (mid Dec) is 09:30 – 14:15 and in the summer (mid Jun) 01:50 – 22:10 the timers have to be adjusted frequently. Perhaps once a month.

2)  The idea

Use a remote switch set.

And use a PIC microcontroller to handle the remote transmitter.

3) Inside the remote transmitter.

Powered by a 3V battery.

Easy to replace the keys with cables to the PIC controller board I have to build. Using only the A on/off switches.

And in the same time replace the Lithium battery with 2 AA cells.

4) General design decisions


How to make PIC to simulate the switch, assuming there is some sort of scanning used in the remote transmitter? Why not use a switch controlled by the PIC? A CD4066 should be fine.

A quick test with a CD4066 showed it worked fine with one of the four switches in a CD4066. But as the CD4066 contains 4 switches I used 2 switches in parallel (2 for A on and 2 for A off) to make sure it will work even with another batch of CD4066/remote transmitter.

Setting time

How to set time. I don’t want to have some display/buttons to set time. The solution is to have a UART/”RS232” interface to a PC and set time that way. This also gives the possibility to change the on/off time.


Yes, I can attach a 32kHz crystal to the Timer1 in the PIC and once initialized from the PC the PIC can handle time.

But the use case to “Change battery” created a bit of problems. The PIC will restart and the time has to be reinitialized from a PC. Not very user friendly.

And then there is leap years. Implement a leap year algorithm in the PIC? No, do not want to do that.

The solution to time was to use a RTC chip. The DS1302 handled both problems (change battery and leap years). The DS1302 interface is not I2C (compared to DS1307) but the possibility to use a backup supercap for the DS1302 made the DS1302 a “better” choice.


Many PIC’s have a built in UART and with the Microchip MCP2221, or other solutions, it is easy to interface with a PC using USB/UART.


Any modern 8-bit PIC can be used but as I have used the PIC16F1829 family before, I selected PIC16F1829. I also have the AC244063 Emulation Extension Pak if needed.

The PIC16F1829 family is nice from a debugging point of view as it has 3 built in breakpoints without using the AC244063. But if I really get into software troubleshooting the AC244063 combined with my REAL ICE is a great help.


No need for any fancy tool. All right, I have access to a Real ICE and an emulator extension pack, AC244063, but it is only “nice to have”. So in this project, I used a Curiosity board! A simple homemade adapter makes the Curiosity an excellent programming/debugging tool. Cheap (US $20) and supported by Microchip MPLAB X.

(And the Curiosity also can provide the necessary 3.3 volt for the board I have to build.)

Debugging visualization

A number of LED’s controlled by the PIC can help a lot in debugging. A RGB LED was included in the design.

On/Off time

Adjusting the on/off time once a month is enough. The PC can initialize the time for every month.

A simple Windows application can be used to select on/off time for every month and then send it to the PIC with current date/time.

Daylight saving

Why should the PIC handle this? Run the PIC on winter time all year around. The PC program can easily handle daylight saving from the user perspective and convert it to winter time for the PIC.

Saving battery life

Keep the PIC in sleep mode as much as possible is a simple rule.

Putting the 1829 in sleep most of the time, how to wake it up when needed?

The only reasonable alternatives are

  • WDT (watch dog timer)
  • IOC (interrupt on change) on some pins.

As not all 1829 pins are capable of IOC so care must be taken to use IOC capable pins for those inputs that needs to wake up the 1829.

The pin RA4 can output the MCU clock (Fosc/4). This can be handy in debugging to see when the 1829 goes to sleep and wakes up. (No clock output during sleep, easy to debug with a simple oscilloscope, if needed.)


MPLAB X is the natural choice. Free and supported by Microchip. Used version 4.20.

Language: MPASM. (Yes I know, using C it is easy to “shoot oneself in the foot”, but using assembler you do it all the time.) But to really get to know a CPU/MCU, assembler is the only way. Used version 5.77 included in MPLAB x 4.20.

Programmer/Debugger: Microchip Cuirosity board (DM164137)