forked from jbsmith96/spaceshark-firmware
-
Notifications
You must be signed in to change notification settings - Fork 0
/
spaceshark.ino
200 lines (173 loc) · 5.56 KB
/
spaceshark.ino
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
// Space Shark microcontroller firmware for Particle Photon
// See project pages at http://github.com/spaceshark
#include "TinyStepper_28BYJ_48.h"
// Define stepper motor pin connections
const int MOTOR_IN1_PIN = 1;
const int MOTOR_IN2_PIN = 2;
const int MOTOR_IN3_PIN = 3;
const int MOTOR_IN4_PIN = 4;
// Constant values defining the value ranges for the alt-az coordinate system:
const float alt_min = -90.0;
const float alt_max = 90.0;
const float az_min = 0.0;
const float az_max = 360.0;
// Create servo motor instances:
Servo servo_alt;
TinyStepper_28BYJ_48 stepper_az;
// These are used to track how long ago each motor had its pointing updated:
float lastUpdate_alt = millis();
float lastUpdate_az = millis();
float stepper_pos = 0;
// The following values are particular to the hardware. Every servo motor is
// a bit different, so the alt and az motors need to be calibrated for their
// maximum and minimum angles. The values below are the ones given to the servo
// 'write' function, which attempts to send control signals matching the angles
// but will be slightly off. These need to be found empirically, e.g. by
// setting the initial pointing to the min and max alt/az angles and then
// nudging these limits either side of their nominal values.
const float limit_alt_lo = 103.0; // Nominally 90.0
const float limit_alt_hi = 9.0; // Nominally 0.0
const float limit_az_lo = 0; // Nominally 0.0
const float limit_az_hi = 2048; // Nominally 360.0
// Set the intial pointing and track rate to use when the Shark is powered on:
float posVal_sky_alt = 0.0; // 0 degrees is horizon, 90 degrees is zenith
float posVal_sky_az = 0.0; // 0 degrees is north, 90 degrees is east
float trackRate_alt = 0.0; // in degrees per second
float trackRate_az = 0.0; // in degrees per second
int optoInt_Val = 0;
bool hasHomed = false;
void setup()
{
// Define servo output pins and register cloud functions:
servo_alt.attach(A4);
stepper_az.connectToPins(MOTOR_IN1_PIN, MOTOR_IN2_PIN, MOTOR_IN3_PIN, MOTOR_IN4_PIN);
Particle.function("point_alt_az", point_alt_az);
Particle.function("track_alt", track_alt);
Particle.function("track_az", track_az);
Serial.begin(9600);
pinMode(D7,OUTPUT);
pinMode(A0,INPUT);
}
void loop()
{
if (hasHomed == true)
{
// This is the main loop, which never stops updating the pointning angles
// based on the current tracking rate.
update_pointing();
set_pos(posVal_sky_alt, posVal_sky_az);
delay(50);
}
else
{
optoInt_Val = analogRead(A0);
Serial.println(optoInt_Val);
if (optoInt_Val <= 1000)
{
hasHomed = true;
}
else
{
signed int x;
x = -64;
stepper_az.setSpeedInStepsPerSecond(2048);
stepper_az.setAccelerationInStepsPerSecondPerSecond(256);
stepper_az.moveRelativeInSteps(x);
}
//delay(5);
}
}
void update_pointing()
{
// Change the current pointing angles based on the current tracking rates
if (trackRate_alt > 0)
{
float now = millis();
float elapsedTime_alt = now - lastUpdate_alt;
posVal_sky_alt = posVal_sky_alt + (trackRate_alt*(elapsedTime_alt/1000.0));
if (posVal_sky_alt > alt_max)
{
posVal_sky_alt = alt_max;
}
lastUpdate_alt = now;
}
else
{
posVal_sky_alt = posVal_sky_alt + 0;
}
if (trackRate_az > 0)
{
float now = millis();
float elapsedTime_az = now - lastUpdate_az;
posVal_sky_az = posVal_sky_az + (trackRate_az*(elapsedTime_az/1000.0));
if (posVal_sky_az > az_max)
{
posVal_sky_az = az_max;
}
lastUpdate_az = now;
}
else
{
posVal_sky_az = posVal_sky_az + 0;
}
}
int set_pos(float alt, float az)
{
// Take current pointing angles, convert them, and move motors:
float posVal_servo_alt = convert_alt(posVal_sky_alt);
float posVal_servo_az = convert_az(posVal_sky_az);
servo_alt.write(posVal_servo_alt);
stepper_az.setSpeedInStepsPerSecond(156);
stepper_az.setAccelerationInStepsPerSecondPerSecond(512);
//float posVal_servo_az_Steps = posVal_servo_az*2048/360;
float diff_move = stepper_pos- posVal_servo_az;
stepper_az.moveRelativeInSteps(diff_move);
stepper_pos = posVal_servo_az;
return 0;
}
// The following functions convert 'sky' coordinates to 'servo' coordinates,
// which account for the motor calibration offsets
float convert_alt(float alt)
{
return sky_to_servo(alt, alt_min, alt_max, limit_alt_lo, limit_alt_hi);
}
float convert_az(float az)
{
return sky_to_servo(az, az_min, az_max, limit_az_lo, limit_az_hi);
}
float sky_to_servo(
float sky,
float sky_min,
float sky_max,
float servo_limit_lo,
float servo_limit_hi)
{
if (sky < sky_min)
return sky_min;
if (sky > sky_max)
return sky_max;
float scale = (sky-sky_min) / (sky_max-sky_min);
return scale * (servo_limit_hi - servo_limit_lo) + servo_limit_lo;
}
// The following fuctions are exposed to the outside world (the cloud):
int point_alt_az(String posString)
{
int sepIndex = posString.indexOf(',');
String posString_alt = posString.substring(0,sepIndex);
String posString_az = posString.substring(sepIndex+1);
posVal_sky_alt = posString_alt.toFloat();
posVal_sky_az = posString_az.toFloat();
float now = millis();
lastUpdate_alt = now;
return 0;
}
int track_alt(String rate)
{
trackRate_alt = rate.toFloat();
return 0;
}
int track_az(String rate)
{
trackRate_az = rate.toFloat();
return 0;
}