From 5320b3fd7bb3a362984a7301b69a1f5390faf8e1 Mon Sep 17 00:00:00 2001 From: Maytastico Date: Sat, 24 Aug 2024 11:09:47 +0200 Subject: [PATCH 1/2] #333-Unity-und-Arduino-Mock --- .../sara/include/makros/ArdunioMakros.hpp | 13 + blickbox/sara/include/makros/FMakro.hpp | 6 + blickbox/sara/include/mock/DHT.hpp | 66 ++++ .../sara/include/mock/SerialLoggerMock.cpp | 132 +++++++ .../sara/include/mock/SerialLoggerMock.hpp | 115 ++++++ ...kFun_Weather_Meter_Kit_Arduino_Library.cpp | 301 ++++++++++++++++ ...arkFun_Weather_Meter_Kit_Arduino_Library.h | 167 +++++++++ blickbox/sara/include/stubs/ArduinoStubs.hpp | 36 ++ blickbox/sara/include/stubs/BLE_Stubs.hpp | 69 ++++ blickbox/sara/include/stubs/SerialStubs.hpp | 26 ++ blickbox/sara/include/types/Numbers.h | 9 + blickbox/sara/include/types/String.h | 8 + blickbox/sara/lib/SaraBLE/src/SaraBLE.cpp | 340 +++++++++--------- blickbox/sara/lib/SaraBLE/src/SaraBLE.hpp | 14 + .../sara/lib/SaraLib/src/sara_battery.hpp | 8 + blickbox/sara/lib/SaraLib/src/sara_data.cpp | 28 +- blickbox/sara/lib/SaraLib/src/sara_data.hpp | 11 + blickbox/sara/lib/SerialLogger/library.json | 33 -- .../lib/SerialLogger/src/SerialLogger.cpp | 124 ------- .../lib/SerialLogger/src/SerialLogger.hpp | 108 ------ blickbox/sara/platformio.ini | 32 ++ blickbox/sara/test/test_main.cpp | 13 + 22 files changed, 1211 insertions(+), 448 deletions(-) create mode 100644 blickbox/sara/include/makros/ArdunioMakros.hpp create mode 100644 blickbox/sara/include/makros/FMakro.hpp create mode 100644 blickbox/sara/include/mock/DHT.hpp create mode 100644 blickbox/sara/include/mock/SerialLoggerMock.cpp create mode 100644 blickbox/sara/include/mock/SerialLoggerMock.hpp create mode 100644 blickbox/sara/include/mock/SparkFun_Weather_Meter_Kit_Arduino_Library.cpp create mode 100644 blickbox/sara/include/mock/SparkFun_Weather_Meter_Kit_Arduino_Library.h create mode 100644 blickbox/sara/include/stubs/ArduinoStubs.hpp create mode 100644 blickbox/sara/include/stubs/BLE_Stubs.hpp create mode 100644 blickbox/sara/include/stubs/SerialStubs.hpp create mode 100644 blickbox/sara/include/types/Numbers.h create mode 100644 blickbox/sara/include/types/String.h delete mode 100644 blickbox/sara/lib/SerialLogger/library.json delete mode 100644 blickbox/sara/lib/SerialLogger/src/SerialLogger.cpp delete mode 100644 blickbox/sara/lib/SerialLogger/src/SerialLogger.hpp create mode 100644 blickbox/sara/test/test_main.cpp diff --git a/blickbox/sara/include/makros/ArdunioMakros.hpp b/blickbox/sara/include/makros/ArdunioMakros.hpp new file mode 100644 index 0000000..202b0f5 --- /dev/null +++ b/blickbox/sara/include/makros/ArdunioMakros.hpp @@ -0,0 +1,13 @@ +#ifndef ARDUINO_MAKROS_HPP +#define ARDUINO_MAKROS_HPP + +#define HIGH true +#define LOW false +#define PIN_ENABLE_SENSORS_3V3 0x33 +#define PIN_ENABLE_I2C_PULLUP 0x21 +#define INPUT 1 +#define OUTPUT 0 +#define LED_PWR 0x35 + + +#endif //ARDUINO_MAKROS_HPP \ No newline at end of file diff --git a/blickbox/sara/include/makros/FMakro.hpp b/blickbox/sara/include/makros/FMakro.hpp new file mode 100644 index 0000000..276c58b --- /dev/null +++ b/blickbox/sara/include/makros/FMakro.hpp @@ -0,0 +1,6 @@ +#ifndef F_MAKROS_HPP +#define F_MAKROS_HPP + +#define F(str) + +#endif //F_MAKROS_HPP \ No newline at end of file diff --git a/blickbox/sara/include/mock/DHT.hpp b/blickbox/sara/include/mock/DHT.hpp new file mode 100644 index 0000000..0373331 --- /dev/null +++ b/blickbox/sara/include/mock/DHT.hpp @@ -0,0 +1,66 @@ +#ifndef DHT_MOCK_HPP +#define DHT_MOCK_HPP + +#include +#include + +class DHT { +public: + DHT(uint8_t pin, uint8_t type, uint8_t count = 6) + : _pin(pin), _type(type), _lastresult(false), pullTime(55) { + std::cout << "DHT initialized with pin: " << (int)pin << ", type: " << (int)type << ", count: " << (int)count << std::endl; + } + + void begin(uint8_t usec = 55) { + std::cout << "DHT begin with usec: " << (int)usec << std::endl; + } + + float readTemperature(bool S = false, bool force = false) { + std::cout << "readTemperature called with S: " << S << ", force: " << force << std::endl; + return 25.0; // Dummy value + } + + float convertCtoF(float celsius) { + std::cout << "convertCtoF called with celsius: " << celsius << std::endl; + return celsius * 9.0 / 5.0 + 32.0; // Dummy conversion + } + + float convertFtoC(float fahrenheit) { + std::cout << "convertFtoC called with fahrenheit: " << fahrenheit << std::endl; + return (fahrenheit - 32.0) * 5.0 / 9.0; // Dummy conversion + } + + float computeHeatIndex(bool isFahrenheit = true) { + std::cout << "computeHeatIndex called with isFahrenheit: " << isFahrenheit << std::endl; + return isFahrenheit ? 77.0 : 25.0; // Dummy value + } + + float computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit = true) { + std::cout << "computeHeatIndex called with temperature: " << temperature << ", percentHumidity: " << percentHumidity << ", isFahrenheit: " << isFahrenheit << std::endl; + return isFahrenheit ? 77.0 : 25.0; // Dummy value + } + + float readHumidity(bool force = false) { + std::cout << "readHumidity called with force: " << force << std::endl; + return 50.0; // Dummy value + } + + bool read(bool force = false) { + std::cout << "read called with force: " << force << std::endl; + return true; // Dummy result + } + +private: + uint8_t data[5]; + uint8_t _pin, _type; + uint32_t _lastreadtime, _maxcycles; + bool _lastresult; + uint8_t pullTime; + + uint32_t expectPulse(bool level) { + std::cout << "expectPulse called with level: " << level << std::endl; + return 1000; // Dummy value + } +}; + +#endif // DHT_MOCK_HPP diff --git a/blickbox/sara/include/mock/SerialLoggerMock.cpp b/blickbox/sara/include/mock/SerialLoggerMock.cpp new file mode 100644 index 0000000..384827b --- /dev/null +++ b/blickbox/sara/include/mock/SerialLoggerMock.cpp @@ -0,0 +1,132 @@ +#include +namespace serial_logger{ + + using namespace debugger; + + DebugLevels level = DebugLevels::DEBUG; + + /** + * @brief Logs a Message with a Debug level + * + * @param message + * @param level + */ + void log(String message, DebugLevels level){ + if(level > NONE){ + switch (level) + { + case DEBUG: + std::cout << state_to_string(DEBUG) << " : " << message << std::endl; + break; + case ERROR: + std::cout << state_to_string(ERROR) << " : " << message << std::endl; + break; + case WARNING: + std::cout << state_to_string(WARNING) << " : " << message << std::endl; + break; + case INFO: + std::cout << state_to_string(INFO) << " : " << message << std::endl; + break; + + default: + break; + } + } + } + + /** + * @brief Logs a Message with prefix + * + * @param prefix + * @param message + */ + void log(String prefix, String message){ + std::cout << prefix << " " << message << std::endl; + } + + /** + * @brief Logs a Message + * + * @param message + */ + void log(String message){ + std::cout << message << std::endl; + } + /** + * @brief Logs a Message + * + * @param message + */ + void log(uint16_t number){ + std::cout << number << std::endl; + } + + DebugLevels get_debug_level(){ + return level; + } + + void set_debug_level(DebugLevels level){ + level = level; + } + +} + + + +namespace debugger { + String state_to_string(DebugLevels state){ + switch (state) { + case NONE: + return "none"; + break; + case ERROR: + return "error"; + break; + case WARNING: + return "warning"; + break; + case INFO: + return "info"; + break; + case DEBUG: + return "debug"; + break; + } + return "UNKNOWN"; + } + +} + +namespace serial_communication{ + RequestPattern CurrentPattern = COMMAND; + String command = ""; + + String inputString = ""; // a String to hold incoming data + bool stringComplete = false; // whether the string is complete + + void handle_serial_message_recieved(){ + // if (Serial.available() > 0) { + // char inChar = (char)Serial.read(); + + // if (inChar == '\n' || inChar == '\r') { + + // stringComplete = true; + // CurrentPattern = COMMAND; + // return; + // } + + // inputString += inChar; + + // switch (CurrentPattern) + // { + // case COMMAND: + // command += inChar; + // if(inChar == ' '){ + // CurrentPattern = ARGUMENT; + // } + // break; + // } + // } + } + +} diff --git a/blickbox/sara/include/mock/SerialLoggerMock.hpp b/blickbox/sara/include/mock/SerialLoggerMock.hpp new file mode 100644 index 0000000..97a841e --- /dev/null +++ b/blickbox/sara/include/mock/SerialLoggerMock.hpp @@ -0,0 +1,115 @@ + #ifndef SerialLogger_HPP + #define SerialLogger_HPP + + #include "stubs/ArduinoStubs.hpp" + #include "makros/FMakro.hpp" + #include "types/String.h" + #include + + namespace serial_communication{ + + /** + * Adds structure for switching between commands and arguments + */ + + enum RequestPattern{ + COMMAND, + ARGUMENT + }; + + /** + * @brief Hält das aktuelle Pattern während der Verarbeitung + * + */ + extern RequestPattern CurrentPattern; + + /** + * @brief Enthält das Kommando + * + */ + extern String command; + + /** + * @brief Hällt den empfangenen String + * + */ + extern String inputString; + + /** + * @brief Speichert ob der String fertig verarbeitet wurde + * + */ + extern bool stringComplete; // whether the string is complete + + /** + * @brief Verwaltet eingehende Bytes der Seriellen Schnittstelle + * sollte im Hauptprogramm ausgeführt werden + * + */ + void handle_serial_message_recieved(); + + + } + + namespace debugger{ + + /** + * @brief Definiert Debuglevel um ausgaben zu definieren + * + */ + enum DebugLevels{ + NONE, + ERROR, + WARNING, + INFO, + DEBUG, + }; + + /** + * @brief Wandelt ein Debuglevel in einen String um + * + * @param state + * @return String + */ + String state_to_string(DebugLevels state); + + } + + namespace serial_logger{ + using namespace debugger; + + /** + * @brief speichert das globale Loglevel + * + */ + extern DebugLevels level; + + /** + * @brief Setzt das globale debuglevel + * + * @param level + */ + void set_debug_level(DebugLevels level); + + /** + * @brief Gibt das globale debuglevel zurück + * + * @return DebugLevels + */ + DebugLevels get_debug_level(); + + /** + * @brief log die definierte message auf der Seriellen Konsole + * Mit dem Level definiert um welche Art von Nachricht es sich handelt. + * + * @param message + * @param level + */ + void log(String message, DebugLevels level); + + void log(String message); + void log(uint16_t message); + } + + #endif // SerialLogger_HPP + diff --git a/blickbox/sara/include/mock/SparkFun_Weather_Meter_Kit_Arduino_Library.cpp b/blickbox/sara/include/mock/SparkFun_Weather_Meter_Kit_Arduino_Library.cpp new file mode 100644 index 0000000..283e3f1 --- /dev/null +++ b/blickbox/sara/include/mock/SparkFun_Weather_Meter_Kit_Arduino_Library.cpp @@ -0,0 +1,301 @@ +#include "mock/SparkFun_Weather_Meter_Kit_Arduino_Library.h" + +// Static member definitions +SFEWeatherMeterKitCalibrationParams SFEWeatherMeterKit::_calibrationParams; +uint32_t SFEWeatherMeterKit::_windCountsPrevious; +uint32_t SFEWeatherMeterKit::_windCounts; +uint32_t SFEWeatherMeterKit::_rainfallCounts; +uint32_t SFEWeatherMeterKit::_lastWindSpeedMillis; +uint32_t SFEWeatherMeterKit::_lastRainfallMillis; +uint8_t SFEWeatherMeterKit::_windDirectionPin; +uint8_t SFEWeatherMeterKit::_windSpeedPin; +uint8_t SFEWeatherMeterKit::_rainfallPin; + +/// @brief Default constructor, sets default calibration values +SFEWeatherMeterKit::SFEWeatherMeterKit(uint8_t windDirectionPin, uint8_t windSpeedPin, uint8_t rainfallPin) +{ + // Set sensors pins + _windDirectionPin = windDirectionPin; + _windSpeedPin = windSpeedPin; + _rainfallPin = rainfallPin; + + // The wind vane has 8 switches, but 2 could close at the same time, which + // results in 16 possible positions. Each position has a different resistor, + // resulting in different ADC values. The expected ADC values has been + // experiemntally determined for various platforms, see the constants file + _calibrationParams.vaneADCValues[WMK_ANGLE_0_0] = SFE_WMK_ADC_ANGLE_0_0; + _calibrationParams.vaneADCValues[WMK_ANGLE_22_5] = SFE_WMK_ADC_ANGLE_22_5; + _calibrationParams.vaneADCValues[WMK_ANGLE_45_0] = SFE_WMK_ADC_ANGLE_45_0; + _calibrationParams.vaneADCValues[WMK_ANGLE_67_5] = SFE_WMK_ADC_ANGLE_67_5; + _calibrationParams.vaneADCValues[WMK_ANGLE_90_0] = SFE_WMK_ADC_ANGLE_90_0; + _calibrationParams.vaneADCValues[WMK_ANGLE_112_5] = SFE_WMK_ADC_ANGLE_112_5; + _calibrationParams.vaneADCValues[WMK_ANGLE_135_0] = SFE_WMK_ADC_ANGLE_135_0; + _calibrationParams.vaneADCValues[WMK_ANGLE_157_5] = SFE_WMK_ADC_ANGLE_157_5; + _calibrationParams.vaneADCValues[WMK_ANGLE_180_0] = SFE_WMK_ADC_ANGLE_180_0; + _calibrationParams.vaneADCValues[WMK_ANGLE_202_5] = SFE_WMK_ADC_ANGLE_202_5; + _calibrationParams.vaneADCValues[WMK_ANGLE_225_0] = SFE_WMK_ADC_ANGLE_225_0; + _calibrationParams.vaneADCValues[WMK_ANGLE_247_5] = SFE_WMK_ADC_ANGLE_247_5; + _calibrationParams.vaneADCValues[WMK_ANGLE_270_0] = SFE_WMK_ADC_ANGLE_270_0; + _calibrationParams.vaneADCValues[WMK_ANGLE_292_5] = SFE_WMK_ADC_ANGLE_292_5; + _calibrationParams.vaneADCValues[WMK_ANGLE_315_0] = SFE_WMK_ADC_ANGLE_315_0; + _calibrationParams.vaneADCValues[WMK_ANGLE_337_5] = SFE_WMK_ADC_ANGLE_337_5; + + // Datasheet specifies 2.4kph of wind causes one trigger per second + _calibrationParams.kphPerCountPerSec = 2.4; + + // Wind speed sampling interval. Longer durations have more accuracy, but + // cause delay and can miss fast fluctuations + _calibrationParams.windSpeedMeasurementPeriodMillis = 1000; + + // Datasheet specifies 0.2794mm of rain per trigger + _calibrationParams.mmPerRainfallCount = 0.2794; + + // Debounce time for rainfall detector + _calibrationParams.minMillisPerRainfall = 100; + + // Reset counters to zero + _windCountsPrevious = 0; + _windCounts = 0; + _rainfallCounts = 0; + + // Reset timers + _lastWindSpeedMillis = millis(); + _lastRainfallMillis = millis(); +} + +/// @brief Sets up sensor pins +/// @param windDirectionPin Wind direction pin, must have an ADC +/// @param windSpeedPin Wind speed pin, must support interrupts +/// @param rainfallPin Rainfall pin, must support interrupts +void SFEWeatherMeterKit::begin() +{ + // Set pins to inputs +} + +/// @brief Gets the current calibration parameters +/// @return Current calibration parameters +SFEWeatherMeterKitCalibrationParams SFEWeatherMeterKit::getCalibrationParams() +{ + return _calibrationParams; +} + +/// @brief Sets the new calibration parameters +/// @param params New calibration parameters +void SFEWeatherMeterKit::setCalibrationParams(SFEWeatherMeterKitCalibrationParams params) +{ + // Copy the provided calibration parameters +} + +/// @brief Adjusts the expected ADC values for the wind vane based on the +/// provided ADC resolution +/// @param resolutionBits Resolution of ADC in bits (eg. 8-bit, 12-bit, etc.) +void SFEWeatherMeterKit::setADCResolutionBits(uint8_t resolutionBits) +{ + for(uint8_t i = 0; i < WMK_NUM_ANGLES; i++) + { + int8_t bitShift = (SFE_WMK_ADC_RESOLUTION) - resolutionBits; + + if(bitShift > 0) + { + _calibrationParams.vaneADCValues[i] >>= bitShift; + } + else if(bitShift < 0) + { + _calibrationParams.vaneADCValues[i] <<= -bitShift; + } + } +} + +/// @brief Measures the direction of the wind vane +/// @return Wind direction in degrees +float SFEWeatherMeterKit::getWindDirection() +{ + // Measure the output of the voltage divider + uint16_t rawADC = analogRead(_windDirectionPin); + + // Now we'll loop through all possible directions to find which is closest + // to our measurement, using a simple linear search. closestDifference is + // initialized to max 16-bit signed value (2^15 - 1 = 32,767) + int16_t closestDifference = 32767; + uint8_t closestIndex = 0; + for (uint8_t i = 0; i < WMK_NUM_ANGLES; i++) + { + // Compute the difference between the ADC value for this direction and + // what we measured + int16_t adcDifference = _calibrationParams.vaneADCValues[i] - rawADC; + + // We only care about the magnitude of the difference + adcDifference = abs(adcDifference); + + // Check if this different is less than our closest so far + if (adcDifference < closestDifference) + { + // This resistance is closer, update closest resistance and index + closestDifference = adcDifference; + closestIndex = i; + } + } + + // Now compute the wind direction in degrees + float direction = closestIndex * SFE_WIND_VANE_DEGREES_PER_INDEX; + + // Return direction in degrees + return direction; +} + +/// @brief Updates the wind speed measurement windows if needed +void SFEWeatherMeterKit::updateWindSpeed() +{ + // The anemometer generates interrupts as it spins. Because these are + // discrete pulses, we can't get an instantaneous measurement of the wind + // speed. Instead, we need to track these signals over time and perform some + // filtering to get an estimate of the current wind speed. There's lots of + // ways to do this, but this library uses a modifed version of a moving + // window filter. + // + // A moving window filter would require an array of values to be stored, + // indicating when each pulse occurred. However for a fixed time window, the + // number of pulses is unknown, so we don't know how big the array needs to + // be. There are some solutions to this, but the one used here is to change + // the moving time window to a static time window, which is illustrated in + // this timing diagram with variable time between pulses: + // + // Pulses | | | | | | | | | + // Window Last window Current window + // Time ------|-----------------------|----------------| + // t_last t_now + // |---Measurement Period--|---Measurement Period--| + // + // A counter is used to track the number of pulses detected in the current + // measurement window; when pulses are detected, the counter is incremented. + // When t_now exceeds the measurement period, the total number of pulses is + // used to calculate the average wind speed for that window. This filter + // only outputs wind speed for the previous window, which does result in + // delayed measurements, but is fine for most data logging applications since + // logs can be synced with the measurement widows + + // Get current time + uint32_t tNow = millis(); + + // Compute time since start of current measurement window + uint32_t dt = tNow - _lastWindSpeedMillis; + + // Check how long it's been since the start of this measurement window + if (dt < _calibrationParams.windSpeedMeasurementPeriodMillis) + { + // Still within the current window, nothing to do (count is not + // incremented here, that's done by the interrupt handler) + } + else + { + // We've passed the end of the measurement window, so we need to update + // some things. But first, we need to check how long it's been since the + // last time we updated, since it's possible we've not received any + // pulses for a long time + if (dt > (_calibrationParams.windSpeedMeasurementPeriodMillis * 2)) + { + // Over 2 measurement periods have passed since the last update, + // meaning the wind speed is very slow or even zero. So we'll reset + // the wind speed and counter, and set the start of the next window + // to be now + _windCountsPrevious = 0; + _windCounts = 0; + _lastWindSpeedMillis = tNow; + } + else + { + // We've only just gone past the end of the measurement period, so + // save the wind counts for the previous window, reset current + // counter, and update time of start of next measurement window + _windCountsPrevious = _windCounts; + _windCounts = 0; + _lastWindSpeedMillis += _calibrationParams.windSpeedMeasurementPeriodMillis; + } + } +} + +/// @brief Gets the measured wind speed +/// @return Measured wind speed in kph +float SFEWeatherMeterKit::getWindSpeed() +{ + // Check if the wind speed needs to be updated + updateWindSpeed(); + + // Calculate the wind speed for the previous window. First compute the + // counts per millisecond + float windSpeed = (float) _windCountsPrevious / _calibrationParams.windSpeedMeasurementPeriodMillis; + + // Convert milliseconds to seconds, and counts per second to kph. Need to + // divide by 2 to account for using both rising and falling edges + windSpeed *= 1000 * _calibrationParams.kphPerCountPerSec / 2; + + // Return wind speed for the previous measurement interval + return windSpeed; +} + +/// @brief Gets the number of wind speed counts +/// @return Number of wind speed counts +uint32_t SFEWeatherMeterKit::getWindSpeedCounts() +{ + // Return total wind speed counts + return _windCounts; +} + +/// @brief Gets the number of rainfall counts +/// @return Number of rainfall counts +uint32_t SFEWeatherMeterKit::getRainfallCounts() +{ + // Return total rainfall counts + return _rainfallCounts; +} + +/// @brief Gets the total rainfall +/// @return Total rainfall in mm +float SFEWeatherMeterKit::getTotalRainfall() +{ + // Return total rainfall in mm + return _rainfallCounts * _calibrationParams.mmPerRainfallCount; +} + +/// @brief Resets the wind speed +void SFEWeatherMeterKit::resetWindSpeedFilter() +{ + _windCountsPrevious = 0; + _windCounts = 0; + _lastWindSpeedMillis = millis(); +} + +/// @brief Resets the total rainfall +void SFEWeatherMeterKit::resetTotalRainfall() +{ + _rainfallCounts = 0; +} + +/// @brief Interrupt handler for wind speed pin +void SFEWeatherMeterKit::windSpeedInterrupt() +{ + // Check if the measurement window needs to be updated + updateWindSpeed(); + + // Increment counts in this measurement window + _windCounts++; +} + +/// @brief Interrupt handler for rainfall pin +void SFEWeatherMeterKit::rainfallInterrupt() +{ + // Debounce by checking time since last interrupt + if ((millis() - _lastRainfallMillis) < _calibrationParams.minMillisPerRainfall) + { + // There's not been enough time since the last interrupt, so this is + // likely just the switch bouncing + return; + } + + // Enough time has passed that this is probably a real signal instead of a + // bounce, so update the time of the last interrupt to be now + _lastRainfallMillis = millis(); + + // Increment counter + _rainfallCounts++; +} \ No newline at end of file diff --git a/blickbox/sara/include/mock/SparkFun_Weather_Meter_Kit_Arduino_Library.h b/blickbox/sara/include/mock/SparkFun_Weather_Meter_Kit_Arduino_Library.h new file mode 100644 index 0000000..abe10c0 --- /dev/null +++ b/blickbox/sara/include/mock/SparkFun_Weather_Meter_Kit_Arduino_Library.h @@ -0,0 +1,167 @@ +#ifndef __SPARKFUN_WEATHER_METER_KIT_H__ +#define __SPARKFUN_WEATHER_METER_KIT_H__ + +#include +#include +#include +#include + +// Enum to define the indexes for each wind direction +enum SFEWeatherMeterKitAnemometerAngles +{ + WMK_ANGLE_0_0 = 0, + WMK_ANGLE_22_5, + WMK_ANGLE_45_0, + WMK_ANGLE_67_5, + WMK_ANGLE_90_0, + WMK_ANGLE_112_5, + WMK_ANGLE_135_0, + WMK_ANGLE_157_5, + WMK_ANGLE_180_0, + WMK_ANGLE_202_5, + WMK_ANGLE_225_0, + WMK_ANGLE_247_5, + WMK_ANGLE_270_0, + WMK_ANGLE_292_5, + WMK_ANGLE_315_0, + WMK_ANGLE_337_5, + WMK_NUM_ANGLES +}; + +// Angle per index of wind vane (360 / 16 = 22.5) +#define SFE_WIND_VANE_DEGREES_PER_INDEX (360.0 / WMK_NUM_ANGLES) + +// The ADC of each platform behaves slightly differently. Some have different +// resolutions, some have non-linear outputs, and some voltage divider circuits +// are different. The expected ADV values have been obtained experimentally for +// various platforms below +#ifdef AVR + // Tested with RedBoard Qwiic with Weather Shield + #define SFE_WMK_ADC_ANGLE_0_0 902 + #define SFE_WMK_ADC_ANGLE_22_5 661 + #define SFE_WMK_ADC_ANGLE_45_0 701 + #define SFE_WMK_ADC_ANGLE_67_5 389 + #define SFE_WMK_ADC_ANGLE_90_0 398 + #define SFE_WMK_ADC_ANGLE_112_5 371 + #define SFE_WMK_ADC_ANGLE_135_0 483 + #define SFE_WMK_ADC_ANGLE_157_5 430 + #define SFE_WMK_ADC_ANGLE_180_0 570 + #define SFE_WMK_ADC_ANGLE_202_5 535 + #define SFE_WMK_ADC_ANGLE_225_0 812 + #define SFE_WMK_ADC_ANGLE_247_5 792 + #define SFE_WMK_ADC_ANGLE_270_0 986 + #define SFE_WMK_ADC_ANGLE_292_5 925 + #define SFE_WMK_ADC_ANGLE_315_0 957 + #define SFE_WMK_ADC_ANGLE_337_5 855 + + #define SFE_WMK_ADC_RESOLUTION 10 +#elif ESP32 + // Tested with ESP32 processor board installed on Weather Carrier + #define SFE_WMK_ADC_ANGLE_0_0 3118 + #define SFE_WMK_ADC_ANGLE_22_5 1526 + #define SFE_WMK_ADC_ANGLE_45_0 1761 + #define SFE_WMK_ADC_ANGLE_67_5 199 + #define SFE_WMK_ADC_ANGLE_90_0 237 + #define SFE_WMK_ADC_ANGLE_112_5 123 + #define SFE_WMK_ADC_ANGLE_135_0 613 + #define SFE_WMK_ADC_ANGLE_157_5 371 + #define SFE_WMK_ADC_ANGLE_180_0 1040 + #define SFE_WMK_ADC_ANGLE_202_5 859 + #define SFE_WMK_ADC_ANGLE_225_0 2451 + #define SFE_WMK_ADC_ANGLE_247_5 2329 + #define SFE_WMK_ADC_ANGLE_270_0 3984 + #define SFE_WMK_ADC_ANGLE_292_5 3290 + #define SFE_WMK_ADC_ANGLE_315_0 3616 + #define SFE_WMK_ADC_ANGLE_337_5 2755 + + #define SFE_WMK_ADC_RESOLUTION 12 +#else + // Values calculated assuming 10k pullup and perfectly linear 16-bit ADC + #define SFE_WMK_ADC_ANGLE_0_0 50294 + #define SFE_WMK_ADC_ANGLE_22_5 25985 + #define SFE_WMK_ADC_ANGLE_45_0 29527 + #define SFE_WMK_ADC_ANGLE_67_5 5361 + #define SFE_WMK_ADC_ANGLE_90_0 5958 + #define SFE_WMK_ADC_ANGLE_112_5 4219 + #define SFE_WMK_ADC_ANGLE_135_0 11818 + #define SFE_WMK_ADC_ANGLE_157_5 8099 + #define SFE_WMK_ADC_ANGLE_180_0 18388 + #define SFE_WMK_ADC_ANGLE_202_5 15661 + #define SFE_WMK_ADC_ANGLE_225_0 40329 + #define SFE_WMK_ADC_ANGLE_247_5 38365 + #define SFE_WMK_ADC_ANGLE_270_0 60494 + #define SFE_WMK_ADC_ANGLE_292_5 52961 + #define SFE_WMK_ADC_ANGLE_315_0 56785 + #define SFE_WMK_ADC_ANGLE_337_5 44978 + + #define SFE_WMK_ADC_RESOLUTION 16 + + // Set macro to indicate that this platform isn't known + #define SFE_WMK_PLAFTORM_UNKNOWN +#endif + +// Calibration parameters for each sensor +struct SFEWeatherMeterKitCalibrationParams +{ + // Wind vane + uint16_t vaneADCValues[WMK_NUM_ANGLES]; + + // Wind speed + uint32_t windSpeedMeasurementPeriodMillis; + float kphPerCountPerSec; + + // Rainfall + float mmPerRainfallCount; + uint32_t minMillisPerRainfall; +}; + +class SFEWeatherMeterKit +{ + public: + // Constructor + SFEWeatherMeterKit(uint8_t windDirectionPin, uint8_t windSpeedPin, uint8_t rainfallPin); + static void begin(); + + // Data collection + static float getWindDirection(); + static float getWindSpeed(); + static float getTotalRainfall(); + + // Sensor calibration params + static SFEWeatherMeterKitCalibrationParams getCalibrationParams(); + static void setCalibrationParams(SFEWeatherMeterKitCalibrationParams params); + + // ADC resolution scaling + static void setADCResolutionBits(uint8_t resolutionBits); + + // Helper functions. These can be helpful for sensor calibration + static uint32_t getWindSpeedCounts(); + static uint32_t getRainfallCounts(); + static void resetWindSpeedFilter(); + static void resetTotalRainfall(); + + private: + // Updates wind speed + static void updateWindSpeed(); + + // Interrupt handlers + static void windSpeedInterrupt(); + static void rainfallInterrupt(); + + // Pins for each sensor + static uint8_t _windDirectionPin; + static uint8_t _windSpeedPin; + static uint8_t _rainfallPin; + + // Sensor calibration parameters + static SFEWeatherMeterKitCalibrationParams _calibrationParams; + + // Variables to track measurements + static uint32_t _windCounts; + static uint32_t _windCountsPrevious; + static uint32_t _rainfallCounts; + static uint32_t _lastWindSpeedMillis; + static uint32_t _lastRainfallMillis; +}; + +#endif \ No newline at end of file diff --git a/blickbox/sara/include/stubs/ArduinoStubs.hpp b/blickbox/sara/include/stubs/ArduinoStubs.hpp new file mode 100644 index 0000000..8a7b109 --- /dev/null +++ b/blickbox/sara/include/stubs/ArduinoStubs.hpp @@ -0,0 +1,36 @@ +// ArduinoStubs.hpp + + +#ifndef ARDUINO_STUBS_HPP +#define ARDUINO_STUBS_HPP + +#include + +// Stub für pinMode +inline void pinMode(uint8_t pin, uint8_t mode) { + // Keine Aktion +} + +// Stub für analogRead +inline int analogRead(uint8_t pin) { + return 0; // Dummy-Wert, kann angepasst werden +} + +inline void digitalWrite(uint8_t pin, bool status) { + +} + +// Stub für delay +inline void delay(uint32_t ms) { + // Keine Aktion +} + +inline uint32_t millis() { + return 1; +} + + + +// Weitere benötigte Arduino-Funktionen hier stubs bereitstellen + +#endif // ARDUINO_STUBS_HPP diff --git a/blickbox/sara/include/stubs/BLE_Stubs.hpp b/blickbox/sara/include/stubs/BLE_Stubs.hpp new file mode 100644 index 0000000..5af0bb5 --- /dev/null +++ b/blickbox/sara/include/stubs/BLE_Stubs.hpp @@ -0,0 +1,69 @@ +// stubs/ArduinoBLEStubs.hpp + +#ifndef ARDUINOBLESTUBS_HPP +#define ARDUINOBLESTUBS_HPP + +#include +#include +#include +#include + +// Stub for BLECharacteristic +class BLECharacteristic { +public: + BLECharacteristic(const char* uuid, unsigned char properties, int size = 20, bool fixedLength = false) {} + void writeValue(uint16_t value) {} + void writeValue(const std::string& value) {} + std::string value() const { return ""; } +}; + +// Stub for BLEService +class BLEService { +public: + BLEService(const char* uuid) {} + bool begin() { return true; } + void addCharacteristic(BLECharacteristic& characteristic) {} +}; + +// Stub for BLEDevice +class BLEDevice { +public: + std::string address() const { return "00:00:00:00:00:00"; } +}; + +// BLE Event Types +enum BLEEvent { + BLEConnected, + BLEDisconnected +}; + +// Stubs for BLE functions +namespace BLE { + std::map> eventHandlers; + + bool begin() { return true; } + void setEventHandler(BLEEvent event, std::function handler) { + eventHandlers[event] = handler; + } + BLEDevice central() { return BLEDevice(); } + void advertise() {} + void stopAdvertise() {} + void setLocalName(const char* name) {} + void setAdvertisedService(BLEService& service) {} + void addService(BLEService& service) {} + + // Simulate BLE Events (for testing) + void simulateConnect() { + if (eventHandlers[BLEConnected]) { + eventHandlers[BLEConnected](BLEDevice()); + } + } + + void simulateDisconnect() { + if (eventHandlers[BLEDisconnected]) { + eventHandlers[BLEDisconnected](BLEDevice()); + } + } +} + +#endif // ARDUINOBLESTUBS_HPP diff --git a/blickbox/sara/include/stubs/SerialStubs.hpp b/blickbox/sara/include/stubs/SerialStubs.hpp new file mode 100644 index 0000000..3d05422 --- /dev/null +++ b/blickbox/sara/include/stubs/SerialStubs.hpp @@ -0,0 +1,26 @@ +#ifndef SERIAL_STUBS_HPP +#define SERIAL_STUBS_HPP + +#ifdef unity_testing + + +// Stubs für die Methoden von Serial +namespace Serial { + void begin(unsigned long baudrate) { + // Stub-Implementierung für begin + } + + void print(const char* str) { + // Stub-Implementierung für print + } + + void println(const char* str) { + // Stub-Implementierung für println + } + + // Weitere Methoden können hier hinzugefügt werden, wenn nötig +} + + +#endif // SERIAL_STUBS_HPP +#endif \ No newline at end of file diff --git a/blickbox/sara/include/types/Numbers.h b/blickbox/sara/include/types/Numbers.h new file mode 100644 index 0000000..373803d --- /dev/null +++ b/blickbox/sara/include/types/Numbers.h @@ -0,0 +1,9 @@ +#ifndef NUMBER_HPP +#define NUMBER_HPP + +// Typdefinitionen, falls stdint.h nicht verfügbar ist +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +typedef float float16_t; +#endif // NUMBER_HPP \ No newline at end of file diff --git a/blickbox/sara/include/types/String.h b/blickbox/sara/include/types/String.h new file mode 100644 index 0000000..9f18a57 --- /dev/null +++ b/blickbox/sara/include/types/String.h @@ -0,0 +1,8 @@ + +#ifndef STRING_HPP +#define STRING_HPP + +#include +typedef std::string String; + +#endif // STRING_HPP \ No newline at end of file diff --git a/blickbox/sara/lib/SaraBLE/src/SaraBLE.cpp b/blickbox/sara/lib/SaraBLE/src/SaraBLE.cpp index be3b221..5d79ecd 100644 --- a/blickbox/sara/lib/SaraBLE/src/SaraBLE.cpp +++ b/blickbox/sara/lib/SaraBLE/src/SaraBLE.cpp @@ -1,174 +1,176 @@ -#include - -namespace sara_ble{ - using namespace serial_logger; - using namespace sara_data; - - - /** - * @brief Gibt die String repräsentation vom Enum zurück - * - * @param state - * @return String - */ - String ble_state_to_String(ble_state state){ - switch (state) - { - case NONE: - return F("NONE"); - break; - case DISCONNECTED: - return F("DISCONNECTED"); - break; - case CONNECTED: - return F("CONNECTED"); - break; - } - } - - /** - * @brief Speichert den aktuellen Bluetooth Verbindungs Status - * - */ - ble_state connection_state = DISCONNECTED; - - /** - * @brief Speichert die MAC Adresse des verbundenen Geräts - * - */ - String connected_device; - - // Definiere BLE Services und Charakteristiken - BLEService airService("1101"); - BLECharacteristic temperatureCharacteristic("2101", BLERead | BLENotify, 16) ; - BLECharacteristic humidityCharacteristic("2102", BLERead | BLENotify, 16); - BLEService weatherStationService("1102"); - BLECharacteristic rainfallCharacteristic("2203", BLERead | BLENotify, 16); - BLECharacteristic winddirectionCharacteristic("2201", BLERead | BLENotify, 16) ; - BLECharacteristic windspeedCharacteristic("2202", BLERead | BLENotify, 16); - BLEService powerService("1103"); - BLECharacteristic batterLevelCharacteristic("2301", BLERead | BLENotify, 16) ; - BLECharacteristic batterVoltageCharacteristic("2302", BLERead | BLENotify, 16); - - - void begin(){ - - // BLE Error Handling - if (!BLE.begin()) { - log(F("ble_failed:Starting BLE failed!"), ERROR); - while (1); + #include + + namespace sara_ble{ + using namespace serial_logger; + using namespace sara_data; + + + /** + * @brief Gibt die String repräsentation vom Enum zurück + * + * @param state + * @return String + */ + String ble_state_to_String(ble_state state){ + switch (state) + { + case NONE: + return F("NONE"); + break; + case DISCONNECTED: + return F("DISCONNECTED"); + break; + case CONNECTED: + return F("CONNECTED"); + break; + } } - // Setze Event Handler - BLE.setEventHandler( BLEConnected, on_connect ); - BLE.setEventHandler( BLEDisconnected, on_disconnect ); + /** + * @brief Speichert den aktuellen Bluetooth Verbindungs Status + * + */ + ble_state connection_state = DISCONNECTED; + + /** + * @brief Speichert die MAC Adresse des verbundenen Geräts + * + */ + String connected_device; - // Setze BLE Name - BLE.setLocalName("SARA Weather Station"); - // Definiere BLE Services und Charakteristiken - BLE.setAdvertisedService(airService); - airService.addCharacteristic(temperatureCharacteristic); - airService.addCharacteristic(humidityCharacteristic); - BLE.setAdvertisedService(weatherStationService); - weatherStationService.addCharacteristic(winddirectionCharacteristic); - weatherStationService.addCharacteristic(windspeedCharacteristic); - weatherStationService.addCharacteristic(rainfallCharacteristic); - BLE.setAdvertisedService(powerService); - powerService.addCharacteristic(batterLevelCharacteristic); - powerService.addCharacteristic(batterVoltageCharacteristic); - BLE.addService(airService); - BLE.addService(weatherStationService); - BLE.addService(powerService); - - // Advertise Services und Charakteristiken - BLE.advertise(); - } + BLEService airService("1101"); + BLECharacteristic temperatureCharacteristic("2101", BLERead | BLENotify, 16) ; + BLECharacteristic humidityCharacteristic("2102", BLERead | BLENotify, 16); + BLEService weatherStationService("1102"); + BLECharacteristic rainfallCharacteristic("2203", BLERead | BLENotify, 16); + BLECharacteristic winddirectionCharacteristic("2201", BLERead | BLENotify, 16) ; + BLECharacteristic windspeedCharacteristic("2202", BLERead | BLENotify, 16); + BLEService powerService("1103"); + BLECharacteristic batterLevelCharacteristic("2301", BLERead | BLENotify, 16) ; + BLECharacteristic batterVoltageCharacteristic("2302", BLERead | BLENotify, 16); + - /** - * @brief Connect Event Handler setzt den Bluetooth Status auf CONNECTED und - * speichert die MAC Adresse des verbundenen Geräts und stoppt das Advertisen der Services - * - * @param central - */ - void on_connect(BLEDevice central ){ - connection_state = CONNECTED; - connected_device = central.address(); - BLE.stopAdvertise(); - log(F("Device Connected"), INFO); - } - - /** - * @brief Disconnect Event Handler setzt den Bluetooth Status auf DISCONNECTED und - * startet das Advertisen der Services - * - * @param central - */ - void on_disconnect(BLEDevice central ){ - connection_state = DISCONNECTED; - connected_device = ""; - BLE.advertise(); - log(F("Device Disconnected"), INFO); - } - - /** - * @brief Schreibt fürs Debugging die aktuellen Bluetooth Status auf der Konsole aus - * - */ - void print_bluetooth_state(){ - Serial.print(F("ble_connection:")); - Serial.println(ble_state_to_String(connection_state)); - Serial.print(F("ble_device:")); - Serial.println(connected_device); - } - - /** - * @brief Aktualisiert die Luftdaten in den BLE Charakteristiken - * wenn das Gerät mit einem Notification Handler verbunden ist - * wird diese über neue Daten informiert. Wandelt die Floats in Ints um indem es - * die Werte mit 100 multipliziert und rundet. - * - * @param air_data - */ - void update_air_data(sara_data::air_data *air_data) { - uint16_t temperature = round(air_data->temperature * 100); - uint16_t humidity = round(air_data->humidity * 100); - - temperatureCharacteristic.writeValue(temperature); - humidityCharacteristic.writeValue(humidity); - } - - /** - * @brief Aktualisiert die Wetterdaten in den BLE Charakteristiken - * wenn das Gerät mit einem Notification Handler verbunden ist - * wird diese über neue Daten informiert. Wandelt die Floats in Ints um indem es - * die Werte mit 100 multipliziert und rundet. - * - * @param weather_data - */ - void update_weather_data(sara_data::weather_station_data *weather_data) { - uint16_t winddirection = round(weather_data->winddirection * 100); - uint16_t windspeed = round(weather_data->windspeed * 100); - uint16_t rainfall = round(weather_data->rainfall * 100); - - winddirectionCharacteristic.writeValue(winddirection); - windspeedCharacteristic.writeValue(windspeed); - rainfallCharacteristic.writeValue(rainfall); - } - - /** - * @brief Aktualisiert die Batteriedaten in den BLE Charakteristiken - * wenn das Gerät mit einem Notification Handler verbunden ist - * wird diese über neue Daten informiert. Wandelt das Batterielevel in ein Int um indem es - * die Werte mit 100 multipliziert und rundet. - * - * @param battery_data - */ - void update_battery_data(sara_data::battery_data *battery_data) { - int16_t battery_voltage = round(battery_data->voltage * 100); - int16_t battery_level = round(battery_data->level * 100); - - batterVoltageCharacteristic.writeValue(battery_voltage); - batterLevelCharacteristic.writeValue(battery_level); - } -} \ No newline at end of file + void begin(){ + + // BLE Error Handling + if (!BLE.begin()) { + log(F("ble_failed:Starting BLE failed!"), ERROR); + while (1); + } + + // Setze Event Handler + BLE.setEventHandler( BLEConnected, on_connect ); + BLE.setEventHandler( BLEDisconnected, on_disconnect ); + + // Setze BLE Name + BLE.setLocalName("SARA Weather Station"); + + // Definiere BLE Services und Charakteristiken + BLE.setAdvertisedService(airService); + airService.addCharacteristic(temperatureCharacteristic); + airService.addCharacteristic(humidityCharacteristic); + BLE.setAdvertisedService(weatherStationService); + weatherStationService.addCharacteristic(winddirectionCharacteristic); + weatherStationService.addCharacteristic(windspeedCharacteristic); + weatherStationService.addCharacteristic(rainfallCharacteristic); + BLE.setAdvertisedService(powerService); + powerService.addCharacteristic(batterLevelCharacteristic); + powerService.addCharacteristic(batterVoltageCharacteristic); + BLE.addService(airService); + BLE.addService(weatherStationService); + BLE.addService(powerService); + + // Advertise Services und Charakteristiken + BLE.advertise(); + } + + /** + * @brief Connect Event Handler setzt den Bluetooth Status auf CONNECTED und + * speichert die MAC Adresse des verbundenen Geräts und stoppt das Advertisen der Services + * + * @param central + */ + void on_connect(BLEDevice central ){ + connection_state = CONNECTED; + connected_device = central.address(); + BLE.stopAdvertise(); + log(F("Device Connected"), INFO); + } + + /** + * @brief Disconnect Event Handler setzt den Bluetooth Status auf DISCONNECTED und + * startet das Advertisen der Services + * + * @param central + */ + void on_disconnect(BLEDevice central ){ + connection_state = DISCONNECTED; + connected_device = ""; + BLE.advertise(); + log(F("Device Disconnected"), INFO); + } + + #ifndef unity_testing + /** + * @brief Schreibt fürs Debugging die aktuellen Bluetooth Status auf der Konsole aus + * + */ + void print_bluetooth_state(){ + Serial.print(F("ble_connection:")); + Serial.println(ble_state_to_String(connection_state)); + Serial.print(F("ble_device:")); + Serial.println(connected_device); + } + #endif + + /** + * @brief Aktualisiert die Luftdaten in den BLE Charakteristiken + * wenn das Gerät mit einem Notification Handler verbunden ist + * wird diese über neue Daten informiert. Wandelt die Floats in Ints um indem es + * die Werte mit 100 multipliziert und rundet. + * + * @param air_data + */ + void update_air_data(sara_data::air_data *air_data) { + uint16_t temperature = round(air_data->temperature * 100); + uint16_t humidity = round(air_data->humidity * 100); + + temperatureCharacteristic.writeValue(temperature); + humidityCharacteristic.writeValue(humidity); + } + + /** + * @brief Aktualisiert die Wetterdaten in den BLE Charakteristiken + * wenn das Gerät mit einem Notification Handler verbunden ist + * wird diese über neue Daten informiert. Wandelt die Floats in Ints um indem es + * die Werte mit 100 multipliziert und rundet. + * + * @param weather_data + */ + void update_weather_data(sara_data::weather_station_data *weather_data) { + uint16_t winddirection = round(weather_data->winddirection * 100); + uint16_t windspeed = round(weather_data->windspeed * 100); + uint16_t rainfall = round(weather_data->rainfall * 100); + + winddirectionCharacteristic.writeValue(winddirection); + windspeedCharacteristic.writeValue(windspeed); + rainfallCharacteristic.writeValue(rainfall); + } + + /** + * @brief Aktualisiert die Batteriedaten in den BLE Charakteristiken + * wenn das Gerät mit einem Notification Handler verbunden ist + * wird diese über neue Daten informiert. Wandelt das Batterielevel in ein Int um indem es + * die Werte mit 100 multipliziert und rundet. + * + * @param battery_data + */ + void update_battery_data(sara_data::battery_data *battery_data) { + int16_t battery_voltage = round(battery_data->voltage * 100); + int16_t battery_level = round(battery_data->level * 100); + + batterVoltageCharacteristic.writeValue(battery_voltage); + batterLevelCharacteristic.writeValue(battery_level); + } + } \ No newline at end of file diff --git a/blickbox/sara/lib/SaraBLE/src/SaraBLE.hpp b/blickbox/sara/lib/SaraBLE/src/SaraBLE.hpp index d7d70f8..1cafb11 100644 --- a/blickbox/sara/lib/SaraBLE/src/SaraBLE.hpp +++ b/blickbox/sara/lib/SaraBLE/src/SaraBLE.hpp @@ -1,11 +1,25 @@ #ifndef SARABLE_HPP #define SARABLE_HPP + + +#ifdef unity_testing +#include +#include +#include +#include +#include + +#include +#include + +#else #include #include #include #include #include +#endif namespace sara_ble{ diff --git a/blickbox/sara/lib/SaraLib/src/sara_battery.hpp b/blickbox/sara/lib/SaraLib/src/sara_battery.hpp index edc4989..25859b2 100644 --- a/blickbox/sara/lib/SaraLib/src/sara_battery.hpp +++ b/blickbox/sara/lib/SaraLib/src/sara_battery.hpp @@ -1,8 +1,16 @@ #ifndef SARA_BATTERY_HPP #define SARA_BATTERY_HPP +#ifdef unity_testing +#include +#include +#include +#else #include #include +#endif + + #include diff --git a/blickbox/sara/lib/SaraLib/src/sara_data.cpp b/blickbox/sara/lib/SaraLib/src/sara_data.cpp index 198a048..25b0947 100644 --- a/blickbox/sara/lib/SaraLib/src/sara_data.cpp +++ b/blickbox/sara/lib/SaraLib/src/sara_data.cpp @@ -48,10 +48,10 @@ namespace sara_data{ * @param battery Ein Zeiger auf die Batteriedatenstruktur. */ void print_battery_data(battery_data* battery){ - Serial.print(F("Battery Data - Raw ADC: ")); - Serial.print(battery->raw_adc); - Serial.print(F(", Level: ")); - Serial.println(battery->level); + serial_logger::log("Battery Data - Raw ADC: "); + serial_logger::log(battery->raw_adc); + serial_logger::log(", Level: "); + serial_logger::log(battery->level); } /** @@ -60,10 +60,10 @@ namespace sara_data{ * @param air Ein Zeiger auf die Luftdatenstruktur. */ void print_air_data(air_data* air){ - Serial.print(F("Air Data - Humidity: ")); - Serial.print(air->humidity); - Serial.print(F(", Temperature: ")); - Serial.println(air->temperature); + serial_logger::log("Air Data - Humidity: "); + serial_logger::log(air->humidity); + serial_logger::log(", Temperature: "); + serial_logger::log(air->temperature); } /** @@ -72,12 +72,12 @@ namespace sara_data{ * @param weather Ein Zeiger auf die Wetterdatenstruktur. */ void print_weather_station_data(weather_station_data* weather){ - Serial.print(F("Weather Station Data - Rainfall: ")); - Serial.print(weather->rainfall); - Serial.print(F(", Windspeed: ")); - Serial.print(weather->windspeed); - Serial.print(F(", Winddirection: ")); - Serial.println(weather->winddirection); + serial_logger::log("Weather Station Data - Rainfall: "); + serial_logger::log(weather->rainfall); + serial_logger::log(", Windspeed: "); + serial_logger::log(weather->windspeed); + serial_logger::log(", Winddirection: "); + serial_logger::log(weather->winddirection); } } diff --git a/blickbox/sara/lib/SaraLib/src/sara_data.hpp b/blickbox/sara/lib/SaraLib/src/sara_data.hpp index c47ae3a..fb41966 100644 --- a/blickbox/sara/lib/SaraLib/src/sara_data.hpp +++ b/blickbox/sara/lib/SaraLib/src/sara_data.hpp @@ -1,9 +1,20 @@ #ifndef SARA_DATA_HPP #define SARA_DATA_HPP +#ifdef unity_testing +#include +#include +#include +#include +#include +#include +#else #include #include #include +#endif + + #include using namespace sara_battery; diff --git a/blickbox/sara/lib/SerialLogger/library.json b/blickbox/sara/lib/SerialLogger/library.json deleted file mode 100644 index 2782288..0000000 --- a/blickbox/sara/lib/SerialLogger/library.json +++ /dev/null @@ -1,33 +0,0 @@ -{ -"name": "SerialLogger", -"version": "1.0.0", -"description": "This library allows you to log messages to the serial port. It is useful for debugging purposes.", -"keywords": [ - "ada", - "debug", - "dfplayer", - "Blickbox", - "IoT" - ], - "frameworks": { - "arduino": { - "required": true - } - }, - "platforms": [ - "espressif8266", - "espressif32" - ], - "authors": [ - { - "name": "Maytastico", - "email": "maytastico@hotmail.com" - } - ], - "homepage": "https://github.com/mxmueller/DHBW-Blickbox", - "repository": { - "type": "git", - "url": "https://github.com/mxmueller/DHBW-Blickbox" - }, - "license": "MIT" -} diff --git a/blickbox/sara/lib/SerialLogger/src/SerialLogger.cpp b/blickbox/sara/lib/SerialLogger/src/SerialLogger.cpp deleted file mode 100644 index 6d6e075..0000000 --- a/blickbox/sara/lib/SerialLogger/src/SerialLogger.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include -namespace serial_logger{ - - using namespace debugger; - - DebugLevels level = DebugLevels::DEBUG; - - /** - * @brief Logs a Message with a Debug level - * - * @param message - * @param level - */ - void log(String message,DebugLevels level){ - if(level > NONE){ - switch (level) - { - case DEBUG: - Serial.print(state_to_string(DEBUG)); - Serial.print(F(":")); - Serial.println(message); - break; - case ERROR: - Serial.print(state_to_string(ERROR)); - Serial.print(F(":")); - Serial.println(message); - break; - case WARNING: - Serial.print(state_to_string(WARNING)); - Serial.print(F(":")); - Serial.println(message); - break; - case INFO: - Serial.print(state_to_string(INFO)); - Serial.print(F(":")); - Serial.println(message); - break; - - default: - break; - } - } - } - - /** - * @brief Logs a Message with prefix - * - * @param prefix - * @param message - */ - void log(String prefix, String message){ - Serial.print(prefix); - Serial.println(message); - } - - DebugLevels get_debug_level(){ - return level; - } - - void set_debug_level(DebugLevels level){ - level = level; - } - -} - - - -namespace debugger { - String state_to_string(DebugLevels state){ - switch (state) { - case NONE: - return F("none"); - break; - case ERROR: - return F("error"); - break; - case WARNING: - return F("warning"); - break; - case INFO: - return F("info"); - break; - case DEBUG: - return F("debug"); - break; - } - return F("UNKNOWN"); - } - -} - -namespace serial_communication{ - RequestPattern CurrentPattern = COMMAND; - String command = ""; - - String inputString = ""; // a String to hold incoming data - bool stringComplete = false; // whether the string is complete - - void handle_serial_message_recieved(){ - if (Serial.available() > 0) { - char inChar = (char)Serial.read(); - - if (inChar == '\n' || inChar == '\r') { - - stringComplete = true; - CurrentPattern = COMMAND; - return; - } - - inputString += inChar; - - switch (CurrentPattern) - { - case COMMAND: - command += inChar; - if(inChar == ' '){ - CurrentPattern = ARGUMENT; - } - break; - } - } - } - -} diff --git a/blickbox/sara/lib/SerialLogger/src/SerialLogger.hpp b/blickbox/sara/lib/SerialLogger/src/SerialLogger.hpp deleted file mode 100644 index f9951b6..0000000 --- a/blickbox/sara/lib/SerialLogger/src/SerialLogger.hpp +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef SerialLogger_HPP -#define SerialLogger_HPP - -#include -namespace serial_communication{ - - /** - * Adds structure for switching between commands and arguments - */ - - enum RequestPattern{ - COMMAND, - ARGUMENT - }; - - /** - * @brief Hält das aktuelle Pattern während der Verarbeitung - * - */ - extern RequestPattern CurrentPattern; - - /** - * @brief Enthält das Kommando - * - */ - extern String command; - - /** - * @brief Hällt den empfangenen String - * - */ - extern String inputString; - - /** - * @brief Speichert ob der String fertig verarbeitet wurde - * - */ - extern bool stringComplete; // whether the string is complete - - /** - * @brief Verwaltet eingehende Bytes der Seriellen Schnittstelle - * sollte im Hauptprogramm ausgeführt werden - * - */ - void handle_serial_message_recieved(); - - -} - -namespace debugger{ - - /** - * @brief Definiert Debuglevel um ausgaben zu definieren - * - */ - enum DebugLevels{ - NONE, - ERROR, - WARNING, - INFO, - DEBUG, - }; - - /** - * @brief Wandelt ein Debuglevel in einen String um - * - * @param state - * @return String - */ - String state_to_string(DebugLevels state); - -} - -namespace serial_logger{ - using namespace debugger; - - /** - * @brief speichert das globale Loglevel - * - */ - extern DebugLevels level; - - /** - * @brief Setzt das globale debuglevel - * - * @param level - */ - void set_debug_level(DebugLevels level); - - /** - * @brief Gibt das globale debuglevel zurück - * - * @return DebugLevels - */ - DebugLevels get_debug_level(); - - /** - * @brief log die definierte message auf der Seriellen Konsole - * Mit dem Level definiert um welche Art von Nachricht es sich handelt. - * - * @param message - * @param level - */ - void log(String message, DebugLevels level); -} - -#endif // SerialLogger_HPP - diff --git a/blickbox/sara/platformio.ini b/blickbox/sara/platformio.ini index 1ade820..bebde74 100644 --- a/blickbox/sara/platformio.ini +++ b/blickbox/sara/platformio.ini @@ -8,6 +8,37 @@ ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html +[options] +platform = nordicnrf52 +board = nano33ble +framework = arduino +unittesting_buildflag = + -std=gnu++11 + -D unitTesting +generic_hw_buildflag = -D generic_hw +coverage_buildflag = + -lgcov + --coverage + -fprofile-abs-path + -Og +test_framework = unity +selected_tests = * + +[env:native_selected_unittests] +platform = native +build_flags = + -D UNITY_INT_WIDTH=16 + -D UNITY_FLOAT_TYPE=float16_t + -D unity_testing + -std=c++11 ; Verwende den C++17 Standard + -DUNITY_INCLUDE_CONFIG_H + -DUNITY_SUPPORT_64 + -DUNITY_SUPPORT_DOUBLE + -I include +lib_deps = + - SaraLIB +test_framework = ${options.test_framework} + [env:ble] platform = nordicnrf52 board = nano33ble @@ -34,3 +65,4 @@ lib_deps = adafruit/Adafruit Unified Sensor@^1.1.14 sparkfun/SparkFun Weather Meter Kit Arduino Library@^1.1.1 powerbroker2/FireTimer@^1.0.5 + fabiobatsilva/ArduinoFake@^0.4.0 diff --git a/blickbox/sara/test/test_main.cpp b/blickbox/sara/test/test_main.cpp new file mode 100644 index 0000000..e7e8135 --- /dev/null +++ b/blickbox/sara/test/test_main.cpp @@ -0,0 +1,13 @@ +#include +#include + + + +int main(int argc, char **argv) +{ + UNITY_BEGIN(); + + // RUN_TEST(test_loop); + + return UNITY_END(); +} \ No newline at end of file From c914fc0329bce1346b67a14dfdf6864163919d81 Mon Sep 17 00:00:00 2001 From: Maytastico Date: Sun, 25 Aug 2024 14:19:59 +0200 Subject: [PATCH 2/2] #333-Komponententest:-Batterielevel-auslesen-und-in-Level-umrechnen --- blickbox/sara/include/stubs/ArduinoStubs.hpp | 2 +- blickbox/sara/lib/LibStubs/library.json | 32 +++++ .../lib/LibStubs/src/makros/ArdunioMakros.hpp | 13 ++ .../sara/lib/LibStubs/src/makros/FMakro.hpp | 6 + blickbox/sara/lib/LibStubs/src/mock/DHT.hpp | 66 +++++++++ .../LibStubs/src/mock/SerialLoggerMock.cpp | 132 ++++++++++++++++++ .../LibStubs/src/mock/SerialLoggerMock.hpp | 115 +++++++++++++++ .../lib/LibStubs/src/stubs/ArduinoStubs.hpp | 36 +++++ .../sara/lib/LibStubs/src/stubs/BLE_Stubs.hpp | 69 +++++++++ .../lib/LibStubs/src/stubs/SerialStubs.hpp | 26 ++++ .../sara/lib/LibStubs/src/types/Numbers.h | 8 ++ blickbox/sara/lib/LibStubs/src/types/String.h | 8 ++ blickbox/sara/platformio.ini | 6 +- blickbox/sara/test/test_battery.cpp | 41 ++++++ blickbox/sara/test/test_main.cpp | 13 -- 15 files changed, 554 insertions(+), 19 deletions(-) create mode 100644 blickbox/sara/lib/LibStubs/library.json create mode 100644 blickbox/sara/lib/LibStubs/src/makros/ArdunioMakros.hpp create mode 100644 blickbox/sara/lib/LibStubs/src/makros/FMakro.hpp create mode 100644 blickbox/sara/lib/LibStubs/src/mock/DHT.hpp create mode 100644 blickbox/sara/lib/LibStubs/src/mock/SerialLoggerMock.cpp create mode 100644 blickbox/sara/lib/LibStubs/src/mock/SerialLoggerMock.hpp create mode 100644 blickbox/sara/lib/LibStubs/src/stubs/ArduinoStubs.hpp create mode 100644 blickbox/sara/lib/LibStubs/src/stubs/BLE_Stubs.hpp create mode 100644 blickbox/sara/lib/LibStubs/src/stubs/SerialStubs.hpp create mode 100644 blickbox/sara/lib/LibStubs/src/types/Numbers.h create mode 100644 blickbox/sara/lib/LibStubs/src/types/String.h create mode 100644 blickbox/sara/test/test_battery.cpp delete mode 100644 blickbox/sara/test/test_main.cpp diff --git a/blickbox/sara/include/stubs/ArduinoStubs.hpp b/blickbox/sara/include/stubs/ArduinoStubs.hpp index 8a7b109..22c9893 100644 --- a/blickbox/sara/include/stubs/ArduinoStubs.hpp +++ b/blickbox/sara/include/stubs/ArduinoStubs.hpp @@ -4,7 +4,7 @@ #ifndef ARDUINO_STUBS_HPP #define ARDUINO_STUBS_HPP -#include +//#include // Stub für pinMode inline void pinMode(uint8_t pin, uint8_t mode) { diff --git a/blickbox/sara/lib/LibStubs/library.json b/blickbox/sara/lib/LibStubs/library.json new file mode 100644 index 0000000..3c0ab05 --- /dev/null +++ b/blickbox/sara/lib/LibStubs/library.json @@ -0,0 +1,32 @@ +{ +"name": "SaraLIB", +"version": "1.0.0", +"description": "Stubs and Mocks for Arduino based frameworks", +"keywords": [ + "ada", + "Blickbox", + "IoT", + "Data", + "Sara" + ], + "frameworks": { + "arduino": { + "required": true + } + }, + "platforms": [ + "nordicnrf52" + ], + "authors": [ + { + "name": "Maytastico", + "email": "maytastico@hotmail.com" + } + ], + "homepage": "https://github.com/mxmueller/DHBW-Blickbox", + "repository": { + "type": "git", + "url": "https://github.com/mxmueller/DHBW-Blickbox" + }, + "license": "MIT" +} diff --git a/blickbox/sara/lib/LibStubs/src/makros/ArdunioMakros.hpp b/blickbox/sara/lib/LibStubs/src/makros/ArdunioMakros.hpp new file mode 100644 index 0000000..202b0f5 --- /dev/null +++ b/blickbox/sara/lib/LibStubs/src/makros/ArdunioMakros.hpp @@ -0,0 +1,13 @@ +#ifndef ARDUINO_MAKROS_HPP +#define ARDUINO_MAKROS_HPP + +#define HIGH true +#define LOW false +#define PIN_ENABLE_SENSORS_3V3 0x33 +#define PIN_ENABLE_I2C_PULLUP 0x21 +#define INPUT 1 +#define OUTPUT 0 +#define LED_PWR 0x35 + + +#endif //ARDUINO_MAKROS_HPP \ No newline at end of file diff --git a/blickbox/sara/lib/LibStubs/src/makros/FMakro.hpp b/blickbox/sara/lib/LibStubs/src/makros/FMakro.hpp new file mode 100644 index 0000000..276c58b --- /dev/null +++ b/blickbox/sara/lib/LibStubs/src/makros/FMakro.hpp @@ -0,0 +1,6 @@ +#ifndef F_MAKROS_HPP +#define F_MAKROS_HPP + +#define F(str) + +#endif //F_MAKROS_HPP \ No newline at end of file diff --git a/blickbox/sara/lib/LibStubs/src/mock/DHT.hpp b/blickbox/sara/lib/LibStubs/src/mock/DHT.hpp new file mode 100644 index 0000000..0373331 --- /dev/null +++ b/blickbox/sara/lib/LibStubs/src/mock/DHT.hpp @@ -0,0 +1,66 @@ +#ifndef DHT_MOCK_HPP +#define DHT_MOCK_HPP + +#include +#include + +class DHT { +public: + DHT(uint8_t pin, uint8_t type, uint8_t count = 6) + : _pin(pin), _type(type), _lastresult(false), pullTime(55) { + std::cout << "DHT initialized with pin: " << (int)pin << ", type: " << (int)type << ", count: " << (int)count << std::endl; + } + + void begin(uint8_t usec = 55) { + std::cout << "DHT begin with usec: " << (int)usec << std::endl; + } + + float readTemperature(bool S = false, bool force = false) { + std::cout << "readTemperature called with S: " << S << ", force: " << force << std::endl; + return 25.0; // Dummy value + } + + float convertCtoF(float celsius) { + std::cout << "convertCtoF called with celsius: " << celsius << std::endl; + return celsius * 9.0 / 5.0 + 32.0; // Dummy conversion + } + + float convertFtoC(float fahrenheit) { + std::cout << "convertFtoC called with fahrenheit: " << fahrenheit << std::endl; + return (fahrenheit - 32.0) * 5.0 / 9.0; // Dummy conversion + } + + float computeHeatIndex(bool isFahrenheit = true) { + std::cout << "computeHeatIndex called with isFahrenheit: " << isFahrenheit << std::endl; + return isFahrenheit ? 77.0 : 25.0; // Dummy value + } + + float computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit = true) { + std::cout << "computeHeatIndex called with temperature: " << temperature << ", percentHumidity: " << percentHumidity << ", isFahrenheit: " << isFahrenheit << std::endl; + return isFahrenheit ? 77.0 : 25.0; // Dummy value + } + + float readHumidity(bool force = false) { + std::cout << "readHumidity called with force: " << force << std::endl; + return 50.0; // Dummy value + } + + bool read(bool force = false) { + std::cout << "read called with force: " << force << std::endl; + return true; // Dummy result + } + +private: + uint8_t data[5]; + uint8_t _pin, _type; + uint32_t _lastreadtime, _maxcycles; + bool _lastresult; + uint8_t pullTime; + + uint32_t expectPulse(bool level) { + std::cout << "expectPulse called with level: " << level << std::endl; + return 1000; // Dummy value + } +}; + +#endif // DHT_MOCK_HPP diff --git a/blickbox/sara/lib/LibStubs/src/mock/SerialLoggerMock.cpp b/blickbox/sara/lib/LibStubs/src/mock/SerialLoggerMock.cpp new file mode 100644 index 0000000..384827b --- /dev/null +++ b/blickbox/sara/lib/LibStubs/src/mock/SerialLoggerMock.cpp @@ -0,0 +1,132 @@ +#include +namespace serial_logger{ + + using namespace debugger; + + DebugLevels level = DebugLevels::DEBUG; + + /** + * @brief Logs a Message with a Debug level + * + * @param message + * @param level + */ + void log(String message, DebugLevels level){ + if(level > NONE){ + switch (level) + { + case DEBUG: + std::cout << state_to_string(DEBUG) << " : " << message << std::endl; + break; + case ERROR: + std::cout << state_to_string(ERROR) << " : " << message << std::endl; + break; + case WARNING: + std::cout << state_to_string(WARNING) << " : " << message << std::endl; + break; + case INFO: + std::cout << state_to_string(INFO) << " : " << message << std::endl; + break; + + default: + break; + } + } + } + + /** + * @brief Logs a Message with prefix + * + * @param prefix + * @param message + */ + void log(String prefix, String message){ + std::cout << prefix << " " << message << std::endl; + } + + /** + * @brief Logs a Message + * + * @param message + */ + void log(String message){ + std::cout << message << std::endl; + } + /** + * @brief Logs a Message + * + * @param message + */ + void log(uint16_t number){ + std::cout << number << std::endl; + } + + DebugLevels get_debug_level(){ + return level; + } + + void set_debug_level(DebugLevels level){ + level = level; + } + +} + + + +namespace debugger { + String state_to_string(DebugLevels state){ + switch (state) { + case NONE: + return "none"; + break; + case ERROR: + return "error"; + break; + case WARNING: + return "warning"; + break; + case INFO: + return "info"; + break; + case DEBUG: + return "debug"; + break; + } + return "UNKNOWN"; + } + +} + +namespace serial_communication{ + RequestPattern CurrentPattern = COMMAND; + String command = ""; + + String inputString = ""; // a String to hold incoming data + bool stringComplete = false; // whether the string is complete + + void handle_serial_message_recieved(){ + // if (Serial.available() > 0) { + // char inChar = (char)Serial.read(); + + // if (inChar == '\n' || inChar == '\r') { + + // stringComplete = true; + // CurrentPattern = COMMAND; + // return; + // } + + // inputString += inChar; + + // switch (CurrentPattern) + // { + // case COMMAND: + // command += inChar; + // if(inChar == ' '){ + // CurrentPattern = ARGUMENT; + // } + // break; + // } + // } + } + +} diff --git a/blickbox/sara/lib/LibStubs/src/mock/SerialLoggerMock.hpp b/blickbox/sara/lib/LibStubs/src/mock/SerialLoggerMock.hpp new file mode 100644 index 0000000..97a841e --- /dev/null +++ b/blickbox/sara/lib/LibStubs/src/mock/SerialLoggerMock.hpp @@ -0,0 +1,115 @@ + #ifndef SerialLogger_HPP + #define SerialLogger_HPP + + #include "stubs/ArduinoStubs.hpp" + #include "makros/FMakro.hpp" + #include "types/String.h" + #include + + namespace serial_communication{ + + /** + * Adds structure for switching between commands and arguments + */ + + enum RequestPattern{ + COMMAND, + ARGUMENT + }; + + /** + * @brief Hält das aktuelle Pattern während der Verarbeitung + * + */ + extern RequestPattern CurrentPattern; + + /** + * @brief Enthält das Kommando + * + */ + extern String command; + + /** + * @brief Hällt den empfangenen String + * + */ + extern String inputString; + + /** + * @brief Speichert ob der String fertig verarbeitet wurde + * + */ + extern bool stringComplete; // whether the string is complete + + /** + * @brief Verwaltet eingehende Bytes der Seriellen Schnittstelle + * sollte im Hauptprogramm ausgeführt werden + * + */ + void handle_serial_message_recieved(); + + + } + + namespace debugger{ + + /** + * @brief Definiert Debuglevel um ausgaben zu definieren + * + */ + enum DebugLevels{ + NONE, + ERROR, + WARNING, + INFO, + DEBUG, + }; + + /** + * @brief Wandelt ein Debuglevel in einen String um + * + * @param state + * @return String + */ + String state_to_string(DebugLevels state); + + } + + namespace serial_logger{ + using namespace debugger; + + /** + * @brief speichert das globale Loglevel + * + */ + extern DebugLevels level; + + /** + * @brief Setzt das globale debuglevel + * + * @param level + */ + void set_debug_level(DebugLevels level); + + /** + * @brief Gibt das globale debuglevel zurück + * + * @return DebugLevels + */ + DebugLevels get_debug_level(); + + /** + * @brief log die definierte message auf der Seriellen Konsole + * Mit dem Level definiert um welche Art von Nachricht es sich handelt. + * + * @param message + * @param level + */ + void log(String message, DebugLevels level); + + void log(String message); + void log(uint16_t message); + } + + #endif // SerialLogger_HPP + diff --git a/blickbox/sara/lib/LibStubs/src/stubs/ArduinoStubs.hpp b/blickbox/sara/lib/LibStubs/src/stubs/ArduinoStubs.hpp new file mode 100644 index 0000000..9f60033 --- /dev/null +++ b/blickbox/sara/lib/LibStubs/src/stubs/ArduinoStubs.hpp @@ -0,0 +1,36 @@ +// ArduinoStubs.hpp + + +#ifndef ARDUINO_STUBS_HPP +#define ARDUINO_STUBS_HPP + +#include + +// Stub für pinMode +inline void pinMode(uint8_t pin, uint8_t mode) { + // Keine Aktion +} + +// Stub für analogRead +inline int analogRead(uint8_t pin) { + return 0; // Dummy-Wert, kann angepasst werden +} + +inline void digitalWrite(uint8_t pin, bool status) { + +} + +// Stub für delay +inline void delay(uint32_t ms) { + // Keine Aktion +} + +inline uint32_t millis() { + return 1; +} + + + +// Weitere benötigte Arduino-Funktionen hier stubs bereitstellen + +#endif // ARDUINO_STUBS_HPP diff --git a/blickbox/sara/lib/LibStubs/src/stubs/BLE_Stubs.hpp b/blickbox/sara/lib/LibStubs/src/stubs/BLE_Stubs.hpp new file mode 100644 index 0000000..5af0bb5 --- /dev/null +++ b/blickbox/sara/lib/LibStubs/src/stubs/BLE_Stubs.hpp @@ -0,0 +1,69 @@ +// stubs/ArduinoBLEStubs.hpp + +#ifndef ARDUINOBLESTUBS_HPP +#define ARDUINOBLESTUBS_HPP + +#include +#include +#include +#include + +// Stub for BLECharacteristic +class BLECharacteristic { +public: + BLECharacteristic(const char* uuid, unsigned char properties, int size = 20, bool fixedLength = false) {} + void writeValue(uint16_t value) {} + void writeValue(const std::string& value) {} + std::string value() const { return ""; } +}; + +// Stub for BLEService +class BLEService { +public: + BLEService(const char* uuid) {} + bool begin() { return true; } + void addCharacteristic(BLECharacteristic& characteristic) {} +}; + +// Stub for BLEDevice +class BLEDevice { +public: + std::string address() const { return "00:00:00:00:00:00"; } +}; + +// BLE Event Types +enum BLEEvent { + BLEConnected, + BLEDisconnected +}; + +// Stubs for BLE functions +namespace BLE { + std::map> eventHandlers; + + bool begin() { return true; } + void setEventHandler(BLEEvent event, std::function handler) { + eventHandlers[event] = handler; + } + BLEDevice central() { return BLEDevice(); } + void advertise() {} + void stopAdvertise() {} + void setLocalName(const char* name) {} + void setAdvertisedService(BLEService& service) {} + void addService(BLEService& service) {} + + // Simulate BLE Events (for testing) + void simulateConnect() { + if (eventHandlers[BLEConnected]) { + eventHandlers[BLEConnected](BLEDevice()); + } + } + + void simulateDisconnect() { + if (eventHandlers[BLEDisconnected]) { + eventHandlers[BLEDisconnected](BLEDevice()); + } + } +} + +#endif // ARDUINOBLESTUBS_HPP diff --git a/blickbox/sara/lib/LibStubs/src/stubs/SerialStubs.hpp b/blickbox/sara/lib/LibStubs/src/stubs/SerialStubs.hpp new file mode 100644 index 0000000..3d05422 --- /dev/null +++ b/blickbox/sara/lib/LibStubs/src/stubs/SerialStubs.hpp @@ -0,0 +1,26 @@ +#ifndef SERIAL_STUBS_HPP +#define SERIAL_STUBS_HPP + +#ifdef unity_testing + + +// Stubs für die Methoden von Serial +namespace Serial { + void begin(unsigned long baudrate) { + // Stub-Implementierung für begin + } + + void print(const char* str) { + // Stub-Implementierung für print + } + + void println(const char* str) { + // Stub-Implementierung für println + } + + // Weitere Methoden können hier hinzugefügt werden, wenn nötig +} + + +#endif // SERIAL_STUBS_HPP +#endif \ No newline at end of file diff --git a/blickbox/sara/lib/LibStubs/src/types/Numbers.h b/blickbox/sara/lib/LibStubs/src/types/Numbers.h new file mode 100644 index 0000000..6e9776a --- /dev/null +++ b/blickbox/sara/lib/LibStubs/src/types/Numbers.h @@ -0,0 +1,8 @@ +#ifndef NUMBER_HPP +#define NUMBER_HPP + +// Typdefinitionen, falls stdint.h nicht verfügbar ist +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef float float16_t; +#endif // NUMBER_HPP \ No newline at end of file diff --git a/blickbox/sara/lib/LibStubs/src/types/String.h b/blickbox/sara/lib/LibStubs/src/types/String.h new file mode 100644 index 0000000..9f18a57 --- /dev/null +++ b/blickbox/sara/lib/LibStubs/src/types/String.h @@ -0,0 +1,8 @@ + +#ifndef STRING_HPP +#define STRING_HPP + +#include +typedef std::string String; + +#endif // STRING_HPP \ No newline at end of file diff --git a/blickbox/sara/platformio.ini b/blickbox/sara/platformio.ini index bebde74..c082e5a 100644 --- a/blickbox/sara/platformio.ini +++ b/blickbox/sara/platformio.ini @@ -27,16 +27,12 @@ selected_tests = * [env:native_selected_unittests] platform = native build_flags = - -D UNITY_INT_WIDTH=16 - -D UNITY_FLOAT_TYPE=float16_t -D unity_testing -std=c++11 ; Verwende den C++17 Standard - -DUNITY_INCLUDE_CONFIG_H - -DUNITY_SUPPORT_64 - -DUNITY_SUPPORT_DOUBLE -I include lib_deps = - SaraLIB + - LibStubs test_framework = ${options.test_framework} [env:ble] diff --git a/blickbox/sara/test/test_battery.cpp b/blickbox/sara/test/test_battery.cpp new file mode 100644 index 0000000..d930f48 --- /dev/null +++ b/blickbox/sara/test/test_battery.cpp @@ -0,0 +1,41 @@ +#include +#include + +using namespace sara_battery; + +#define BATTERY_PIN 6 +SaraBatteryManager battery_manager (BATTERY_PIN); + + +void setUp(void) { +} + +void tearDown(void) { +} + +void test_correct_ADC_units(){ + float units = ADC_REF_VOLTAGE / ADC_UNITS; + TEST_ASSERT_EQUAL_FLOAT(units, 0.003222656); +} + +void test_battery_calculate_voltage_from_ADC_Value() { + uint16_t raw_battery_value = 512; + float battery_voltage = calculate_battery_voltage(raw_battery_value); + TEST_ASSERT_EQUAL_FLOAT(battery_voltage, 3.3); +} + +void test_battery_map_voltage() { + uint8_t voltage = 3.69; + float battery_percent = map_to_battery_level(voltage); + TEST_ASSERT_EQUAL_INT8(battery_percent, 10); +} + +int main( int argc, char **argv) { + UNITY_BEGIN(); + + RUN_TEST(test_correct_ADC_units); + RUN_TEST(test_battery_calculate_voltage_from_ADC_Value); + RUN_TEST(test_battery_map_voltage); + UNITY_END(); +} + \ No newline at end of file diff --git a/blickbox/sara/test/test_main.cpp b/blickbox/sara/test/test_main.cpp deleted file mode 100644 index e7e8135..0000000 --- a/blickbox/sara/test/test_main.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include - - - -int main(int argc, char **argv) -{ - UNITY_BEGIN(); - - // RUN_TEST(test_loop); - - return UNITY_END(); -} \ No newline at end of file