the higher current used by the speaker, the voltage on the
output of Q1 varied enough to cause the circuit to function
erratically. I would have had to lower the base resistor
considerably if I wanted to keep that design.
I found that with the final version of the circuit, I could
not measure the current draw with my meter (Fluke 79).
I put a 1K resistor in series with the supply and there was
less than 1 mV across it. So, the current must be less than 1
µA when the system is off.
All the parts are thru-hole with no SMDs (
surface-mount devices). Resistors R1 and R2 were mounted
vertically to save board space. The volume control, R4, is
mounted close to the edge of the board for convenience
and is a vertically mounted trim pot with a “thumb wheel”
adjustment. You can mount a horizontal trim pot instead to
have a side adjustment.
I mounted the PIC (U1) in a socket, but you don’t
have to do that. I used 1N914s for the diodes since I had
a supply of them, but almost any signal diode (such as
1N4148s) will do.
As you can see from Figure 3, the board is quite small:
1.3” x 1.3”. I soldered the wires for the speaker directly to
the board instead of using a connector. The white dot to
the left of the B1 connector is a score from a silver marking
pen (which I always use to indicate the positive connection
of the power supply).
The board is light enough that I used a single 2-56
mounting bolt and standoff to attach it to the housing.
There is room enough for the three AA cell battery holder
above the board. Since jumpers 0, 1, and 2 are
not installed, I’m using sequence 0.
The software is very much table-driven.
There are three tables that the program uses:
1. Frequency of available notes
2. The notes to play for a sequence
3. Which sequence to play
The table of the notes looks like this:
C4 dw HIGH .137, LOW .137 ;262
D4 dw HIGH .154, LOW .154 ;294
C4 and D4 are the label references for
the two notes shown; dw is the assembler
directive to store a word or words at the
current memory location. HIGH and LOW are
the assembler syntax that selects the high byte
and low byte of the value to be stored. (Even
though the program memory is 14 bits per
location, only eight bits can be accessed using memory
read commands.) The comments show the frequency of
the note for the entry.
The value stored must be the desired frequency
multiplied by 0.524, which is due to the accumulator
length of the NCO and the frequency of the CPU clock
driving it. There are comments in the source code that
explain this more fully. The frequencies used in the table
for the notes were obtained from
The table must be completely within the first 256 bytes
of program memory. This allows the sequence lists to use a
single byte entry for the address of each note to be played.
The table can be expanded to cover as many notes as you
may need, provided you stay within the 256-byte limit.
There is a conditional assembly directive following
the table which will cause a warning message if the table
becomes too big. The table can be increased beyond this
256-byte limit as long as you make the appropriate changes
in the routine that accesses them, as well as the entries in
the table described next.
Within the table is an entry for MC_NOTE. This is the
note I use for those sequences for which I have not defined
a song or other sequence. The notes I have entered are the
Morse Code dots and dashes representing the number of
the sequence (1.. 7) based on Sws 0-2.
The next table contains the lists of notes used for the
sequences of the eight possible states of Sws 0-2. This is an
example for sequence 0 (Sw3 closed, Sw0.. 2 open):
; FIGURE 3.
24 September/October 2018