YaK:: W6REK/B HF Beacon (amateur radio transmitter) [Changes]   [Calendar]   [Search]   [Index]   [PhotoTags]   
[mega_changes]
[photos]

W6REK/B HF Beacon (amateur radio transmitter)

W6REK/B 10m Coordinated Beacon [28.2143] (Oct 2017 & on)

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).

2018

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:~ $

2017

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:~ $




W6REK/B HF Beacon for Eclipse Science (OLD: August 2017)

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

  • beacon.sh
  • beacon.sh
  • beacon-fast28.sh
  • radiolog.txt
  • beacon25nov.txt
  • beacon26nov.txt
  • beacon26nov.txt

    
    /* 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
    }
    
    
  • (unless otherwise marked) Copyright 2002-2014 YakPeople. All rights reserved.
    (last modified 2018-08-28)       [Login]
    (No back references.)