Sketch Version 0.9

#include <string>

// ###### BEGIN OF CONFIGURATION SECTION ######

// Release 0.9

// This parameters can be adapted to your own needs.

// Some relais are switching on at HIGH and some at LOW.

// If your relais switches on at HIGH set the following configuration parameter to true.

static boolean const HEATING_RELAIS_SWITCHES_ON_AT_HIGH = false;

// Define the possible target temperatures ..

static int const TARGET_TEMPERATURE_HEATING_OFF = -999;

static int const TARGET_TEMPERATURE_HEATING_FROST = 10;

static int const TARGET_TEMPERATURE_HEATING_NIGHT = 15;

static int const TARGET_TEMPERATURE_HEATING_WARM = 21;

// Arduino will switch off the heating relay if current temperature is more than

// MAX_DEGREES_ABOVE_TARGET_TEMPERATURE higher than target temperature.

// Example: if target temperature is 21° and MAX_DEGREES_ABOVE_TARGET_TEMPERATURE is 3°

//          then arduino will switch off heating relay at a current temperature of 24°.

// This value should not be defined too low because it prevents that Truma is switched on/off in short cycles.

static int const MAX_DEGREES_ABOVE_TARGET_TEMPERATURE = 3;

// Heating status and current temperature is automatically sent from Arduino to App.

// TIME_BETWEEN_STATUS_MESSAGES_IN_MILLIS defines the time between status messages.

// Note: each status message is forwarded to chat user by smart Camper App.

//       So, if this time is reduced then smart Camper App communicates more frequently with chat user.

//       This also increases the consumed data volume on the mobile network.

static unsigned long const TIME_BETWEEN_STATUS_MESSAGES_IN_MILLIS = 300000; // Corresponds to 5 minutes.

// Time between reading the temperature sensor input

static unsigned long const TIME_BETWEEN_READING_TEMPERATURE_IN_MILLIS = 20;

// ###### END OF CONFIGURATION SECTION ######

// Heating Status that is sent back to App.

// Unfortunately the App sometimes receives incomplete data from Arduino via bluetooth connection.

// So, status is transferred with 5 digits – App then receives at least 2 of them.

static String const HEATING_STATUS_OFF = „11111“;

static String const HEATING_STATUS_FROST = „22222“;

static String const HEATING_STATUS_NIGHT = „33333“;

static String const HEATING_STATUS_WARM = „44444“;

// Pin usage

static int const HEATING_RELAY_PIN = 7;

static int const TEMPERATURE_SENSOR_PIN = A0;

// Global variables for temperature detection …

static int targetTemperature = TARGET_TEMPERATURE_HEATING_OFF;

static int currentTemperature = 999;

// Global variables for clock / timer functions …

static unsigned long currentMillis;

static int currentHour = 0;

static int currentMinute = 0;

static int currentDay = 0;

// This function is called right after arduino was powered on …

void setup() {

pinMode(HEATING_RELAY_PIN, OUTPUT);

if (HEATING_RELAIS_SWITCHES_ON_AT_HIGH) {

digitalWrite(HEATING_RELAY_PIN, LOW);

}

else {

digitalWrite(HEATING_RELAY_PIN, HIGH);

}

Serial.begin(9600);

}

// This is the main loop – it runs until arduino is powered off.

// IMPORTANT: do not add coding that blocks execution (e.g. sleep).

//            Otherwise smart Camper won’t work properly anymore.

void loop() {

 

// Clock simulation …

tickTock();

 

// Determine the current temperature …

detectCurrentTemperature();

 

// Check whether Truma has to be switched on or off …

checkTemperatureAndSwitchHeating();

 

// Receive commands from App via bluetooth or USB terminal and execute this command …

getAndExecuteCommandFromApp();

 

// Send status update to App on a regular base …

sendStatusUpdateToApp();

 

}

void checkTemperatureAndSwitchHeating() {

 

// Switch heating on if current temperature is below target temperature …

if (currentTemperature < targetTemperature) {

// Switch heating on …

if (HEATING_RELAIS_SWITCHES_ON_AT_HIGH) {

digitalWrite(HEATING_RELAY_PIN, HIGH);

} else {

digitalWrite(HEATING_RELAY_PIN, LOW);

}

}

 

// Switch heating off if current temperature is high enough …

if ((currentTemperature – targetTemperature) >= MAX_DEGREES_ABOVE_TARGET_TEMPERATURE) {

// Switch heating off …

if (HEATING_RELAIS_SWITCHES_ON_AT_HIGH) {

digitalWrite(HEATING_RELAY_PIN, LOW);

} else {

digitalWrite(HEATING_RELAY_PIN, HIGH);

}

}

 

}

void sendStatusUpdateToApp() {

static unsigned long previousMillisForStatusUpdateToApp = 0;

static boolean firstCall = true; // send status to App right after Arduino was powered on

 

// Current status is sent back to the app regularly …

if( firstCall || (abs(currentMillis – previousMillisForStatusUpdateToApp) > TIME_BETWEEN_STATUS_MESSAGES_IN_MILLIS)) {

// serialPrintStatus();

firstCall = false;

previousMillisForStatusUpdateToApp = currentMillis;

}

}

// Arduino does not have a hardware clock or timer included.

// But Arduino is able to count the milliseconds since it was started.

// Based on this we simulate a clock.

// Note: the current time can be set via command over bluetooth.

//       But this is currently not supported by smart Camper App.

