Category Archives: Amateur Satellite

Weekend Update…

This is just a short set of updates for my weekend projects, meant to keep me in the habit. I’ll write up a more complete version of these projects going forward.

First of all, a new acquisition. My Anet A8 3D printer has proven to be, well, not the most reliable of gadgets. I still haven’t gotten around to fixing its heated bed, but should get to it shortly. But as it happens, a small windfall came my way, so I decided to get a Creality CR-10 which I caught on a good price for less than $400. Unlike the laser-cut, hours-to-assemble Anet A8, the Creality is mostly assembled. It has a 300mmx300mm bed, a much taller range of travel, and is constructed by aluminum extrusions that make for a nice, stiff, and easy to assemble printer. I mostly assembled it in a little less than an hour, but ran out of steam and decided to go to a movie with Carmen and then watch the Superbowl. I’m hoping to print a Benchy when I get home tonight: the only thing I have left to do is get the bed leveled.

I also spent some more time on the ISS clock. I added a new display mode that shows details of upcoming passes, including a diagram of the pass, showing its path across the sky and its maximum elevation. I also updated the epoch that the Plan 13 code was using so that it would be more accurate, and now it compares to within about a degree or so with what other, more sophisticated models have. There are still a couple of lingering glitches. Occasionally it looks for the next pass before the current pass is complete. I suspect that is because I used a number of global variables to communicate between processes, and something in the logic isn’t quite right. But as they say, any program worth writing is worth rewriting. I’ll try to get a version of the code up on github tonight, even though it’s kind of embarrassing.

Stay tuned for CR-10 print experiences and more on the ISS clock.

More progress on the ISS clock project…

I haven’t posted an update here recently, but I am (mostly) living up to my New Year’s resolution to spend at least 30 minutes a day working on a project. This has taken the form of some stupid but necessary chores (like fixing the broken pull cord on my lawnmower) but has mostly taken the form of additional incremental additions and improvements to my ISS clock project. This has mostly taken the form of noting a small deficiency, and then working until that deficiency is ameliorated.

The ESP32/Arduino environment still has access to the FreeRTOS operating system below to create tasks, semaphores and queues. I decided that I would implement the program as a set of tasks of different priorities. One task’s job is to compute the current latitude, longitude, altitude and azimuth for the satellite. Another lower priority task scans forward in time, and finds the next time when the satellite rises and sets. When it finds those, it pauses until the current time is beyond the found set time, and then continues searching for the next rise/set pair. The final task runs the display, showing all the current information. If the time of the next satellite rise time (or AOS — Acquisition of Signal) is set, then the display process will give a countdown in hours/minutes/seconds.

This was all working reasonably well, except that I noticed that the time display would frequently “jump” a second, skipping from 42 seconds to 40 seconds in countdown, and sometimes even in the clock display jumping from 10 to 12 seconds for example. I didn’t think any critical path in the code would account for anywhere near that amount of delay in switching between processes, but tried reorganizing the code in various ways to be sure.

In the end, I realized that it had nothing to do with multitasking or the like. I had written code in two different places to convert an internal representation of time used by my Plan 13 satellite library into H:M:S format, and had committed the same error in both locations.

The thing that I realized is that unlike normal Unix time calls, internally my code represents the current time of day as a double which represents fraction of a day. To step the time forward by one hour, I increment that value by 1/24. I have a function whose purpose is to convert this internal representation separate hours, minutes, and seconds.

Here is a (slightly edited) version of my original code.

void
DateTime::gettime(int &h, int &m, double &s)
{
    double t = TN ;  // TN is the time in fractions of a day
    t *= 24. ;
    h = (int) t ;
    t -= h ;
    t *= 60 ;
    m = (int) t ;
    t -= m ;
    t *= 60 ;
    s = t ;
}

The problem appears to be rounding interacting with the timing of the display process. Staring at this code, I’m not sure what I was thinking. I rewrote this code in the following way:

