YaK:: W6REK/B HF Beacon (amateur radio transmitter) | [Changes] [Calendar] [Search] [Index] [PhotoTags] |
The beacon is being spotted by N6TV locally (San Jose, Calif) and by other stations DX on the Reverse Beacon Network: http://www.reversebeacon.net/dxsd1/dxsd1.php?f=0&c=w6rek%2Fb&t=dx
Currently an Icom IC-7200 rig at 25% power (i.e. about 25 Watts).
Scripts running on a Raspberry Pi 3 model B (which has 4 cores; these scripts use 2 of them):
(* Launched by /etc/rc.local like this: ( while sleep 30 ; do su pi /bin/bash -c 'cd ; bash run.sh >/tmp/beacon.log 2>&1 ' ; done >/tmp/b.log 2>&1) & *) pi@raspberrypi:~ $ cat -n run.sh 1 #!/bin/bash 2 set -x 3 export PATH="/usr/local/bin:$PATH" 4 5 while true 6 do 7 test -f stop && break 8 9 taskset 8 python beacon-bars.py | taskset 4 bash beacon-slave.sh 10 11 sleep 60 12 done pi@raspberrypi:~ $ pi@raspberrypi:~ $ cat -n beacon-bars.py 1 # 30 seconds schedule (300 deciseconds) 2 # First 15 seconds for ID. 3 # Tone bars at 15, 17, 19, 21, & 23 seconds. 4 5 import gpiozero 6 import datetime, os, sys, time 7 8 Ascii = 'vvv de w6rek/b' 9 10 PowerSchedule = { 11 142: '0.25', 12 162: '0.10', 13 182: '0.05', 14 202: '0.02', 15 222: '0.00', 16 242: '0.25', 17 292: '0.25', 18 } 19 20 MORSE = { 21 ' ': " ", 22 'a': ".-", 23 'b': "-...", 24 'c': "-.-.", 25 'd': "-..", 26 'e': ".", 27 'f': "..-.", 28 'g': "--.", 29 'h': "....", 30 'i': "..", 31 'j': ".---", 32 'k': "-.-", 33 'l': ".-..", 34 'm': "--", 35 'n': "-.", 36 'o': "---", 37 'p': ".--.", 38 'q': "--.-", 39 'r': ".-.", 40 's': "...", 41 't': "-", 42 'u': "..-", 43 'v': "...-", 44 'w': ".--", 45 'x': "-..-", 46 'y': "-.--", 47 'z': "--..", 48 '1': ".----", 49 '2': "..---", 50 '3': "...--", 51 '4': "....-", 52 '5': ".....", 53 '6': "-....", 54 '7': "--...", 55 '8': "---..", 56 '9': "----.", 57 '0': "-----", 58 '/': "-..-.", 59 '.': ".-.-.-", 60 ',': "--..--", 61 '?': "..--..", 62 '=': "-...-", 63 '-': "-....-", 64 '(': "-.--.-", 65 ')': "-.--.-", 66 ':': "---...", 67 '"': ".-..-.", 68 '\'': ".----.", 69 } 70 71 Morse = ' '.join(MORSE[ch] for ch in Ascii) 72 print >>sys.stderr, repr(Morse) 73 74 BEEPS = { 75 '.': 'X', 76 '-': 'XXX', 77 ' ': '_', 78 } 79 80 Output = ' '.join(BEEPS[ch] for ch in Morse) 81 N = len(Output) 82 print >>sys.stderr, N, repr(Output) 83 84 Output = '%-150s' % Output 85 Output += 'XXXXXXXXXX' 86 Output += '~~~~~~~~~~' 87 Output += 'XXXXXXXXXX' 88 Output += '~~~~~~~~~~' 89 Output += 'XXXXXXXXXX' 90 Output += '~~~~~~~~~~' 91 Output += 'XXXXXXXXXX' 92 Output += '~~~~~~~~~~' 93 Output += 'XXXXXXXXXX' 94 Output += '~~~~~~~~~~' 95 N = len(Output) 96 print >>sys.stderr, N, repr(Output) 97 98 99 RomanUnits = { 100 0: '', 101 1: 'i', 102 2: 'ii', 103 3: 'iii', 104 4: 'iv', 105 5: 'v', 106 6: 'vi', 107 7: 'vii', 108 8: 'viii', 109 9: 'ix', 110 } 111 RomanTens = { 112 0: '', 113 1: 'x', 114 2: 'xx', 115 3: 'xxx', 116 4: 'xl', 117 5: 'l', 118 6: 'lx', 119 7: 'lxx', 120 8: 'lxxx', 121 9: 'xc', 122 } 123 124 def Roman(n): 125 t = int(n / 10) 126 u = n % 10 127 rt = RomanTens[t] 128 ru = RomanUnits[u] 129 return '%s%s' % (rt, ru) 130 131 def RomanTime(t): 132 dt = datetime.datetime.fromtimestamp(t) 133 h = dt.hour 134 m = dt.minute 135 return '%s . %s egeszsegere ...' % (Roman(h), Roman(m)) 136 137 led = gpiozero.LED(17) 138 was = 0 139 print "pid %d" % os.getpid() 140 sys.stdout.flush() 141 142 SPECIAL = 3000 143 TOOTS = [(SPECIAL - 10 - i*10) for i in range(4)] 144 145 alternate = None 146 while True: 147 t = int(time.time() * 10.0) 148 while t == int(time.time() * 10.0): 149 pass 150 k = (t + 1) % 300 # deciseconds, modulo 30 seconds. 151 kk = (t + 1) % SPECIAL # deciseconds, modulo SPECIAL seconds. 152 153 if kk == 0: 154 alt_morse = ' '.join(MORSE[ch] for ch in RomanTime(time.time())) 155 alternate = 'XXXXXXXXXX ' + ' '.join(BEEPS[ch] for ch in alt_morse) 156 normal = False 157 158 o = Output 159 if kk < 300 and alternate: 160 o = alternate 161 else: 162 alternate = None 163 164 if k < len(o) and o[k] == 'X' or kk in TOOTS: 165 led.off() # Active low. 166 if was: 167 print "swr" 168 sys.stdout.flush() 169 was = 1 170 else: 171 led.on() # Passive high. 172 was = 0 173 174 if not alternate: 175 rfpower = PowerSchedule.get(k) 176 if rfpower: 177 print "power %s" % rfpower 178 sys.stdout.flush() 179 180 pass # NOT REACHED pi@raspberrypi:~ $ pi@raspberrypi:~ $ cat -n beacon-slave.sh 1 #!/bin/bash 2 3 set -x 4 5 UART=$(ls /dev/serial/by-id/usb-*_IC-7200_* | head -1) 6 7 function rig() { 8 /usr/local/bin/rigctl -m "361" -s 19200 -r $UART "$@" 9 } 10 11 trap 'rig T 0; sleep 0.3; rig T 0; exit' 0 1 2 3 12 13 rig T 0 14 rig F 28214300 15 rig M CW 250 16 rig L KEYSPD 12 17 rig L RFPOWER 0.01 18 19 while read cmd arg junk 20 do 21 case $cmd in 22 pid) 23 MASTER="$arg" 24 ;; 25 power) 26 rig F 28214300 27 rig M CW 250 28 rig L RFPOWER "$arg" 29 rig T 1 30 31 echo RFPOWER "$arg" 32 date -u "+%Y-%m-%d %H:%M:%S Z" 33 ;; 34 swr) 35 s=$(rig l SWR) 36 echo SWR $s 37 case $s in 38 1.[0123]* ) 39 : ok 40 ;; 41 [123456789]* ) 42 # Bad SWR 43 date > stop 44 kill $MASTER 45 sleep 1 46 kill $MASTER 47 exit 48 ;; 49 *) 50 # Ignore communication errors. 51 date -u "+Communcation Error: %Y-%m-%d %H:%M:%S Z" 52 sleep 0.2 53 ;; 54 esac 55 ;; 56 *) 57 kill $MASTER 58 sleep 1 59 kill $MASTER 60 exit 61 ;; 62 esac 63 done pi@raspberrypi:~ $ |
Originally it was using a Realistic HTX-100 at 5 watts on 28.2143 MHz (plus or minus; I'm trying to tune it better).
The Morse Code Keyer is an ATtiny45 microcontroller toggling a single output:
#define LED_BUILTIN 0 /* SparkFun Tiny Programmer for ATtiny45*/ #define PAUSE 5 /* seconds before repeating */ #define WPM 12 #define DIT ((int)(1200/(WPM))) /* 100 milliseconds is 12 WPm */ #define W ".-- " #define _6 "-.... " #define R ".-. " #define E ". " #define K "-.- " #define SL "-..-. " #define B "-... " #define __ " " #define C "-.-. " #define M "-- " #define _9 "----. " #define _7 "--... " #define D "-.. " const char Message[] = D E __ W _6 R E K SL B __ W _6 R E K SL B __ C M _9 _7; // the setup function runs once when you press reset or power the board void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(LED_BUILTIN, OUTPUT); } // Use macros with constants, to avoid needing to multiply at runtime. #define Beep(NDITS) { digitalWrite(LED_BUILTIN, HIGH); delay(NDITS*DIT); } #define Gap(NDITS) { digitalWrite(LED_BUILTIN, LOW); delay(NDITS*DIT); } void Fist(int ch) { switch (ch) { case '.': Beep(1); Gap(1); break; case '-': Beep(3); Gap(1); break; default: Gap(2); break; } } void loop() { int i = 0; int ch; while (ch = Message[i++]) { Fist(ch); } delay(PAUSE * 1000); } |
new message 2017-10-23:
#define VVV "...- ...- ...- " #define W ".-- " #define _6 "-.... " #define R ".-. " #define E ". " #define K "-.- " #define SL "-..-. " #define B "-... " #define __ " " #define C "-.-. " #define M "-- " #define _9 "----. " #define _7 "--... " #define D "-.. " #define A ".- " #define H ".... " //#define EGESZSEGERE ". --. . ... --.. ... . --. . .-. . " #define EGESZSEGERE ". --. ..-.. ... --.. ... ..-.. --. ..-.. .-. . " const char Message[] = VVV __ D E __ W _6 R E K SL B __ W _6 R E K SL B __ C M _9 _7 A H __ EGESZSEGERE __ D E __ W _6 R E K SL B; |
This one is for a Raspberry Pi, using GPIO 17 for keying.
I run the GPIO 17 output (with a 1K pullup to +V) through three CMOS inverting buffers (half a CMOS 4049) in series, then through a diode, to pull down the tranceiver's CW key input. I power the 4049 from a +5 output on the Raspberry Pi. pi@raspberrypi:~ $ cat beacon.py import gpiozero import time MORSE = { 'V': '...-', 'D': '-..', ' ': ' ', 'W': '.--', '6': '-....', 'R': '.-.', 'E': '.', 'K': '-.-', '/': '-..-.', 'B': '-...', } Ascii = 'VVV DE W6REK/B ' Morse = ' '.join(MORSE[ch] for ch in Ascii) print repr(Morse) BEEPS = { '.': 'X', '-': 'XXX', ' ': '_', } Output = ' '.join(BEEPS[ch] for ch in Morse) N = len(Output) print N, repr(Output) led = gpiozero.LED(17) while True: t = int(time.time() * 10) # i = 0 while t == int(time.time() * 10): # i += 1 pass # print i if Output[t % N] == 'X': led.on() else: led.off() pass # NOT REACHED pi@raspberrypi:~ $ |
PLEASE SEE http://eclipse.yak.net/
The plan is to operate before, during, and after the Aug 21, 2017, eclipse from Edgefield Country, South Carolina, USA.
This Bash script (for linux) sends a beacon on the frequencies and the powers shown on the SCHED= line.
It currently stays on each frequency about 40 seconds, with a 28 second transmission (plus time for the automatic tuner to respond).
HF Spots: http://www.reversebeacon.net/dxsd1/dxsd1.php?f=0&c=w6rek%2Fb&t=dx
Solar Eclipse Ham Science: http://hamsci.org/basic-project/2017-total-solar-eclipse
3 SCHED='28071111:80 14071111:80 7071111:80 3571111:50' 4 5 alias rig="rigctl -m 370 -s 19200 -r /dev/ttyUSB0" 6 trap 'rig T 0' 0 1 2 3 7 8 set -e 9 while true 10 do 11 for sched in $SCHED 12 do 13 set / $(echo $sched | tr ':' ' ') 14 F=$2 15 P=$3 16 date 17 echo "T 0 18 F $F 19 M CW 250 20 L RFPOWER $(echo "puts [format %.2f [expr 0.01+$P/100.0]]" | tclsh) 21 L KEYSPD 20 22 T 0 23 " | rig - 24 sleep 1 25 rig G TUNE 26 sleep 8 27 rig T 1 28 rig b ". eclipse test " 29 rig b "de w6rek/b w6rek/b " 30 rig b "cm97ah ${P}w ." 31 32 for x in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 33 do 34 sleep 1 35 echo "exit [expr { $(rig l SWR) > 1.4 }] " | tclsh 36 done 37 38 done 39 done |
Here's a single frequency beacon on 28.242400:
1 #!/bin/bash 2 3 alias rig="rigctl -m 370 -s 19200 -r /dev/ttyUSB0" 4 trap 'rig T 0' 0 1 2 3 5 6 set -e 7 rig T 0 8 rig F 28242400 9 rig M CW 250 10 rig L RFPOWER 0.8 11 rig L KEYSPD 20 12 rig G TUNE 13 sleep 8 14 rig T 1 15 sleep 1 16 17 while true 18 do 19 date 20 rig b "de w6rek/b cm97" 21 for x in 1 2 3 4 5 6 7 8 9 10 11 12 22 do 23 sleep 1 24 echo "exit [expr { $(rig l SWR) > 1.2 }] " | tclsh 25 done 26 done |
alias rig="rigctl -m 370 -s 19200 -r /dev/ttyUSB0" trap 'sleep 0.888; rig T 0' 0 1 2 3 set -e POWER=${POWER:-0.05} FREQ=${FREQ:-28242424} SPEED=${SPEED:-12} rig F $FREQ rig M CW 250 rig L RFPOWER $POWER rig L KEYSPD $SPEED while true do date rig T 1 sleep 1 rig b "DE W6REK/B W6REK/B CM97" while [ 1 = "$(rig t)" ] do echo "exit [expr { $(rig l SWR) > 1.2 }] " | tclsh sleep 0.3 rig T 0 done sleep 1 done |
/* rts_dtr_beacon */ #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <sys/types.h> #include <termios.h> #include <time.h> #include <unistd.h> #define W ".-- " #define _6 "-.... " #define R ".-. " #define E ". " #define K "-.- " #define SLASH "-..-. " #define B "-... " #define __ " " #define C "-.-. " #define M "-- " #define _9 "----. " #define _7 "--... " #define D "-.. " const char Message[] = D E __ W _6 R E K SLASH B __ __ __; char codes[1000]; struct timespec deci_second = { 0, 100 * 1000 * 1000 }; void cw_beacon(int fd) { char* p = codes; for (const char* cp = Message; *cp; cp++) { if (*cp == '.') { *p++ = 1; } else if (*cp == '-') { *p++ = 1; *p++ = 1; *p++ = 1; } else { *p++ = 0; *p++ = 0; } *p++ = 0; } int rts = TIOCM_RTS; ioctl(fd, TIOCMBIS, &rts); while (1) { char* q; for (q = codes; q < p; q++) { int dtr = TIOCM_DTR; if (*q) { ioctl(fd, TIOCMBIS, &dtr); } else { ioctl(fd, TIOCMBIC, &dtr); } struct timespec remainder = { 0, 0 }; nanosleep(&deci_second, &remainder); } } } int main() { int fd = open("/dev/ttyUSB0", O_RDWR); if (fd < 0) { perror("/dev/ttyUSB0"); exit(3); } cw_beacon(fd); #if 0 int mu = open("/dev/audio1", O_RDWR); if (mu < 0) { perror("/dev/audio1"); exit(3); } #endif } |
(last modified 2019-05-17) [Login] |