Skip to content

Commit b7415d0

Browse files
committed
[SD] Handle sd cards of varying capacities!
1 parent d1ac920 commit b7415d0

File tree

5 files changed

+81
-29
lines changed

5 files changed

+81
-29
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
22
"files.associations": {
33
"limits": "c",
4-
"type_traits": "c"
4+
"type_traits": "c",
5+
"vector": "cpp"
56
},
67
"C_Cpp.dimInactiveRegions": false,
78
"dotnet.defaultSolution": "disable",

src/components/analogIO/controller.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,10 @@ void AnalogIOController::update() {
271271
// Read the pin's raw value
272272
uint16_t value = _analogio_hardware->GetPinValue(pin.name);
273273
// Encode and publish it to the broker
274-
EncodePublishPinValue(pin.name, value);
274+
if (!EncodePublishPinValue(pin.name, value)) {
275+
WS_DEBUG_PRINTLN("[analogio] ERROR: Unable to record pin value!");
276+
continue;
277+
}
275278
pin.prv_period = cur_time; // Reset the pin's period
276279
} else if (pin.read_mode ==
277280
wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE) {

src/components/digitalIO/controller.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,10 @@ void DigitalIOController::Update() {
364364
continue; // No change in pin value detected, move onto the next pin
365365

366366
// Encode and publish the event
367-
if (!EncodePublishPinEvent(pin.pin_name, pin.pin_value))
368-
continue; // Unable to encode and publish event, move onto the next pin
367+
if (!EncodePublishPinEvent(pin.pin_name, pin.pin_value)) {
368+
WS_DEBUG_PRINTLN("[digitalio] ERROR: Unable to record pin value!");
369+
continue;
370+
}
369371
} else if (
370372
pin.sample_mode ==
371373
wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_TIMER) {
@@ -374,8 +376,10 @@ void DigitalIOController::Update() {
374376
continue; // Timer has not expired yet, move onto the next pin
375377

376378
// Encode and publish the event
377-
if (!EncodePublishPinEvent(pin.pin_name, pin.pin_value))
378-
continue; // Failed to encode and publish event, move onto the next pin
379+
if (!EncodePublishPinEvent(pin.pin_name, pin.pin_value)) {
380+
WS_DEBUG_PRINTLN("[digitalio] ERROR: Unable to record pin value!");
381+
continue;
382+
}
379383
} else {
380384
// Invalid sample mode
381385
WS_DEBUG_PRINT("[digitalio] ERROR: DigitalIO Pin ");

src/provisioning/sdcard/ws_sdcard.cpp

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
ws_sdcard::ws_sdcard() {
2323
is_mode_offline = false;
2424
_use_test_data = false;
25-
_sz_log_file = 0;
25+
_sz_cur_log_file = 0;
2626
}
2727

2828
/**************************************************************************/
@@ -45,16 +45,36 @@ ws_sdcard::~ws_sdcard() {
4545
*/
4646
/**************************************************************************/
4747
bool ws_sdcard::InitSDCard() {
48-
if (WsV2.pin_sd_cs == PIN_SD_CS_ERROR) {
49-
is_mode_offline = false;
48+
is_mode_offline = false;
49+
csd_t csd;
50+
if (WsV2.pin_sd_cs == PIN_SD_CS_ERROR)
51+
return is_mode_offline;
52+
53+
if (!_sd.begin(WsV2.pin_sd_cs)) {
54+
WS_DEBUG_PRINTLN(
55+
"SD initialization failed.\nDo not reformat the card!\nIs the card "
56+
"correctly inserted?\nIs there a wiring/soldering problem\n");
5057
return is_mode_offline;
5158
}
5259

53-
if (_sd.begin(WsV2.pin_sd_cs)) {
54-
is_mode_offline = true;
55-
} else {
56-
is_mode_offline = false;
60+
// Calculate the maximum number of log files that can be stored on the SD card
61+
if (!_sd.card()->readCSD(&csd)) {
62+
WS_DEBUG_PRINTLN("ERROR: Could not read sdcard information");
63+
return is_mode_offline;
64+
}
65+
// get the complete sdcard capacity in bytes
66+
_sd_capacity = (uint64_t)512 * csd.capacity();
67+
// account for 3-5% fatfs overhead utilization
68+
size_t sd_capacity_usable = _sd_capacity * (1 - 0.05);
69+
// proportionally set sz of each log file to 10% of the SD card's usable capacity
70+
_max_sz_log_file = sd_capacity_usable / 10;
71+
// Regardless of sd card size, cap log files to 512MB
72+
if (_max_sz_log_file > MAX_SZ_LOG_FILE) {
73+
_max_sz_log_file = MAX_SZ_LOG_FILE;
5774
}
75+
_sd_max_num_log_files = sd_capacity_usable / _max_sz_log_file;
76+
77+
is_mode_offline = true;
5878
return is_mode_offline;
5979
}
6080

@@ -430,6 +450,12 @@ bool ws_sdcard::AddSignalMessageToSharedBuffer(
430450
*/
431451
/**************************************************************************/
432452
bool ws_sdcard::CreateNewLogFile() {
453+
if (_sd_cur_log_files >= _sd_max_num_log_files) {
454+
WS_DEBUG_PRINTLN(
455+
"[SD] Maximum number of log files for SD card capacity reached!");
456+
return false;
457+
}
458+
433459
File32 file;
434460
// Generate a name for the new log file using the RTC's timestamp
435461
String logFilename = "log_" + String(GetTimestamp()) + ".json";
@@ -444,6 +470,7 @@ bool ws_sdcard::CreateNewLogFile() {
444470
return false;
445471
WS_DEBUG_PRINT("[SD] Created new log file on SD card: ");
446472
WS_DEBUG_PRINTLN(_log_filename);
473+
_sd_cur_log_files++;
447474
return true;
448475
}
449476

@@ -473,6 +500,14 @@ bool ws_sdcard::ValidateChecksum(JsonDocument &doc) {
473500
*/
474501
/**************************************************************************/
475502
bool ws_sdcard::parseConfigFile() {
503+
// TODO: THIS IS JUST DEBUG!
504+
WS_DEBUG_PRINT("SD card capacity: ");
505+
WS_DEBUG_PRINTLN(_sd_capacity);
506+
WS_DEBUG_PRINT("Maximum number of log files: ");
507+
WS_DEBUG_PRINTLN(_sd_max_num_log_files);
508+
WS_DEBUG_PRINT("Maximum size of log file: ");
509+
WS_DEBUG_PRINTLN(_max_sz_log_file);
510+
476511
int max_json_len = 4096;
477512
DeserializationError error;
478513
JsonDocument doc;
@@ -785,12 +820,13 @@ bool ws_sdcard::LogJSONDoc(JsonDocument &doc) {
785820
szJson = serializeJson(doc, Serial); // TODO: Add buffering here, too?
786821
Serial.print("\n"); // JSONL format specifier
787822
#endif
788-
_sz_log_file = szJson + 2; // +2 bytes for "\n"
823+
_sz_cur_log_file = szJson + 2; // +2 bytes for "\n"
789824

790-
if (_sz_log_file > MAX_LOG_FILE_SZ) {
791-
WS_DEBUG_PRINTLN("[SD] Log file size has exceeded maximum size, creating "
792-
"a new file...");
793-
CreateNewLogFile();
825+
if (_sz_cur_log_file >= _max_sz_log_file) {
826+
WS_DEBUG_PRINTLN("[SD] Log file has exceeded maximum size! Attempting to "
827+
"create a new file...");
828+
if (!CreateNewLogFile())
829+
return false;
794830
return false;
795831
}
796832

src/provisioning/sdcard/ws_sdcard.h

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818
#include "SdFat.h"
1919
#include "StreamUtils.h"
2020
#include "Wippersnapper_V2.h"
21+
#include "sdios.h"
2122

2223
#define SD_FAT_TYPE 3 ///< SdFat type (3 = SdFs)
23-
#define MAX_LOG_FILE_SZ 500 ///< Maximum log file size of 500 bytes
2424
#define PIN_SD_CS_ERROR 255 ///< Error code for invalid SD card CS pin
2525
#define UNKNOWN_VALUE "unknown" ///< Unknown JSON field value
26+
#define MAX_SZ_LOG_FILE (512 * 1024 * 1024) ///< Maximum log file size, in Bytes
2627

2728
// forward decl.
2829
class Wippersnapper_V2;
@@ -78,16 +79,23 @@ class ws_sdcard {
7879
void BuildJSONDoc(JsonDocument &doc, uint8_t pin, bool value,
7980
wippersnapper_sensor_SensorType read_type);
8081
bool LogJSONDoc(JsonDocument &doc);
81-
bool
82-
AddSignalMessageToSharedBuffer(wippersnapper_signal_BrokerToDevice &msg_signal);
83-
SdFat _sd; ///< SD object from Adafruit SDFat library
84-
bool is_mode_offline; ///< True if offline mode is enabled, False otherwise
85-
String _serialInput; ///< Serial input buffer
86-
const char *json_test_data; ///< Json test data
87-
const char *_log_filename; ///< Path to the log file
88-
size_t _sz_log_file; ///< Size of the current log file, in Bytes
89-
RTC_DS3231 *_rtc_ds3231 = nullptr; ///< DS3231 RTC object
90-
RTC_DS1307 *_rtc_ds1307 = nullptr; ///< DS1307 RTC object
82+
bool AddSignalMessageToSharedBuffer(
83+
wippersnapper_signal_BrokerToDevice &msg_signal);
84+
85+
SdFat _sd; ///< SD object from Adafruit SDFat library
86+
size_t _sd_capacity; ///< Capacity of the SD card, in Bytes
87+
size_t _sz_cur_log_file; ///< Size of the current log file, in Bytes
88+
size_t _max_sz_log_file; ///< Calculated maximum size of a log file, in Bytes
89+
int _sd_max_num_log_files; ///< Maximum number of log files that can fit on
90+
///< the SD card
91+
int _sd_cur_log_files; ///< Current number of log files that can fit on the SD
92+
///< card
93+
bool is_mode_offline; ///< True if offline mode is enabled, False otherwise
94+
String _serialInput; ///< Serial input buffer
95+
const char *json_test_data; ///< Json test data
96+
const char *_log_filename; ///< Path to the log file
97+
RTC_DS3231 *_rtc_ds3231 = nullptr; ///< DS3231 RTC object
98+
RTC_DS1307 *_rtc_ds1307 = nullptr; ///< DS1307 RTC object
9199
RTC_PCF8523 *_rtc_pcf8523 = nullptr; ///< PCF8523 RTC object
92100
RTC_Millis *_rtc_soft = nullptr; ///< Software RTC object
93101
bool _use_test_data; ///< True if sample data is being used for testing

0 commit comments

Comments
 (0)