void
DateTime::gettime(int &h, int &m, double &s)
{
    double t = TN ;  // TN is the time in fractions of a day
    int ts = (int) round(t * 24. * 60. * 60.) ;
    s = ts % 60 ;
    ts /= 60 ;
    m = ts % 60 ;
    ts /= 60 ;
    h = ts % 24 ;
}

This code works much better. I had coded a similar routine in new code which had the same error. I must admit that I’m still a little fuzzy about how the timing of the display process interacts with this rounding issue to introduce the errors that I observed, but I suspect it has to do with the fact that I inserted delays in the display process to keep that process from updating somewhere around two times a second. I think that the prediction task (which runs for about twenty seconds usually) may be starving the low priority display task just often enough to cause the rounding error to manifest.

I’ll ponder it more later.

Things that are now percolating to the top of my todo list are to understand the event handling of the NtpClientLib library. Occasionally it will toss errors from the WiFiUdp.cpp file, and error handling is not appropriate (sometimes it doesn’t set time properly). I suspect I’ll have to dig into the networking code in the library a bit deeper.

Addendum: The display on this thing is one of those tiny 0.91″ OLED displays. It’s really at the limits of what I can comfortably read, and I’d like to have more space (and potentially color). I have some small 1.8″ LCD boards, but I stumbled across the M5Stack board which appears to be available on banggood.com. It looks like a cool little box.

I ordered it from this link on banggood for about $33. Besides having an ESP32 module, it includes a case, a 320×240 2″ color LCD panel, and three buttons. The larger display size and buttons are a great fit for my ISS project. When it arrives, I’ll quickly work on a port of this code to that.

If that doesn’t work, I’ll probably work on adapting it to some of the ST7735 modules I have lying around that I ordered from icstation.com.

Stay tuned for more progress, and eventually links to the git repository for the code when I am not embarrassed by the code.

Brief Update on my ESP32 ISS Clock

Several days ago, I cobbled together a short bit of code to make an NTP enabled clock out of an ESP32/OLED module. I had previously used an ESP8266 and a separate module to make a little demo that predicted the location of the ISS. I thought that the ESP32 would make a better development platform, for a number of reasons:

  • It’s faster.
  • It is dual core.
  • It includes a small real time operating system that allows you to create communicating tasks.

My early example didn’t make any use of that, it was just a clock. So today I spent a little more than an hour to expand the basic code outline to include some new features:

  • It now links in my C++ library that implements the Plan 13 algorithm for doing satellite prediction.
  • The previous NTPClient library wasn’t really very good: it didn’t include any way of accessing day/month/year. I switched it to use NTPClientLibinstead, which is much better.
  • I experimented with using the xTaskCreate call to create different tasks, one of who updates the current satellite position, and the other which updates the display. This proved to not be difficult and works remarkably well. I anticipate that this will make my final version of the code easier to write. I can implement one process whose job it is to scan forward in time, looking for the next satellite pass. When it finds one, it can use a queue to send it to the display task, and can continue. This makes the program easier to write and more modular.
  • I also did some work to fetch orbital elements directly from celestrak.com so that the display will always be up to date.

The code is not in a state to share yet but I think it is going to be pretty neat when I’m done. The gadget could easily be mounted in a small case and carried into the field, where it could be entirely battery powered.

Stay tuned for updates.

pinMode v. digitalWrite: what’s with this use (abuse?) of internal pullups?

This post is the kind of round about post you get first thing in the morning.   I’ll get to the title question at the end.

This morning, I was interested in doing a tiny bit of tinkering. I had found one of these 4 digit 7 segment LED displays while digging around for something else. You can get these modules for about $2.50 from banggood, and potentially for as little as a buck on eBay.

