-
Notifications
You must be signed in to change notification settings - Fork 0
/
bluetooth.cpp
127 lines (110 loc) · 3.05 KB
/
bluetooth.cpp
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
#include "bluetooth.hpp"
#include "config.hpp"
#include "log.hpp"
#include "print.hpp"
#include <Arduino.h>
#include <SD.h>
#include <SoftwareSerial.h>
namespace cvslpr {
static SoftwareSerial bluetooth(BLUETOOTH_TX_PIN, BLUETOOTH_RX_PIN);
volatile bool bluetooth_switch_interrupt_registered = false;
enum class BluetoothMode
{
DATA,
COMMAND
};
static const char* BLUETOOTH_MODE_NAMES[] = { "data", "command" };
static void
bluetooth_turn_on(const BluetoothMode mode)
{
digitalWrite(BLUETOOTH_KEY_PIN, mode == BluetoothMode::DATA ? LOW : HIGH);
delay(300);
bluetooth.begin(mode == BluetoothMode::DATA ? BLUETOOTH_SERIAL_BAUD_RATE_DATA
: BLUETOOTH_SERIAL_BAUD_RATE_CMD);
msg_print(F("Bluetooth turned on with "));
msg_print(BLUETOOTH_MODE_NAMES[static_cast<int>(mode)]);
msg_println(F(" mode."));
}
static void
on_bluetooth_switch_interrupt()
{
msg_println(F("Bluetooth switch interrupt registered."));
bluetooth_switch_interrupt_registered = true;
}
static bool
wait_for_connection()
{
// Let the signal settle
delay(200);
msg_println(F("Waiting for bluetooth connection..."));
bool connected = false;
for (;;) {
if (digitalRead(BLUETOOTH_STATE_PIN) == HIGH) {
msg_println(F("Bluetooth connected."));
return true;
}
if (digitalRead(BLUETOOTH_SWITCH_INTERRUPT_PIN) == LOW) {
msg_println(F("Bluetooth switched off while waiting for connection."));
return false;
}
}
}
static void
wait_for_off()
{
msg_println(F("Waiting for bluetooth module to be turned off..."));
while (digitalRead(BLUETOOTH_SWITCH_INTERRUPT_PIN) == HIGH) {
}
// The delay prevents multiple interrupt triggers being handled
delay(200);
}
static void
bluetooth_transfer_data()
{
auto logfile = open_log();
if (!logfile) {
bluetooth.write(F("Failed to open log file."));
return;
}
msg_println(F("Transferring data..."));
bluetooth.write(FormattedLogEntry::HEADER);
LogEntry entry;
while (load_log_entry(logfile, entry)) {
FormattedLogEntry formatted_entry(entry);
if constexpr (PRINT_DEBUG) {
const auto written = bluetooth.write(
(const uint8_t*)(formatted_entry.data), formatted_entry.size);
if (written != formatted_entry.size) {
msg_println(F("Failed to write all data to bluetooth."));
}
} else {
bluetooth.write((const uint8_t*)(formatted_entry.data),
formatted_entry.size);
}
}
bluetooth.flush();
logfile.close();
msg_println(F("Data transfer done."));
}
bool
init_bluetooth()
{
pinMode(BLUETOOTH_KEY_PIN, OUTPUT);
pinMode(BLUETOOTH_STATE_PIN, INPUT);
pinMode(BLUETOOTH_SWITCH_INTERRUPT_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(BLUETOOTH_SWITCH_INTERRUPT_PIN),
on_bluetooth_switch_interrupt,
RISING);
msg_println(F("Bluetooth initialized."));
return true;
}
void
bluetooth_handle_transfer()
{
bluetooth_turn_on(BluetoothMode::DATA);
if (wait_for_connection()) {
bluetooth_transfer_data();
wait_for_off();
}
}
} // namespace cvslpr