Skip to content

Commit

Permalink
add case temperature controller
Browse files Browse the repository at this point in the history
case temperature controller: add library for DS18B20 temperature sensor as submodule

case temperature controller: add OneWire library for DS18B20 temperature sensor as submodule, turn temperature source code into own class

case temperature controller: add some more information to README

case temperature controller: turn fan code into own class

case temperature controller: remove loop from code

case temperature controller: turn printf into actual log

case temperature controller: remove unused libraries

case temperature controller: remove simulation (not needed anymore, temperature sensor works)

case temperature controller: cleanup

case temperature controller: add monitoring target to README

case temperature controller: add counter to controller so it doesn't execute on every loop through

case temperature controller: turn setSpeed into void function since it cannot return errors

case temperature controller: fix fan bug

case temperature controller: add circuit plan to README

case temperature controller: add recursive checkout of submodules to CICD

case temperature controller: assign correct pins for temperature sensor and fan

case temperature controller: renamend caseTemperatureController() to readTemperatureAndAdjustFanSpeed(), reformat caseTempController.cpp

case temperature controller: reformat temperature.cpp, fan.cpp

case temperature controller: include OneWire and Arduino-Temperature-Control-Library via pio package manager instead of submodules
  • Loading branch information
Anna Wagner committed Dec 1, 2020
1 parent ca67b71 commit 23bc0d1
Show file tree
Hide file tree
Showing 14 changed files with 301 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ jobs:
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
with:
submodules: 'recursive'
# Install python 3.x
- uses: actions/setup-python@v2
with:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- uses: actions/setup-python@v2
with:
python-version: '3.9.0'
Expand Down
30 changes: 29 additions & 1 deletion firmware/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,29 @@
Firmware
## Instructions for Linux

- Install platformio.

