Menu
Index

Contact
Atom Feed
Comments Atom Feed

Similar Articles

2013-12-21 21:16
PICing up 433MHz Signals for OSS Home Automation - Part 2
2014-06-21 22:10
PICing up 433MHz Signals for OSS Home Automation - Part 8
2014-07-21 18:37
PICing up 433MHz Signals for OSS Home Automation - Part 9
2014-02-16 13:12
PICing up 433MHz Signals for OSS Home Automation - Part 5
2014-04-19 09:42
PICing up 433MHz Signals for OSS Home Automation - Part 6

Recent Articles

2019-07-28 16:35
git http with Nginx via Flask wsgi application (git4nginx)
2018-05-15 16:48
Raspberry Pi Camera, IR Lights and more
2017-04-23 14:21
Raspberry Pi SD Card Test
2017-04-07 10:54
DNS Firewall (blackhole malicious, like Pi-hole) with bind9
2017-03-28 13:07
Kubernetes to learn Part 4

Glen Pitt-Pladdy :: Blog

PICing up 433MHz Signals for OSS Home Automation - Part 1

With working out common 433MHz protocols for cheap home automation devices, I've turned to working out a way to interface with these devices. The fundamental thing is to create a piece of hardware universal enough to be able to offload all RX and TX tasks to, however avoiding doing any protocol decodes as these are likely to be where a lot of extension and development is likely to happen - that's better left to userspace code running on the host system.

Hardware

After a bit of investigation I decided that either I would need a networkable device with some GPIO, or a peripheral device (USB or perhaps even serial/RS-232) which could be used as the go-between with the 433MHz RF modules I already have.

433MHz RX and TX Modules

Initially I started looking at PIC devices which can do both serial and USB (or even a serial class USB device to make things really easy!). The thing that got me was the cost of programmers makes them prohibitive for this project.

On the other hand a Raspberry Pi has GPIO, runs Linux and can be programmed.... well on the device it's self or by shoving the SD card into a reader on another machine. The problem I hit here is that because it's a preemptive multitasking OS (Linux) and there is very limited support for hardware assisted receiving (ie. using the timer module to time GPIO pin changes) it looks like it would need kernel hacking to make it a viable choice. Transmission looks easy though - there's already hardware assisted pulse generation and Python (yay!) classes for that.

Stumped, I looked around some more and stumbled onto this: USB-GPIO12 Module

USB-GPIO12 PIC18F14K50 Module

It's a tiny module based on a PIC18F14K50 and ships with the PIC USBHID bootloader (which means the application can be programmed over USB with no additional kit needed). USB connection is already there as well as a bunch of GPIO and a couple LEDs - everything needed almost completely ready-to-go! I got one on eBay shipped and everything for £16.21

Firmware... initial experiments

Tools

It's many years since I hacked PIC code... and then I was an assembler freak. These days it's all C and the USB stack supplied is all C as well. The big surprise was when I went to download tools, they have toolchains for Windows, Linux and Mac! Cool or what?! Even a set of free C compilers. That saved me the effort of rustling up a Windows VM.

Code

Devantech (aka robot-electronics.co.uk) provide a bundle of examples for this module, the one I'm interested in is the Serial Echo project which appears to be derived from Microchip example code. This is likely a good starting point for me to learn about using this device/module for my application. First problem I hit is that this code (including Microchip examples which are actually much more up to date) is old and intended to be used on the deprecated C18 compiler. The new XC8 compiler doesn't like them... but more about that in a moment.

After some major surgery, I removed all the superfluous files (for other devices) and cleared major redundant #ifdef sections for other devices so again getting down to just what is needed for this module.

It still doesn't compile with the XC8 compiler at this point... or more specifically, the compiler gives a bunch of warnings and the linker can't make the memory fit. There are a bunch of compiler warnings for #pragma statements which presumably only mean something to the C18 compiler. Almost all the errors seem to actually relate to the USB stack libraries. Ouch!

Making it work

After a bit of searching around I came to some Microchip forum posts about these problems.... if only their site didn't start every morning saying "Service Unavailable"

The real answers came from the thread and the solution presented by "jtemples" in the Microchip forums about Building USB stack projects with XC8 compiler.

