brainwagon "There is much pleasure in useless knowledge." — Bertrand Russell


Exciting AMSAT-NA opportunity…

I read this today:

AMSAT is excited to announce that we have accepted an opportunity to participate in a potential rideshare as a hosted payload on a geostationary satellite planned for launch in 2017. An amateur radio payload, operating in the Amateur Satellite Service, will fly on a spacecraft which Millennium Space Systems (MSS) of El Segundo, CA is contracted to design, launch, and operate for the US government based on their Aquila M8 Series Satellite Structure.

Complete Press Release Here

This would be very exciting. The only satellites I've worked have really worked with any regularity have been the FM satellites in low earth orbit. I'd love to have an opportunity to develop a station to work a bird in geostationary orbit. I'll be watching this closely, and probably kicking in some donations to AMSAT-NA to grease the skids.


SSTV from the ISS…

Well, it's not pretty, but I was just using a 17" whip antenna on my VX-8GR, recorded it with Audacity, and then decoded it with MultiScan on my Macbook. The first bit of the recording is pretty rocky, so I had to start the sync myself. I've bean meaning to do some experiments with bad audio and sync recovery, now I have more data.

Oh, in case this was all gibberish to you, the Russians have been running "events" from the International Space Station to honor their cosmonauts by transmitting pictures via slow scan television (SSTV). I received this picture using what most people would call a walkie talkie, a whip antenna, and a laptop.

As decoded by Multiscan:


I thought a second image would have begun later in the pass, but didn't hear it.

I think an antenna with a little more gain, and/or a preamplifier would help a lot. You really need pretty noise free audio to make a good picture. Still, a fun experiment. I might try the 12:30AM pass tonight.

Addendum: The second pass was also a little rocky. Got the tail end of one transmission fairly cleanly, but the three minute gap to the next one meant it was low. This is what I got.

second pass


Slow Scan Television from the ISS this weekend…

Note: This post was adapted by an email that I sent out to our ham radio club.

If anyone is interested in a fun little ham radio related activitytonight, you can try to receive slow scan television from the International Space Station this weekend. I haven't done this in a while,but I think I'll give it a try and see what I can come up with.

You can read about this event here:

AMSAT UK on the upcoming ISS event

They will be on 145.800Mhz (in the 2m band).

The way I usually "work" these is to use one of my HTs. A better antenna than the stock one is usually good (a longer whip, or even a yagi) but you might just see what you can here with the stock antenna. The ISS transmits with 25 watts of power, which is usually pretty easy to hear. I have a set of earphones that I hook with a splitter. One half goes to my earbuds, the other to a small digital audio recorder I have. Turn the squelch on your radio off so you can here the signal when it is weak. You may find that moving your antenna round will help a bit, so monitor with your earphones. Don't be shocked if you don't hear the ISS right at the rise time: it has 3 minutes of dead time between transmissions, which take about 3 minutes to send. It sounds a bit like a ticking of a clock, with a whistle in between, if you click this link, you can hear what it sounds like:

I like to record the audio, then play it back into my Windows PC and use the MMSSTV program, but you can actually go completely low tech and try an inexpensive iphone app, held up to the speaker of your HT. I use

Black Cat System's SSTV program for the iPhone/Ipad

which works okay, not amazing. If you are out doors in a windy or noisy location, your image won't be as good this way: the bg noise will cause interference.

To help out, I computed a set of rise/set/max elevation tables centered on San Francisco. If you live close, you can probably use these times. If you live in other parts of the country, you might try looking at the Heaven's Above website. Select "Passes to include" to be all, and enter your location in the upper right. The table below was calculated by my own software.

Rise time           Azi    Max Elev Time        Elev  Set time             Azi
2015/04/11 16:24:33 178.90 2015/04/11 16:28:52   9.27 2015/04/11 16:33:10  74.10 (Local Time)
2015/04/11 23:24:34 178.90 2015/04/11 23:28:52   9.27 2015/04/11 23:33:11  74.10 (UTC)

2015/04/11 17:59:18 232.14 2015/04/11 18:04:47  76.70 2015/04/11 18:10:17  49.52 (Local Time) [1]
2015/04/12 00:59:18 232.14 2015/04/12 01:04:48  76.70 2015/04/12 01:10:17  49.52 (UTC)

2015/04/11 19:36:48 276.47 2015/04/11 19:41:38  13.93 2015/04/11 19:46:28  40.34 (Local Time)
2015/04/12 02:36:48 276.47 2015/04/12 02:41:38  13.93 2015/04/12 02:46:28  40.34 (UTC)

2015/04/11 21:15:06 309.66 2015/04/11 21:19:13   7.29 2015/04/11 21:23:21  47.92 (Local Time)
2015/04/12 04:15:06 309.66 2015/04/12 04:19:14   7.29 2015/04/12 04:23:21  47.92 (UTC)

2015/04/11 22:52:10 319.85 2015/04/11 22:56:52  12.34 2015/04/11 23:01:34  78.97 (Local Time) [2]
2015/04/12 05:52:10 319.85 2015/04/12 05:56:53  12.34 2015/04/12 06:01:35  78.97 (UTC)

