Full-color, full-resolution graphics from the pages of QRP Homebrewer

QHB #9 -- November 2002

 

Build the "AVV" Audio Visual Voltmeter, by Joe Everhart, N2CX

'*************************************************************************

' AVV.BS2 Rev 0.3

'

' Joe Everhart, N2CC

' 214 New Jersey Rd

' Brooklawn, NJ 08030

' e-mail: n2cx@voicenet.com

'

' This program is written for TTAM13 to appear in the Oct 2002 issue of

' ARCI's QRP Quarterly. It is an expansion of the Audio Voltmeter from

' Quickie 43 that appears in the same issue.

'

' AVV stands for Audio/Visual Voltmeter. It is an 8-bit digital multimeter

' using an ADC0831 in conjunction with a Parallax BASIC STAMP chip and a

' Seetron BPI16 serial LCD module.

'

' The AVV measures 0-2VDC and ouputs a 3-digit numeric display. The LCD

' output is always active while two audible "display" options can be

' chosen. The first is a variable pitch output that varies linearly within

' approx. 300 to 300 Hz and is proportional to the voltage value measured.

' The second audible output is sent as 3 digits of MORSE code at approx.

' 12 wpm.

'

' The audible outputs are chosen by pressing a pushbutton. Operation

' cycles through three modes - no audible output, variable tone output and

' MORSE audible output.

'

' The original implementation is made using the Parallax Board of

' Education. Future revisions of this program will use the QuickieLab

' prototyping system described by George Heron, N2APB in the October 2002

' QRP Quarterly. The "QL" adds a Ubicom SX-28 I/O Extender (IOX) to the

' BS-2 to provide a serial interface expansion. The IOX interfaces a

' 12-button keypad, a frequency counter, the ADC0831 ADC and a digital

' potentiometer.

'

' If the program is modified to read a different maximum voltage the

' variable Volts200 and voltage scaling in the MAIN ROUTINE must be

' suitably changed. Since Volts200 is also used in the MORSE subroutine

' The new variable must also be changed there. Naturally the associated

' circuitry must be modified as well.

'

' Revision History:

' -----------------

' Rev 0 8/14/2002 Draft release #1

' Rev 0.1 8/22/2002 Revised LCD routine, added LCD init on startup

' Note Volts 200 scaling interim 5V

' Rev 0.2 8/22/2002 Fixed Morse freq at 2000 Hz for piezo spkr

' Rev 0.3 10/3/2002 Redesigned to use QL with IOX

' Rev 1.0 10/3/2002 Debugged final version using IOX on QL

'

'*************************************************************************

' Copyright 2002, J. Everhart, N2CX All rights reserved. Permission is

' granted for personal, non-profit use.

'

'*************************************************************************

'{$STAMP BS2}

'*******************

' VARIABLES

'*******************

DitTime con 100 'MORSE dit time, 100 ms is 12 wpm

LcdClr con 1 'LCD clear screen instruction

CMD con 254 'LCD instruction prefix

Baud con 375 'IOX data rate 2400 baud

L1C1 con 128 'LCD screene line 1, column 1

L2C6 con 198 'LCD screen line 2, column 7

TonePin con 5 'Tone output pin

AdcOut var word '8-bit ADC outout value

I var byte 'Loop index variable

Volts200 var word '3-digit decimal ADC output scaled 0-200

Dig1 var byte 'Voltage least signif digit

Dig2 var byte 'Volts middle digit

Dig3 var byte 'Volts most signif digit

Freq var word 'VARTONE frequency in Hz

MorseChar var byte 'Hold packed Morse to be sent

Mode var nib 'Operating mode

TestChar var byte 'Variable used to check for DIT or DAH

VoltDigit var byte 'Morse dit to be sent

'*************************************************************************'

' MAIN PROGRAM

'*************************************************************************

INITSETUP:

serout 0,Baud,20, [CMD,LcdClr] 'Clear the LCD screen

START:

serout 0,Baud,20,[CMD,80]

serin 1,Baud,[ADCout]

' Change next line to 50/64 for final 0-2V scaling

Volts200 = AdcOut * 125 / 64 'Scale voltage to 0-500 - test

Dig1 = Volts200 dig 2 'Grab indiv digits from

Dig2 = Volts200 dig 1 'Volts200

Dig3 = Volts200 dig 0

gosub LCDDISP 'Visual display

gosub CHECKMODE 'Check operating mode

if Mode = 0 then START 'No audbile opt get new rdg

if Mode = 1 then VARTONE 'Variable tone "bar graph"

if Mode = 2 then MORSE 'Audible Morse "display"

goto START 'By default get new reading

'*************************************************************************

' LCDDISP - Visual LCD display routine using the IOX to access the

' display. Data rate is 2400 baud.

'*************************************************************************

LCDDISP:

serout 0,Baud,7,[CMD,L1C1] 'Move cursor to start of display

