Created
April 28, 2019 17:21
-
-
Save abrhm/f424b36db9e8d5d43831483b998efecc to your computer and use it in GitHub Desktop.
Arduino solar panel controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <OneWire.h> | |
#include <DallasTemperature.h> | |
struct TempSensor { | |
OneWire wire; | |
DallasTemperature sensor; | |
DeviceAddress address; | |
TempSensor(const uint8_t pin) | |
: wire(pin) { | |
sensor = DallasTemperature(&wire); | |
} | |
void init() { | |
sensor.begin(); | |
sensor.getAddress(address, 0); | |
} | |
float getTemp() { | |
sensor.requestTemperatures(); | |
return sensor.getTempC(address); | |
} | |
}; | |
struct Thresholds { | |
const float minimum = 0; | |
const float maximum = 100; | |
const float delta = 0; | |
Thresholds(const float minimum, const float maximum, const float delta) | |
: minimum(minimum) | |
, maximum(maximum) | |
, delta(delta) | |
{} | |
}; | |
/********** PARAMETERS **********/ | |
// Delay after each cycle | |
const int delayMs = 5000; | |
// Sensors with the pin | |
TempSensor solarSensor(5); | |
TempSensor furnaceSensor(6); | |
TempSensor innerSensor(4); | |
TempSensor bufferMinSensor(2); | |
TempSensor bufferMaxSensor(3); | |
// Relay pins | |
const int solarPumpPin = 9; | |
const int furnacePumpPin = 10; | |
const int innerPumpPin = 11; | |
// Thresholds | |
// (min, max, delta) | |
Thresholds solarThresholds(40, 85, 5); | |
Thresholds furnaceThresholds(50, 85, 0); | |
// Delta to start innerPump | |
const float innerDelta = 2.5; | |
/********** LOGIC **********/ | |
void setup() { | |
Serial.begin(9600); | |
Serial.println("Setup"); | |
pinMode(LED_BUILTIN, OUTPUT); | |
// HIGH is the off state | |
pinMode(solarPumpPin, OUTPUT); | |
digitalWrite(solarPumpPin, HIGH); | |
pinMode(furnacePumpPin, OUTPUT); | |
digitalWrite(furnacePumpPin, HIGH); | |
pinMode(innerPumpPin, OUTPUT); | |
digitalWrite(innerPumpPin, HIGH); | |
// Init the sensors | |
solarSensor.init(); | |
furnaceSensor.init(); | |
innerSensor.init(); | |
bufferMinSensor.init(); | |
bufferMaxSensor.init(); | |
Serial.println("Setup done"); | |
} | |
void loop() { | |
float bufferMinTemp = bufferMinSensor.getTemp(); | |
float bufferMaxTemp = bufferMaxSensor.getTemp(); | |
Serial.print("Buffer min: "); | |
Serial.println(bufferMinTemp); | |
Serial.print("Buffer max: "); | |
Serial.println(bufferMaxTemp); | |
controlSolarCircle(bufferMinTemp); | |
Serial.println("##########"); | |
controlFurnaceCircle(bufferMinTemp); | |
Serial.println("##########"); | |
controlInnerCircle(bufferMaxTemp); | |
Serial.println("##########"); | |
// Toggle the board LED to show the progress | |
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); | |
delay(delayMs); | |
} | |
// Helper function | |
bool canHeatWithThreshold(const float circleTemp, const float referenceTemp, const Thresholds& thresholds) { | |
if (circleTemp < thresholds.minimum) { | |
Serial.println("Temp is below minimum"); | |
return false; | |
} | |
if (circleTemp > thresholds.maximum) { | |
Serial.println("Temp is above maximum"); | |
return true; | |
} | |
return (circleTemp - referenceTemp - thresholds.delta) > 0; | |
} | |
/********** CIRCLE CONTROLS **********/ | |
void controlSolarCircle(const float bufferMinTemp) { | |
const float solarTemp = solarSensor.getTemp(); | |
Serial.print("Solar temp: "); | |
Serial.println(solarTemp); | |
const bool canHeat = canHeatWithThreshold(solarTemp, bufferMinTemp, solarThresholds); | |
Serial.print("Set solar pump to "); | |
Serial.println(canHeat); | |
// Negate because reverse logic | |
digitalWrite(solarPumpPin, !canHeat); | |
} | |
void controlFurnaceCircle(const float bufferMinTemp) { | |
const float furnaceTemp = furnaceSensor.getTemp(); | |
Serial.print("Furnace temp: "); | |
Serial.println(furnaceTemp); | |
const bool canHeat = canHeatWithThreshold(furnaceTemp, bufferMinTemp, furnaceThresholds); | |
Serial.print("Set furnace pump to "); | |
Serial.println(canHeat); | |
// Negate because reverse logic | |
digitalWrite(solarPumpPin, !canHeat); | |
} | |
void controlInnerCircle(const float bufferMaxTemp) { | |
const float innerTemp = innerSensor.getTemp(); | |
Serial.print("Inner temp: "); | |
Serial.println(innerTemp); | |
const bool canHeat = (bufferMaxTemp - innerTemp - innerDelta) > 0; | |
Serial.print("Set inner pump to "); | |
Serial.println(canHeat); | |
// Negate because reverse logic | |
digitalWrite(innerPumpPin, !canHeat); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment