File core.cpp¶
Location: src/core.cpp
Includes¶
graph LR
10["core.h"]
click 10 "core_8h.md#core_8h"
12["mqtt.h"]
click 12 "mqtt_8h.md#mqtt_8h"
12 --> 2
11["network.h"]
click 11 "network_8h.md#network_8h"
11 --> 2
2["platform.h"]
click 2 "platform_8h.md#platform_8h"
2 --> 3
2 --> 4
2 --> 5
2 --> 6
2 --> 7
2 --> 8
2 --> 9
13["sensor.h"]
click 13 "sensor_8h.md#sensor_8h"
13 --> 2
14["storage.h"]
click 14 "storage_8h.md#storage_8h"
14 --> 2
14 --> 15
1["src/core.cpp"]
click 1 "core_8cpp.md#core_8cpp"
1 --> 2
1 --> 10
1 --> 11
1 --> 12
1 --> 13
1 --> 14
1 --> 16
7["Adafruit_ADT7410.h"]
3["Arduino.h"]
8["ArduinoJson.h"]
9["ArduinoMqttClient.h"]
6["RTClib.h"]
5["SdFat.h"]
4["Wire.h"]
15["cstdio"]
16["secrets.h"]
Variables¶
Variable rtc¶
Definition: src/core.cpp
(line 17)
Type: RTC_DS3231
Variable tempsensor¶
Definition: src/core.cpp
(line 18)
Type: Adafruit_ADT7410
Variable sd¶
Definition: src/core.cpp
(line 19)
Type: SdFat
Variable wifiClient¶
Definition: src/core.cpp
(line 20)
Type: WiFiClient
Variable CHIP_SELECT¶
Definition: src/core.cpp
(line 29)
SD card chip select pin.
Type: const uint8_t
Variable SENSOR_ID_ONE¶
Definition: src/core.cpp
(line 30)
Type: const char *
Variable SENSOR_ID_IN_USE¶
Definition: src/core.cpp
(line 31)
const char* SENSOR_ID_IN_USE = [SENSOR\_ID\_ONE](core_8cpp.md#core_8cpp_1adfea6785b2b85c4960d78d8c64a1af5d)
Type: const char *
Variable SENSOR_TYPE¶
Definition: src/core.cpp
(line 34)
Type: const char *
Variable MQTT_TOPIC¶
Definition: src/core.cpp
(line 35)
Type: const char *
Variable WIFI_CONNECT_TIMEOUT_MS¶
Definition: src/core.cpp
(line 41)
Type: const unsigned long
Variable LOOP_DELAY_MS¶
Definition: src/core.cpp
(line 42)
Type: const unsigned long
Variable CLIENT_ID_BUFFER_SIZE¶
Definition: src/core.cpp
(line 43)
Type: const size_t
Variable SD_SCK_FREQUENCY_MHZ¶
Definition: src/core.cpp
(line 45)
Type: const uint8_t
Variable RECONNECT_INTERVAL_MS¶
Definition: src/core.cpp
(line 47)
Type: const int
Variable lastLoggedMinute¶
Definition: src/core.cpp
(line 53)
Type: int
Variable seqCount¶
Definition: src/core.cpp
(line 54)
Type: int
Variable recoverySent¶
Definition: src/core.cpp
(line 55)
Type: bool
Variable lastReconnectAttempt¶
Definition: src/core.cpp
(line 56)
Type: unsigned long
Functions¶
Function mqttClient¶
Parameters:
Return type: MqttClient
Function IsWifiConnected¶
Return type: bool
Function IsMqttConnected¶
Return type: bool
Function FatDateTime¶
Callback function for FAT file system timestamp generation.
This function is used by the SdFat library to obtain current date and time for file system operations. It retrieves the time from the RTC and converts it to the FAT file system format using the appropriate macros.
Parameters:
- date: Pointer to store the encoded FAT date (year, month, day)
- time: Pointer to store the encoded FAT time (hour, minute, second)
?> This function is registered as a callback with SdFile::dateTimeCallback()
See also: FAT_DATE, FAT_TIME macros for encoding format details
Parameters:
- uint16_t * date
- uint16_t * time
Return type: void
Function CoreSetup¶
Initializes all core system components and peripherals.
This function performs comprehensive system initialization including:
Network Setup:
* Establishes WiFi connection with timeout handling
-
Configures MQTT client with unique sensor-based ID
-
Attempts initial MQTT broker connection
Hardware Initialization:
* Initializes DS3231 real-time clock module
-
Adjusts RTC time if power was lost (uses compilation timestamp)
-
Sets up SD card with SPI communication
-
Initializes ADT7410 temperature sensor
Data Recovery:
* Registers FAT file system timestamp callback
!> Warning \
This function will halt program execution (infinite loop) if any critical component fails to initialize (RTC, SD card, or temperature sensor)
?> The function uses compile-time constants for timeouts and configuration
See also: WIFI_CONNECT_TIMEOUT_MS, CLIENT_ID_BUFFER_SIZE, SD_SCK_FREQUENCY_MHZ
Return type: void
Function CoreLoop¶
Main operational loop for continuous sensor monitoring, MQTT transmission, and robust data recovery.
This function implements the primary logic for the temperature monitoring system, including:
* Real-time sensor measurement and transmission via MQTT with QoS 1
-
Intelligent WiFi and MQTT connection management with automatic reconnection
-
Fallback to CSV batch storage during connectivity outages
-
Recovery and transmission of offline data after successful reconnection
-
Comprehensive error handling and status reporting
Operational Flow: 1. Time Management: Reads current time from RTC, tracks minute changes to avoid duplicate measurements. 2. WiFi Connection: Monitors status, attempts reconnection, falls back to CSV logging if offline. 3. MQTT Connection: Verifies broker connectivity, reconnects as needed, falls back to CSV logging if offline. 4. Data Recovery: Sends pending CSV data after reconnection, ensures recovery only once per cycle. 5. Normal Operation: Measures temperature, transmits via MQTT, polls for incoming messages.
Error Handling:
* Network or broker failures trigger CSV fallback storage for all measurements.
-
Connection attempts are rate-limited to prevent resource exhaustion.
-
All measurement data is preserved and recovered after connectivity is restored.
?> Maintains a fixed loop delay for consistent timing and system stability.
See also: RECONNECT_INTERVAL_MS, LOOP_DELAY_MS for timing configuration, saveToCsvBatch() for offline data storage, sendPendingData() for data recovery and MQTT retransmission
Return type: void
Source¶
#include "platform.h"
#include "core.h"
#include "network.h"
#include "mqtt.h"
#include "sensor.h"
#include "storage.h"
#ifdef UNIT_TEST
#include "secrets_example.h"
#else
#include "secrets.h"
#endif
#ifndef UNIT_TEST
// Global hardware objects for real hardware only
RTC_DS3231 rtc;
Adafruit_ADT7410 tempsensor;
SdFat sd;
static WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
#endif
// =============================================================================
// SYSTEM CONFIGURATION CONSTANTS
// =============================================================================
static const uint8_t CHIP_SELECT = 4;
static const char* SENSOR_ID_ONE = "Sensor_One";
static const char* SENSOR_ID_IN_USE = SENSOR_ID_ONE;
// static const char* SENSOR_ID_TWO = "Sensor_Two";
// static const char* SENSOR_ID_IN_USE = SENSOR_ID_TWO; // Uncomment to use the second
static const char* SENSOR_TYPE = "temp";
static const char* MQTT_TOPIC = "dhbw/ai/si2023/2/";
// =============================================================================
// TIMING AND CONNECTION CONSTANTS
// =============================================================================
static const unsigned long WIFI_CONNECT_TIMEOUT_MS = 15000;
static const unsigned long LOOP_DELAY_MS = 1000;
static const size_t CLIENT_ID_BUFFER_SIZE = 64;
#ifndef UNIT_TEST
static const uint8_t SD_SCK_FREQUENCY_MHZ = 25;
#endif
static const int RECONNECT_INTERVAL_MS = 2000;
// =============================================================================
// SYSTEM STATE VARIABLES
// =============================================================================
static int lastLoggedMinute = -1;
static int seqCount = 0;
static bool recoverySent = false;
static unsigned long lastReconnectAttempt = 0;
// =============================================================================
// CONNECTION STATUS FUNCTIONS
// =============================================================================
bool IsWifiConnected() {
return WiFi.status() == WL_CONNECTED;
}
bool IsMqttConnected() {
return mqttClient.connected();
}
// =============================================================================
// FAT FILE SYSTEM CALLBACK FUNCTIONS
// =============================================================================
void FatDateTime(uint16_t* date, uint16_t* time) {
DateTime now = rtc.now();
*date = FAT_DATE(now.year(), now.month(), now.day());
*time = FAT_TIME(now.hour(), now.minute(), now.second());
}
// =============================================================================
// SYSTEM INITIALIZATION FUNCTIONS
// =============================================================================
void CoreSetup() {
ConnectToWiFi(WIFI_CONNECT_TIMEOUT_MS);
char clientId[CLIENT_ID_BUFFER_SIZE];
snprintf(clientId, sizeof(clientId), "IsoPruefi_%s", SENSOR_ID_IN_USE);
mqttClient.setId(clientId);
if (IsWifiConnected()) {
ConnectToMQTT(mqttClient);
}
if (!rtc.begin()) {
Serial.println("RTC not found!");
while (1);
}
// Set RTC time if power was lost (uses compilation timestamp)
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Register callback for SD file timestamps and initialize SD card
SdFile::dateTimeCallback(FatDateTime);
if (!sd.begin(CHIP_SELECT, SD_SCK_MHZ(SD_SCK_FREQUENCY_MHZ))) {
Serial.println("SD card failed.");
while (1);
}
if (!InitSensor(tempsensor)) {
Serial.println("ADT7410 init failed!");
while (1);
}
DateTime now = rtc.now();
Serial.print("Current time: ");
Serial.println(now.timestamp(DateTime::TIMESTAMP_FULL));
Serial.print("Lost Power? ");
Serial.println(rtc.lostPower() ? "YES" : "NO");
Serial.println("Setup complete.");
}
// =============================================================================
// MAIN OPERATIONAL LOOP
// =============================================================================
void CoreLoop() {
DateTime now = rtc.now();
static bool alreadyLoggedThisMinute = false;
if (now.minute() != lastLoggedMinute) {
lastLoggedMinute = now.minute();
alreadyLoggedThisMinute = false;
}
// Step 1: Check WiFi connection
if (!IsWifiConnected()) {
if (millis() - lastReconnectAttempt > RECONNECT_INTERVAL_MS) {
lastReconnectAttempt = millis();
Serial.println("WiFi not connected. Trying to reconnect...");
ConnectToWiFi(WIFI_CONNECT_TIMEOUT_MS);
}
if (!IsWifiConnected()) {
Serial.println("WiFi reconnect failed. Skipping loop.");
if (!alreadyLoggedThisMinute) {
float c = ReadTemperatureInCelsius();
SaveTempToBatchCsv(now, c, seqCount);
alreadyLoggedThisMinute = true;
seqCount++;
}
delay(LOOP_DELAY_MS);
return;
}
}
// Step 2: Check MQTT connection
if (!IsMqttConnected()) {
Serial.println("MQTT not connected. Trying to reconnect...");
if (!ConnectToMQTT(mqttClient)) {
Serial.println("MQTT reconnect failed. Skipping loop.");
if (!alreadyLoggedThisMinute) {
float c = ReadTemperatureInCelsius();
SaveTempToBatchCsv(now, c, seqCount);
alreadyLoggedThisMinute = true;
seqCount++;
}
delay(LOOP_DELAY_MS);
return;
}
Serial.println("MQTT reconnected successfully.");
recoverySent = false; // Allow recovery again
}
// Step 3: After successful MQTT reconnect → send old CSVs
if (!recoverySent && IsConnectedToServer(mqttClient)) {
if (SendPendingDataToMqtt(mqttClient, MQTT_TOPIC, SENSOR_TYPE, SENSOR_ID_IN_USE, now)) {
recoverySent = true;
}
}
// Step 4: Normal measurement and MQTT transmission
if (!alreadyLoggedThisMinute && IsConnectedToServer(mqttClient)) {
float c = ReadTemperatureInCelsius();
SendTempToMqtt(mqttClient, MQTT_TOPIC, SENSOR_TYPE, SENSOR_ID_IN_USE, c, now, seqCount);
alreadyLoggedThisMinute = true;
seqCount++;
}
// Step 5: MQTT loop and wait time
mqttClient.poll();
delay(LOOP_DELAY_MS);
}