2015/04/12 00:28:22 312.09 2015/04/12 00:33:48  58.58 2015/04/12 00:39:14 122.75 (Local Time) [3]
2015/04/12 07:28:22 312.09 2015/04/12 07:33:49  58.58 2015/04/12 07:39:15 122.75 (UTC)

2015/04/12 02:05:15 289.69 2015/04/12 02:09:49  11.95 2015/04/12 02:14:23 174.60 (Local Time)
2015/04/12 09:05:16 289.69 2015/04/12 09:09:50  11.95 2015/04/12 09:14:24 174.60 (UTC)

[1] Probably the easiest pass, the ISS passes almost straight overhead,
should be loud and easy.

[2] A low night time pass, but the ISS should be visible to the naked eye.

[3] Another night time pass, but too late for the ISS to catch any
sun. 58 degrees is a good pass, the second one.

If I get any good images, I'll send them out next week.


Increasing pyephem’s accuracy for satellite rise/set calculations…

A few years ago, I created my own Python implementation of the Plan13 satellite prediction code written by James Miller (G3RUH). The Plan13 algorithm isn't very complicated: you can easily run it on processors like the Arduino (in fact, I used it for my ANGST satellite tracker) But somehow, I managed to misplace the source code for the Python version, probably on a hard drive for a computer that died, and so when I wanted to do some ISS calculations, I decided that I'd go ahead and use PyEphem, a much more complete package that can do all sorts of astronomical calculations, and which includes an implementation of the fairly standard SGP4 model.

It's fairly simple to write some code to predict ISS passes from any position on earth. Here's a quick example, with the TLEs for the ISS hard coded, as well as an observer position:

#!/usr/bin/env python

from math import degrees
import ephem

# create an observer
obs = ephem.Observer() = '38.0'
obs.lon = '-122'
obs.elevation = 100.

# create the iss object...

iss = ephem.readtle("ISS (ZARYA)             ",
    "1 25544U 98067A   15067.48441091  .00017347  00000-0  26069-3 0  9998",
    "2 25544  51.6448 227.0292 0008846  83.1031  17.2346 15.54929647932364")

# figure out the next pass...
# only interested in rt (rise time), tt (transit time) and st (set time)

rt, razi, tt, televation, st, sazi = obs.next_pass(iss)

print "Rise Time:   ", rt
print "Transit Time:", tt
print "Set Time:    ", st

But I was somewhat chagrined that if I ran this little snippet multiple times, I got different answers. Not by a lot, but by several seconds:

pi@blueberrypi ~ $ !.
Rise Time:    2015/3/8 22:30:12
Transit Time: 2015/3/8 21:00:52
Set Time:     2015/3/8 21:04:09
pi@blueberrypi ~ $ !!
Rise Time:    2015/3/8 22:30:12
Transit Time: 2015/3/8 21:00:53
Set Time:     2015/3/8 21:04:10
pi@blueberrypi ~ $ !!
Rise Time:    2015/3/8 22:30:13
Transit Time: 2015/3/8 21:00:53
Set Time:     2015/3/8 21:04:10
pi@blueberrypi ~ $ !!
Rise Time:    2015/3/8 22:30:03
Transit Time: 2015/3/8 21:00:49
Set Time:     2015/3/8 21:04:11

Digging in the code, it's not hard to see what's going on. The code is stepping forward by intervals of about 1 minute, trying to catch the satellite as it peaks over the horizon. When it does, it then uses twenty iterations of the secant method to find the point where the satellite crosses zero altitude. But there is an early out: if the interval drops below ten seconds, it goes ahead and exists. Similarly, it only locates the time of the transit to within 15 seconds. But these can be fixed with some quick, and probably undisciplined changes to the code will make things behave better.

Both edits are in the file riset_cir.c which is part of libastro-3.7.5 (your version might change, but will probably be the same). Near the top you'll find the declaration for TMACC

#define TMACC   (10./3600./24.0)        /* convergence accuracy, days */

Change this to 0.5 seconds instead.

#define TMACC   (0.5/3600./24.0)        /* convergence accuracy, days */

You might want to increase MAXPASSES in the find_0alt function, but I had no difficulty with leaving it at 20.

Similarly, we need to change the error in find_transit:

static int
find_transit (double dt, Now *np, Obj *op)
#define MAXLOOPS        10
#define MAXERR          (0.25/60.)              /* hours */

The number of iterations is pretty low (just 10) and the MAXERR was 15 seconds. I decided to add some iterations to ensure convergence, and to set the MAXERR to be just one second.

static int
find_transit (double dt, Now *np, Obj *op)
#define MAXLOOPS        20
#define MAXERR          (1./3600.)              /* hours */

With these changes in place, you get times which are accurate to around one second. Note: I do not mean to imply that these numbers are somehow absolutely better. It is known that the SGP4 model can only locate satellites to errors of around 1km per day at best, so trying to converge them to insane levels of accuracy isn't meaningful. But for my application, I want to count down to transits, and having the estimate jump around by a few seconds made the count down look funny. Of course, I could have just computed the times once, and used that, but I still think it's kind of odd that the estimates vary by a human discernable amount depending solely on what time you decide to try to compute from. This additional accuracy makes the program a very tiny bit slower, but is worth it for my application.

