Skip to main content

A CW Keyer Project

So, you decided to build the CW transmitter project... good for you but now you need a CW control/keyer and we turn to AI for that piece. This part does not need to be consistent with the constraints document. You can cut and paste the code embedded in the link below.




Using an Arduino Nano write a sketch for a CW Transmitter controller. Input pins are A0, A1 and A2. Output pins are 4, 5, 6,7 and 12.

Got it 👍 — you want an Arduino Nano sketch that uses A0, A1, A2 as inputs and controls digital pins 4, 5, 6, 7, and 12 as outputs for a CW (Continuous Wave) transmitter controller.

Here’s a clean, well‑structured example sketch:

cpp
/*
  CW Transmitter Controller for Arduino Nano
  Inputs:  A0, A1, A2
  Outputs: 4, 5, 6, 7, 12
*/

const int inputPins[]  = {A0, A1, A2};
const int outputPins[] = {4, 5, 6, 7, 12};

void setup() {
  // Configure input pins
  for (int i = 0; i < 3; i++) {
    pinMode(inputPins[i], INPUT_PULLUP);  // use pullups for switches
  }

  // Configure output pins
  for (int i = 0; i < 5; i++) {
    pinMode(outputPins[i], OUTPUT);
    digitalWrite(outputPins[i], LOW);     // start off
  }
}

void loop() {
  // Read inputs
  int in0 = digitalRead(inputPins[0]);
  int in1 = digitalRead(inputPins[1]);
  int in2 = digitalRead(inputPins[2]);

  // Example control logic:
  // - A0 controls pin 4 (keying line)
  // - A1 controls pin 5 and 6 (TX enable)
  // - A2 controls pin 7 and 12 (sidetone or indicator)
  
  digitalWrite(4, (in0 == LOW) ? HIGH : LOW);   // active LOW input
  digitalWrite(5, (in1 == LOW) ? HIGH : LOW);
  digitalWrite(6, (in1 == LOW) ? HIGH : LOW);
  digitalWrite(7, (in2 == LOW) ? HIGH : LOW);
  digitalWrite(12,(in2 == LOW) ? HIGH : LOW);

  // Add timing or Morse keying logic here if needed
}

🔧 How this works

  • Inputs (A0–A2): assumed to be pushbuttons or control lines. Using INPUT_PULLUP means they are normally HIGH and go LOW when pressed/activated.

  • Outputs (4,5,6,7,12): drive relays, LEDs, or transmitter control lines.

  • Logic mapping:

    • A0 → pin 4

    • A1 → pins 5 & 6

    • A2 → pins 7 & 12

This is just a basic controller skeleton. For a real CW transmitter, you’d likely add:

  • Morse keying logic (timing dots/dashes, spacing).

  • Sidetone generation (using tone() on a pin).

  • Debouncing for inputs.

👉 Do you want me to extend this into a full Morse keyer (with dot/dash timing and sidetone), or just keep it as a simple on/off controller for the transmitter lines?

Add in keying logic, sidetone and debouncing

Perfect — let’s turn that skeleton into a real CW keyer controller with:

  • Debouncing for clean input reads

  • Keying logic (dot/dash timing, spacing)

  • Sidetone using Arduino’s tone() function

Here’s a complete sketch you can load onto your Arduino Nano:

cpp
/*
  CW Transmitter Controller with Keying Logic, Sidetone, and Debouncing
  Inputs:  A0 (DOT), A1 (DASH), A2 (Straight Key)
  Outputs: 4, 5, 6, 7, 12 (TX control lines)
  Sidetone: Pin 12 (piezo buzzer or audio output)
*/

const int dotPin   = A0;
const int dashPin  = A1;
const int keyPin   = A2;

const int txPins[] = {4, 5, 6, 7};   // transmitter control lines
const int sidetonePin = 12;          // buzzer or audio output

// Morse timing (adjust WPM here)
const int wpm = 20;                  // words per minute
const int dotDuration = 1200 / wpm;  // ms per dot
const int dashDuration = dotDuration * 3;
const int intraCharGap = dotDuration;       // between elements
const int interCharGap = dotDuration * 3;   // between letters
const int wordGap = dotDuration * 7;        // between words

// Debounce settings
unsigned long lastDebounceTimeDot = 0;
unsigned long lastDebounceTimeDash = 0;
unsigned long lastDebounceTimeKey = 0;
const unsigned long debounceDelay = 20; // ms

int lastDotState = HIGH;
int lastDashState = HIGH;
int lastKeyState = HIGH;

void setup() {
  pinMode(dotPin, INPUT_PULLUP);
  pinMode(dashPin, INPUT_PULLUP);
  pinMode(keyPin, INPUT_PULLUP);

  for (int i = 0; i < 4; i++) {
    pinMode(txPins[i], OUTPUT);
    digitalWrite(txPins[i], LOW);
  }

  pinMode(sidetonePin, OUTPUT);
}

void loop() {
  // Debounced input reads
  int dotState  = debounceRead(dotPin, lastDotState, lastDebounceTimeDot);
  int dashState = debounceRead(dashPin, lastDashState, lastDebounceTimeDash);
  int keyState  = debounceRead(keyPin, lastKeyState, lastDebounceTimeKey);

  // Straight key (manual keying)
  if (keyState == LOW) {
    keyDown();
  } else {
    keyUp();
  }

  // Automatic dot/dash keyer
  if (dotState == LOW) {
    sendElement(dotDuration);
  }
  if (dashState == LOW) {
    sendElement(dashDuration);
  }
}

