Skip to content

Commit 4e2b2b9

Browse files
committed
multithreaded mic sampling
1 parent 1fea0b6 commit 4e2b2b9

File tree

3 files changed

+87
-91
lines changed

3 files changed

+87
-91
lines changed

noisemeter-device/api.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,19 +168,20 @@ std::optional<JsonDocument> API::responseToJson(const String& response)
168168
API::API(UUID id_, String token_):
169169
id(id_), token(token_) {}
170170

171-
bool API::sendMeasurements(const std::list<DataPacket>& pkts)
171+
bool API::sendMeasurements(const std::list<DataPacket>& packets,
172+
const std::list<DataPacket>::const_iterator from)
172173
{
173174
String send;
174175
JsonDocument doc;
175176
auto data = doc["data"].to<JsonArray>();
176177

177-
for (const auto& packet : pkts) {
178+
for (auto it = from; it != packets.cend(); it++) {
178179
auto entry = data.add<JsonObject>();
179-
entry["timestamp"] = String(packet.timestamp);
180-
entry["min"] = std::lround(packet.minimum);
181-
entry["max"] = std::lround(packet.maximum);
182-
entry["mean"] = std::lround(packet.average);
183-
}
180+
entry["timestamp"] = String(it->timestamp);
181+
entry["min"] = std::lround(it->minimum);
182+
entry["max"] = std::lround(it->maximum);
183+
entry["mean"] = std::lround(it->average);
184+
};
184185

185186
const auto size = serializeJson(data, send);
186187

noisemeter-device/api.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ class API
8383
*/
8484
bool sendMeasurement(const DataPacket& packet);
8585

86-
bool sendMeasurements(const std::list<DataPacket>& pkts);
86+
bool sendMeasurements(const std::list<DataPacket>& packets,
87+
const std::list<DataPacket>::const_iterator from);
8788

8889
/**
8990
* Sends diagnostic/analytic data to the server along with a DataPacket.

noisemeter-device/noisemeter-device.ino

Lines changed: 77 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ static Storage Creds;
5656
/** Linked list of completed data packets.
5757
* This list should only grow if WiFi is unavailable. */
5858
static std::list<DataPacket> packets;
59-
/** Tracks when the last measurement upload occurred. */
60-
static Timestamp lastUpload = Timestamp::invalidTimestamp();
61-
/** Tracks when the last OTA update check occurred. */
62-
static Timestamp lastOTACheck = Timestamp::invalidTimestamp();
6359
/** Track first measurement upload so diagnostics can be sent/included. */
6460
static bool firstSend;
6561

@@ -92,10 +88,14 @@ UUID buildDeviceId();
9288
*/
9389
int tryWifiConnection(wifi_mode_t mode = WIFI_STA, int timeout = WIFI_CONNECT_TIMEOUT_SEC);
9490

91+
static TaskHandle_t measurementTask;
92+
static void measurementHandler(void *);
93+
9594
/**
9695
* Firmware entry point and initialization routine.
9796
*/
98-
void setup() {
97+
void setup()
98+
{
9999
pinMode(PIN_LED1, OUTPUT);
100100
digitalWrite(PIN_LED1, LOW);
101101

@@ -151,114 +151,108 @@ void setup() {
151151
esp_deep_sleep_start();
152152
}
153153

154-
Timestamp now;
155-
lastUpload = now;
156-
lastOTACheck = now;
157154
firstSend = true;
158155

159156
SERIAL.println("Connected to the WiFi network.");
160157
SERIAL.print("Local ESP32 IP: ");
161158
SERIAL.println(WiFi.localIP());
162159
SERIAL.print("Current time: ");
163-
SERIAL.println(now);
160+
SERIAL.println(Timestamp());
164161
#endif // !UPLOAD_DISABLED
165162

166163
digitalWrite(PIN_LED1, HIGH);
167-
}
168164

169-
/**
170-
* Main loop for the firmware.
171-
* This function is run continuously, getting called within an infinite loop.
172-
*/
173-
void loop() {
174-
if (auto db = SPL.readMicrophoneData(); db) {
175-
packets.front().add(*db);
176-
printReadingToConsole(*db);
165+
if (xTaskCreate(measurementHandler, "dba", 1024, nullptr,
166+
uxTaskPriorityGet(nullptr), &measurementTask) == pdFAIL)
167+
{
168+
SERIAL.println("xTaskCreate failed!");
177169
}
170+
}
178171

172+
void loop()
173+
{
179174
#ifndef UPLOAD_DISABLED
180-
const auto now = Timestamp();
175+
static int wakeupCount = 0;
176+
177+
vTaskDelay(pdMS_TO_TICKS(SEC_TO_MS(UPLOAD_INTERVAL_SEC)));
181178

182-
if (lastUpload.secondsBetween(now) >= UPLOAD_INTERVAL_SEC) {
183-
packets.front().timestamp = now;
179+
packets.front().timestamp = Timestamp();
180+
packets.emplace_front();
184181

185-
if (WiFi.status() != WL_CONNECTED) {
186-
SERIAL.println("Attempting WiFi reconnect...");
187-
WiFi.reconnect();
188-
delay(5000);
189-
}
182+
if (WiFi.status() != WL_CONNECTED) {
183+
SERIAL.println("Attempting WiFi reconnect...");
184+
WiFi.reconnect();
185+
delay(5000);
186+
}
190187

191-
if (WiFi.status() == WL_CONNECTED) {
192-
API api (buildDeviceId(), Creds.get(Storage::Entry::Token));
188+
if (WiFi.status() == WL_CONNECTED) {
189+
API api (buildDeviceId(), Creds.get(Storage::Entry::Token));
193190

194-
if (firstSend) {
195-
const bool success = api.sendMeasurementWithDiagnostics(
196-
packets.front(), NOISEMETER_VERSION, lastUpload);
191+
if (firstSend) {
192+
const bool success = api.sendMeasurementWithDiagnostics(
193+
packets.back(), NOISEMETER_VERSION, String(millis() / 1000));
197194

198-
if (success) {
199-
packets.pop_front();
200-
firstSend = false;
201-
}
195+
if (success) {
196+
packets.pop_back();
197+
firstSend = false;
202198
}
199+
}
203200

204-
if (!packets.empty()) {
205-
const bool success = (++packets.cbegin() != packets.cend())
206-
? api.sendMeasurements(packets)
207-
: api.sendMeasurement(packets.front());
208-
209-
if (success)
210-
packets.clear();
211-
}
201+
const auto size = packets.size();
202+
if (size > 1) {
203+
if (size == 2 && api.sendMeasurement(packets.back())) {
204+
packets.pop_back();
205+
} else if (size > 2 && api.sendMeasurements(packets, ++packets.cbegin())) {
206+
packets.erase(++packets.cbegin(), packets.cend());
207+
} else {
208+
SERIAL.print(size - 1);
209+
SERIAL.println(" packets still need to be sent!");
212210

213-
#if defined(BOARD_ESP32_PCB)
214-
// We have WiFi: also check for software updates
215-
if (lastOTACheck.secondsBetween(now) >= OTA_INTERVAL_SEC) {
216-
lastOTACheck = now;
217-
SERIAL.println("Checking for updates...");
218-
219-
const auto ota = api.getLatestSoftware();
220-
if (ota) {
221-
if (ota->version.compareTo(NOISEMETER_VERSION) > 0) {
222-
SERIAL.print(ota->version);
223-
SERIAL.println(" available!");
224-
225-
if (downloadOTAUpdate(ota->url, api.rootCertificate())) {
226-
SERIAL.println("Download success! Restarting...");
227-
delay(1000);
228-
ESP.restart();
229-
} else {
230-
SERIAL.println("Update download failed.");
231-
}
232-
} else {
233-
SERIAL.println("No new updates.");
234-
}
235-
} else {
236-
SERIAL.println("Failed to reach update server!");
211+
if (size >= MAX_SAVED_PACKETS) {
212+
SERIAL.println("Discarded a packet!");
213+
packets.pop_back();
237214
}
238215
}
239-
#endif // BOARD_ESP32_PCB
240216
}
241217

242-
if (!packets.empty()) {
243-
const auto count = std::distance(packets.cbegin(), packets.cend());
244-
SERIAL.print(count);
245-
SERIAL.println(" packets still need to be sent!");
246-
247-
if (count >= MAX_SAVED_PACKETS) {
248-
SERIAL.println("Discarded a packet!");
249-
packets.pop_back();
250-
}
218+
#if defined(BOARD_ESP32_PCB)
219+
// We have WiFi: also check for software updates
220+
if (++wakeupCount >= OTA_INTERVAL_SEC / UPLOAD_INTERVAL_SEC) {
221+
wakeupCount = 0;
222+
SERIAL.println("Checking for updates...");
223+
224+
const auto ota = api.getLatestSoftware();
225+
if (ota) {
226+
if (ota->version.compareTo(NOISEMETER_VERSION) > 0) {
227+
SERIAL.print(ota->version);
228+
SERIAL.println(" available!");
229+
230+
if (downloadOTAUpdate(ota->url, api.rootCertificate())) {
231+
SERIAL.println("Download success! Restarting...");
232+
delay(1000);
233+
ESP.restart();
234+
} else { SERIAL.println("Update download failed."); }
235+
} /*else { SERIAL.println("No new updates."); }*/
236+
} else { SERIAL.println("Failed to reach update server!"); }
251237
}
252-
253-
// Create new packet for next measurements
254-
packets.emplace_front();
255-
lastUpload = now;
238+
#endif // BOARD_ESP32_PCB
256239
}
257240
#endif // !UPLOAD_DISABLED
258241
}
259242

260-
void printReadingToConsole(double reading) {
261-
String output = "";
243+
void measurementHandler(void *)
244+
{
245+
while (1) {
246+
if (const auto db = SPL.readMicrophoneData(); db) {
247+
packets.front().add(*db);
248+
printReadingToConsole(*db);
249+
}
250+
}
251+
}
252+
253+
void printReadingToConsole(double reading)
254+
{
255+
String output;
262256
output += std::lround(reading);
263257
output += "dB";
264258

0 commit comments

Comments
 (0)