[{"element_type":"text","content":"\n  \n  \n  \n  \n  \n        \u003cp\u003eAdafruit Feather RP2040\u003c/p\u003e\n\u003cp\u003eNoel J Petit, WB0VGI\u003c/p\u003e\n\u003cp\u003eThis project expands on a keyer developed in 2020 using a previous \u0026nbsp;microcontroller and touch sensitive sensors. Keyers should have:\u003c/p\u003e\n\u003cp\u003eTouch pads for dash and dot\u003c/p\u003e\n\u003cp\u003ePush buttons for preprogrammed messages (CQ, RST, etc)\u003c/p\u003e\n\u003cp\u003eRotary encoders to adjust keying rate\u003c/p\u003e\n\u003cp\u003eThe Adafruit Feather RP2040 has interfaces and a library of code for all three of the above. \u0026nbsp;The advantage of the Feather RP2040 controller over previous microcontrollers is that the 2040 has touch sensitive pins on the controller itself. This means that minimal external devices are needed as most of the control is provided by software. Touch pins were programmed to control dot and dash. Touch control lines need to sense detection over a given time and not sense multiple detection as the key is touched and removed. This “debouncing” is difficult to do in hardware, but the language we use, CircuitPython provides deboucing for touch panels and switches.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eIn early 2021, the Raspberry Pi Foundation introduced the RP2040 \u0026nbsp;microcontroller chip. They produced a microcontroller board and Adafruit expanded on that board with a Feather Board. The Feather is specifically made to interface with external devices. Adafruit immediately expanded its library of CircuitPython functions for the Raspberry Pi Pico RP 2040. As a microcontroller, the RP 2040 is not meant to have a fully functional operating system with files and interfaces to things like keyboards and mice. The microcontroller is designed to run one program and interface with many different kinds of inputs and outputs (digital, analog, I2C, SPI, USB…).\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eKeyers provide services to CW operators for an easier life. Most modern transceivers include an internal electronic keyer that uses either the straight key or dual paddle key to key the transmitter. Timing of the dots and dashes depends on the operator (for the straight key) or the radio's internal keyer (for the paddles). In addition to character timing, some radios include the ability to store messages such as 'CQ CQ CQ DE WB0VGI'. My particular Yaesu FT-897’s include dual paddle dots and dashes timing but cannot store messages. Additionally, to change the keying speed, the Yaesu must stop sending, choose one of the menus, change the speed and then continue the \u0026nbsp;CW conversation. I found this challenging and slow. Programmable keyers allow you to change CW speed while sending and to send preset messages with a touch of a button.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eTo perform these tasks, a microcontroller is needed. The computer is the Raspberry Pi Foundation’s Feather RP2040 -- a small computer built around a dual-core Arm Cortex-M0+ processor with 264KB internal RAM and support for up to 16MB of off-chip Flash. This is a 32-bit computer running at about 133 Mhz. This small computer is built to run small devices with a language called Circuit-Python (CP). CP is a subset of the python language to talk to and display many digital and analog data sources. Included on the RP2040 are pins that can be digital inputs or outputs (high or low voltage), some analog pins (converted to or from binary numbers).\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eFigure 1\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eThe RP2040 Keyer uses these touch sensitive pads as inputs to key the transmitter with dots and dashes. An additional rotary encoder increases or decreases the CW sending speed. This means I can adjust the speed without having to stop conversing For touch sensors, all that is needed is a small piece of copper coated PC board glued to a metal plate (in this case another PC board) When touched, the output is a high logic value.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eFigure 2\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eThe Feather RP2040 Keyer is built in an aluminum Bud Box with the Feather computer on a small breadboard (this allows for changes as needed). The key sticks out the middle on a piece of copper two-sided circuit board soldered to a base piece of circuit board that fits in the top of the Bud Box. One circuit board for the base is 4” x 2 ¾”\u0026nbsp; and bolted to the top of the Bud Box. The key extension is 4 ½”\u0026nbsp; x 2” and soldered perpendicular to the base PC board. The key extension must be notched to fit the edge of the bud box. External capacitive touch pads are wired to the RP2040 with 28 gauge wire and message/speed selection via push button switches atop the Bud Box (see figure 2 and 3).\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eCapacitive touch keying takes some time to get used to. For the traditional paddle key, the paddles move back and forth and you feel the motion toward the dot or dash. For capacitive touch you must touch the surface to activate the key and remove you finger from the touch pad to stop the dot or dash. You do not get the sensation of moving the key and you must completely be off the touch pad to turn it off. I am still getting used to it. Capacitive touch pads in figure 2 are used as the dot and dash keys. Note that the Bud Box is not heavy enough to be a comfortable key. My MFJ dual paddle key weighs 2.5 pounds, but the Bud box and its circuitry only weighs about 10 ounces. The solution is use heavy washers or other weights in the removable U shaped bottom of the keyer. I have the box up to about 1.5 pounds and it is quite comfortable.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eFigure 3\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eYour laptop/desktop programs the Feather with a simple editor called MU. The MU editor can, edit python files, check python files for correctness, load or store files onto the Feather , and monitor the output from the Feather. Normally the output appears as either interface pins (digitally on or off) or output is the result of program steps such as the python print() statement. Only one program runs on the Feather and it is called \"code.py\" but it can have many subprograms called from code.py. Once loaded onto the Feather, \"code.py\" runs and the results are seen on the serial screen of MU. Since the memory on the Feather is non-volatile flash, as long as the Feather has power it will run code.py but without power, the Feather remembers the program and restarts code.py upon power up. Figure 4 is the layout of the inside of the keyer. Beneath the power connector on the left is the Feather and its breadboard. To the right are two 1/8” sockets for keying the transmitters. A toggle switch between them selects the radio to be keyed.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eFigure 4\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eThe schematic is simple. The Feather \u0026nbsp;receives power from the USB-C connector or an external supply of 5 volts. I chose both to use up some of the plug-in supplies in my collection. 220 uf and 0.01 uf capacitors filter the supply’s input. RF will get into the 5 Volt DC input so you may need ferrites or repositioning of the wires to prevent the Feather from chaos. \u0026nbsp;Inputs are pins A2-A3 for the rotary encoder, D25 and D9 for the pre-programmed messages, D5 and SCL for the Dash and Dot. The output pin D11 lights an LED on key. Output pin D12 is goes low to key the transmitter. The circuit is wired with wire wrap 28 gauge wire. Cut pins from wire wrap sockets to use as wire wrap terminals on the breadboard.\u0026nbsp; The SPDT switch on the output determines which radio is keyed. This avoids changing the mode of the radio when satellite up and down links are reversed.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eFigure 5\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eA Feather starts life as a simple microcontroller that expects and executable file of type .UF2 as its operating system. You can download .UF2 files from the Adafruit site and see that the device works correctly. When plugged into a laptop/desktop the Feather appears as one of the disk drives on your PC. To do your own programming, load the latest version of Circuit-Python onto the Feather with just a drag and drop. Once loaded, the Feather expects a python program named code.py. The MU editor will load and store programs for the Feather from then on. All the details are available on the Adafruit learning pages.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eAdditionally, the Feather has many libraries for multiple devices. These libraries are available from Adafruit as a bundle of about 300 files. You will need some libraries listed in the “import’ statements at the beginning of the Python Code. Also, libraries from Adafruit provide interface to all sorts of things: temperature, magnetic field, displays, humidity, servo motors, LED’s, acceleration (which way is up?) and so on. \u0026nbsp;Download the library .zip file and extract all of the libraries into a directory on your laptop/desktop. When you need a library, drag it from your laptop/desktop’s library to the “lib” folder on the Feather.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eBefore coding the keyer, you can program and test the Feather without connecting the Feather to any peripherals (how's that for cool?). Connect your laptop/desktop computer to the Feather through a USB to USB C adapter and watch the Feather light up. Follow the instructions for set up of the Feather at the Adafruit.com learning pages. This puts in Circuit-Python, downloads and starts the MU editor for you. Get sample python programs from Adafruit's pages as well. Sample code for the Feather Touch and Digital keyers are at links below. Be sure to change the names of the files to code.py to run them on the Feather . I keep the names descriptive on my PC but change them to code.py on the Feather.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eA rotary encoder changes the CW speed up and down. The other two push buttons on top of the keyer provide preprogrammed messages. In my case, one is CQ and the other a standard 599 response. The dash and dot keys are inactive during the message.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eOnce programmed, the Feather can run with just a power supply connected on the Feather side of the box. It automatically starts the code.py program when powered up. 1/8\" coaxial connectors on the keyer side connect to the key inputs of the radios.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eThe parts list has specific Digikey and Adafruit numbers. Everything except U1 – the Feather RP2040 can be substituted for whatever you have in the shop. Resistors, capacitors, and diodes of anywhere near these specifications will work just fine. Capacitive touch pads are made from cut pieces of copper printed circuit board. I found that smaller touch pads work best. The Dot and Dash pads are 5/8” x 3/8” to be very responsive. \u0026nbsp;Keep the pads small as their percentage change in capacitance is more than a large pad when touched. This may require some experimentation.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eReferences:\u003c/p\u003e\n\u003cp\u003eAdafruit.com Learning Page: \u003ca href=\"https://learn.adafruit.com/adafruit-qt-py\"\u003ehttps://learn.adafruit.com/adafruit-qt-py\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eAdafruit.com Products: \u003ca href=\"https://www.adafruit.com/\"\u003ehttps://www.adafruit.com/\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eSample Program for RP2040 \u0026nbsp;Touch: \u003ca href=\"https://bit.ly/37aWhse\"\u003ehttps://bit.ly/37aWhse\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eSample Program for RP2040 \u0026nbsp;Digital: \u003ca href=\"https://bit.ly/373RZTp\"\u003ehttps://bit.ly/373RZTp\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eParts List\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eChassis\u0026nbsp; Bud CU-3006-A\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Digikey 377-1093-ND\u003c/p\u003e\n\u003cp\u003ePrinted Circuit Board (10” x 8”) \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Digikey 182-1017-ND\u003c/p\u003e\n\u003cp\u003eMini Breadboard\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Digikey 1471-1522-ND or Adafruit Product ID 4539\u003c/p\u003e\n\u003cp\u003eJ1-J3 (1/8” jacks)\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Digikey 889-1821-ND\u003c/p\u003e\n\u003cp\u003eD1 Diode 1N4004 (any will do)\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Digikey 1N4004GOS-ND\u003c/p\u003e\n\u003cp\u003eC1 0.01 uf disc \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Digikey 1255PH-ND\u003c/p\u003e\n\u003cp\u003eC2 220 uf @\u0026nbsp; 6.3 VDC Electrolytic\u0026nbsp;\u0026nbsp; Digikey P829-ND\u003c/p\u003e\n\u003cp\u003eR1,2\u0026nbsp;\u0026nbsp;\u0026nbsp; 100 ohm ½ watt\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Digikey 100H-ND\u003c/p\u003e\n\u003cp\u003eR3,4\u0026nbsp;\u0026nbsp;\u0026nbsp; 10K ohm ½ watt\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Digikey 1MH-ND\u003c/p\u003e\n\u003cp\u003eS1,2\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Push Button\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Digikey EG1930-ND\u003c/p\u003e\n\u003cp\u003eL1\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Red LED\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Digikey L513HD\u003c/p\u003e\n\u003cp\u003eS1\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; SPDT Switch\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Digikey 2368-54-302PC-ND\u003c/p\u003e\n\u003cp\u003eU1\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Feather RP2040 \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Adafruit Product ID 4884\u003c/p\u003e\n\u003cp\u003eX1\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Rotary Encoder\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Adafruit Product ID 377\u003c/p\u003e\n\u003cp\u003eP1\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; 5 VDC USB-C Supply\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Adafruit Product ID 4298\u003c/p\u003e\n\u003cp\u003eUSB-A to USB-C cable\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp; Adafruit Product ID 4472\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eFigure Captions\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003eFigure 1 – Adafruit Feather RP2040 \u0026nbsp;microcontroller\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eFigure 2 – Adafruit Feather RP2040 \u0026nbsp;Digital Keyer with push buttons for messages, rotary encoder for CW speed and external capacitive touch sensors for dots and dashes\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eFigure 3 – Adafruit Feather RP2040 \u0026nbsp;Pin out diagram\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eFigure 4 – Adafruit Feather RP2040 \u0026nbsp;mounted on Mini Breadboard inside the keyer\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eFigure 5 – Adafruit Feather RP2040 \u0026nbsp;schematic\u003c/p\u003e\n      \n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/577/original/1-AdaFeatherSTM32F405Express.JPG?1704379890","metadata":{"caption":""}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/578/original/2-FRPOutside.jpg?1704380144","metadata":{"caption":""}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/579/original/3-_RP2040Pinout300DPI.png?1704380163","metadata":{"caption":""}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/580/original/4-Inside2.jpg?1704380185","metadata":{"caption":""}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/581/original/Schematic.JPG?1704380374","metadata":{"caption":""}},{"element_type":"code","content":"# touch_keyer.py for QT PY connected to 6 touch pads and output\n# via one digital line\n# touch pads are best small (\u003c 1/2\" square) and wired directly to QT PY\n# NJP 20 November 2020\n# added anti bounce to commands msg0, msg1, up, down\n# NJP 22 November 2020\n# NJP 2 December 2020 changed timing of msg0, ms1, rdown and rup to debounce\nimport time\nfrom touchio import TouchIn\nfrom digitalio import DigitalInOut, Direction\nimport board\nimport rotaryio\nglobal dash_length\nglobal dot_length\nglobal ratio\nglobal rate\n\nrate = 20  # initial rate\nminrate = 5\nbaserate = 15\nmaxrate = 25\ndot_length = 1.6/rate\nratio = 3  #   between dot and dash length\ndash_length = ratio * dot_length\n# key output on D10 (M0) pin\nkeyed = DigitalInOut(board.D10)\nkeyed.direction = Direction.OUTPUT\n# rotary encoder for CW speed\nencoder = rotaryio.IncrementalEncoder(board.D5, board.D6) # rate encoder\nlast_position = None\n# the rest are touch keys\ndash = TouchIn(board.SDA)\ndot = TouchIn(board.D4)\nmsg0 = TouchIn(board.SCL)#  preprogrammed message0\nmsg1 = TouchIn(board.TX) #  preprogrammed message1\n\n# morse code converter dictionary o = dot, a = dash\ncode = { ' ':'','A': 'oa', 'B':'aooo', 'C':'aoao','D':'aoo', 'E':'o',\n'F':'ooao' ,'G':'aao', 'H':'oooo','I':'oo','J':'oaaa',\n'K':'aoa','L':'oaoo', 'M':'aa', 'N':'ao', 'O':'aaa','P':'ooao',\n'Q':'aaoa','R':'oao','S':'ooo','T':'a','U':'ooa','V':'oooa',\n'W':'oaa','X':'oaao','Y':'aoaa', 'Z':'aaoo','0':'aaaaa','1':'oaaaa',\n'2':'ooaaa','3':'oooaa','4':'ooooa','5':'ooooo','6':'aoooo','7':'aaooo',\n'8':'aaaoo','9':'aaaao','?':'ooaaoo',',':'aaooaa','.':'oaoaoa'}\n\n# message0 = 'CQ CQ CQ DE WB0VGI WB0VGI WB0VGI K'  #  extend these to make a full message\n# message1 = 'RST 599 599 QTH HARRIS, MN HARRIS, MN OP NOEL NOEL BTU DE WB0VGI KN'\nmessage0 = 'CQ' # short versions for testing remove # above for full messages\nmessage1 = 'RST'\n\ndef adj_rate():  # set rate by setting the dot and dash length\n    global rate\n    global dot_length\n    global dash_length\n    if rate \u003e maxrate:\n        rate = maxrate\n    if rate \u003c minrate:\n        rate = minrate\n    dot_length = 1.6/rate\n    dash_length = 3.0 * dot_length\n    print('CW rate ', rate, ' wpm')\n\ndef check_rotary():\n    global position\n    global last_position\n    global rate\n    position = encoder.position   # check to see if rate changed\n    if position != last_position:\n        rate = baserate - position # rotary connection is reversed so subtract\n        adj_rate()                  # set new dot and dash length\n    last_position = position\n\ndef letter(letin):  # convert a string to morse code\n    for i in range(0, len(letin)):\n        mcode = code[letin[i]]\n        if letin[i] == '':\n            print('word space')\n        else:\n            for j in range(0, len(mcode)):\n                if mcode[j] == 'a':\n                    my_dash()\n                else:\n                    my_dot()\n            print('char space')\n            time.sleep(dash_length) # intercharacter length\n\ndef key(length): # this is the key down command with interbit length\n    global dot_length\n    keyed.value = True\n    time.sleep(length)\n    keyed.value = False\n#  check_rotary()\n    time.sleep(dot_length) # inter bit length\n\ndef my_dash():\n    print('dash')\n    key(dash_length)\n\ndef my_dot():\n    print('dot')\n    key(dot_length)\n\nkeyed.value = False\nprint('waiting')\nwhile True:\n    if dot.value:\n        my_dot()\n    if dash.value:\n        my_dash()\n    if msg0.value:\n        print('message0')\n        letter(message0)\n        time.sleep(1.0)\n    if msg1.value:\n        print('message1')\n        letter(message1)\n        time.sleep(1.0)\n    check_rotary()","metadata":{"language":"auto","linenums":false}}]