Addendum: A few more lines of code make the code a bit more useful. This now outputs the next pass expressed in the localtime rather than UTC, and gives you a bit of a countdown.

#!/usr/bin/env python

from math import degrees
import ephem
import datetime

# create an observer
obs = ephem.Observer() = '38.0'
obs.lon = '-122'
obs.elevation = 100.

# create the iss object...

iss = ephem.readtle("ISS (ZARYA)             ",
    "1 25544U 98067A   15067.48441091  .00017347  00000-0  26069-3 0  9998",
    "2 25544  51.6448 227.0292 0008846  83.1031  17.2346 15.54929647932364")

# figure out the next pass...
# only interested in rt (rise time), tt (transit time) and st (set time)

n =

rt, razi, tt, televation, st, sazi = obs.next_pass(iss)

print "%d" % round((rt - n) * 3600 * 24), "seconds until the next pass."

rt = ephem.localtime(rt).strftime("%x %X")
tt = ephem.localtime(tt).strftime("%x %X")
st = ephem.localtime(st).strftime("%x %X")

print "Rise Time:   ", rt, "Azimuth:   %5.1f" % degrees(razi)
print "Transit Time:", tt, "Elevation: %5.1f" % degrees(televation)
print "Set Time:    ", st, "Azimuth:   %5.1f" % degrees(sazi)

Addendum2: A few more lines of code fetches a current set of orbital elements from A future revision of this will probably cache a local copy of these orbital elements so you don't unnecessarily hammer their server.

#!/usr/bin/env python

from math import degrees
import ephem
import datetime
import urllib2

req = urllib2.Request("")
response = urllib2.urlopen(req)
data = 

objs = []

for idx in range(0, len(data), 3):
    objs.append(ephem.readtle(data[idx], data[idx+1], data[idx+2]))

# create an observer
obs = ephem.Observer() = '38.0'
obs.lon = '-122'
obs.elevation = 100.

# create the iss object...

iss = ephem.readtle("ISS (ZARYA)             ",
    "1 25544U 98067A   15067.48441091  .00017347  00000-0  26069-3 0  9998",
    "2 25544  51.6448 227.0292 0008846  83.1031  17.2346 15.54929647932364")

# figure out the next pass...
# only interested in rt (rise time), tt (transit time) and st (set time)

tlist = []

for obj in objs:
    r = obs.next_pass(obj)
    tlist.append((r[0], obj, r))


for t, obj, r in tlist:

    n =

    rt, razi, tt, televation, st, sazi = r

    print "%d" % round((rt-n) * 3600 * 24), "seconds until the next pass."

    rt = ephem.localtime(rt).strftime("%x %X")
    tt = ephem.localtime(tt).strftime("%x %X")
    st = ephem.localtime(st).strftime("%x %X")

    print "Rise Time:   ", rt, "Azimuth:   %5.1f" % degrees(razi)
    print "Transit Time:", tt, "Elevation: %5.1f" % degrees(televation)
    print "Set Time:    ", st, "Azimuth:   %5.1f" % degrees(sazi)


The output is now a list of all the amateur satellites that it fetched, sorted in order of the passes which are soonest appear first.

410 seconds until the next pass.
Rise Time:    03/08/15 18:33:03 Azimuth:   272.2
Transit Time: 03/08/15 18:37:54 Elevation:   8.1
Set Time:     03/08/15 18:42:45 Azimuth:     9.4

526 seconds until the next pass.
Rise Time:    03/08/15 18:34:59 Azimuth:    31.0
Transit Time: 03/08/15 18:41:08 Elevation:  16.4
Set Time:     03/08/15 18:47:16 Azimuth:   153.1

1228 seconds until the next pass.
Rise Time:    03/08/15 18:46:41 Azimuth:    91.6
Transit Time: 03/08/15 18:53:13 Elevation:   8.5
Set Time:     03/08/15 18:59:45 Azimuth:     6.5

OSCAR 7 (AO-7)
1251 seconds until the next pass.
Rise Time:    03/08/15 18:47:04 Azimuth:   229.2
Transit Time: 03/08/15 18:54:42 Elevation:   8.5
Set Time:     03/08/15 19:02:20 Azimuth:   317.9

2080 seconds until the next pass.
Rise Time:    03/08/15 19:00:54 Azimuth:    29.7
Transit Time: 03/08/15 19:07:39 Elevation:  19.3
Set Time:     03/08/15 19:14:25 Azimuth:   157.0

2515 seconds until the next pass.
Rise Time:    03/08/15 19:08:08 Azimuth:   173.2
Transit Time: 03/08/15 19:15:24 Elevation:  24.3
Set Time:     03/08/15 19:22:39 Azimuth:    41.1

CUTE-1.7+APD II (CO-65)
2940 seconds until the next pass.
Rise Time:    03/08/15 19:15:14 Azimuth:    81.8
Transit Time: 03/08/15 19:17:56 Elevation:   1.9
Set Time:     03/08/15 19:20:37 Azimuth:    31.8

JAS-2 (FO-29)
2956 seconds until the next pass.
Rise Time:    03/08/15 19:15:30 Azimuth:   255.5
Transit Time: 03/08/15 19:19:08 Elevation:   2.2
Set Time:     03/08/15 19:22:47 Azimuth:   307.5

