From deb162d7b49948e72a47f0d0b54d3cf902e7518f Mon Sep 17 00:00:00 2001 From: philippd Date: Tue, 14 May 2024 22:04:15 +0200 Subject: [PATCH] Dateien nach "RIU" hochladen --- RIU/RIU.ino | 305 ++++++++++++++++++++++++++++++++++++++++++++++++ RIU/launch.json | 8 ++ 2 files changed, 313 insertions(+) create mode 100644 RIU/RIU.ino create mode 100644 RIU/launch.json diff --git a/RIU/RIU.ino b/RIU/RIU.ino new file mode 100644 index 0000000..57e6c35 --- /dev/null +++ b/RIU/RIU.ino @@ -0,0 +1,305 @@ +#include +#include +#include + +// BMP280 Sensor +Adafruit_BMP280 bmp; // use I2C interface +Adafruit_Sensor *bmp_temp = bmp.getTemperatureSensor(); +Adafruit_Sensor *bmp_pressure = bmp.getPressureSensor(); + +// Constants +const int MAX_REQUESTS = 100; +const int BUSY_THRESHOLD = 20; + +// Parameters +int pressureOffset = 0; +Adafruit_BMP280::sensor_sampling pressureSampling = Adafruit_BMP280::SAMPLING_X1; +int temperatureOffset = 0; +Adafruit_BMP280::sensor_sampling temperatureSampling = Adafruit_BMP280::SAMPLING_X1; + +// State Variables +int requestCount = 0; +bool startupReceived = false; +String lastSensorValue = ""; + +// Communication state for 4-step process +struct CommunicationState { + bool requestConfirmed = false; + bool confirmConfirmed = false; + bool checkConfirmed = false; +}; + +CommunicationState commState; + +// Function Prototypes +void handleCommand(String command); +void handleGetSensor(String command, String sensor); +void handleSetParameter(String param, String value); +void handleGetParameter(String param); +void resetSensors(); +String getRawSensorData(String sensor); +bool randomFailure(float chance); +String* splitString(String data, char separator, int* size); +Adafruit_BMP280::sensor_sampling getSamplingFromUserInput(String value); +String samplingToString(Adafruit_BMP280::sensor_sampling sampling); +String floatToBinary(float value); + +void setup() { + Serial.begin(115200); + while (!Serial) { + ; // Wait for serial port to connect. + } + + while (!startupReceived) { + if (Serial.available()) { + String command = Serial.readStringUntil('\n'); + if (command.startsWith("STARTUP")) { + startupReceived = true; + } + } + } + + unsigned status = bmp.begin(0x76); + if (!status) { + Serial.println(F("Could not find a valid BMP280 sensor, check wiring or try a different address!")); + while (1) delay(10); + } + + bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */ + temperatureSampling, /* Temp. oversampling */ + pressureSampling, /* Pressure oversampling */ + Adafruit_BMP280::FILTER_X16, /* Filtering. */ + Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */ + + Serial.println("READY - Tübingen Instruments RIU-9000"); +} + +void loop() { + if (Serial.available()) { + String command = Serial.readStringUntil('\n'); + delay(50); // Small delay to make communication more interesting + handleCommand(command); + } +} + +void handleCommand(String command) { + if (requestCount >= MAX_REQUESTS && !command.startsWith("RESET_SENSORS")) { + return; + } + + if (requestCount > 0 && requestCount % BUSY_THRESHOLD == 0) { + Serial.println("BUSY"); + requestCount++; + return; + } + + int size; + String* parts = splitString(command, ' ', &size); + + if (parts[0] == "GET_SENSOR" && size == 3) { + handleGetSensor(parts[1], parts[2]); + } else if (parts[0] == "SET_PARAMETER" && size == 3) { + handleSetParameter(parts[1], parts[2]); + } else if (parts[0] == "GET_PARAMETER" && size == 2) { + handleGetParameter(parts[1]); + } else if (parts[0] == "RESET_SENSORS" && size == 1) { + resetSensors(); + } else { + Serial.println("ERROR: UNKNOWN COMMAND"); + } + + delete[] parts; + requestCount++; +} + +void handleGetSensor(String command, String sensor) { + + if (command == "REQUEST") { // request data from the RUI (which will request it from the sensor) + if (!commState.requestConfirmed && randomFailure(0.1)) { + Serial.println("ERROR"); + return; + } + lastSensorValue = getRawSensorData(sensor); + Serial.println("OK"); + commState.requestConfirmed = true; + + } else if (command == "CONFIRM") { // did you request the data from the sensor? + if (!commState.confirmConfirmed && randomFailure(0.1)) { + Serial.println("FALSE"); + return; + } + if (commState.requestConfirmed) { + Serial.println("TRUE"); + commState.confirmConfirmed = true; + } else { + Serial.println("FALSE"); + } + } else if (command == "CHECK") { // did you get the data from the sensor? + if (!commState.checkConfirmed && randomFailure(0.5)) { + Serial.println("FALSE"); + } else { + if (commState.requestConfirmed) { + Serial.println("TRUE"); + commState.checkConfirmed = true; + } else { + Serial.println("FALSE"); + } + } + } else if (command == "SEND") { // send the data to the user + if (commState.requestConfirmed) { + Serial.println(lastSensorValue); + commState = CommunicationState(); // Reset communication state + } else { + Serial.println("FALSE"); + } + } else if (command == "CANCEL") { + commState = CommunicationState(); // Reset communication state + Serial.println("OK"); + } else { + Serial.println("ERROR: UNKNOWN COMMAND"); + } +} + +void handleSetParameter(String param, String value) { + if (param == "PRESSURE_OFFSET") { + pressureOffset = value.toInt(); + Serial.println("OK"); + } else if (param == "PRESSURE_SAMPLING") { + pressureSampling = getSamplingFromUserInput(value); + bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */ + temperatureSampling, /* Temp. oversampling */ + pressureSampling, /* Pressure oversampling */ + Adafruit_BMP280::FILTER_X16, /* Filtering. */ + Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */ + Serial.println("OK"); + } else if (param == "TEMPERATURE_OFFSET") { + temperatureOffset = value.toInt(); + Serial.println("OK"); + } else if (param == "TEMPERATURE_SAMPLING") { + temperatureSampling = getSamplingFromUserInput(value); + bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */ + temperatureSampling, /* Temp. oversampling */ + pressureSampling, /* Pressure oversampling */ + Adafruit_BMP280::FILTER_X16, /* Filtering. */ + Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */ + Serial.println("OK"); + } else { + Serial.println("ERROR: UNKNOWN PARAMETER"); + } +} + +void handleGetParameter(String param) { + if (param == "PRESSURE_OFFSET") { + Serial.println(pressureOffset); + } else if (param == "PRESSURE_SAMPLING") { + Serial.println(samplingToString(pressureSampling)); + } else if (param == "TEMPERATURE_OFFSET") { + Serial.println(temperatureOffset); + } else if (param == "TEMPERATURE_SAMPLING") { + Serial.println(samplingToString(temperatureSampling)); + } else { + Serial.println("ERROR: UNKNOWN PARAMETER"); + } +} + +void resetSensors() { + requestCount = 0; + commState = CommunicationState(); // Reset communication state + Serial.println("OK"); +} + +String getRawSensorData(String sensor) { + sensors_event_t temp_event, pressure_event; + + if (sensor == "PRESSURE") { + bmp_pressure->getEvent(&pressure_event); + float pressure = pressure_event.pressure + pressureOffset; + return floatToBinary(pressure); // in hPa + } else if (sensor == "TEMPERATURE") { + bmp_temp->getEvent(&temp_event); + float temperature = temp_event.temperature + temperatureOffset; + return floatToBinary(temperature); // in °C + } + + return ""; +} + +bool randomFailure(float chance) { + return random(0, 100) < (chance * 100); +} + +String* splitString(String data, char separator, int* size) { + int found = 0; + int strIndex[] = {0, -1}; + int maxIndex = data.length() - 1; + int count = 1; + + for (int i = 0; i <= maxIndex; i++) { + if (data.charAt(i) == separator) { + count++; + } + } + + String* result = new String[count]; + *size = count; + + found = 0; + for (int i = 0; i <= maxIndex && found < count; i++) { + if (data.charAt(i) == separator || i == maxIndex) { + strIndex[0] = strIndex[1] + 1; + strIndex[1] = (i == maxIndex) ? i + 1 : i; + result[found] = data.substring(strIndex[0], strIndex[1]); + found++; + } + } + + return result; +} + +Adafruit_BMP280::sensor_sampling getSamplingFromUserInput(String value) { + if (value == "SAMPLING_NONE") return Adafruit_BMP280::SAMPLING_NONE; + if (value == "SAMPLING_X1") return Adafruit_BMP280::SAMPLING_X1; + if (value == "SAMPLING_X2") return Adafruit_BMP280::SAMPLING_X2; + if (value == "SAMPLING_X4") return Adafruit_BMP280::SAMPLING_X4; + if (value == "SAMPLING_X8") return Adafruit_BMP280::SAMPLING_X8; + if (value == "SAMPLING_X16") return Adafruit_BMP280::SAMPLING_X16; + return Adafruit_BMP280::SAMPLING_NONE; +} + +String samplingToString(Adafruit_BMP280::sensor_sampling sampling) { + switch (sampling) { + case Adafruit_BMP280::SAMPLING_NONE: + return "SAMPLING_NONE"; + case Adafruit_BMP280::SAMPLING_X1: + return "SAMPLING_X1"; + case Adafruit_BMP280::SAMPLING_X2: + return "SAMPLING_X2"; + case Adafruit_BMP280::SAMPLING_X4: + return "SAMPLING_X4"; + case Adafruit_BMP280::SAMPLING_X8: + return "SAMPLING_X8"; + case Adafruit_BMP280::SAMPLING_X16: + return "SAMPLING_X16"; + default: + return "UNKNOWN_SAMPLING"; + } +} + +String floatToBinary(float value) { + union FloatUnion { + float value; + byte bytes[4]; + }; + + FloatUnion floatUnion; + floatUnion.value = value; + + String binaryString = ""; + for (int i = 3; i >= 0; i--) { + for (int j = 7; j >= 0; j--) { + binaryString += String((floatUnion.bytes[i] >> j) & 1); + } + } + + return binaryString; +} diff --git a/RIU/launch.json b/RIU/launch.json new file mode 100644 index 0000000..7e4253b --- /dev/null +++ b/RIU/launch.json @@ -0,0 +1,8 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + "version": "0.2.0", + "configurations": [ + + ] +}