- Install (udev rules)[https://docs.platformio.org/en/latest/faq.html#platformio-udev-rules].

- Add yourself to the dialout and tty group:

```sh
sudo usermod -a -G tty $USER
sudo usermod -a -G dialout $USER
sudo usermod -a -G plugdev $USER
```

Disconnect your board, then log out and log in again for the changes to take place.

Check if your ESP32 is connected:

```sh
ll /dev | grep ttyUSB*
```

You should then be able to flash the code onto your board by running

```sh
platformio run --target upload --target monitor
```

Afterwards, an access point should spawn (namend ```CleanAirDevice```). The password is ```12345678```. Afterwards, the configuration page should be reachable under e.g. ```http://172.217.28.1/_ac``` (you need to fill in the correct IP address, of course).
40 changes: 40 additions & 0 deletions firmware/include/caseTempController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//*****************************************//
// includes //
//*****************************************//
#include "caseTempController/config.h"
#include "caseTempController/temperature.h"
#include "caseTempController/fan.h"

//*****************************************//
// class //
//*****************************************//
class CaseTempController
{
private:

// a history of the last TAU temperature errors
int temperature_errors[TAU];

// marks the place of the oldest info in the temperature_errors array
int* p_oldest_temperature_error;

// temperature sensor
TempSensor tempSensor;

// fan
Fan fan;

// counter used to check if controller should start measuring/calculating
int sleep_check;

public:

CaseTempController()
{
this->sleep_check = 0;
}

int init(void);

int readTemperatureAndAdjustFanSpeed(void);
};
12 changes: 12 additions & 0 deletions firmware/include/caseTempController/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//*****************************************//
// configuration //
//*****************************************//
#define K_P 1 // proportional factor of the PID controller
#define K_I 0.1 // integral factor of the PID controller
#define K_D 0.5 // derivative factor of the PID controller
#define TAU 20 // number of measurements viewed in calculation, reduce to save space and calculation times
#define GOAL_TEMP 30 // goal temperature of 30°C
#define TEMP_GPIO 26 // the GPIO data pin of the temperature sensor
#define FAN_GPIO 23 // the PWM pin for fan control
#define FAN_PWM_CHANNEL 0 // the PWM channel for fan control
#define SLEEP 30000 // defines how many loop-throughs the controller will wait until measuring again
20 changes: 20 additions & 0 deletions firmware/include/caseTempController/fan.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//*****************************************//
// includes //
//*****************************************//
#include "Arduino.h"
#include "config.h"


//*****************************************//
// class //
//*****************************************//
class Fan
{
public:

Fan() {}

void init(void);

void setSpeed(int fan_speed);
};
30 changes: 30 additions & 0 deletions firmware/include/caseTempController/temperature.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//*****************************************//
// includes //
//*****************************************//
#include <DS18B20.h>
#include "config.h"


//*****************************************//
// class //
//*****************************************//
class TempSensor
{
private:

OneWire* oneWire;

DS18B20* sensors;

public:

TempSensor()
{
oneWire = new OneWire(TEMP_GPIO);
sensors = new DS18B20(oneWire);
}

void init(void);

int read(void);
};
2 changes: 2 additions & 0 deletions firmware/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ lib_deps =
hieromon/AutoConnect@^1.1.7
mathertel/RotaryEncoder@^1.3.0
lorol/LittleFS_esp32@1.0.0
paulstoffregen/OneWire@^2.3.5
robtillaart/DS18B20@^0.1.6
monitor_speed = 115200
monitor_filters = esp32_exception_decoder
build_flags =
Expand Down
11 changes: 11 additions & 0 deletions firmware/src/caseTempController/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Case Temperature Controller

Sub-program for regulating a PWM controlled fan to keep a steady temperature within the case.

Written for ESP32, Xinda Temperature Sensor, Noctua NF-A4x20 in C.

This program is basically implementing a PID controller. To understand the underlying calculation, check the following wikipedia article: https://en.wikipedia.org/wiki/PID_controller#Alternative_nomenclature_and_forms

# Circuit Diagram

![](circuit.png)
92 changes: 92 additions & 0 deletions firmware/src/caseTempController/caseTempController.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//*****************************************//
// includes //
//*****************************************//
#include <stdbool.h>
#include "caseTempController.h"

//*****************************************//
// functions //
//*****************************************//
int CaseTempController::init(void)
{
// variables
int i; // loop counter
int temperature; // current actual temperature
int temperature_error; // the current difference between wished temperature and actual temperature

ESP_LOGD(TAG, "Configuration:");
ESP_LOGD(TAG, " Proportional factor: %i", K_P);
ESP_LOGD(TAG, " Integral factor: %f", K_I);
ESP_LOGD(TAG, " Differential factor: %f", K_D);
ESP_LOGD(TAG, " Viewed number of measurements: %i", TAU);
ESP_LOGD(TAG, " Goal temperature: %i°C", GOAL_TEMP);
ESP_LOGD(TAG, "Initialize hardware.");
fan.init();
tempSensor.init();

ESP_LOGD(TAG, "Fill the temperature_errors array with inital values.");
for (i = 0; i < TAU; i++)
{
temperature = tempSensor.read();
temperature_errors[i] = ((temperature_error = temperature - GOAL_TEMP) > 0 ? temperature_error : 0);
}
p_oldest_temperature_error = &temperature_errors[0];

return 0;
}


int CaseTempController::readTemperatureAndAdjustFanSpeed(void)
{
if (sleep_check % SLEEP == 0)
{
// variables
int i; // loop counter
int temperature; // current actual temperature
int temperature_error; // the current difference between wished temperature and actual temperature
int temperature_error_sum; // the sum of the last TAU temperature errors
int pr, in, di; // proportional, integral, and differential adjustment
int fan_speed; // the fan speed that shall be set

// read in newest temperature error, put it in place of the oldest value
temperature = tempSensor.read();
*p_oldest_temperature_error = temperature_error = (temperature_error = temperature - GOAL_TEMP) > 0 ? temperature_error : 0;
ESP_LOGD(TAG, "Newest temperature error: %i°C", temperature_error);


// set p_oldest_temperature_error to next place in array
if (p_oldest_temperature_error == &temperature_errors[TAU - 1])
p_oldest_temperature_error = &temperature_errors[0];
else
p_oldest_temperature_error++;


// calculate proportional adjustment
pr = K_P * temperature_error;
ESP_LOGD(TAG, "Proportional adjustment: %i", pr);


// calculate integral adjustment
temperature_error_sum = 0;
for (i = 0; i < TAU; i++)
temperature_error_sum += temperature_errors[i];
in = K_I * temperature_error_sum;
ESP_LOGD(TAG, "Integral adjustment: %i", in);


// calculate differential adjustment
di = K_D * (temperature_error - *p_oldest_temperature_error);
ESP_LOGD(TAG, "Differential adjustment: %i", di);


// calculate and set new fan speed
fan_speed = pr + in + di;
if (fan_speed < 0) fan_speed = 0;
if (fan_speed > 100) fan_speed = 100;
ESP_LOGD(TAG, "Resulting fan speed: %i%%", fan_speed);
fan.setSpeed(fan_speed);
}

sleep_check++;
return 0;
}
Binary file added firmware/src/caseTempController/circuit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions firmware/src/caseTempController/fan.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//*****************************************//
// includes //
//*****************************************//
#include "caseTempController/fan.h"


//*****************************************//
// defines //
//*****************************************//
#define FREQUENCY 25000 // the PWM frequency (fan runs best at 25kHz)
#define RESOLUTION 8 // the duty cycle resolution in bits (8 means 255 steps)

//*****************************************//
// functions //
//*****************************************//

void Fan::init(void)
{
ledcSetup(0, FREQUENCY, RESOLUTION);
ledcAttachPin(FAN_GPIO, FAN_PWM_CHANNEL);
setSpeed(0);
return;
}


void Fan::setSpeed(int fan_speed)
{
ledcWrite(FAN_PWM_CHANNEL, (int)(fan_speed * (255 / 100)));
}
23 changes: 23 additions & 0 deletions firmware/src/caseTempController/temperature.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//*****************************************//
// includes //
//*****************************************//
#include "caseTempController/temperature.h"

//*****************************************//
// functions //
//*****************************************//
void TempSensor::init(void)
{
(*sensors).begin();
return;
}


int TempSensor::read(void)
{
int temperature = 0;
(*sensors).requestTemperatures();
temperature = (*sensors).getTempC();
ESP_LOGD(TAG, "Newest temperature: %i°C", temperature);
return temperature;
}
9 changes: 9 additions & 0 deletions firmware/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "rotary.h"
#include "operationHourCounter.h"
#include "updateService.h"
#include "caseTempController.h"

void setFanSpeed(int speed);

Expand All @@ -40,6 +41,9 @@ OperationHourCounter operationHourCounter;
// Define the fans controller.
FanController fanController;

// Define case temperature controller.
CaseTempController caseTempController;

// Define the adpter to handle hardware related io things.
Rotary rotary;

Expand Down Expand Up @@ -196,6 +200,8 @@ void setup()
rotary.setup(jsonHandler, setFanSpeed);
updateService.setup(jsonHandler);

caseTempController.init();

configureNetwork();

ESP_LOGI(TAG, "Setup complete %s", TAG);
Expand All @@ -222,4 +228,7 @@ void loop()

// handlet the current rotary position
rotary.handle();

// regulate case temperature
caseTempController.readTemperatureAndAdjustFanSpeed();
} // loop

0 comments on commit 23bc0d1

Please sign in to comment.