3635 seconds until the next pass.
Rise Time:    03/08/15 19:26:49 Azimuth:   354.1
Transit Time: 03/08/15 19:32:20 Elevation:  12.4
Set Time:     03/08/15 19:37:52 Azimuth:   247.0

3940 seconds until the next pass.
Rise Time:    03/08/15 19:31:54 Azimuth:   347.2
Transit Time: 03/08/15 19:37:10 Elevation:   9.9
Set Time:     03/08/15 19:42:26 Azimuth:   248.6

4134 seconds until the next pass.
Rise Time:    03/08/15 19:35:08 Azimuth:   194.6
Transit Time: 03/08/15 19:42:31 Elevation:  27.0
Set Time:     03/08/15 19:49:53 Azimuth:   334.6

4222 seconds until the next pass.
Rise Time:    03/08/15 19:36:36 Azimuth:   235.6
Transit Time: 03/08/15 19:40:29 Elevation:   4.5
Set Time:     03/08/15 19:44:22 Azimuth:   310.9

4468 seconds until the next pass.
Rise Time:    03/08/15 19:40:41 Azimuth:    13.2
Transit Time: 03/08/15 19:47:14 Elevation:  82.2
Set Time:     03/08/15 19:53:46 Azimuth:   192.3

CUTE-1 (CO-55)
4562 seconds until the next pass.
Rise Time:    03/08/15 19:42:16 Azimuth:   198.2
Transit Time: 03/08/15 19:49:30 Elevation:  23.6
Set Time:     03/08/15 19:56:44 Azimuth:   332.9

4714 seconds until the next pass.
Rise Time:    03/08/15 19:44:47 Azimuth:    18.5
Transit Time: 03/08/15 19:52:18 Elevation:  49.9
Set Time:     03/08/15 19:59:48 Azimuth:   181.1

4722 seconds until the next pass.
Rise Time:    03/08/15 19:44:55 Azimuth:   342.9
Transit Time: 03/08/15 19:44:56 Elevation:  -0.0
Set Time:     03/08/15 19:44:56 Azimuth:   342.9

5115 seconds until the next pass.
Rise Time:    03/08/15 19:51:28 Azimuth:   279.5
Transit Time: 03/08/15 19:57:25 Elevation:   3.7
Set Time:     03/08/15 20:03:21 Azimuth:   342.8

5411 seconds until the next pass.
Rise Time:    03/08/15 19:56:24 Azimuth:    92.7
Transit Time: 03/08/15 20:00:09 Elevation:   3.9
Set Time:     03/08/15 20:03:54 Azimuth:    25.1

UOSAT 2 (UO-11)
6509 seconds until the next pass.
Rise Time:    03/08/15 20:14:43 Azimuth:    95.0
Transit Time: 03/08/15 20:18:33 Elevation:   4.5
Set Time:     03/08/15 20:22:23 Azimuth:    22.8

6557 seconds until the next pass.
Rise Time:    03/08/15 20:15:30 Azimuth:   127.3
Transit Time: 03/08/15 20:21:07 Elevation:  16.4
Set Time:     03/08/15 20:26:43 Azimuth:     6.7

6694 seconds until the next pass.
Rise Time:    03/08/15 20:17:48 Azimuth:    76.8
Transit Time: 03/08/15 20:20:03 Elevation:   1.3
Set Time:     03/08/15 20:22:18 Azimuth:    35.9

7326 seconds until the next pass.
Rise Time:    03/08/15 20:28:20 Azimuth:   128.2
Transit Time: 03/08/15 20:36:14 Elevation:   6.0
Set Time:     03/08/15 20:44:09 Azimuth:    56.8

7721 seconds until the next pass.
Rise Time:    03/08/15 20:34:55 Azimuth:   139.6
Transit Time: 03/08/15 20:41:44 Elevation:  28.3
Set Time:     03/08/15 20:48:33 Azimuth:     0.7

9556 seconds until the next pass.
Rise Time:    03/08/15 21:05:29 Azimuth:   126.2
Transit Time: 03/08/15 21:11:12 Elevation:  15.9
Set Time:     03/08/15 21:16:56 Azimuth:     7.5

9914 seconds until the next pass.
Rise Time:    03/08/15 21:11:28 Azimuth:   125.2
Transit Time: 03/08/15 21:17:05 Elevation:  15.3
Set Time:     03/08/15 21:22:43 Azimuth:     8.0

9936 seconds until the next pass.
Rise Time:    03/08/15 21:11:49 Azimuth:   118.8
Transit Time: 03/08/15 21:17:04 Elevation:  11.9
Set Time:     03/08/15 21:22:20 Azimuth:    11.1

10153 seconds until the next pass.
Rise Time:    03/08/15 21:15:26 Azimuth:   121.9
Transit Time: 03/08/15 21:20:52 Elevation:  13.4
Set Time:     03/08/15 21:26:17 Azimuth:     9.6

DELFI-C3 (DO-64)
11107 seconds until the next pass.
Rise Time:    03/08/15 21:31:21 Azimuth:   142.9
Transit Time: 03/08/15 21:37:20 Elevation:  29.2
Set Time:     03/08/15 21:43:19 Azimuth:   359.6