Essentially it comes down to FAR not working with XC8 and a bit of extra config being needed to make sure all the critical parts of the USB stack end up in the right memory (a special dual-port bank so the USB hardware can share it with the CPU). Most the existing USB stack (espcially .h files) work just fine with a bit of grumpiness about #pragma statements which don't break the build.

My reference project on the USB-GPIO12 is the "ComPortEcho" project available for this module. My dev machine is a Linux Mint VM running the Linux set of tools. I've created a complete MPLAB.X project ready to go which references Microchip Libraries installed below /opt/microchip/LibrariesForApplications/ with all modified libraries in the project under MicrochipUSB-Tweaked/ to keep them separate. You will need to fix up the project according to your install paths.

The key thing is the compiler include paths which need to be the project directory, the modified Libraries and then the shipped libraries in that order so that the modified files take precedence over shipped files.

The other setup thing is the linker which needs the Codeoffset set to 0x1000 for the USBHID Bootloader, Config bits disabling and Hex generation enabling. All this is in the project. This is essentially the downloadable examples from Devantech updated with current Microchip PIC Libraries for the XC8 Compiler.

Download: XC8 Compatible USB-GPIO12 ComPortEcho Project

Interface Spec

Before starting work on the real protocol decode/encode, it's worth doing a bit of planning. Yup... you may not be allowed the time to do this in the commercial world, but my free time is too valuable to waste it with poor planning.

I want a minimal binary (yes, you read right - I need the data to be tight for as well as avoid converting back and forward to binary again in the host code) interface which can handle all (hopefully!) eventual packets that may need to be transmitted or received irrespective of the particular encoding. The aim is to allow easily extendible code on the host to handle (or record) any formats it sees via plugins (or similar) and not have to mess with firmware unnecessarily. I would also like a few refinements like the option to power manage the RF modules (ie. switch them on and off as needed).

TX

Transmit is the easy bit - we define a sequence of time and state and (4 sections should easily do... everything I've seen so far would only need 2) for each of 0-bit / 1-bit, and then we fill a buffer and tell it how many bits to transmit from that buffer. Simple! The only risk here is sufficient space in the tiny memory for the buffer.

The other consideration is that it's probably going to be best to shut down the TX module when not in use, and potentially we may want to shut down the RX module when the TX module is in use. That requires some power controls as well.

RX

This is a bit more tricky since we need to be able to describe anything we could receive in an asynchronous manner that could be then decoded by the host. The only practical thing would be a minimalist run length based approach: what state was found and how long it was in that state. What will also be needed is a timeout when an excessively long period is found since we can't really have an infinite counter to measure the times.

Hardware Configuration

PIC microcontrollers have a lot of configurable hardware assistance like Interrupt-on-Change on ports, multiple timers and much more. These can drastically reduce the work done in firmware as well as improve accuracy (eg. timers would still be keeping time while ISRs are running).

Power Control

This is ordinary low-speed (not that it matters) GPIO stuff. We just need to reserve one pin for controlling the power to each RF module. RC0 and RC1 have no special functions so are perfect for RX and TX power controls.

TX Data

We need an output to control modulation with the TX module. This is a bit more of a tricky consideration since there is potential for using hardware assistance. The reality though is that even with hardware assistance, an ISR is still going to have to work out the next state, load timers etc. and while it's at it might as well just set an ordinary GPIO pin, so RC2 it is then.

RX Data

This is far more tricky. This absolutely does need to generate interrupts and/or interact with hardware timers. The only Interrupt-on-Change capable pins that don't already have stuff on them is RB4-7. If the Capture&Compare Module (CCPM) was brought into play then there's a conflict with the CCP1 pin which has an LED on it. The CCPM also supports only rising or falling edge triggers which would mean it would need constant reconfiguration for each edge.

Short of starting to chop tracks on the USB-GPIO12 the only practical approach is to rely on a PortB pin. The one with peripherals on it I'm least likely to want to use in the future is RB7.

Next... (planning again!)

At this point I'm ready to start coding. Since to test I will need to be able to shuffle data back to the host from the RX module, the sensible place to start would seem to be the RX aspects of Host Interfacing followed by the RX decoding.

Then a similar approach can be taken for the TX chain, however before that it's probably worth implementing the control (eg. module power) aspects of the Host Interfacing.

Comments:




Note: Identity details will be stored in a cookie. Posts may not appear immediately