#picaxe 28x2 ' * *** ************************************************************************************************* ' * *** ' * *** PICAXE Morse Keyer ' * *** Iambic A Version 2.1 ' * *** Chris Pearson, G5VZ ' * *** October 2012 ' * *** ' * *** Version 2 updates: ' * *** Rotary control for speed selection ' * *** Output to key a transmitter ' * *** Version 2.1: minor corrections - ' * *** 1 LED Active high (Not low!) ' * *** 2 Use keyRig flag so transmit control is selectable (eg FB is not transmitted!) ' * *** ' * *** ************************************************************************************************* ' * *** ' * *** Storage ' * *** EEPROM (%01001000, %00011000) ' "FB" ' * *** ************************************************************************************************* ' * *** ' * *** Inputs and outputs ' * *** symbol dahPin = 1 ' Touch input - ADC channel 1 symbol ditPin = 0 ' Touch input - ADC channel 0 symbol speedPot = 2 ' Rotary speed setting: IO pin A.2 is ADC channel 2 symbol sidePin = B.6 ' Side-tone audio output symbol ledPin = B.7 ' Panel LED - active high low ledPin ' LED off symbol txPin = B.5 ' Default rig keyer output low txPin ' Rig control line inactive (Receive mode) ' * *** ' * *** Control values ' * *** symbol sideTone = 100 ' Side tone note symbol silentTone = 0 ' Silence ' * *** ' * *** Variables ' * *** symbol storedByte = b0 ' Used to read out of EEPROM store symbol loopCount = b1 ' Loop counter symbol bitValue = b2 ' Used in bit shifting symbol characterCounter = b3 ' Used to count characters in a string symbol keyRig = b4 ' Flag determines whether to key attached radio keyRig = 0 ' Default setting is don't key transmit line symbol startFlag = b5 ' Flag start bit in character code symbol touchValue = w10 ' Touch sensor input value symbol speedValue = b6 ' Raw speed pot reading symbol currentSpeed = b7 ' Active raw speed value currentSpeed = 0 symbol ditLength = b10 symbol dahLength = b11 symbol silencePeriod = b12 symbol betweenCharacters = b13 ' * *** ************************************************************************************************* ' * *** ' * *** Blink the LED ' * *** low ledPin ' LED off pause 100 gosub blinkLED ' * *** ' * *** Send welcoming "FB" ' * *** gosub setSpeed ' Set Morse speed to current pot position gosub sendFB ' * *** ************************************************************************************************* ' * *** ' * *** Main program loop ' * *** main: keyRig = 1 ' All Morse now echoed to key rig output line do touch16 dahPin,touchValue ' Read dah touch sensor into touchValue ''sertxd("dahPin value is ", #touchValue, cr, lf) if touchValue > 600 then gosub sendDit endif touch16 ditPin,touchValue ' Read dit touch sensor into touchValue ''sertxd("ditPin value is ", #touchValue, cr, lf) if touchValue > 600 then gosub sendDah endif gosub setSpeed ' Sending speed may be changed loop end ' * *** ' * *** End of main program loop ' * *** ' * *** ************************************************************************************************* ' * *** ' * *** Subroutines ' * *** sendDit: ' * *** Subroutine to output a single dit low ledPin if keyRig = 1 then high txPin ' Transmit line toggled when keyRig set high end if sound sidePin, (sideTone, ditLength) high ledPin low txPin sound sidePin, (silentTone, silencePeriod) return sendDah: ' * *** Subroutine to output a single dah low ledPin if keyRig = 1 then high txPin ' Transmit line toggled when keyRig set high end if sound sidePin, (sideTone, dahLength) high ledPin low txPin sound sidePin, (silentTone, silencePeriod) return sendChar: ' * *** Subroutine to send one Morse character startFlag = 0 ' Start flag reset for loopCount = 0 to 7 bitValue = storedByte % 2 ' Shift out LSB if startFlag = 0 then if bitValue = 1 then startFlag = 1 ' Start of character data end if else if bitValue = 1 then ' Send element of character data ''sertxd("Dah",cr,lf) gosub sendDah else ''sertxd("Dit",cr,lf) gosub sendDit end if end if storedByte = storedByte / 2 ' Shift byte one bit right next loopCount ''sertxd("Character space", cr, lf) gosub sendSpace ' Space between characters return sendSpace: ' * *** Subroutine to wait inter-character space sound sidePin, (silentTone, silencePeriod) return sendFB: ' * *** Reads the welcome message (Default is "FB") from store and output the Morse for characterCounter = 0 to 1 ' Two characters of "FB" read characterCounter,storedByte ' Read Morse character from store ''sertxd("Byte read is ", #storedByte) gosub SendChar ' and send it next characterCounter return blinkLED: ' * *** Briefly illuminate the LED high ledPin ' LED on pause 100 low ledPin ' LED off return setSpeed: readadc speedPot,speedValue ' Speed pot processing speedValue = 255 - speedValue ' Reverse direction of rotary control (!) if currentSpeed <> speedValue then ''sertxd("Raw pot value changed to ", #speedValue, cr, lf) currentSpeed = speedValue ditLength = currentSpeed / 12 ' Scale the basic timing unit if ditLength < 2 then ditLength = 2 ' No extreme speeds! end if ''sertxd("Speed set to ", #ditLength, cr, lf) dahLength = ditLength * 3 silencePeriod = ditLength betweenCharacters = ditLength * 3 end if return ' * *** ' * *** End of program ' * *** ' * *** *************************************************************************************************