12799 seconds until the next pass.
Rise Time:    03/08/15 21:59:32 Azimuth:   133.5
Transit Time: 03/08/15 22:05:21 Elevation:  20.4
Set Time:     03/08/15 22:11:09 Azimuth:     4.0

13942 seconds until the next pass.
Rise Time:    03/08/15 22:18:36 Azimuth:   136.2
Transit Time: 03/08/15 22:24:17 Elevation:  22.0
Set Time:     03/08/15 22:29:58 Azimuth:     3.0

15152 seconds until the next pass.
Rise Time:    03/08/15 22:38:45 Azimuth:   129.1
Transit Time: 03/08/15 22:44:45 Elevation:  18.7
Set Time:     03/08/15 22:50:44 Azimuth:     4.6

15611 seconds until the next pass.
Rise Time:    03/08/15 22:46:24 Azimuth:    92.6
Transit Time: 03/08/15 22:50:05 Elevation:   4.0
Set Time:     03/08/15 22:53:46 Azimuth:    24.0

16144 seconds until the next pass.
Rise Time:    03/08/15 22:55:18 Azimuth:   204.1
Transit Time: 03/08/15 23:00:40 Elevation:   6.1
Set Time:     03/08/15 23:06:02 Azimuth:   124.2

16575 seconds until the next pass.
Rise Time:    03/08/15 23:02:29 Azimuth:    35.0
Transit Time: 03/08/15 23:07:53 Elevation:  12.7
Set Time:     03/08/15 23:13:17 Azimuth:   148.7

17209 seconds until the next pass.
Rise Time:    03/08/15 23:13:03 Azimuth:   176.4
Transit Time: 03/08/15 23:15:40 Elevation:   1.1
Set Time:     03/08/15 23:18:17 Azimuth:   139.8

18892 seconds until the next pass.
Rise Time:    03/08/15 23:41:05 Azimuth:    73.7
Transit Time: 03/08/15 23:43:37 Elevation:   1.4
Set Time:     03/08/15 23:46:09 Azimuth:    31.4

19177 seconds until the next pass.
Rise Time:    03/08/15 23:45:51 Azimuth:   170.5
Transit Time: 03/08/15 23:52:00 Elevation:  17.7
Set Time:     03/08/15 23:58:10 Azimuth:    47.9

19303 seconds until the next pass.
Rise Time:    03/08/15 23:47:57 Azimuth:    77.8
Transit Time: 03/08/15 23:50:51 Elevation:   2.0
Set Time:     03/08/15 23:53:45 Azimuth:    28.8

19890 seconds until the next pass.
Rise Time:    03/08/15 23:57:44 Azimuth:   141.2
Transit Time: 03/09/15 00:03:57 Elevation:  28.7
Set Time:     03/09/15 00:10:10 Azimuth:   359.5

21056 seconds until the next pass.
Rise Time:    03/09/15 00:17:09 Azimuth:   104.3
Transit Time: 03/09/15 00:22:11 Elevation:   8.1
Set Time:     03/09/15 00:27:12 Azimuth:    14.2

24703 seconds until the next pass.
Rise Time:    03/09/15 01:17:56 Azimuth:    96.4
Transit Time: 03/09/15 01:22:04 Elevation:   5.2
Set Time:     03/09/15 01:26:12 Azimuth:    20.4

25871 seconds until the next pass.
Rise Time:    03/09/15 01:37:24 Azimuth:    29.2
Transit Time: 03/09/15 01:44:13 Elevation:  20.0
Set Time:     03/09/15 01:51:01 Azimuth:   157.9

26776 seconds until the next pass.
Rise Time:    03/09/15 01:52:30 Azimuth:    42.8
Transit Time: 03/09/15 01:57:50 Elevation:   7.6
Set Time:     03/09/15 02:03:10 Azimuth:   133.0

27579 seconds until the next pass.
Rise Time:    03/09/15 02:05:52 Azimuth:    41.3
Transit Time: 03/09/15 02:11:26 Elevation:   8.3
Set Time:     03/09/15 02:17:00 Azimuth:   134.4

31680 seconds until the next pass.
Rise Time:    03/09/15 03:14:13 Azimuth:    41.7
Transit Time: 03/09/15 03:19:13 Elevation:   8.3
Set Time:     03/09/15 03:24:13 Azimuth:   137.6

38130 seconds until the next pass.
Rise Time:    03/09/15 05:01:43 Azimuth:   115.2
Transit Time: 03/09/15 04:15:25 Elevation: -74.9
Set Time:     03/09/15 05:01:43 Azimuth:   115.2

Addendum3: Hmm. If you look carefully, the last entry in the test output is bogus: the time of maximum elevation does not fall between the rise and set time, and the elevation is negative. Staring at the code some more, I'm now worried about the logic of the root finder. I'll have to ponder it some more.


Digital ATV resources…

I've been doing a bunch of reading about digital ATV operations lately. I was originally motivated by hearing about the HamTV project aboard the ISS. Back in 2007, I got re-energized into ham radio by learning that for the 50th anniversary of Sputnik, the amateur satellite AO-51 would broadcast a cool message that I heard with a simple HT. I'm wondering if I'm having that kind of a moment now: the idea of creating a station to broadcast digital television seems challenging but doable.

