Close
0%
0%

How Far is Mars

A project to continually display the distance to every planet

Similar projects worth following
The Arduino controller will calculate the distance from Earth to Mars and display it. I'll use the reference source "Astronomical Algorithms" by Jean Meeus. (ISBN 0-943396-61-1) The precision that I can approximate will determine the number of digits on the display.

The formulas to calculate the position of Mars and Earth are documented in Meeus' book. The book's formulas are truncated from the original formulas for conciseness.

The formula system is called "VSOP87". It's one crucial property is that you can choose the accuracy of the result by using different numbers of terms. In addition, you can calculate the accuracy explicitly using the values in the system.

The systems are available to calculate XYZ of the planets as well as spherical coordinates. Once the earth's xyz and mars' xyz are known, it's simple trig to get the distance from a given longitude, latitude and altitude.

Earth.js

Coefficient tables for the position of Earth

javascript - 226.47 kB - 10/25/2018 at 22:57

Download

Mercury.js

Coefficient table for Mercury

javascript - 442.19 kB - 10/25/2018 at 22:58

Download

Venus.js

Coefficient table for Venus

javascript - 158.77 kB - 10/25/2018 at 22:58

Download

Mars.js

Coefficients for Mars

javascript - 442.86 kB - 10/25/2018 at 22:58

Download

Jupiter.js

Coefficients for Jupiter

javascript - 293.47 kB - 10/25/2018 at 22:59

Download