A little over a week ago, I was tinkering with a WeMOS D1 Mini board that I had acquired, and decided to port my Plan-13 library to it. Long (long long) time readers may remember some years ago that I wrote this code to predict the position of satellites, first in Python, but then ported it to C and had it running on the Arduino as part of my ANGST (Arduino ‘n Gameduino Satellite Tracker) project. But that project had a number of shortcomings:

  • It was fairly complicated, and required a number of additional add-ons to work.  I used the Gameduino to generate graphics, had an external RTC and EEPROM to store orbital data, and used an optical shaft encoder to move around.  Yes, it was attractive and fun, but not cost effective.
  • It had no easy way to update orbital elements.  You had to connect it to a PC and reprogram it with new orbital elements each time you needed an update.

But these WeMOS boards are built around the ESP8266 modules, which have a number of advantages:

  • They are based around an 80Mhz 32 bit processor, instead of a 16Mhz 8 bit processor.
  • They have 4Mbytes of flash memory.  You can easily configure some small part of that to serve as a miniature file system, ample to store orbital elements without any additional hardware.
  • They are cheap: around $5.
  • And most intriguingly: they have WiFi. 

So, I worked on the spiritual descendent of ANGST.   Using the platformio system I moved a copy of my Plan13 library to a new project, and started tinkering.   As of now, the project:

  • Wakes up and connects to my local WiFi network
  • Establishes a connection to an NTP server, so I can get the time
  • Connects to Celestrak and downloads the latest orbital elements for the ISS
  • Predicts the next three passes from my home location
  • And then enters a loop, predicting the sub-satellite latitude and longitude, its location relative to some major world cities, and if it is above the horizon, then the azimuth and altitude of the satellite.

Here is the current data as I write this:

But the one thing it did not have until this morning was an external display.  Hence, the TM1637, and a little tinkering.

Time is in GMT, but eventually I will also have it have the option of using local time (it is more convenient to use GMT for the satellite computations.)

To get this to work, I could have dusted off the work to drive the similar TM1640 based displays that I used in another project, but I thought that I’d use a standard library instead.   The platformio system has a pretty nifty library manager, so I searched for a library, found one (cool!) and it claimed compatibility with the ESP8266.  Neat.

So I read some of the example code, patched it to output the time in the main loop(), and tried it.

It didn’t work.

I double-checked connections.

It didn’t work.

I tried their example.

It didn’t work.  The displays remained dark.

Grumble.  I opened up the code and tried to see what was going on.   It didn’t take me too long to figure out what was going on:

Here is a link to the code, and a screen grab of the offending lines:

Link to the source on github

It’s not exactly my first rodeo, so I was immediately suspicious when I saw that the initializer set the mode for the two pins to INPUT, rather than OUTPUT, but then immediately wrote to them.  That doesn’t seem right, does it?

Well, this isn’t even my second rodeo.  I know that Arduino’s ATMega328 processor has internal pull up resistors, and I’ve seen odd code which used pinMode to swap back and forth between high and low, not using pinMode.

But the ESP8266 (thought I) doesn’t have internal pull ups.   I’m pretty sure that’s true, but I never got to verify it, because all of a sudden, with no change whatsoever, my program started working.

hate it when that happens. 

It’s been that kind of a week.

But it made me think about how this works.  Here is my guess, and I’d appreciate corrections.

During initialization, it sets pinMode to INPUT, and writes a LOW value to the data pin.   Even though we’ve written a LOW, the pin is pulled HIGH by the action of the (external) pull up resistor.

When the driver wishes to shift the output pin to LOW, it uses pinMode() to shift the type for the pin to OUTPUT.   When it wants it to be high, it sets pinMode() to INPUT.

I find this odd in a couple of ways:

  • It is not any shorter or more efficient than using digitalWrite.
  • It is certainly no clearer.

Is there something I’m missing about why you would code this stuff this way?

Of course, I wouldn’t have dug into this code at all had I not had a mysterious (and fleeting) failure at the beginning, so I am not sure how it really matters.