While reading up on the necessary bits for a HamTV downlink station, I found that this little satellite receiver which sells for less than twenty-five dollars could be used to decode signals from the ISS. It receives DVB-S signals, which are used by direct satellite broadcasters like Dish Network. But in thinking about how to go forward with the project, it seemed to me like trying to aim directly for a satellite downlink station was likely to be a frustrating endeavor. It requires a number of different subsystem to work together, but trying to receive the DVB-S from the ISS (given an intermittent schedule) would be difficult to test together. So, I started looking for resources that I could use to build a similar terrestrial station, including both a transmitter and receiver.

A couple of cool links:

The DATV-Express board is a $300 exciter board that is in limited production. It seems very cool. Reading the Tech Talks on this site yielded a lot of good information, I'm particularly pondering the information in this one, about designing a digital TV station.

Another similar project, but available more as a board/kit is the Digilite project. An interesting variation of this project is the DigiliteZL project, which makes for a compact and interesting setup.

I also like the CQ-DATV magazine. It's got lots of cool information, published in a series of magazines available in a variety of e-book formats. They also have a broad collection of interesting articles on the Digilite project, which I'm currently reading over.

I'll probably stick to more experimentation with SSTV, but this stuff fascinates me, and I may have the opportunity to do something interesting with it in the future.


Building a distributed satellite ground station network (or not…)

My twitter intro says that I am an "enthusiast for enthusiasm". When I wrote that, it was simply because there are some questions that I really think aren't helpful at all. Questions like:

  • Why didn't you just buy X instead of building your own?
  • Didn't somebody do that years ago? Why are you playing with that old technology?
  • Why are you writing a program to do that, when you could just use Y, some program/framework/application that I use.

I hate questions like this because they aren't really questions at all: they are simply trying to tell you that what you are doing is stupid or pointless. Here's the thing: I mostly understand why I do the projects that I do, and I'm perfectly okay with you not understanding my rationale, or agreeing with it even if you do understand. The proper answer is "why climb a mountain?" isn't "because it was there". It's not even "because no one has before". The proper answer is "because I've not done it, and I enjoy mountain climbing." Interestingly, most people won't try to convince you that you shouldn't like mountain climbing, but all sorts of people will try to tell you that your technical projects are a waste of time. This kind of conversation actually irritates me.

And with all this introduction, I'm going to now criticize a project, which is going to seem a bit hypocritical. Hang with me to the end, and I'll try to resolve the apparent hypocrisy, at least partially.

The topic is the plethora of news stories about a talk given at the Chaos Communication Congress (28c3) recently held in Berlin. Some links to news stories:

Hackers aim to launch Internet satellite network, moon mission
Hacker satellite grid to counter Internet censorship??
Hackers Plan Satellite Network to Fight Internet Censorship

So, what's my beef? After all, any reader to this blog knows that I'm interested in amateur satellite and communications, surely this is right up my alley?

And indeed it is. But the motivation is just... well... it's stupid. Not stupid because fighting censorship is a bad idea: it's a very, very good idea. Even essential. But the idea that satellites constructed by amateurs can play any role (much less any significant role) in fighting censorship is fantasy.

First of all, launching satellites is expensive. Really expensive. While the hardware of cubesats can be constructed quite economically, launches have costs which are multiples of ten thousand dollars, for masses which are less than 1kg launched into low earth orbit. Currently AMSAT has a project called FOX to develop a communication satellite that fits the cubesat form factor, but it's capacity and power are very limited, mostly by the physical size and weight limitations imposed by available launch opportunities. To launch a satellite into MEO or HEO would require costs measured in the millions of dollars.

Secondly, you can't get spectrum to operate a satellite network like they imagine. Amateur radio frequencies are subject to regulation and treaties just like any other spectrum, and the uses of such frequency are dictated by regulation and treaty. The governing international body is the IARU (the International Amateur Radio Union) and member nations enact local regulations to enforce treaty restrictions to comply with the regulations of the IARU. The purpose of amateur radio satellites must be to "(1) provide communication for the general amateur radio community and/or (2) self training and technical investigations relating to radio technique". While these topics are fairly broad, they are not broad enough to provide a general replacement for the Internet. In fact, in the U.S. amateur radio is specifically prohibited from carrying "communications, on a regular basis, which could reasonably be furnished alternatively through other radio services." You can't get the frequency allocations. Nobody will launch a satellite without frequency coordination.

Third, if your concern is to bypass the censorship of governments, it seems odd to do it by launching a satellite, because governments tend to have very strict and tight controls over satellites and satellite technology. For instance, in the U.S. ITAR regulations essential prohibit the transfer of dual use technologies to other countries, even to our allies. This isn't just a theoretical concern: American participation in the amateur satellite projects of other countries have been significantly stifled But even more basic than these issues are the fact that access to space is currently under the control of the very governments we are concerned about. While increasing commercialization is eroding that to a certain degree, we cannot rely on commercial entities to operate in defiance of the governments of the countries in which they operate. There is some possibility that an organization such as Copenhagen Suborbitals might be able provide launches, but these operations must operate within the regulations of the countries from which they operate as well, so I think the idea of access to space independent of governmental interference is a fantasy.