View all 8 files

  • 1 × Duemilanove To create a (way) stripped down version (i.e. it's in my parts bin)
  • 3 × quad 5/8" seven segment LED displays 7 segment displays in my parts box
  • 2 × 74LS138 display decoder
  • 2 × 74ALS240 display drivers
  • 7 × 2200 ohm resisters LED load wresistors

View all 6 components

  • Web page released

    Bill Smith01/17/2021 at 01:58 0 comments

    I finally made a final version out of this. It ended up being a web page http://www.sesquibits.com/mars

    One link,  How far are the planets from Earth? (sesquibits.com) does what the initial goal intended, to continuously update a display of relative distance, speed and acceleration.

    The other, bigger page How far is Mars? (sesquibits.com) lets the user search for events like maximum distance and opposition.

    Both pages can be retargeted to any planet.

    One feature that I like is that you can create a link to the current display  For example, How far is Mars? (sesquibits.com) is the opposition of Mars wrt. Earth that happened.

    [Perhaps I should change the title when you do capture image so that you can see what it represents in the title.]

  • Too big

    Bill Smith08/01/2020 at 19:53 0 comments

    The size of the coefficient tables is too big to include in an AVR. I haven't attempted to fit it into  a Beaglebone or Raspberry Pi. I'm sure it'll fit, but I haven't started to go that way.

    I've been working on a couple web pages for quite a while. One page dynamically updates the distances. The other draws an explorable graph of distance, relative speed and relative acceleration.

    I have been moving very slowly on the project but it's not forgotten.

  • Moving to HTML

    Bill Smith10/25/2018 at 22:56 0 comments

    I've given up on making this in hardware and am developing a web page instead.

    I have a Perl script to convert the data tables from VSOP87 ftp://ftp.imcce.fr/pub/ephem/planets/vsop87 and described in

    The coefficient tables used by the website are derived from 
    Planetary" class="redactor-linkify-object">http://adsabs.harvard.edu/full/1988A%26A...202..309B">Planetary theories in rectangular and spherical variables-VSOP 87 solutions by 
    Pierre Bretagnon, Pierre, and Gérard Francou and published in
    Astronomy and Astrophysics, vol. 202, Aug. 1988, p. 309-315. 

    I've attached the VSOP87C tables converted to Javascript.

  • First light

    Bill Smith11/18/2015 at 18:14 0 comments

    I got the first test of the circuit going yesterday. I went down to TekVenture to see whether I'm more productive down there away from all of the distractions at home.

    Here's the top & bottom of the display circuit's circuit board

    The scribbling on the board helped me avoid making mistakes as I was assembling it. It worked because all of the LEDs worked first time. I'm short one 74xx138 so the left four digits don't have any power.

    Here's the demo program at work...

  • Won't Fit

    Bill Smith11/12/2015 at 05:00 0 comments

    I used my scripts to build a full set of arrays of the function tables. I used all of the data from the files of formulas to generate fixed-point C constant files.

    I compiled the C constants. The .o file was 254218 bytes long. I'm not sure how much overhead there is in the .o file, but it can't be much considering the data is all large unsigned char arrays.

    That means that the data tables won't fit in a AVR. I don't want to upgrade to a 32 bit AVR or ARM that have enough flash to save the tables. I like that making an AVR as the host is something that I can put on a PCB and be pretty confident that it will work the first time. I'm pretty confident different platform than 8 bit AVR would be better but I don't want to go there yet.

    In my parts box I have a 4 MB flash chip that I can use to hold the parameters.

    Today's project was writing Perl multiple precision algorithms to build CORDIC algorithms and make the calculations outside of the microcontroller. I only got multiplication working because I spent a lot (too much) time writing testing code.

    It's looking like I'm fortunate that you can calculate the d/dt of the position. That way I can do the full calculations in the background yet keep the display moving continuously.

  • Processing the data tables

    Bill Smith11/03/2015 at 04:19 0 comments

    I have a script that takes the raw numeric tables and truncates the list and estimates the accuracy. It generates a .pm file

    When the values are being calculated, fixed point arithmetic will be used.

    Here is a bit of the Earth.pm file:

    package Earth;
    @params_X_exp0_A = (
    	"A: X: T ^ 0",
    	"0.99986069925",
    	"0.02506324281",
    	"0.00835274807",
    	"0.00010466796",
    	"0.00003490608",
    	"0.00003110838",
    	"0.00002561408"
    );
    
    @params_X_exp0_B = (
    	"B: X: T ^ 0",
    	"1.75347045757",
    	"4.93819429098",
    	"1.71033525539",
    	"1.66721984219",
    	"4.44373803231",
    	"0.66875189331",
    	"0.58588607490"
    );
    
    @params_X_exp0_C = (
    	"C: X: T ^ 0",
    	"6283.31966747490",
    	"0.24381748350",
    	"12566.39551746630",
    	"18849.47136745770",
    	"6282.83203250789",
    	"83997.09113559539",
    	"529.93478257810"
    );
    
    Then, a second script converts these numbers into a truncated binary representation. I put the numbers into a little-endian unsigned char array. The different exponents of T are combined into single arrays with the startIndex indicating the boundary between exponents.

    For example, from above, I get info6.h;

    extern const int bytesPerFraction;
    extern const int bytesPerInteger[];
    extern const unsigned char earth_AHi_X[ ];
    extern const unsigned char earth_ALo_X[ ];
    extern const unsigned char earth_BHi_X[ ];
    extern const unsigned char earth_BLo_X[ ];
    extern const unsigned char earth_CHi_X[ ];
    extern const unsigned char earth_CLo_X[ ];
    extern const int earth_sections_X;
    extern const int earth_startIndex_X[1];
    extern const int earth_terms_X;
    
    and info6.c
    /*
    6 Digits
    BCOUNT (fraction): 3
    BCOUNT[A] (integer): 1, max max 1.51664432758
    BCOUNT[B] (integer): 1, max max 6.20347631684
    BCOUNT[C] (integer): 3, max max 84334.66158130829
    Earth:
    	X_A: T ^ 0: 0.99986069925
    	X_B: T ^ 0: 4.93819429098
    	X_C: T ^ 0: 83997.09113559539
    ... 
    */
    
    const int bytesPerFraction = 3; /* 24; 16777216 */
    const int bytesPerInteger[] = {
    	1 /* A: 1.51664432758 */,
    	1 /* B: 6.20347631684 */,
    	3 /* C: 84334.66158130829 */
    };
    
    const unsigned char earth_AHi_X[ ] = {
    	0x00	/* 0 0x0 */,
    	0x00	/* 0 0x0 */,
    	0x00	/* 0 0x0 */,
    	0x00	/* 0 0x0 */,
    	0x00	/* 0 0x0 */,
    	0x00	/* 0 0x0 */,
    	0x00	/* 0 0x0 */
    };
    
    const unsigned char earth_ALo_X[ ] = {
    	0xde, 0xf6, 0xff	/* 16774878 0xfff6de */,
    	0x8b, 0x6a, 0x06	/* 420491 0x66a8b */,
    	0x67, 0x23, 0x02	/* 140135 0x22367 */,
    	0xdc, 0x06, 0x00	/* 1756 0x6dc */,
    	0x49, 0x02, 0x00	/* 585 0x249 */,
    	0x09, 0x02, 0x00	/* 521 0x209 */,
    	0xad, 0x01, 0x00	/* 429 0x1ad */
    };
    
    const unsigned char earth_BHi_X[ ] = {
    	0x01	/* 1 0x1 */,
    	0x04	/* 4 0x4 */,
    	0x01	/* 1 0x1 */,
    	0x01	/* 1 0x1 */,
    	0x04	/* 4 0x4 */,
    	0x00	/* 0 0x0 */,
    	0x00	/* 0 0x0 */
    };
    
    const unsigned char earth_BLo_X[ ] = {
    	0x70, 0xe3, 0xc0	/* 12641136 0xc0e370 */,
    	0x80, 0x2d, 0xf0	/* 15740288 0xf02d80 */,
    	0x88, 0xd8, 0xb5	/* 11917448 0xb5d888 */,
    	0xeb, 0xce, 0xaa	/* 11194091 0xaaceeb */,
    	0xd0, 0x98, 0x71	/* 7444688 0x7198d0 */,
    	0x52, 0x33, 0xab	/* 11219794 0xab3352 */,
    	0xa1, 0xfc, 0x95	/* 9829537 0x95fca1 */
    };
    
    const unsigned char earth_CHi_X[ ] = {
    	0x8b, 0x18, 0x00	/* 6283 0x188b */,
    	0x00, 0x00, 0x00	/* 0 0x0 */,
    	0x16, 0x31, 0x00	/* 12566 0x3116 */,
    	0xa1, 0x49, 0x00	/* 18849 0x49a1 */,
    	0x8a, 0x18, 0x00	/* 6282 0x188a */,
    	0x1d, 0x48, 0x01	/* 83997 0x1481d */,
    	0x11, 0x02, 0x00	/* 529 0x211 */
    };
    
    const unsigned char earth_CLo_X[ ] = {
    	0xba, 0xd5, 0x51	/* 5363130 0x51d5ba */,
    	0xd2, 0x6a, 0x3e	/* 4090578 0x3e6ad2 */,
    	0xa1, 0x40, 0x65	/* 6635681 0x6540a1 */,
    	0x89, 0xab, 0x78	/* 7908233 0x78ab89 */,
    	0x15, 0x00, 0xd5	/* 13959189 0xd50015 */,
    	0xa9, 0x54, 0x17	/* 1529001 0x1754a9 */,
    	0xe9, 0x4d, 0xef	/* 15683049 0xef4de9 */
    };
    
    const int earth_sections_X = 1;
    const int earth_startIndex_X[1] = {
    	0
    };
    const int earth_terms_X = 7;
    
    
    These were generated with at least 6 decimal digits of fractions.

  • The current time in millennia

    Bill Smith10/04/2015 at 23:56 0 comments

    sub JulianDate
    {
            splice @_, $#_ + 1, 0, 0, 0, 0;
    	my( $mo, $day, $yr, $hr, $min, $sec) = @_;
    
    	if( $mo <= 2 ) {
    		$yr -= 1;
    		$mo += 12;
    	}
    
    	# Assumes after 10/4/1582 (Gregorian calendar)
    	my $a = int( $yr / 100);
    	my $b = 2 - $a + int($a/ 4);
    	$day += ((($sec / 60.0 + $min) / 60.0) + $hr) / 24.0;
    	return int( 365.25 * ($yr + 4716) + int(30.601 * ($mo + 1))) + $day + $b - 1524.5;
    }
    
    
    The formulas require the date from the year 2000
    
    (JulianDate(....) - 2451545.0) / 365250;
    

  • Mathematical resources

    Bill Smith10/04/2015 at 20:54 0 comments

    Here's a reference source http://www.caglow.com/info/compute/vsop87

    The formulas are available to calculate the positions of Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, and Neptune.

    What's cool is that one version of the formulas give the positions in X,Y,Z which makes distance calculations really simple.

  • Accuracy estimate

    Bill Smith10/03/2015 at 22:56 0 comments

    The reference book gave a way of estimating the accuracy of the results. What I found is that the formulas can give me the answer within 1000km.

    This means that a 6 segment display will be enough (between ~54Mkm and ~400Mkm)

    If I go from center of earth to center of mars, the calculations will save a step and it will simplify the information that is needed to just be the current time/date.

View all 9 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates