acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

Orrery.ino (4688B)

      1 // Display an Orrery
      2 // Works for all display sizes but 320x480 minimum size recommended
      3 // Whole planet orbits only visible in 480 x 800 display
      4 
      5 // Flicker free sprite example for TFT_eSPI:
      6 // https://github.com/Bodmer/TFT_eSPI
      7 // Sketch coded by Bodmer
      8 // Uses astronomy engine created by Don Cross
      9 
     10 #include <TFT_eSPI.h>                 // Hardware-specific library
     11 
     12 TFT_eSPI    tft = TFT_eSPI();         // Invoke library
     13 
     14 TFT_eSprite img = TFT_eSprite(&tft);  // Sprite class
     15 
     16 #define sunX tft.width()/2
     17 #define sunY tft.height()/2
     18 
     19 uint16_t orb_inc;
     20 uint16_t planet_r;
     21 
     22 #include <stdio.h>
     23 #include "astronomy.h"
     24 #define TIME_TEXT_BYTES  25
     25 
     26 astro_time_t astro_time;
     27 
     28 uint16_t grey;
     29 
     30 static const astro_body_t body[] = {
     31   BODY_SUN, BODY_MERCURY, BODY_VENUS, BODY_EARTH, BODY_MARS,
     32   BODY_JUPITER, BODY_SATURN, BODY_URANUS, BODY_NEPTUNE
     33 };
     34 
     35 static const uint16_t bodyColour[] = {
     36   TFT_YELLOW, TFT_DARKGREY, TFT_ORANGE, TFT_BLUE, TFT_RED,
     37   TFT_GOLD, TFT_BROWN, TFT_DARKCYAN, TFT_CYAN
     38 };
     39 
     40 
     41 // =========================================================================
     42 // Setup
     43 // =========================================================================
     44 void setup() {
     45   Serial.begin(115200);
     46   tft.begin();
     47   tft.setRotation(1);
     48   tft.fillScreen(TFT_BLACK);
     49 
     50   // Test with smaller display sizes
     51   //tft.setViewport(10,10,160,128);
     52   //tft.setViewport(10,10,320,240);
     53   //tft.setViewport(10,10,480,320);
     54   //tft.frameViewport(TFT_GREEN, -1);
     55 
     56   img.createSprite(19, 19);
     57 
     58   grey = tft.color565(30, 30, 30);
     59 
     60   astro_time = Astronomy_MakeTime(2020, 10, 16, 19, 31, 0) ;
     61   tft.fillCircle(sunX, sunY, 10, TFT_YELLOW);
     62 
     63   // i initialised to 1 so Sun is skipped
     64   for (int i = 1; i < sizeof(body) / sizeof(body[0]); ++i)
     65   {
     66     tft.drawCircle(sunX, sunY, i * 28, grey);
     67   }
     68 }
     69 
     70 
     71 // =========================================================================
     72 // Loop
     73 // =========================================================================
     74 void loop() {
     75   uint32_t dt = millis();
     76   plot_planets();
     77   showTime(astro_time);
     78 
     79   // Add time increment (more than 0.6 days will lead to stray pixel on screen
     80   // due to the way previous object images are erased)
     81   astro_time = Astronomy_AddDays(astro_time, 0.25); // 0.25 day (6 hour) increment
     82 
     83   dt = millis()-dt;
     84   //Serial.println(dt);
     85   //delay(1000);
     86 }
     87 
     88 // =========================================================================
     89 // Get coordinates of end of a vector, pivot at x,y, length r, angle a
     90 // =========================================================================
     91 // Coordinates are returned to caller via the xp and yp pointers
     92 #define DEG2RAD 0.0174532925
     93 void getCoord(int x, int y, int *xp, int *yp, int r, float a)
     94 {
     95   float sx1 = cos( -a * DEG2RAD );
     96   float sy1 = sin( -a * DEG2RAD );
     97   *xp =  sx1 * r + x;
     98   *yp =  sy1 * r + y;
     99 }
    100 
    101 // =========================================================================
    102 // Convert astronomical time to UTC and display
    103 // =========================================================================
    104 void showTime(astro_time_t time)
    105 {
    106     astro_status_t status;
    107     char text[TIME_TEXT_BYTES];
    108 
    109     status = Astronomy_FormatTime(time, TIME_FORMAT_SECOND, text, sizeof(text));
    110     if (status != ASTRO_SUCCESS)
    111     {
    112         fprintf(stderr, "\nFATAL(PrintTime): status %d\n", status);
    113         exit(1);
    114     }
    115     
    116     tft.drawString(text, 0, 0, 2);
    117 }
    118 
    119 // =========================================================================
    120 // Plot planet positions as an Orrery
    121 // =========================================================================
    122 int plot_planets(void)
    123 {
    124   astro_angle_result_t ang;
    125 
    126   int i;
    127   int num_bodies = sizeof(body) / sizeof(body[0]);
    128 
    129   // i initialised to 1 so Sun is skipped
    130   for (i = 1; i < num_bodies; ++i)
    131   {
    132     ang = Astronomy_EclipticLongitude(body[i], astro_time);
    133 
    134     int x1 = 0; // getCoord() will update these
    135     int y1 = 0;
    136 
    137     getCoord(0, 0, &x1, &y1, i * 28, ang.angle); // Get x1 ,y1
    138 
    139     img.fillSprite(TFT_TRANSPARENT);
    140     img.fillCircle(9, 9, 9, TFT_BLACK);
    141     img.drawCircle(9 - x1, 9 - y1, i * 28, grey);
    142     img.fillCircle(9, 9, 5, bodyColour[i]);
    143     img.pushSprite(sunX + x1 - 9, sunY + y1 - 9, TFT_TRANSPARENT);
    144 
    145     if (body[i] == BODY_EARTH)
    146     {
    147       astro_angle_result_t mang = Astronomy_LongitudeFromSun(BODY_MOON, astro_time);
    148 
    149       int xm = 0;
    150       int ym = 0;
    151 
    152       getCoord(x1, y1, &xm, &ym, 15, 180 + ang.angle + mang.angle); // Get x1 ,y1
    153 
    154       img.fillSprite(TFT_TRANSPARENT);
    155       img.fillCircle(9, 9, 7, TFT_BLACK);
    156       img.drawCircle(9 - xm, 9 - ym, i * 28, grey);
    157       img.fillCircle(9, 9, 2, TFT_WHITE);
    158       img.pushSprite(sunX + xm - 9, sunY + ym - 9, TFT_TRANSPARENT);
    159     }
    160   }
    161 
    162   return 0;
    163 }