Here's the bottom line though: if your goal is to prevent government censorship, every dollar that you spend could do orders of magnitude more benefit using more conventional earth-bound technology. Funding projects like the FreedomBox Foundation, HTTPS Anywhere or The Tor Project, or working to generate a mesh based Wifi capability in your area are much, much stronger ways to work to combat Internet censorship.

If you want to build satellites, it's a perfectly reasonable thing to do. But to try to sell the idea by saying that it provides a way to combat Internet censorship? That's misleading at best.

Addendum: Here's the actual talk at the Chaos Communication Conference. It's actually got some cute stuff in it, mostly because it leaves behind the fantasy that a satellite communication network will provide a hedge against censorship in the first five minutes.


ANGST: the Arduino n’ Gameduino Satellite Tracker

I've stopped hacking on my Arduino/Gameduino satellite tracker for now. Here's the final video demonstrating it running:

I'm currently working on the final schematic which will be posted on this permanent page. The code will be available, for right now, it includes the library that I wrote that does the satellite prediction. I'll be updating the code sometime later this week.

If you take it and use it, let me know: it will motivate me to do more with the code.


What’s Up: A Visual Database of Satellites and Debris

I've pondered creating something like this a bunch of times: a way to visualize all the satellites currently in Earth orbit. Somebody beat me to it, using Google Earth and a .kml file. It's pretty astounding just how packed low earth orbit is, and it's cool to check out the band of geostationary satellites as well.

Check it out!

What’s Up: A Visual Database of Satellites and Debris.


Still more on my Arduino/Gameduino Satellite Tracker…

I need to think up a better name for this project. Calling it the "Arduino/Gameduino Satellite Tracker" is just too damned cumbersome for words.

Progress was slow today. I woke up around 4:00AM with a sore throat and a miserable cough. A quick trip to the urgent care clinic when it opened reassured me that I didn't have strep throat, but I do have some kind of upper respiratory infection going. Lots of rest today. I did spend a couple of hours listlessly programming and watching the Tigers/Rangers game though, the main result being I now plot the position of the sun on the map:

While the text at the bottom still says "ISS", the satellite being tracked is actually AO-51. As you can see, it is a polar orbiting satellite, and reaches much greater latitudes than the ISS.

I've been trying to remodularize the original Plan 13 code in BASIC, and that has made me go through the code and restructure it a bit. The solar calculations in Plan 13 are actually a bit odd: it goes through the trouble of converting the sun's orbital elements into the same epoch as the satellite you are watching, mostly so you can reuse the "T" variable. It's actually quite a bit simpler to just use the sun's orbital elements directly, and that means the sun can be a completely independent object.

I've also got a bit more hardware on the way. I decided I wanted to store a fairly large number of satellite elements, so I ordered some AT24C1024 serial EEPROMS with a capacity of 128Kbytes. I can easily chain up to 4 of those together, to store 512K which should be more than enough.

I've also got some Zigbee radios coming, so I can send new orbital elements and synchronize the time easily from my desktop. (It's mostly an excuse to play with Zigbee, but it will make for a nice setup).

After the clinic this morning, I stopped by Fry's in Walnut Creek and found that they carry OSEPP's clones of the Arduino. I'd rather spend my money at Sparkfun, but it's nice to have a local supplier for those moments where immediate gratification is essential. I bought one of their OSEPP FIO boards, which have sockets in place for Zigbee modules. What I didn't realize is that these boards aren't programmable over USB: I'll have to get one of those FTDI serial boards. For now, it will sit in its plastic case until I have need of it. It is cool that the FIO is actually cheaper than the Zigbee shield that I ordered. I'll figure out some reason to use one.

I'll shoot another video once I get multiple satellites loaded and some improvements in the user interface.

Addendum: It dawned on me that one way to test my solar calculations was to run them at the same time every day and see if the sun traced out an Analemma, the figure-eight shaped curve that you might have seen on a globe and given very little thought to. What's cool is my simulation shows this effect pretty clearly.


Scrappy introduces my Arduino/Gameduino Satellite Tracker

My cat Scrappy decided it was time to film a brief progress video of my Arduino/Gameduino satellite tracker. I completed the basic port and testing of my Plan13 implementation to C++ for the Arduino, and got it running pretty well. It doesn't seem to be much more compact than Bruce Robertson's qrpTracker code, but it isn't any worse, and I like the way I modularized and call it a bit better. Eventually all this code will be released on this website for anyone crazy enough to want to build one for themselves.

More progress as it occurs.


More progress on the Arduino/Gameduino satellite tracker…

Okay, I got about half of the Plan 13 code ported to C++. It's a fresh port of the original BASIC code, but modularized into objects better, and with a few bits of tidiness that C++ provides over basic. I estimate another hour or so to finish the code, if I work carefully and efficiently.