serout 0,Baud,7,["N2CX AVV"] 'Print vanity message

serout 0,Baud,7,[CMD, L2C6] 'Move cursor to Line 2 Col 6

serout 0,Baud,7,[Dec Dig1,".",Dec Dig2, Dec Dig3, " V"]

'display voltage value

return 'To main program

'*************************************************************************

' CHECKMODE- This subroutine checks the Mode pushbutton switch on pin 2 and

' sets the operating mode appropriately. The program begins

' with only the LDC enabled and no audio outputs. When the MODE

' button is pressed and detected, operation changes to the

' VARTONE mode in which a tone is output whose frequency is

' proportional to the measured voltage. A second switch

' depression results in an audible MORSE output. The next

' detected button push begins operation with only the LCD on.

' since the BS2 has no interrupts, the switch must be polled

' and CHECKMODE follows display on the LCD. Thus the switch

' must be held long enough to cycle through the current

' operating mode then a new reading and LCD output. In order

' to avoid switch bounce and uncertainty of being detected,

' operation ceases until the switch is released. The new

' mode proceeds at that time.

'

'************************************************************************

CHECKMODE: 'Checks mode select pushbutton

if in2 = 1 then ENDOFCHECKMODE 'If not pressed no mode change

if in2 = 0 and Mode = 0 then SETVARTONE 'Pressed and NOTONE set VARTONE

if in2 = 0 and Mode = 1 then SETMORSE 'Pressed and VARTONE set MORSE

goto SETNOTONE 'Pressed and MORSE set NOTONE

SETVARTONE:

if in2 = 0 then SETVARTONE 'Loop until key is released

Mode = 1 'Mode 1 is VARTONE

return 'To top of main program

SETMORSE:

if in2 = 0 then SETMORSE 'Loop until key is released

Mode = 2 'Mode 2 is MORSE

return 'To top of main program

SETNOTONE:

if in2 = 0 then SETNOTONE 'Loop until key is released

Mode = 0 'Mode 0 is NOTONE

ENDOFCHECKMODE

return 'To top of main program

'*************************************************************************

 

'*************************************************************************

' VARTONE - This subroutine outputs a tone whose pitch varies directly

' with the measured voltage. In order to be compatible with

' transmission via a voice-quality communications path, the

' lowest input voltage produces an output at 300 Hz while a

' full-scale 8-bit reading of 255 gives a tone at 2850 Hz.

'

'*************************************************************************

VARTONE:

Freq = AdcOut * 10 + 300 'Scale value between 300 and 2850 Hz

freqout TonePin, 300, Freq 'Output VARTONE for 200 ms (use with BOE)

'(3o0 ms works better with IOX

return 'To main program

 

'*************************************************************************

'MORSE - This subroutine outputs a tone keyed with those digits. The

'letter "R" is sent as a decimal point.

'*************************************************************************

MORSE:

Freq = 2000 'Morse tone freq = 2000 Hz

for i = 2 to 0 'Pick off AD digits

VoltDigit = Volts200 dig I 'Grab individual decimal digits

'Get packed Morse characters

lookup VoltDigit,[$FC,$7C,$3C,$1C,$0C,$04,$84,$C4,$E4,$F4],MorseChar

gosub SENDMORSE 'Send Morse character

if I = 2 then SENDR 'Add "R' for decimal point after ms digit

goto SKIPR 'If not most signif digit

SENDR:

MorseChar = $50 'Packed Morse representation for "R"

gosub SENDMORSE

 

SKIPR:

next

pause 500 '1/2 sec delay between MORSE readouts

return 'To main program

'*************************************************************************

' SENDMORSE - This subroutine picks apart packed morse characters stored in

' MorseChar and ouputs audible MORSE characters on TonePin of

' the BS2. Speed is set to 12 wpm initally by variable DitTime.

'*************************************************************************

 

SENDMORSE: 'Sends audible morse chars

CHECKMORSE: 'Process packed morse variable

if MorseChar = $80 then SENDCHARSPACE 'All dits and dahs shifted out

TestChar = MorseChar & $80 'Get high bit

MorseChar = MorseChar *2 'Shift out used char

if TestChar = $80 then SENDDAH 'Char is a DAH so send it

'If not, it's a DIT so fall thru

SENDDIT:

freqout TonePin, DitTime, Freq 'Unit time dit tone

freqout TonePin, DitTime, 0 'Unit time space

goto CHECKMORSE 'Go back for next char

SENDDAH

freqout TonePin, 3*DitTime, Freq '3*Unit time dit tone

freqout TonePin, DitTime, 0 'Unit time space

goto CHECKMORSE 'Go back for next char

SENDCHARSPACE:

freqout TonePin, 2*DitTime, 0 '2*unit time space

return 'To main program

 

STOP 'Something has gone badly wrong

'to get here!

'*************************************************************************

' END OF PROGRAM AVV

'*************************************************************************

 

Back to QHB #9

 

Last Modified: January 2003