One of the problems that had to be solved for the J-Box was how to design the frequency counter and RF detector. As RF is harvested (see earlier posts on RF Harvesting 1 2 3 4), a small portion is used to wake up the MCU and cause it to become a frequency counter. We need to know the RF transmit frequency in order to make the proper auto-tuning decision at each J-Box; i.e., whether to switch each antenna node’s RF Relay to open vs. closed, based upon the J-Box’s position within the overall antenna.
I wanted to minimize the number of additional components involved for the frequency counter, and leverage the power of the MCU to calculate the frequency. So I decided to prescale the incoming RF signal from Mhz to Khz, to make it easier (less time-consuming) for the MCU to handle this job. In this post, I will describe how the prescaler works, along with its software and programming.
The RF Prescaler Circuit
Let’s begin with the J-Box schematic to understand the overall flow. You can find the full J-Box schematic here.
RF flows through C1 and a portion across C7 to D7. D7 allows the positive swing voltages to pass, while blocking voltages near and below zero, so U5, the Schmitt trigger only receives a positive signal. D8 clamps the positive swing to 5 volts, to prevent overrunning the TTL logic maximum input voltage ratings. U5 detects each positive swing and converts from a half sine wave into a square wave output. The square wave flows into pin 2 of the PIC12F675 microcontroller – its “clock” pin.
This conditioned clock signal, which can be up to 54 Mhz for 6 meter operation, is what drives the PIC microcontroller, which operates as a divide-by-1000 prescaler. The assembly program loaded into the PIC generates one output transition for each 1,000 input transitions, through the use of an exact set of delay loops that consume 1,000 instructions each. It’s a brilliant way to implement a frequency counter, created by the folks at LeapSecond.com, who are (apparently) preoccupied with time and timing.
The PIC12F675 microcontroller is an amazingly powerful little device, with only 8 physical pins, 2 of which are for power and ground. As is common with microcontrollers these days, the 6 I/O pins are heavily multiplexed and can serve different purposes depending upon how the mux mapping is configured. To learn more about this powerful, inexpensive device, check out the datasheet. During normal operation, with full transmit RF power flowing through it, I measured power usage at around 485 microamps (less than half a milliamp), so this low power counter is well-matched to our needs.
So why use a microcontroller to divide by 1,000, when there are chips available to do that? In a word, lower cost. The chips required to divide by 1,000 that can operate in the targeted Mhz frequency range are actually quite a bit more expensive than the PIC ($4 to $6 or more each, often requiring two of them to divide by 1,000 as each one only divides by 100 maximum). By contrast, this PIC 8-bit microcontroller is under a dollar in small quantities. I have found them as cheap as 49 cents on EBay. Additionally, what if it’s determined that interrupting the MCU tens of thousands of times per second level is taking too much power or isn’t accurate enough? By using the PIC and its flexibility, it’s a simple matter of using different software and no hardware changes are required to optimize things further.
Besides, this is a software-defined resonant antenna, so it’s more fun to learn about and use the microcontroller to do this job; however, it’s also more work to get it programmed.
Programming the PIC12F675 to divide by 1,000
In order to program the PIC microcontroller, we need the right tools. Here’s what I’m using. Incidentally, these tools can be used to develop for and program most MicroChip controllers.
- Microchip MPLAB IDE for development
- Microchip PICkit 2 programming software
- CanaKit USB PIC programmer
Each of these are show below, followed by the source code. The original source code came from LeapSecond’s “PICDIV” project. It has been slightly modified for our use (to minimize power usage by disabling the additional output ports on the PIC, which are not required in this use case).
Below we see the CanaKit USB PIC programmer, with a PIC12F675 microcontroller chip locked into the ZIF programming socket. This programmer was $50 at Amazon.
You can see the PIC device locked in the ZIF programming socket.
To program the PIC microcontroller via the CanaKit programmer device, it is plugged into a PC using a USB cable.
The PicKit 2 programming software takes a hex binary file, which is then downloaded into the PIC microcontroller, as shown below.
To create the hex file, we need a development environment and Assembler program (in this case, the PIC is being programmed in Assembly language – “C” tools are also available).
Above we see the MPLAB IDE, which contains a project file and associated source code files. All project and source files are available to download here.
Finally, here’s the source listing of the divide by 1,000 code, adapted from the original PICDIV source below. This code was originally developed and calibrated at 10 Mhz. I have tested it at up to 29.5 Mhz (10 meters), and it is more than accurate enough for our purposes here.
; PD03 — PIC “4-pin” 10^3 frequency divider (10 MHz to 10 kHz)
; Modified 4-8-2017 W5FCX disabled pins 3 and 6 (no longer used for output)
; This PIC program implements a digital frequency divider: the external
; input clock is divided by a factor of 1 thousand (1e3). For example,
; if the input clock is 10 MHz then the output clock will be 10 kHz.
; Diagram: ; ---__--- ; 5V (Vdd) +++++ |1 8| Ground (Vss) ; input clock --> |2 PIC 7| output clock ; unused o|3 6|o unused ; unused o|4 5|o unused ; --------
; Only 4 pins are required: power (2.0-5.5V), ground, input and output.
; o Tie input pin4/GP3 and pin5/GP2 to Vdd or Vss.
; o Tie output pings pin3/GP4 and pin6/GP1 to ground (unused)
; Output frequency accuracy is the same as clock input accuracy.
; Output drive current is 25 mA maximum per pin.
; Coded for Microchip 12F675 but any ‘609 ‘615 ‘629 ‘635 ‘675 ‘683 works.
; 30-Jul-2008 Tom Van Baak (tvb) www.LeapSecond.com/pic
; Microchip MPLAB IDE assembler code (mpasm).
__config _EC_OSC & _MCLRE_OFF & _WDT_OFF
; Register definitions.
cblock 0x20 ; define register base
gpcopy ; shadow of output pins
; One-time PIC 12F675 initialization.
org 0 ; power-on entry here
bcf STATUS,RP0 ; bank 0
clrf GPIO ; set all pins low
movlw 07h ; set mode to turn
movwf CMCON ; comparator off
bsf STATUS,RP0 ; bank 1
clrf ANSEL-0x80 ; set digital IO (no analog A/D)
movlw b’111110′ ; set GP0 as output(0) and
;; movlw b’101100′ ; set GP0,GP1,GP4 as output(0) and
movwf TRISIO-0x80 ; other pins are input(1)
bcf STATUS,RP0 ; bank 0
clrf gpcopy ; initialize shadow output
; With an external 10 MHz PIC clock the (4:1) execution rate is 2.5 MIPS.
; A 125 instruction (400 ns each) loop takes exactly 50 microseconds.
; Output pins are toggled once per loop creating a 10 kHz square wave.
loop: movlw 0xFF ; -1
xorwf gpcopy,F ; toggle bits
movf gpcopy,W ; gpcopy -> W
movwf GPIO ; W -> output pin(s)
movlw d’118’ ;
call DelayW1 ; delay (15 <= W <= 255)
goto loop ;
include delayw.asm ; precise delay functions
What’s Next – The MCU Frequency Counter Piece
I will cover the MCU portion of the frequency counter in more detail in a separate post; however, here’s basically how it operates.
As the RF signal is collected and divided down into Khz, it passes out of the PIC12F675 microcontroller and into the AO_GPIO_0 pin of the Atmel Samb11 MCU. This particular pin is one of several pins designed to wake the MCU up from its deepest sleep state. This wakeup event manifests itself as a software interrupt and the processing that occurs during the interrupt handler. This pin can be configured to trigger (wake) on either the rising or falling edge of the incoming signal.
So once per cycle, the incoming Khz signal wakes the MCU, triggering the pin’s interrupt handler. This handler then simply increments a counter, then returns, allowing the MCU to go back into low-power sleep mode. Periodically, another task wakes up and looks at how many transitions have arrived during the most recent task cycle. Based upon number of transitions arriving, the period of the interrupting signal is determined. This period is then converted into frequency, then back into Mhz.
Finally, this Mhz frequency value is compared with this J-Box’s “cutoff frequency”. If the measured frequency is below the cutoff frequency, this J-Box’s RF relay is closed. For example, if this particular J-Box has its cutoff frequency set to 27.999 Mhz (10 meters) and the currently transmitting RF signal is measured to be 14.225 Mhz (20 meters), then this J-Box will close its relay and become part of the 20-meter antenna element pathway. If the measured signal was 28.750 Mhz, then this J-Box would open its relay. If the signal were even higher, let’s say 52 Mhz (6 meters), this J-Box would also open its relay (along with the 6 meter J-Box above it, closer to the feedline).
In summary, each J-Box contains its own frequency counter circuit and logic, which is used for auto-tuning. The PIC microcontroller provides a flexible, convenient and inexpensive way to divide the Mhz signal down into Khz, so the frequency can be counted at a more leisurely pace by the main J-Box MCU.