I wasn't feeling up to working carefully and efficiently this evening, so I thought I'd try to figure out a few mostly cosmetic issues. I had the idea that I wanted to change the map to color, which was easy enough to achieve. Then, I thought a large time display at the bottom. I had an 8x8 character font already in memory, so using it to generate huge characters at the bottom didn't seem to be that hard. The problem is that the screen is only 50 characters wide, so that makes just six characters. I dummied it up to display six digits of time and the bottom, and it's simply too big. Check it:

Clearly, the 8x8 character set isn't quite what I need. I have a 3x5 charset which might do the trick, but I'll have to get that formatted and loaded into flash. I'll try that tomorrow.


ISS tracking on the Arduino/Gameduino

Well, tonight I had some mild success! My Gameduino satellite tracker is up and running! It's not got much in the way of a user interface, but it here you see the ISS position marked with a purple/magenta dot, and then dots showing the position of the ISS every three minutes for the next two hours. My own location is indicated by the small star.

Compare this to the identical time using the tracker from the AMSAT website:

It seems to match up pretty well. I had originally planned to port my own code for Plan13 that I wrote in Python, but I am currently using VE9QRP's Plan13 qrpTracker for the Arduino. It works pretty darned well, which significantly blunts my enthusiasm for porting code. We shall see.

Addendum: I'm planning on adding some interface elements to allow you to switch between multiple satellites, maybe a rotary encoder + push button. And I have some software changes in mind.


Homemade GPS Receiver

This article was linked from hackaday, and seems very, very cool. Sure, GPS receivers are cheap, but building one is cool. I am not likely to be doing a project like this, but it's cool to read about.

Homemade GPS Receiver.


Thoughts on SSTV…

My recent playing with SSTV images coming from ARRISSat-1 have made me think a bit more about SSTV. I used two different applications to decode SSTV images (MMSSTV on Windows, and Multiscan on OS X), and got slightly different results in terms of performance from each. This leads me to ask "just what are the limits of performance for analog SSTV imagery, and how closely do existing applications approach these limits?"

Whenever I ask a question like this, there seems to be two complementary approaches: doing research and doing experiments.

Luckily, courtesy of Google, research has never really been easier. Relatively quickly I found this article by Lionel and Roland Cordesses:

Some Thoughts on "Real Time" SSTV Processing by Lionel and Roland Cordesses, QEX May/Jun 2003

It's a great article, with many good ideas. The authors have apparently implemented them in the F2DC SSTV program, which apparently in need of some repair (written for Borland tools and Win95) but could provide the basis for a new, good implementation. But their paper provides some basic ideas, and I'm not sure I agree 100% with their implementation of them, so perhaps it is more valuable as inspiration.

They use a fairly old but still useful technique based upon the Hough Transform to do high quality deskewing of the incoming image signal. Much of the paper is devoted to details of making that work. In the past, I've used RANSAC to figure out sync pulse locations in my NOAA satellite decoder. Their technique is almost certainly less computationally intensive, but RANSAC can match more complex models (including Doppler shift, which is important for NOAA images), and I find RANSAC less "fussy" to implement (it is relatively indifferent to the model you choose, which makes modularization easier).

The other part of their paper deals with robustly estimating frequency. The simplest (and worse performing) demodulators estimate frequency from just two or three samples surrounding the current pixel location. The authors instead determine frequency by convolving a window function 37 samples long around the current position (they are sampling at 44100 samples per second) or about .83 ms. In the Martin-1 mode they use, a pixels is about .57ms long, so they are looking at a window of just about 1.5 pixels. That seems okay to me, but I'm confused by some of the choices.

They choose to digitize at 44100, which seems excessive to me. SSTV information is confined to the regions between 1200 and 2300 Hz, so according to the Nyquist theorem, even sample rates of 8Khz contain all the information needed to do a decode (assuming the signals actually are bandwidth limited). I was thinking of using 11025 samples per second. The corresponding window functions that would correspond to the 37 tap filter would be about 9 samples long, which would still provide the same level of frequency discrimination, but at a lower computational cost. I can't imagine any practical reason to use finer sampling (DSP experts can point out any errors in my thinking in comments).

The cool part of their system is that they estimate the signal to noise ratio of the signal (by comparing power inside and outside the SSTV bandwidth) and use longer filters to estimate frequency when the SNR is poor. This makes a tradeoff between resolution and noise immunity, which seems in practice to be quite effective.

It would be interesting to make modern implementation, using gcc and fftw3 as a basis, and documenting all of the design choices. I think it would also be good to test the decoders against both AWGN (additive white Gaussian noise) and perhaps using an HF channel simulator to judge their performance. I'm most interested in the Robot36 mode, since that seems to be a common choice for satellites, but Scottie and Martin modes are also essential.

If anyone else has any interesting references on SSTV transmission and reception, feel free to add them via comments.


NOAA 19 recording, and atpdec…

Some of you may remember that I wrote my own APT satellite decoder. I ran across someone else who did the same:

ATPDEC by Thierry Leconte (F4DWV)

It has the same basic philosophy as my own crude efforts: hand it a WAV file, and it will find and produce the APT imagery from inside it. I went outside and recorded some of the NOAA 19 pass over my location today, and came up with the following:

Pretty nifty! I did have some trouble with some of the older recordings though: I suspect that noise may toss off his calibration in some way which isn't entirely obvious. I'll have to play with it more.