PIC Domotic station

I use this Microchip’s PIC program made in C to control my domotic system for quite some time now, and I think it’s ready to be published.

Below is the readme file, to read the last version, directly go to :


PIC Domotic station


PIC program for a domotic station controlling two temperature sensors, multiple relay, a USB port (for power only) and connected to a PC using UART to receive its instructions.

It uses a PIC18F23K20 but should work on most of them. The PC sends simple commandes through /dev/ttyUSB0 like “A 32” to enable the device 32, or “E 32” to disable it. “T” to get temperature, … See the source code in main.c.

This is MPLAB X IDE project. The only usefull file is in fact main.c, the rest is auto-generated, but I include them if someone would want to directly program the binaries, for example.

Technology used

If you’re looking for sample code, you may find here how to :

  • Use the UART to communicate with a PC (UART is connected to a “uart usb” module very cheaped that you can find on ebay for example) .
  • Use the watchdog timer to ensure a device reset if something goes wrong
  • Use Brown-out to jump to do an interrupt and do “something” (blink in my case) if the voltage goes below some threshold
  • Use the ADC to read the temperature given by two LM35
  • Read/write to eeprom
  • Control a 5V relay board with a 3.3V relay board using NPN Transistors (when I’ll add the schematic though)

The python script used to manage the PIC controller is available athttps://github.com/tbarbette/monitoring/blob/master/scripts/relay.py and a small HTTP server allowing you to remotely control it is available athttps://github.com/tbarbette/monitoring/blob/master/scripts/server.py

Read and write PIC EEPROM

More a little post-it than a post, I wanted to put somewhere the commands :

Using the eeprom is as simple as these two commands :


A little example (reading from the USART a value and putting it in the EEPROM address 0x00)

while (!DataRdyUSART());
char data = ReadUSART();

Note that theses header are defined in the standard xc8 header which will include (or , …) or High Tech C headers if you come from the past :

// MACROS for EEPROM Access
/* macro versions of EEPROM read and write */

EEPROM_READ() is NOT safe to use immediately after any
write to EEPROM, as it does NOT wait for WR to clear. This is by
design, to allow minimal code size if a sequence of reads is
desired. To guarantee uncorrupted writes insert
before calling EEPROM_READ().

#if _EEPROMSIZE > 0 && defined(_PLIB)
#define EEPROM_READ(addr) Read_b_eep(addr)
#define eeprom_read(addr) Read_b_eep(addr)
#define EEPROM_READ(addr) 0 // Added only for code portability
#define eeprom_read(addr) 0

#if _EEPROMSIZE > 0 && defined(_PLIB)
#define EEPROM_WRITE(addr, value) (Busy_eep(), Write_b_eep(addr,value))
#define eeprom_write(addr, value) (Busy_eep(), Write_b_eep(addr,value))
#define EEPROM_WRITE(addr, value) // Added only for code portability
#define eeprom_write(addr, value)