void tickTock() {

static long previousMillis = 0;

static long const interval = 60000;

 

currentMillis = millis();

 

if(abs(currentMillis – previousMillis) > interval) {

previousMillis = currentMillis;

currentMinute++;

if (currentMinute > 59) {

currentMinute = 0;

if (++currentHour > 23) {

currentHour = 0;

if (++currentDay > 6) {

currentDay = 0;

}

}

}

}

}

void getAndExecuteCommandFromApp() {

String serialInput = „“;

String command;

String subCommand;

String timeToSet;

 

if (Serial.available() > 0) {

serialInput = Serial.readStringUntil(‚\n‘);

command = getValue(serialInput, ‚ ‚, 0);

 

// Return status …

if(strcmp(command.c_str(), „s“) == 0) {

serialPrintStatus();

}

 

// Heating commands:

// h off => heating relay is never switched on by Arduino

// h frost => frost protection

// h night => temperature for night

// h warm => warm temperature

if(strcmp(command.c_str(), „h“) == 0) {

subCommand = getValue(serialInput, ‚ ‚, 1);

if(strcmp(subCommand.c_str(), „off“) == 0) {

targetTemperature = TARGET_TEMPERATURE_HEATING_OFF;

}

if(strcmp(subCommand.c_str(), „frost“) == 0) {

targetTemperature = TARGET_TEMPERATURE_HEATING_FROST;

}

if(strcmp(subCommand.c_str(), „night“) == 0) {

targetTemperature = TARGET_TEMPERATURE_HEATING_NIGHT;

}

if(strcmp(subCommand.c_str(), „warm“) == 0) {

targetTemperature = TARGET_TEMPERATURE_HEATING_WARM;

}

}

 

// Set the clock

// c s 10:00 0 => sets clock to 10:00 and day to monday (0)

// this clock is currently not used by smartCamper App

// but will be useful for upcoming functions

if(strcmp(command.c_str(), „c“) == 0) {

// Serial.println(„Uhr Kommando empfangen“);

subCommand = getValue(serialInput, ‚ ‚, 1);

if(strcmp(subCommand.c_str(), „s“) == 0) {

// Serial.println(„Uhr setzen Kommando empfangen“);

timeToSet = getValue(serialInput, ‚ ‚, 2);

// Serial.println(timeToSet);

String hour = getValue(timeToSet, ‚:‘, 0);

String minute = getValue(timeToSet, ‚:‘, 1);

currentHour = hour.toInt();

currentMinute = minute.toInt();

currentDay = getValue(serialInput, ‚ ‚, 3).toInt();

}

 

// send current time to App or terminal

// c g => shows current time

if(strcmp(subCommand.c_str(), „g“) == 0) {

serialPrintCurrentTime();

}

}

}

}

// this function determines the current temperature

// Values that are provided by temperature sensor are a little bit flaky

// so, it is necessary to take 10 values that are read with 20 ms in between

// and then calculate the average of those 10 values

void detectCurrentTemperature() {

static int temperature = 0;

static int temp[10];

static int temperaturePoint = 1;

static int previousTemperature = 1111;

static unsigned long previousMillisForTemperturePoint = 0;

 

if(abs(currentMillis – previousMillisForTemperturePoint) > TIME_BETWEEN_READING_TEMPERATURE_IN_MILLIS) {

temp[temperaturePoint] = map(analogRead(TEMPERATURE_SENSOR_PIN), 0, 410, -50, 150);

if (temperaturePoint == 10) {

temperature=(temp[1]+temp[2]+temp[3]+temp[4]+temp[5]+temp[6]+temp[7]+temp[8]+temp[9]+temp[10])/10;

if (temperature != currentTemperature) {

previousTemperature = currentTemperature;

currentTemperature = temperature;

}

}

if (++temperaturePoint > 10) {

temperaturePoint = 1;

}

previousMillisForTemperturePoint = currentMillis;

}

}

// sends the current heating status and temperature to serial device / bluetooth …

void serialPrintStatus() {

String hStatus = „“;

switch(targetTemperature)

{

case TARGET_TEMPERATURE_HEATING_OFF:

hStatus = HEATING_STATUS_OFF;

break;

case TARGET_TEMPERATURE_HEATING_FROST:

hStatus = HEATING_STATUS_FROST;

break;

case TARGET_TEMPERATURE_HEATING_NIGHT:

hStatus = HEATING_STATUS_NIGHT;

break;

case TARGET_TEMPERATURE_HEATING_WARM:

hStatus = HEATING_STATUS_WARM;

break;

}

Serial.println(„s“ + hStatus + “ t“ + String(currentTemperature));

}

void serialPrintCurrentTime() {

Serial.print(„Uhrzeit: „);

Serial.print(currentHour);

Serial.print(„:“);

if (currentMinute < 10) {

Serial.print(„0″);

}

Serial.print(currentMinute);

Serial.print(“ „);

Serial.println(currentDay);

}

// String helper for serial read …

String getValue(String data, char separator, int index)

{

int found = 0;

int strIndex[] = {

0, -1                      };

int maxIndex = data.length()-1;

 

for(int i=0; i<=maxIndex && found<=index; i++){

if(data.charAt(i)==separator || i==maxIndex){

found++;

strIndex[0] = strIndex[1]+1;

strIndex[1] = (i == maxIndex) ? i+1 : i;

}

}

 

return found>index ? data.substring(strIndex[0], strIndex[1]) : „“;

}

One thought to “Sketch Version 0.9”

Schreibe einen Kommentar