Skip to content

Commit 99fd39c

Browse files
Merge pull request #8 from Alpha-CubeSat/fa24
Add Alive signal mode, finalize LoRa parameters, faster radio init, and debugging LEDs
2 parents 28298fb + 4242e18 commit 99fd39c

12 files changed

Lines changed: 137 additions & 108 deletions

src/ControlTasks/RadioControlTask.cpp

Lines changed: 66 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@ RadioControlTask::RadioControlTask()
77
void RadioControlTask::init()
88
{
99
if (!sfr::radio::initialized) {
10-
switch (sfr::radio::start_progress) {
11-
case 0:
10+
if (sfr::radio::start_progress == 0) {
1211
#ifdef VERBOSE
13-
Serial.print(F("Radio: Initializing ... "));
12+
Serial.println(F("Radio: Initializing ... "));
1413
#endif
15-
// initialize SX1278 with default settings
14+
// Initialize SX1278 with default settings
1615
code = radio.begin(constants::radio::freq, constants::radio::bw, constants::radio::sf, constants::radio::cr,
1716
constants::radio::sw, constants::radio::pwr, constants::radio::pl, constants::radio::gn);
1817
if (code == RADIOLIB_ERR_NONE) {
@@ -23,12 +22,13 @@ void RadioControlTask::init()
2322
Serial.println(code);
2423
#endif
2524
}
26-
break;
27-
case 1:
25+
}
26+
27+
if (sfr::radio::start_progress == 1) {
2828
#ifdef VERBOSE
29-
Serial.print(F("Radio: Setting CRC parameter ... "));
29+
Serial.println(F("Radio: Setting CRC parameter ... "));
3030
#endif
31-
// set CRC parameter to true so it matches the CRC parameter on the TinyGS side
31+
// Set CRC parameter to true so it matches the CRC parameter on the TinyGS side
3232
code = radio.setCRC(true);
3333
if (code == RADIOLIB_ERR_NONE) {
3434
sfr::radio::start_progress++;
@@ -38,39 +38,51 @@ void RadioControlTask::init()
3838
Serial.println(code);
3939
#endif
4040
}
41-
break;
42-
case 2:
41+
42+
if (sfr::radio::start_progress == 2) {
4343
#ifdef VERBOSE
44-
Serial.print(F("Radio: Setting forceLDRO parameter ... "));
44+
Serial.println(F("Radio: Setting forceLDRO parameter ... "));
4545
#endif
46-
// set forceLDRO parameter to true so it matches the forceLDRO parameter on the TinyGS side
47-
code = radio.forceLDRO(true);
48-
if (code == RADIOLIB_ERR_NONE) {
49-
sfr::radio::start_progress++;
50-
} else {
46+
// Set forceLDRO parameter to true so it matches the forceLDRO parameter on the TinyGS side
47+
code = radio.forceLDRO(true);
48+
if (code == RADIOLIB_ERR_NONE) {
49+
sfr::radio::initialized = true;
50+
} else {
5151
#ifdef VERBOSE
52-
Serial.print(F("failed, code "));
53-
Serial.println(code);
52+
Serial.print(F("failed, code "));
53+
Serial.println(code);
5454
#endif
55+
}
5556
}
56-
break;
57-
case 3: // completed initialization
58-
sfr::radio::initialized = true;
59-
break;
6057
}
6158
}
6259
}
6360

6461
bool RadioControlTask::transmit(uint8_t *packet, uint8_t size)
6562
{
63+
// Blink LED during transmit
64+
if (millis() - sfr::gps::boot_time > constants::led::led_on_time) {
65+
digitalWrite(constants::led::led_pin, HIGH);
66+
}
67+
68+
#ifdef VERBOSE
6669
uint32_t start = millis();
70+
#endif
6771
code = radio.transmit(packet, size);
72+
#ifdef VERBOSE
6873
uint32_t time = millis() - start;
74+
#endif
75+
76+
if (millis() - sfr::gps::boot_time > constants::led::led_on_time) {
77+
digitalWrite(constants::led::led_pin, LOW);
78+
}
79+
#ifdef VERBOSE
6980
Serial.print(F("Time to transmit (ms): "));
7081
Serial.println(time);
82+
#endif
7183

7284
if (code == RADIOLIB_ERR_NONE) {
73-
// the packet was successfully transmitted
85+
// The packet was successfully transmitted
7486
#ifdef VERBOSE
7587
Serial.println(F("success!"));
7688
Serial.print(F("[SX1278] Datarate:\t"));
@@ -81,10 +93,10 @@ bool RadioControlTask::transmit(uint8_t *packet, uint8_t size)
8193
} else {
8294
#ifdef VERBOSE
8395
if (code == RADIOLIB_ERR_TX_TIMEOUT) {
84-
// timeout occurred while transmitting packet
96+
// Timeout occurred while transmitting packet
8597
Serial.println(F("timeout!"));
8698
} else {
87-
// some other error occurred
99+
// Some other error occurred
88100
Serial.print(F("failed, code "));
89101
Serial.println(code);
90102
}
@@ -104,23 +116,13 @@ bool RadioControlTask::receive()
104116
// packet was successfully received
105117
Serial.println(F("success!"));
106118

107-
// print the data of the packet
108119
Serial.print(F("[SX1278] Data:\t\t\t"));
109-
110-
// print the RSSI (Received Signal Strength Indicator)
111-
// of the last received packet
112120
Serial.print(F("[SX1278] RSSI:\t\t\t"));
113121
Serial.print(radio.getRSSI());
114122
Serial.println(F(" dBm"));
115-
116-
// print the SNR (Signal-to-Noise Ratio)
117-
// of the last received packet
118123
Serial.print(F("[SX1278] SNR:\t\t\t"));
119124
Serial.print(radio.getSNR());
120125
Serial.println(F(" dB"));
121-
122-
// print frequency error
123-
// of the last received packet
124126
Serial.print(F("[SX1278] Frequency error:\t"));
125127
Serial.print(radio.getFrequencyError());
126128
Serial.println(F(" Hz"));
@@ -129,13 +131,13 @@ bool RadioControlTask::receive()
129131
} else {
130132
#ifdef VERBOSE
131133
if (code == RADIOLIB_ERR_RX_TIMEOUT) {
132-
// timeout occurred while waiting for a packet
134+
// Timeout occurred while waiting for a packet
133135
Serial.println(F("timeout!"));
134136
} else if (code == RADIOLIB_ERR_CRC_MISMATCH) {
135-
// packet was received, but is malformed
137+
// Packet was received, but is malformed
136138
Serial.println(F("CRC error!"));
137139
} else {
138-
// some other error occurred
140+
// Some other error occurred
139141
Serial.print(F("failed, code "));
140142
Serial.println(code);
141143
}
@@ -146,14 +148,25 @@ bool RadioControlTask::receive()
146148

147149
void RadioControlTask::execute()
148150
{
149-
// implements the state machine described in: https://github.com/Alpha-CubeSat/oop-chipsat-code/wiki
151+
// Implement the state machine described in https://github.com/Alpha-CubeSat/oop-chipsat-code/wiki
150152
switch (sfr::radio::mode) {
151153
case radio_mode_type::init: {
152154
#ifdef VERBOSE
153155
Serial.println(F("Radio: Init State"));
154156
#endif
155157
init();
156158
if (sfr::radio::initialized) {
159+
sfr::radio::mode = radio_mode_type::aliveSignal;
160+
}
161+
break;
162+
}
163+
case radio_mode_type::aliveSignal: {
164+
#ifdef VERBOSE
165+
Serial.println(F("Radio: Alive Signal State"));
166+
#endif
167+
normalReportDownlink();
168+
sfr::radio::alive_signal_dlinks++;
169+
if (sfr::radio::alive_signal_dlinks == constants::radio::max_alive_signal_dlinks) {
157170
sfr::radio::mode = radio_mode_type::downlink;
158171
sfr::radio::listen_period_start = millis();
159172
downlinkSettings();
@@ -164,24 +177,24 @@ void RadioControlTask::execute()
164177
#ifdef VERBOSE
165178
Serial.println(F("Radio: Downlink State"));
166179
#endif
167-
// downlink when slot reached
180+
// Downlink when slot reached
168181
if (!sfr::radio::downlinked_in_slot && millis() - sfr::radio::downlink_window_start >= constants::radio::transmit_slot_length * sfr::radio::downlink_slot) {
169182
executeDownlink();
170183
sfr::radio::downlinked_in_slot = true;
171184
}
172185

173-
// go into listen mode if listen period reached
186+
// Go into listen mode if listen period reached
174187
if (millis() - sfr::radio::listen_period_start >= constants::radio::listen_period) {
175188
sfr::radio::mode = radio_mode_type::listen;
176189

177190
#ifdef VERBOSE
178191
Serial.println(F("Radio: Listen Flag Downlink"));
179192
#endif
180-
// downlink with listen flag = true
193+
// Downlink with listen flag = true
181194
normalReportDownlink();
182195
sfr::radio::command_wait_start = millis();
183196
}
184-
// reset window and choose slot for next downlink
197+
// Reset window and choose slot for next downlink
185198
else if (millis() - sfr::radio::downlink_window_start >= sfr::radio::downlink_window_length) {
186199
downlinkSettings();
187200
}
@@ -191,7 +204,7 @@ void RadioControlTask::execute()
191204
#ifdef VERBOSE
192205
Serial.println(F("Radio: Listen State"));
193206
#endif
194-
// built in timeout is 100 LoRa symbols
207+
// Built in timeout is 100 LoRa symbols
195208
bool receive_success = receive();
196209
if (receive_success) {
197210
processUplink();
@@ -225,7 +238,7 @@ bool RadioControlTask::executeDownlink()
225238
if (millis() - sfr::radio::last_callsign_time < constants::radio::callsign_interval) {
226239
return normalReportDownlink();
227240
} else {
228-
uint8_t dlink[] = {'K', 'D', '2', 'W', 'T', 'Q'};
241+
uint8_t dlink[] = {'K', 'C', '3', 'V', 'A', 'T', 'K', 'D', '2', 'W', 'T', 'Q', 'K', 'E', '2', 'A', 'T', 'R'};
229242
sfr::radio::last_callsign_time = millis();
230243
#ifdef VERBOSE
231244
Serial.println(F("Callsign Report"));
@@ -237,17 +250,18 @@ bool RadioControlTask::executeDownlink()
237250

238251
bool RadioControlTask::normalReportDownlink()
239252
{
240-
// see https://github.com/Alpha-CubeSat/oop-chipsat-code/wiki/2.-Telemetry for more info
253+
// See https://github.com/Alpha-CubeSat/oop-chipsat-code/wiki/2.-Telemetry for more info
241254
uint16_t lat = sfr::gps::latitude * 100;
242255
uint16_t lon = sfr::gps::longitude * 100;
243256
uint16_t alt = sfr::gps::altitude / 10;
244257

245258
uint8_t flags = 0;
246-
flags |= constants::radio::id << 6;
247-
flags |= sfr::gps::valid_msg << 5; // gps valid
248-
flags |= sfr::imu::initialized << 4; // imu valid
249-
flags |= sfr::gps::on << 3; // boot mode flag
250-
flags |= (sfr::radio::mode == radio_mode_type::listen) << 2; // listen flag
259+
flags |= constants::radio::id << 6; // chipsat ID #
260+
flags |= sfr::gps::valid_location << 5; // gps position valid
261+
flags |= sfr::gps::valid_altitude << 4; // gps altiude valid
262+
flags |= sfr::imu::initialized << 3; // imu valid
263+
flags |= sfr::gps::on << 2; // boot mode flag
264+
flags |= (sfr::radio::mode == radio_mode_type::listen) << 1; // listen flag
251265

252266
uint8_t dlink[] = {
253267
(uint8_t)lat, (uint8_t)(lat >> 8),
@@ -286,7 +300,7 @@ uint8_t RadioControlTask::map_range(float value, int min_val, int max_val)
286300

287301
void RadioControlTask::processUplink()
288302
{
289-
// see https://github.com/Alpha-CubeSat/oop-chipsat-code/wiki/3.-Commands for more info
303+
// See https://github.com/Alpha-CubeSat/oop-chipsat-code/wiki/3.-Commands for more info
290304
switch (received[0]) {
291305
case constants::opcodes::no_op: // No-Op
292306
#ifdef VERBOSE

src/ControlTasks/RadioControlTask.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ class RadioControlTask
2121
void init();
2222

2323
/**
24-
* Resets the transmit window start time and picks a new slot
24+
* @brief Resets the transmit window start time and picks a new slot
2525
*/
2626
void downlinkSettings();
2727

2828
/**
29-
* @brief Wrapper around RadioLib's transmit() to provide metadata (TODO: Redundant?)
29+
* @brief Wrapper around RadioLib's transmit() to provide metadata
3030
*/
3131
bool transmit(uint8_t *packet, uint8_t size);
3232

3333
/**
34-
* @brief Attempts to receive a 3 byte command (TODO: Redundant?)
34+
* @brief Attempts to receive a 3 byte command
3535
*/
3636
bool receive();
3737

src/MainControlLoop.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,24 @@ void MainControlLoop::execute()
6161
Serial.print(F("GPS Altitude (m): "));
6262
Serial.println(sfr::gps::altitude);
6363

64-
Serial.print("Downlink Slot: ");
64+
Serial.print(F("Downlink Slot: "));
6565
Serial.println(sfr::radio::downlink_slot);
6666

67+
Serial.print(F("Alive Time: "));
68+
Serial.println(millis() - sfr::gps::boot_time);
69+
6770
#endif
6871

6972
temp_monitor.execute();
7073
imu_monitor.execute();
7174
gps_monitor.execute();
7275
radio_control_task.execute();
7376

77+
// Turn off LED 5 seconds after boot
78+
if (millis() - sfr::gps::boot_time > constants::led::led_on_time) {
79+
digitalWrite(constants::led::led_pin, LOW);
80+
}
81+
7482
wdt_reset();
7583

7684
#ifdef VERBOSE

src/Modes/radio_mode_type.enum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
enum class radio_mode_type : unsigned char
55
{
66
init = 0,
7+
aliveSignal,
78
downlink,
89
listen
910
};

src/Monitors/GPSMonitor.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ void GPSMonitor::init()
99
digitalWrite(constants::gps::reset_pin, LOW);
1010
sfr::gps::on = true;
1111

12-
// writes NMEA output message type to SRAM and Flash
12+
// Writes NMEA output message type to SRAM and Flash
1313
uint8_t SetNMEA[] = {
1414
0xA0, 0xA1, 0x00, 0x03, 0x09, 0x01, 0x01, 0x09, 0x0D, 0x0A};
1515

@@ -19,6 +19,7 @@ void GPSMonitor::init()
1919

2020
void GPSMonitor::execute()
2121
{
22+
// Turn on GPS after boot mode is over (10 seconds)
2223
if (!sfr::gps::on) {
2324
if (millis() - sfr::gps::boot_time > constants::gps::boot_time) {
2425
init();
@@ -33,10 +34,8 @@ void GPSMonitor::execute()
3334
gps.encode(ss.read());
3435
serial_reads++;
3536
}
36-
// while (*gpsStream) {
37-
// gps.encode(*gpsStream++);
38-
// }
3937

38+
// Read GPS values if they are valid
4039
if (gps.location.isUpdated() && gps.location.isValid()) {
4140
sfr::gps::latitude = gps.location.lat();
4241
sfr::gps::longitude = gps.location.lng();
@@ -50,6 +49,9 @@ void GPSMonitor::execute()
5049
sfr::gps::utc_time = gps.time.value();
5150
}
5251

52+
sfr::gps::valid_location = gps.location.isValid();
53+
sfr::gps::valid_altitude = gps.altitude.isValid();
54+
5355
#ifdef VERBOSE
5456
Serial.print(F("Chars="));
5557
Serial.print(gps.charsProcessed());

src/Monitors/GPSMonitor.hpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,9 @@ class GPSMonitor
2727
SoftwareSerial ss = SoftwareSerial(constants::gps::rx_pin, constants::gps::tx_pin);
2828

2929
/**
30-
* Begins the software serial instance and configures the GPS receiver
30+
* @brief Begins the software serial instance and configures the GPS receiver
3131
*/
3232
void init();
33-
34-
// TODO: Test edge cases for lat, lon, alt
35-
const char *gpsStream = "$GPGGA,045104.000,3014.1985,N,09749.2873,W,1,09,1.2,211.6,M,-22.5,M,,0000*62\r\n"
36-
"$GPGGA,045201.000,3014.3864,N,09748.9411,W,1,10,1.2,200.8,M,-22.5,M,,0000*6C\r\n"
37-
"$GPGG@,045252.000,3014.4273,S,09749.0628,W,1,09,1.3,206.9,M,-22.5,M,,0000*6F\r\n";
3833
};
3934

4035
#endif

0 commit comments

Comments
 (0)