Addendum:  While I was typing this, the ISS did a 65 degree elevation pass which was captured thusly.  I only then noticed that it was producing duplicate messages for each five second message.  Must have goofed when I installed the code to blink the clock’s “colon” segments.  I’ll get it sorted later.

 

How making an ISS clock turns into researching an optimization problem involving spherical Voronoi diagrams…

A few years ago, I got seriously interested in amateur radio and satellites. I would often haul out a small Yagi antenna and my trusty Kenwood TH-D7A and try to talk to other hams by bouncing signals off the various satellites which acted as amateur radio repeaters. During that time, I wrote a Python version of G3RUH’s Plan-13 algorithm for predicting satellite locations. Eventually, I converted that code to C++ and made an Arduino/Gameduino version that I called “Angst”.



But there were a number of problems with it as a general project. Most notably, it utilized some special hardware which made it more expensive than I would like, and it required an external display. I suppose I could have found a small composite display, but one serious issue remained: there was no simple way to update the orbital elements that are used to predict the satellite locations. The ISS is particularly problematic, since it is in low earth orbit and frequently fires its engines to boost it to a higher orbit, which is not something that can be accounted for statically.

But in the years since I did that project, the ESP8266 has taken the world by storm. Not only is it cheap (I got some WeMos D1 Mini clones for less than $5 shipped from China) but it is faster (an 80Mhz 32 bit processor) and most importantly includes WiFi.

For the last couple of days, I’ve been tinkering my old Plan-13 code together with some new code written especially for the ESP8266 to create a “clock” that will automatically tell me the position of the ISS and details about the next pass. The nice thing is that since the ESP8266 has WiFi, it can update itself automatically. Right now, I have code running that contacts celestrak.com, finds the latest orbital elements, predicts the next three passes, and then enters a loop where it shows the current position of the ISS every five seconds. Right now, it just echoes that information out on the serial line, but eventually I’ll get a tiny TFT or LED display to display the live information:

But just seeing the latitude and longitude of the “sub satellite” point didn’t really help me know where the satellite was in its orbit. Sure, I could (and probably will) make a little graphical display for the gadget sooner or later, but I thought it might be nice if I could have it tell me when it was passing close to certain major cities. To give this a try, I found a list of world cities and their coordinates and population, and selected the top fifty cities of the world and within the United States (make one hundred cities total) and then when I do a prediction, quickly compute the distance and bearing to each of the cities and display the closest one. And that works, and doesn’t take too much time. You can see in the run above that the closest city was Honolulu.

But, I noticed a problem.

If you imagine that the earth is a sphere, and imagine that the each city is a point on the surface which you can think of as a seed. If you collect all points on the sphere that are closest (in the great circle) sense to that point than any other seed, you end up with the globe being divided up into a number of regions, each bounded by arcs of a great circle. If you took the same computer and math classes as me, you can recognize this as a “spherical voronoi diagram”. You can read about them here where I swiped the illustration from. Here is the Voronoi diagram of the earth with seeds at each of the World Airports:

You’ll notice something: the regions are widely varying in size. If I had loaded my ISS code with these locations, it would spend a lot of time talking about how it is thousands of miles from some remote airport in the middle of the Pacific, but when it was flying over the United States, it would rapidly shift from region to region. Indeed, because population centers are often close, it might be fairly rare for it to be closest to New York City, even though it is perhaps an obvious landmark, more obvious than the smaller ones that surround it. It might also be the case that if you have two population centers which are fairly close to one another, that approaching from one side would be masked by the other city.

Ideally, we’d like a collection of cities which:

  • are well known
  • divide the globe into a number of Voronoi regions which are nearly the same size
  • and where shape of the Voronoi regions are not too lopsided, so the cities are near the center of a roughly circular region

I haven’t figured out how to do this yet, but I’m betting that I am going to use some kind of genetic algorithm/simulated annealing approach. Stay tuned.

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:

iss

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…

WordPress › Error

There has been a critical error on this website.

Learn more about troubleshooting WordPress.