{"id":1335,"date":"2019-03-03T19:41:54","date_gmt":"2019-03-04T00:41:54","guid":{"rendered":"http:\/\/abrammorphew.com\/notes\/?p=1335"},"modified":"2026-03-16T13:44:01","modified_gmt":"2026-03-16T18:44:01","slug":"7mhz-transmitter-with-avr-soft-keyer","status":"publish","type":"post","link":"http:\/\/abrammorphew.com\/notes\/2019\/03\/03\/7mhz-transmitter-with-avr-soft-keyer\/","title":{"rendered":"7MHz Transmitter with AVR Soft-keyer"},"content":{"rendered":"\n<p>In my last post, I went over the design of a Colpitts crystal oscillator design that put out a moderately clean 7 MHz signal. In order to match the output impedance to 50 \u03a9, an NPN feedback pair (at least that&#8217;s what I&#8217;m calling it) was designed. While meeting the specs for driving an ADE-1 mixer, it consumed an unnecessary amount of current. I&#8217;ve been designing a tremolo effect recently (which I should be making on post on as well in the future) where I used a BS170 MOSFET to amplitude modulate an incoming audio signal. Without going into too much detail, I decided to adjust the DC bias point of an emitter-follower to sit at the threshold voltage of the BS170 to prevent from having to have a DC block immediately followed by another DC bias point. While looking at different transmitter designs on <a href=\"http:\/\/konstruktor.ha5khc.hu\/linkgyujtemeny\/linkgyujtemeny.htm\">Homebrew RF Circuit Design Ideas<\/a>, I came across a class C amplifier that used a similar technique to what I was doing in the tremolo effect combined with a Pierce oscillator. I did some experimentation and came up with the following circuit. <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"909\" height=\"676\" src=\"http:\/\/abrammorphew.com\/notes\/wp-content\/uploads\/2019\/03\/7MHz-Beacon-Rev-B.png\" alt=\"\" class=\"wp-image-1336\"\/><\/figure>\n\n\n\n<p>To be fair, this schematic is revision B, and it hasn&#8217;t been built yet. Revision A, however, is pretty much the same thing except R1 is omitted and the drain of Q3 connects to the source of Q6. The ATTiny85 takes the single-throw switch as the only input. When you turn it on, the switch acts like a standard on-off keyer for banging out morse code. If you hold the key down for 5 seconds, it changes to a beacon mode and starts tapping out my call sign. Holding the key down again changes operation into pulse mode with a frequency around 1 kHz. In pulse mode, you can actually pick up the signal on a standard AM receiver as seen in the demo video. The transmitter itself puts out 28 dBm running on a 12V supply and is around 82% efficient.     <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"2000\" height=\"2032\" src=\"http:\/\/abrammorphew.com\/notes\/wp-content\/uploads\/2019\/03\/7MHz_beacon_board_RevA.jpg\" alt=\"\" class=\"wp-image-1337\"\/><\/figure>\n\n\n\n<p>The PCB layout came out pretty quickly. It was the first time I have ever done double-sided PCB etching. Overall, I think it came out pretty well. There was  small offset as you can see from the placement of the drill holes, but no harm, no foul. Performance was even a little better than the prototype. I mounted the board inside a Hammond 1590A enclosure and made a short demonstration video. It&#8217;s extremely simple, but I think it will be a useful piece of a larger project that I&#8217;m working on. It can also be easily adapted to a number of frequencies using a different crystal or loading Q2 to act as a frequency multiplier. I did experiment with this somewhat and was able to produce fairly strong second and third harmonics at the output. That&#8217;s about as far as I got though since I got distracted making theremin type sounds on my shortwave radio receiver. <\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"DIY 40m QRP transmitter\/beacon with AVR soft-key demonstration (2019)\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/y7cyIbbYk7Y?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:false,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-c++src&quot;,&quot;theme&quot;:&quot;darcula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C++&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;cpp&quot;}\">#define cbi(sfr, bit) (_SFR_BYTE(sfr) &amp;amp;= ~_BV(bit))\n#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))\n\n#define CTL 0         \/\/ TX enable pin\n#define SW  3        \/\/ input switch pin\n#define N   10      \/\/ N periods in monopulse mode\n\nbool            sw = LOW; \nbool            trig = LOW;               \/\/ monopulse trigger status\nbool            tx = LOW;                \/\/ flag for TX enable\nbool            keyer = LOW;            \/\/ flag for start of key press\nint             mode = 0;              \/\/ modes: 0 =&amp;gt; Key mode (default), 1 =&amp;gt; ID mode, 2 =&amp;gt; Monopulse\nint             dit = 50;             \/\/ delay time for dit in ms\nint             dash = 150;          \/\/ delay time for dash in ms\nunsigned long   hold = 5e6;         \/\/ max hold value in microseconds\nunsigned long   pause = 1e7;       \/\/ max pause between IDs in microseconds \nunsigned long   start = 0;        \/\/ start time in microseconds\nunsigned long   last = 0;        \/\/ time of last ID;\nlong            c = 0;          \/\/ count variable for mode change\n\n\n\nvoid setup() {\n  pinMode(CTL,OUTPUT);\n  pinMode(SW, INPUT);\n\n  cli(); \n  \/*--- TIMER1 CONFIG ---*\/  \n  TCCR1  = 0b01101000;\n  GTCCR  = 0b00100000;\n  \n  TCCR0A = 0b00100000;\n  TCCR0B = 0b00001011;    \/\/ last 3 bits set prescalar for Timer0\n\n  cbi(TIFR,OCF1A);\n  sbi(TIMSK,OCIE1A);\n  OCR1A = 128;\n  sei();\n\n\/* --- interrupt enable\n    GIMSK = 0b00100000;     \/\/ turns on pin change interrupts\n    PCMSK = 0b00001000;    \/\/ turn on interrupts on pins PB3\n    sei(); \n*\/\n}\n\nvoid loop() {  \n  \/*\n    if (sw == LOW) { \n      start = micros();\n      if (keyer == HIGH) {\n       modeChk(); \n      } else {\n       keyer = HIGH;\n      }\n    } else {\n     keyer = LOW;\n    }\n  *\/\n  \/\/ perform function based on mode\n  switch(mode) {\n    case 0:\n      if (sw == LOW) {\n        digitalWrite(CTL, HIGH); \n      } else {\n        digitalWrite(CTL, LOW);\n      }\n    break;\n    \n    case 1:\n      if (last == 0) {\n        id();\n      } else if ((micros() - last) &amp;gt; pause) {\n        id();\n      }\n    break;\n    \n    case 2:\n      if (sw == LOW) {\n        pulse();\n      }\n    break;\n  }\n\n  trig = LOW;                 \/\/ monopulse trigger reset  \n}\n\nISR(TIMER1_COMPA_vect) {\n    sw = digitalRead(SW);\n    if (sw == LOW) { \n      if (keyer == HIGH) {\n       modeChk(); \n      } else {\n       start = micros();\n       keyer = HIGH;\n       trig = HIGH;\n      }\n    } else {\n     keyer = LOW;\n    }\n} \n\nvoid modeChk() {\n  if ((micros() - start) &amp;gt; hold) {\n     if (mode &amp;lt; 2) {\n       mode++;\n     } else {\n       mode = 0;\n     }\n     start = micros();\n     stat();\n     delay(1000);\n  }\n}\n\nvoid pulse() {\n  \/\/ pulse TX on and off N times\n  for(int n = 0; n &amp;lt; N; n++) {\n      digitalWrite(CTL,HIGH);\n      delayMicroseconds(500);\n      digitalWrite(CTL,LOW);\n      delayMicroseconds(500);\n  }\n}\n\nvoid stat() {\n  \/\/ tap out mode number in morse code\n  for(int n = 0; n &amp;lt; mode; n++) {\n      digitalWrite(CTL,HIGH);\n      delay(dit);\n      digitalWrite(CTL,LOW);\n      delay(dit);\n  }\n\n    for(int n = 0; n &amp;lt; (5 - mode); n++) {\n      digitalWrite(CTL,HIGH);\n      delay(dash);\n      digitalWrite(CTL,LOW);\n      delay(dit);\n  }\n}\n\nvoid id() {\n  \/\/ tap out ID for K2NXF\n  \n\/\/ K\n  digitalWrite(CTL,HIGH);\n  delay(dash);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dit);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dash);\n\n  digitalWrite(CTL,LOW);\n  delay(dash);\n  \n\/\/ 2 \n  digitalWrite(CTL,HIGH);\n  delay(dit);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dit);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dash);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dash);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dash);\n  digitalWrite(CTL,LOW);\n  delay(dash);\n\n\/\/ N\n  digitalWrite(CTL,HIGH);\n  delay(dash);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dit);\n  digitalWrite(CTL,LOW);\n  delay(dash);\n\n\/\/ X\n  digitalWrite(CTL,HIGH);\n  delay(dash);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dit);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dit);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dash);\n  digitalWrite(CTL,LOW);\n  delay(dash);\n\n\/\/ F\n  digitalWrite(CTL,HIGH);\n  delay(dit);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dit);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dash);\n  digitalWrite(CTL,LOW);\n  delay(dit);\n  digitalWrite(CTL,HIGH);\n  delay(dit);\n  digitalWrite(CTL,LOW);\n  delay(dash);\n\n\/\/ new word\n  digitalWrite(CTL,LOW);\n  delay(dash);\n\nlast = micros();          \/\/ store current time at end of ID\n  \n} <\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"<p>In my last post, I went over the design of a Colpitts crystal oscillator design that put out a moderately clean 7 MHz signal. In order to match the output impedance to 50 \u03a9, an NPN feedback pair (at least that&#8217;s what I&#8217;m calling it) was designed. While meeting the specs for driving an ADE-1 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1337,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[312,316,278,21,102,143,288,24,294,265,227,319,317,320,315,277,185,61,310,309],"class_list":["post-1335","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-notes","tag-40m","tag-7mhz","tag-amateur-radio","tag-amplifier","tag-arduino","tag-atmel","tag-attiny85","tag-circuit","tag-cnc","tag-cnc-milling","tag-cw","tag-filter","tag-hf","tag-low-frequency","tag-morse","tag-morse-code","tag-pcb","tag-radio","tag-rf","tag-transmitter"],"_links":{"self":[{"href":"http:\/\/abrammorphew.com\/notes\/wp-json\/wp\/v2\/posts\/1335","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/abrammorphew.com\/notes\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/abrammorphew.com\/notes\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/abrammorphew.com\/notes\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/abrammorphew.com\/notes\/wp-json\/wp\/v2\/comments?post=1335"}],"version-history":[{"count":11,"href":"http:\/\/abrammorphew.com\/notes\/wp-json\/wp\/v2\/posts\/1335\/revisions"}],"predecessor-version":[{"id":1604,"href":"http:\/\/abrammorphew.com\/notes\/wp-json\/wp\/v2\/posts\/1335\/revisions\/1604"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/abrammorphew.com\/notes\/wp-json\/wp\/v2\/media\/1337"}],"wp:attachment":[{"href":"http:\/\/abrammorphew.com\/notes\/wp-json\/wp\/v2\/media?parent=1335"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/abrammorphew.com\/notes\/wp-json\/wp\/v2\/categories?post=1335"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/abrammorphew.com\/notes\/wp-json\/wp\/v2\/tags?post=1335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}