-
Notifications
You must be signed in to change notification settings - Fork 0
/
Open_Cosmos_qbcan_releaser_source_code.ino
172 lines (132 loc) · 3.47 KB
/
Open_Cosmos_qbcan_releaser_source_code.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
/* --------------------------------
This code is provided to the European Space Agency by
Open Cosmos Ltd. for the qbcan Cansat Releaser.
The qbcan user manual can be found on http://doc.open-cosmos.com/
For queries regarding purchase of qbcan and qbcan releaser,
please visit www.open-cosmos.com/shop or contact qbshop@open-cosmos.com
Find more information about Open Cosmos at www.open-cosmos.com
Open Cosmos Ltd. 2016
-----------------------------------
*/
#include <stdlib.h>
#include <stdio.h>
#include <SimpleTimer.h>
#include <Servo.h>
// Timer Variables
//----------------------------------------------------------
//*******************************
//* Release time in miliseconds *
//*******************************
const unsigned long int release_time = 60000; // [ms]
//----------------------------------------------------------
SimpleTimer timer;
int timers_set = 0;
int timerId;
int flashId;
const int flash_period = 800;
// Servo Variables
Servo servo1;
const int pos1 = 180; // [deg] servo does not go above 180
const int pos2 = 12; // [deg] servo lower limit is 12
int servoState = 0;
// Pin Assignments
const int servoPin = 10;
const int ledPin = 17;
const int switchPin = 2;
void activate_servo();
void close_system();
void check_switch();
void flash_led();
void set_timers();
void unset_timers();
void setup()
{
servo1.attach(servoPin);
/* "Timer active" LED */
pinMode(ledPin, OUTPUT);
// Timer Setup
set_timers();
// Mechanical Switch Setup
pinMode(switchPin, INPUT_PULLUP);
Serial.println("Starting");
}
void set_timers()
{
if (timers_set) {
unset_timers();
}
timerId = timer.setTimeout(release_time, activate_servo);
flashId = timer.setInterval(flash_period / 2, flash_led);
digitalWrite(ledPin, LOW);
Serial.println("Timer enabled");
timers_set = 1;
}
void unset_timers() {
if (!timers_set) {
return;
}
timer.deleteTimer(timerId);
timer.deleteTimer(flashId);
digitalWrite(ledPin, HIGH);
Serial.println("Timer disabled");
timers_set = 0;
}
void loop()
{
// Check switch position and control servo as needed
check_switch();
// Update Timer
timer.run();
}
void activate_servo()
{
Serial.println("Opening releaser");
servo1.write(pos1); // servo position set as (+) 180 deg
/* Disable the timer */
unset_timers();
delay(15);
}
void close_system()
{
Serial.println("Closing releaser");
servo1.write(pos2); // servo position set as (+) 180 deg
/* Enable the timer */
set_timers();
delay(15);
}
void flash_led()
{
static int state = 0;
state ^= 1;
digitalWrite(ledPin, state ? HIGH : LOW);
}
void check_switch()
{
int switchState = digitalRead(switchPin);
const int threshold = 5;
static int hysteresis = 0;
static int lastAction = 0;
int action;
/* Hysteretic state tracker, generates action if counter exceeds threshold */
hysteresis += switchState == LOW ? 1 : -1;
if (hysteresis > threshold) {
hysteresis = threshold;
action = 1;
} else if (hysteresis < -threshold) {
hysteresis = -threshold;
action = -1;
} else {
return;
}
/* If action is same as last action, do nothing */
if (action == lastAction) {
return;
}
lastAction = action;
if (action == 1) {
activate_servo();
} else if (action == -1) {
close_system();
}
delay(50);
}