-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConmunicate Code
More file actions
339 lines (319 loc) · 10.4 KB
/
Conmunicate Code
File metadata and controls
339 lines (319 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
#include <NeoSWSerial.h>
#include <NMEAGPS.h>
#include <GPSport.h>
#include <ServoTimer2.h>
#define I2C_ADDRESS 0x3C
#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"
#define I2C_ADDRESS 0x3C
SSD1306AsciiAvrI2c oled;
NMEAGPS gps; // The NMEAGPS object:
gps_fix fix; // Data placeholder 8 -> TX 9 -> RX
// GPS VARIABLES
// latitude and longitude in float from GPS module,init your GPS north is +, east is + (Tuebingen)
int Year = 2020; // Date (Year)
int Month = 10; // Date (Month)
int Day = 10; // Date (Day)
int timeHH=12; // Time (Hours)
int timeMM=00; // Time (Minutes)
int timeSS=0; // Time (Seconds)
float Latitude=48.5216; // Latitude (signed degrees)
float Longitude=9.0576; // Longitude (signed degrees)
int32_t no_satellites; // Number of satellites
#define pi 3.14159265
#define rad2deg(X) ((X)/pi*180)
#define deg2rad(X) ((X)/180*pi)
double Timenow;
double juliandate;
double gstresult;
double lstresult;
//hour angle 时角
float HA;
//高度,方位 Altitude and Azimuth
float Alt = 0.0, Az = 0.0; // Target star Altitude and Azimuth
float Alt_position = 0, Az_position = 0; // Servo position of Target star Altitude and Azimuth
double ra; //These variables are used in the calculations, double/float/int/byte depending on the type of number needed.
double dec;
//input form stellarium
char inputChar[20];
//init RAHH,RAMM,RASS to visualize the star pointer;
char RAHH[3]="12",RAMM[3]="00",RASS[3]="00";
//init DECSign,DECDeg,DECMM,DECSS to visualize the star pointer;
char DECSign[2]="-",DECDeg[3]="12",DECMM[3]="00",DECSS[3]="00";
String RAtargetString, DECtargetString;
float RADegree, DECDegree;
#define Alt_movepin 10
#define Az_movepin 11
// Servo Objects for PWM Signal Generation
ServoTimer2 Alt_move;
ServoTimer2 Az_move;
void setup() {
Serial.begin(9600); // Main Baud Rate
gpsPort.begin(9600); // Gps Baud Rate
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.setFont(System5x7);
oled.clear();
oled.println("Hey ");
Alt_move.attach(Alt_movepin);
Az_move.attach(Az_movepin);
}
void loop() {
if (gps.available(gpsPort)) {
oled.setCursor(0, 0);
fix = gps.read();
update_gps();
}
while(Serial.available()){
// communicate with Stellarium
todoActions();
getRADEC_in_Degree();
juliandate = julian();
gstresult = UT_to_GST();
lstresult = GST_to_LST();
HA = hourangle();
azalt();
oled.setCursor(0, 0);
break;
}
}
void todoActions(){
int i=0;
inputChar[i++] = Serial.read();
delay(5);
while((inputChar[i++] = Serial.read()) != '#'){
delay(5);
}
inputChar[i]='\0';
oled.setCursor(0, 9);
oled.print(inputChar);
//inputString=inputChar;
//ask telescope RA
//ask telescope present RA 命令#:GR# stellarium询问现在望远镜指向的RA值
if(inputChar[1]==':' && inputChar[2]=='G' && inputChar[3]=='R' && inputChar[4]=='#'){
answerTelRA();//answer telescope RA
}
//ask telescope present DEC 命令#:GD# stellarium询问现在望远镜指向的DEC值
if(inputChar[1]==':' && inputChar[2]=='G' && inputChar[3]=='D' && inputChar[4]=='#'){
answerTelDEC();//answer telescope DEC
}
if(inputChar[1]==':' && inputChar[2]=='Q' && inputChar[3]=='#'){
// quite stop servo motor
}
//arduino get targetRA when user type ctrl+1 #:Q#:Sr 10:10:10# stellarium发送目标RA值命令
if(inputChar[0]==':' && inputChar[1]=='S' && inputChar[2]=='r'){
getTargetRA();
}
//arduino get targetDEC when user type ctrl+1 #:Sd +76:24:55# stellarium发送目标DEC值命令
if(inputChar[0]==':' && inputChar[1]=='S' && inputChar[2]=='d'){
getTargetDEC();
}
if(inputChar[0]==':' && inputChar[1]=='M' && inputChar[2]=='S' && inputChar[3]=='#'){ //:MS# Slew to Target Object
//RETURNS 0 means OK
Servo_Move();
Serial.print("0");
}
}
void answerTelRA(){
Serial.print(RAHH);
Serial.print(":");
Serial.print(RAMM);
Serial.print(":");
Serial.print(RASS);
Serial.print("#");
}
void answerTelDEC(){
Serial.print(DECSign);
Serial.print(DECDeg);
Serial.print((char)223);
Serial.print(DECMM);
Serial.print(":");
Serial.print(DECSS);
Serial.print("#");
}
void getTargetRA(){
Serial.print("1");
RAHH[0]=inputChar[3];
RAHH[1]=inputChar[4];
RAMM[0]=inputChar[6];
RAMM[1]=inputChar[7];
RASS[0]=inputChar[9];
RASS[1]=inputChar[10];
RAtargetString="RA: ";
RAtargetString+=RAHH;
RAtargetString+="h ";
RAtargetString+=RAMM;
RAtargetString+="m ";
RAtargetString+=RASS;
RAtargetString+="s";
}
void getTargetDEC(){
Serial.print("1");
DECSign[0]=inputChar[3];
DECDeg[0]=inputChar[4];
DECDeg[1]=inputChar[5];
DECMM[0]=inputChar[7];
DECMM[1]=inputChar[8];
DECSS[0]=inputChar[10];
DECSS[1]=inputChar[11];
DECtargetString="DEC: ";
DECtargetString+=DECSign;
DECtargetString+=DECDeg;
DECtargetString+="deg ";
DECtargetString+=DECMM;
DECtargetString+="' ";
DECtargetString+=DECSS;
DECtargetString+="''";
}
void update_gps() {
if (fix.valid.time) {
Year = fix.dateTime.year,
Month = fix.dateTime.month,
Day = fix.dateTime.date,
timeHH = fix.dateTime.hours;
timeMM = fix.dateTime.minutes;
timeSS = fix.dateTime.seconds;
Timenow = ((double)timeHH + ((((double)timeSS / 60.0) + (double)timeMM) / 60.0));
}
if (fix.valid.location) {
Latitude = fix.latitudeL()/10000000.0;
Longitude = fix.longitudeL()/10000000.0;
}
no_satellites = fix.satellites;
//Serial.println(no_satellites);
oled.setCursor(0, 1);
oled.print("Lat: ");
oled.println(fix.latitudeL()/10000000.0, 6);
Serial.print(fix.latitudeL()/10000000.0, 6);
oled.setCursor(0, 2);
oled.print("Lon: ");
oled.print(fix.longitudeL()/10000000.0,6);
oled.setCursor(90, 2);
oled.print("Sat#:");
oled.println(fix.satellites, 6);
oled.setCursor(0, 3);
oled.print("Date: "); printDate();
oled.setCursor(0, 4);
oled.print("Time: "); printTime();
}
void getRADEC_in_Degree(){
//RAHH in char, get RA Degree which is hour *15, one hour = 15 degrees
RADegree = (atof(RAHH) + (atof(RAMM)/60) +(atof(RASS)/3600)) *15; // degrees in decimal
//get DEC Degree
DECDegree = (atof(DECDeg) + atof(DECMM)/60 + atof(DECSS)/3600); // degrees in decimal
if (DECSign[0] == '-'){
DECDegree = 0- DECDegree;
}
}
float julian(){ // follow the book [Practical Astronomy with your Calculator or Spreadsheet_4thEd]
//julian date at 0h
double Today = double(Day); //longitude in the west need to minus 1, today like 2009 June (i.e. 6 pm on 19 June is 19.75).
if(Month == 1 || Month == 2){
Month = Month + 12;
Year = Year - 1;
}
int a = floor(Year / 100); // floor to get trunc
int b = 2 - a + floor(a / 4);
float jd = floor(365.25 * (Year + 4716)) + floor(30.6001 * (Month + 1)) + Today + b - 1524.5;
return jd; // get the Julianday i.e. jd = 2455002.25
}
float UT_to_GST(){ //converts Univeral time to Greenwich Sideral time
double s = juliandate - 2451545.0;
double t = s / 36525.0;
double T0 = 6.697374558 + (2400.051336 * t) + (0.000025862 * t * t);
//Reduce the result to the range 0 to 24 by adding or subtracting multiples of 24.
double n1 = floor (T0 /24);
T0 = T0 - (n1 * 24);
double h1 = (Timenow * 1.002737909);
//reduce to the range 0 to 24 if necessary by subtracting or adding 24.
double n2 = floor((T0 + h1)/ 24.0);
double gst = (T0 + h1)- (n2 * 24.0);
return gst; // result with Decimal
}
float GST_to_LST(){ //convers Greenwich time to Local sidereal time
double geolon = (Longitude/15); //Convert the geographical longitude in degrees to its equivalent in hours by dividing by 15.
double lst;
if ((Longitude * -1) > 0){
gstresult = gstresult -geolon;
}
else {
gstresult = gstresult + geolon;
}
if (gstresult > 24){
lst = gstresult - 24;
}
else if ((gstresult * -1)>0){
lst = gstresult +24;
}
else{
lst = gstresult;
}
return lst; // result with Decimal in degrees
}
float hourangle(){ //Hour Angle of star = Local Sidereal Time- Right Ascension of star
float Ha = lstresult - (RADegree/15);
Ha = Ha*15; // Multiply by 15 to convert Ha to degrees
if (Ha < 0){
Ha = 360 + Ha;
}
return Ha ; //hour angle in degrees
}
void azalt() { //This section calculates the Azimuth and the Altitude of the target object.
oled.setCursor(0, 10);
oled.print(HA);
dec = ((DECDegree / 360) * (2 * PI));
Alt=rad2deg(asin(sin(deg2rad(DECDegree))*sin(deg2rad(Latitude))+cos(deg2rad(DECDegree))*cos(deg2rad(Latitude))*cos(deg2rad(HA))));
Az=rad2deg(acos((sin(deg2rad(DECDegree)) -(sin(deg2rad(Alt))*sin(deg2rad(Latitude))))/(cos(deg2rad(Alt)) * cos(deg2rad(Latitude)))));
//if sin(HA) is positive, the angle AZ is 360 - AZ
if (rad2deg(sin(deg2rad(HA))) > 0) {
Az= 360 - Az;
}
if ((Alt*-1)>0) { //If altitude is below 0 degrees, then the object is below the observer's horizon.
oled.setCursor(0, 9);
oled.print("IS BELOW HORIZON");
}
oled.setCursor(0, 5);
oled.print("ALT: ");
oled.println(Alt, 8);
oled.setCursor(0, 6);
oled.print("AZ: ");
oled.println(Az, 8);
}
void printDate()
{
oled.print(fix.dateTime.date);
oled.print("/");
oled.print(fix.dateTime.month);
oled.print("/");
oled.println(fix.dateTime.year);
}
void printTime()
{
oled.print(fix.dateTime.hours);
oled.print(":");
if (fix.dateTime.minutes < 10) oled.print('0');
oled.print(fix.dateTime.minutes);
oled.print(":");
if (fix.dateTime.seconds < 10) oled.print('0');
oled.println(fix.dateTime.seconds);
}
void Servo_Move(){
//Azimuth_Move();
}
void Azimuth_Move(){
if (Az >=0 && Az <=360){
if(Az > Az_position){
for(int val = Az; val >= Az_position; val +=2){
Az_position= val;
Az_move.write(map(Az_position, 0, 180, 750, 2250));
delay(1000);
}
}
else{
for(int val = Az; val <= Az_position; val -=2){
Az_position= val;
Az_move.write(map(Az_position, 0, 360, 750, 2250));
delay(1000);
}
}
}
}