From 2f6b0e2d12a9334cad0a4a46ceba058a293f9949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6rkem?= Date: Sat, 15 Feb 2025 17:18:50 -0800 Subject: [PATCH] archive code for AstroClock --- Firmware/Astroclock.ino | 316 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 Firmware/Astroclock.ino diff --git a/Firmware/Astroclock.ino b/Firmware/Astroclock.ino new file mode 100644 index 0000000..83f6419 --- /dev/null +++ b/Firmware/Astroclock.ino @@ -0,0 +1,316 @@ +#include +#include +#include +#include + +//display pins +#define CLK 8 +#define DIO 9 + +//varibles to calculate LST +double M,Y,D,MN,H,S,A,B; +double LST_hours,LST_degrees; + +//define GPS pins and The serial connection to the GPS device +static const int RXPin = 3, TXPin = 2; +static const uint32_t GPSBaud = 9600; +TinyGPSPlus gps; +SoftwareSerial ss(RXPin, TXPin); +int gpsOld = gps.time.minute(); + +//define 7-digit display pins +TM1637Display display(CLK, DIO); + +//----------------------8x8 matrix display-------------------- + +int INTENSITYMIN = 0; // minimum brightness, valid range [0,15] +int INTENSITYMAX = 8; // maximum brightness, valid range [0,15] + +int DIN_PIN = 4; // data in pin +int CS_PIN = 5; // load (CS) pin +int CLK_PIN = 6; // clock pin + +// MAX7219 registers +byte MAXREG_DECODEMODE = 0x09; +byte MAXREG_INTENSITY = 0x0a; +byte MAXREG_SCANLIMIT = 0x0b; +byte MAXREG_SHUTDOWN = 0x0c; +byte MAXREG_DISPTEST = 0x0f; + +//----------------------Moon phases-------------------------- +unsigned char fullMoon[] = +{ + B00111100, + B01111110, + B11111111, + B11111111, + B11111111, + B11111111, + B01111110, + B00111100 +}; + +const unsigned char newMoon[] = +{ + B00111100, + B01000010, + B10000001, + B10000001, + B10000001, + B10000001, + B01000010, + B00111100 +}; + +const unsigned char firstQuarter[] = +{ + B00001100, + B00001110, + B00001111, + B00001111, + B00001111, + B00001111, + B00001110, + B00001100 +}; + +const unsigned char thirdQuarter[] = +{ + B00110000, + B01110000, + B11110000, + B11110000, + B11110000, + B11110000, + B01110000, + B00110000 +}; + +const unsigned char waningCrescent[] = +{ + B00111100, + B01110000, + B11100000, + B11100000, + B11100000, + B11100000, + B01110000, + B00111100 +}; + +const unsigned char waxingCrescent[] = +{ + B00111100, + B00001110, + B00000111, + B00000111, + B00000111, + B00000111, + B00001110, + B00111100 +}; + +unsigned char waxingGibbous[] = +{ + B00111100, + B01011110, + B10111111, + B10111111, + B10111111, + B10111111, + B01011110, + B00111100 +}; + +unsigned char waningGibbous[] = +{ + B00111100, + B01111010, + B11111101, + B11111101, + B11111101, + B11111101, + B01111010, + B00111100 +}; + +//----------------------------------------------------------- +void setup() { + Serial.begin(115200); //Serial communication + ss.begin(GPSBaud); //Serial communication for GPS + + pinMode(DIN_PIN, OUTPUT); + pinMode(CLK_PIN, OUTPUT); + pinMode(CS_PIN, OUTPUT); + + // initialization of the MAX7219 + setRegistry(MAXREG_SCANLIMIT, 0x07); + setRegistry(MAXREG_DECODEMODE, 0x00); // using an led matrix (not digits) + setRegistry(MAXREG_SHUTDOWN, 0x01); // not in shutdown mode + setRegistry(MAXREG_DISPTEST, 0x00); // no display test + setRegistry(MAXREG_INTENSITY, 0x0f & INTENSITYMAX); + + +} + +void loop() { + + smartDelay(0); + display.setBrightness(0x0f); + + if(gps.time.minute()!=gpsOld){ + LST_time(); + int rHours =(int) LST_hours; + int rMinutes = ((int)floor((LST_hours-rHours)*60)); + display.clear(); //reset display + display.showNumberDecEx(((rHours*100)+rMinutes),0b01000000,true,4,0); + int moonAge = ConwayMoon(gps.date.year(),gps.date.month(),gps.date.day()); + drawMoon(moonAge); //draw the moon to 8x8 display + gpsOld = gps.time.minute(); + + //Serial print for debuging + /* + Serial.print("UTC: "); + Serial.print(gps.time.hour()); + Serial.print(":"); + Serial.println(gps.time.minute()); + Serial.print("Sidereal: "); + Serial.println(LST_hours); + Serial.print("Moon age: "); + Serial.println(moonAge); + */ + } +} + +//smart delay for GPS +static void smartDelay(unsigned long ms){ + unsigned long start = millis(); + do + { + while (ss.available()) + gps.encode(ss.read()); + } while (millis() - start < ms); +} + +void LST_time(){ + //Calculates local sidereal time based on this calculation, + //http://www.stargazing.net/kepler/altaz.html + M = (double) gps.date.month(); + Y = (double) gps.date.year(); + D = (double) gps.date.day(); + MN = (double) gps.time.minute(); + H = (double) gps.time.hour(); + S = (double) gps.time.second(); + A = (double)(Y-2000)*365.242199; + B = (double)(M-1)*30.4368499; + double JDN2000=A+B+(D-1)+gps.time.hour()/24; + double decimal_time = H+(MN/60)+(S/3600) ; + double LST = 100.46 + 0.985647 * JDN2000 + gps.location.lng() + 15*decimal_time; + LST_degrees = (LST-(floor(LST/360)*360)); + LST_hours = LST_degrees/15; + + +} + +void setRegistry(byte reg, byte value){ + digitalWrite(CS_PIN, LOW); + + putByte(reg); // specify register + putByte(value); // send data + + digitalWrite(CS_PIN, LOW); + digitalWrite(CS_PIN, HIGH); +} + +void putByte(byte data){ + byte i = 8; + byte mask; + while (i > 0) + { + mask = 0x01 << (i - 1); // get bitmask + digitalWrite( CLK_PIN, LOW); // tick + if (data & mask) // choose bit + digitalWrite(DIN_PIN, HIGH); // send 1 + else + digitalWrite(DIN_PIN, LOW); // send 0 + digitalWrite(CLK_PIN, HIGH); // tock + --i; // move to lesser bit + } +} +int ConwayMoon(int cYear,int cMonth,int cDay){ + int s; + int yy; + int d; + s = cYear % 100; + s = s % 19; + if (s>9){ + s -= 19; + } + + s = ((s * 11) % 30) + cMonth + cDay; + + if (cMonth<3){ + s += 2; + } + s = ((int)floor(s-7.8))%30; + + if(s<0){ + s = s+30; + } + return s; +} +int drawMoon(int s){ + //drawing the moon + switch (s) { + case 0: case 1: case 29: + // New moon + for (int i = 0; i < 8; i++){ + setRegistry(i+1,newMoon[i]); + } + break; + case 2: case 3: case 4: case 5: case 6: + // waxing crescent + for (int i = 0; i < 8; i++){ + setRegistry(i+1,waxingCrescent[i]); + } + break; + case 7: case 8: + // first quarter + for (int i = 0; i < 8; i++){ + setRegistry(i+1,firstQuarter[i]); + } + break; + case 9: case 10: case 11: case 12: case 13: + // waxing gibbous + for (int i = 0; i < 8; i++){ + setRegistry(i+1,waxingGibbous[i]); + } + break; + case 14: case 15: case 16: + // full moon + for (int i = 0; i < 8; i++){ + setRegistry(i+1,fullMoon[i]); + } + break; + case 17: case 18: case 19: case 20: case 21: + // waning gibbous + for (int i = 0; i < 8; i++){ + setRegistry(i+1,waningGibbous[i]); + } + break; + case 22: case 23: + // third quarter + for (int i = 0; i < 8; i++){ + setRegistry(i+1,thirdQuarter[i]); + } + break; + case 24: case 25: case 26: case 27: case 28: + // waning crescent + for (int i = 0; i < 8; i++){ + setRegistry(i+1,waningCrescent[i]); + } + default: + // empty moon + break; + } +}