// --- Helper Functions ---

int debounceRead(int pin, int &lastState, unsigned long &lastTime) {
  int reading = digitalRead(pin);
  if (reading != lastState) {
    lastTime = millis();
  }
  if ((millis() - lastTime) > debounceDelay) {
    lastState = reading;
  }
  return lastState;
}

void keyDown() {
  // Activate transmitter lines
  for (int i = 0; i < 4; i++) {
    digitalWrite(txPins[i], HIGH);
  }
  tone(sidetonePin, 600); // sidetone frequency in Hz
}

void keyUp() {
  for (int i = 0; i < 4; i++) {
    digitalWrite(txPins[i], LOW);
  }
  noTone(sidetonePin);
}

void sendElement(int duration) {
  keyDown();
  delay(duration);
  keyUp();
  delay(intraCharGap);
}

🔊 How it works

  • Inputs:

    • A0 → Dot paddle

    • A1 → Dash paddle

    • A2 → Straight key (manual)

  • Outputs:

    • Pins 4–7 → TX control lines

    • Pin 12 → Sidetone buzzer

  • Debouncing: Each input is stabilized with a 20 ms debounce.

  • Keying logic:

    • Dot = 1 unit, Dash = 3 units

    • Intra-character spacing = 1 unit

    • Inter-character spacing = 3 units

    • Word spacing = 7 units

  • Sidetone: A 600 Hz tone plays while the key is down.

Well that only took me 30 seconds to write and Caveat Emptor, I haven't actually tried it. This is bad news for those earning a living as coders. It would take me weeks to grope and poke to originate this code and it only took a few seconds to write up what I wanted and less time to spit it out for you. The bonus... it's free.

For those who abhor Nano's and Arduino sketches then check out this Keyer Project from NN1DX. Yeah, IC's another kiss of death to those who know nothing about electronics but are Extra Class Licensee's.

Next, I asked Copilot a dangerous question regarding non-elected officials of the current administration. It was a fun exercise and something you can do in the privacy of your home.

The current administration has been in power for 10 Months. Colorful, questionable, and lacking in gravitas might describe some of those non-elected personnel in key assignments and offices (positions of power). 

I asked copilot who is most at risk of being sacked before the end of 2025.  One simply cannot take that AI generated information and publish it. But you can individually ask your favorite AI program in the privacy of your own home without fear of being found out whose head is on the chopping block. 

Similar to Murder on the Orient Express... the list is likely more than 1 or 2 names. Hopefully those key administration names that show up on your list are not making any expensive and irreversible long-term commitments as AI may be foretelling their sacking. 

Generic reasons for the sacking suggest the lack of 500% loyalty and failing to carry out attack dog tactics the size of a Mastiff on Democrats and Democratic policies.


Mastiff 32 Inches high and weighs 230 Pounds

Telling is the high-profile resignations from the current administration.

Them that know can make things go.

73's
Pete N6QW


Popular posts from this blog

January 26, 2024. A simple CW Transceiver/Transmitter

Cruise through the lower part of the ham bands bands and what do you hear? Well, FT-8 and CW. Often you will not hear any SSB stations yet go to the lower part of the bands, and it is a cacophony (I love that word) of bad sounding signals and some high-speed keying. Fast is not so much of the issue as is bad, run together and jerky keying. But none the less our hobby started there.    So, you could crank down your ICOM 7300 and watch the waterfall on CW or you could homebrew a radio. Actually, to do CW right you need more thought up front than you do with a SSB transceiver. Often, I will state that a CW Transceiver is much more difficult to build than a simple SSB rig. I published two articles in QRP Quarterly on CW transceivers and all I got was a yawn so maybe history will repeat itself.  Yawn!   30M CW Transceiver with RIT!   Of interest is that the LO is a Varactor tuned LC oscillator using a NE602. Look closely at the RIT circuit which is only activated on ...

March 31, 2024. Happy Easter to those who celebrate this day.

What a great day to Binge on Chocolate and experience the pain of that filling that has been leaking.  I would be in that category with the leaking filling(s) had I not just spent an amount equivalent to one of the fancy new uptown appliance box transceivers on two filling repairs. Well at least I can binge on the Chocolate bunnies without fear of pain. Regrettably everything appears to have jumped in price including the price of parts. Well not so much the parts as the shipping costs.  That notably is seen in the eBay treasures. I spotted a nice heathkit DX-20 for about $50 and the shipping was $65. Likely it is a twofer with part being a way to in effect charge a higher price by inflating the shipping and in part by increased shipping costs. Shipping with insurance across the US was about $150 for this jewel and that was three years ago. 6AM on the Left Coast ~ 20M Easter Sunday! My only hope is the cost of Chocolate Bunnies remains steady although a pound of See's Candies f...

August 30, 2024. A PNP 20M SSB Transceiver

Shown below is the Block Diagram for the 20M PNP SSB Transceiver steered in the  Transmit Mode . The components shown in the dotted block are relay steered so that the block module is single pass and amplifies in a single direction. The Block diagram show steered in Transmit.  Essentially the steering process works so that the IF Module input follows the Balanced Modulator on Transmit and then the input side follows the Receive Mixer on Receive. All done with some relays and a bit of RG174U coax. For those who count things in detail, this block diagram is not unlike what was used for the PSSST Transceiver which can be found on my website . Yes, a warmed over P3ST only using PNP devices. TYGNYBNT. 73's Pete N6QW