FanLedCtrl/src/main.cpp
2024-12-07 11:42:04 +01:00

234 lines
5.7 KiB
C++

/**
* @file main.cpp
* @author Ollo
* @brief
* @version 0.5
* @date 2024-11-28
*
* @copyright Copyright (c) 2024
*
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <Adafruit_NeoPixel.h>
#include "ColorUtil.h"
#include "controller.h"
#include "SerialCmd.h"
/******************************************************************************
* MACROS
******************************************************************************/
/******************************************************************************
* DEFINES
******************************************************************************/
#define DELAY_TIME 1000 /**< time between measurements [ms] */
#define MIN_FAN_SPEED_PERCENT 24 /**< minimum fan speed [%] */
#define MIN_TEMP 25 /**< turn fan off below [deg C] */
#define MAX_TEMP 40 /**< turn fan to full speed above [deg C] */
#define INVALID_TEMP (MAX_TEMP+MAX_TEMP) /**< Invalid temperature (on sensor failures)*/
#define TEMP_SENSOR_MEASURE_SERIES 5 /**< Maximum resets */
#define FAN_RPM_READLEVEL 100
#define RPM_CONTROL_DEACTIVATED -1
/******************* Settings for command mode ***************/
#define COMMAND_BRIGHTNESS 200
/******************************************************************************
* LOCAL VARIABLES
******************************************************************************/
Adafruit_NeoPixel* pixels;
Adafruit_NeoPixel* singleLed;
OneWire oneWire(GPIO_DS18B20);
DallasTemperature sensors(&oneWire);
static int mAutomaticTargetRPM = RPM_CONTROL_DEACTIVATED;
/******************************************************************************
* LOCAL FUNCTIONS
******************************************************************************/
/**
* @brief Get the Fan Speed in round per minutes
*
* @return int
*/
int getFanSpeedRpm() {
int highTime = pulseIn(SIGNAL_PIN, HIGH);
int lowTime = pulseIn(SIGNAL_PIN, LOW);
int period = highTime + lowTime;
if (period == 0) {
return 0;
}
float freq = 1000000.0 / (float)period;
return (freq * 60.0) / 2.0; // two cycles per revolution
}
/**
* @brief Set the Fan Speed
*
* @param p expected percentage
*/
void setFanSpeedPercent(int p) {
int value = (p / 100.0) * 255;
analogWrite(FAN_PIN, value);
}
float readTemperature(void)
{
int sensorCount = sensors.getDeviceCount();
if (sensorCount > 0)
{
sensors.requestTemperatures();
float temp1Raw = sensors.getTempCByIndex(0);
if (temp1Raw > 0)
{
return temp1Raw;
}
}
return INVALID_TEMP;
}
/******************************************************************************
* STANDARD ARDUINO FUNCTIONS
******************************************************************************/
/**
* @brief Called once at start
* Initialize hardware pins
*/
void setup()
{
pixels = new Adafruit_NeoPixel(WS2812STRIP_LEDS, WS2812STRIP_GPIO_PIN, NEO_GRB + NEO_KHZ400);
singleLed = new Adafruit_NeoPixel(WS2812SINGLE_LEDS, WS2812SINGLE_GPIO_PIN, NEO_GRB + NEO_KHZ400);
Serial.begin(115200);
WiFi.mode(WIFI_OFF);
if (WiFi.getMode() == WIFI_OFF)
{
Serial.println(F("\nWifi mode is WIFI_OFF"));
}
SerialCmd_clearCmdArray();
/* Setup FAN Control */
pinMode(FAN_PIN, OUTPUT);
pinMode(SIGNAL_PIN, INPUT);
pixels->begin();
pixels->clear();
pixels->setBrightness(100);
pixels->fill(Color(255,0,0));
pixels->show();
/* Initialize Temperature sensor */
sensors.begin();
for(int j=0; j < TEMP_SENSOR_MEASURE_SERIES && sensors.getDeviceCount() == 0; j++)
{
delay(100);
sensors.begin();
Serial.println("Reset 1-Wire Bus");
}
pixels->fill(Color(0,255,0));
pixels->setBrightness(50);
pixels->show();
/* prepare LED strip pin */
singleLed->begin();
singleLed->clear();
singleLed->setBrightness(100);
singleLed->fill(Color(255,0,0));
singleLed->show();
}
/**
* @brief Endless loop
* (is called as fast as possible)
*/
void loop()
{
static int i = 0;
static int actualFanSpeedRpm = -1;
float temp = readTemperature();
Serial.print(temp);
Serial.print(";");
int fanSpeedPercent;
if (temp < MIN_TEMP) {
fanSpeedPercent = 0;
} else if (temp > MAX_TEMP) {
fanSpeedPercent = 100;
} else {
fanSpeedPercent = (100 - MIN_FAN_SPEED_PERCENT) * (temp - MIN_TEMP) / (MAX_TEMP - MIN_TEMP) + MIN_FAN_SPEED_PERCENT;
}
if ((actualFanSpeedRpm >= 0) && (actualFanSpeedRpm < LOW_FAN_SPEED))
{
if (i > FAN_RPM_READLEVEL)
{
actualFanSpeedRpm = getFanSpeedRpm();
i = 0;
}
i++;
}
else
{
actualFanSpeedRpm = getFanSpeedRpm();
i = 0;
}
int readCharacter = SerialCmd_readFromSerial();
if (readCharacter > 0)
{
int checkCmd = SerialCmd_checkCmdArrayForPrefix();
if(checkCmd == 0)
{
Serial.println(F("if you dont know what to do type \"" SERIALCMD_COMMAND_HELP "\""));
}
else
{
char type = SerialCmd_type();
switch (type)
{
case SERIALCMD_COMMAND_SETLED[0]:
{
uint32_t color = SerialCmd_parseColor(SERIALCMD_PARAMETER_OFFSET);
pixels->fill(color);
pixels->setBrightness(COMMAND_BRIGHTNESS);
}
break;
case SERIALCMD_COMMAND_AUTOMATIC[0]:
mAutomaticTargetRPM = RPM_CONTROL_DEACTIVATED;
break;
}
}
}
pixels->show();
Serial.print(fanSpeedPercent);
Serial.print("%;");
setFanSpeedPercent(fanSpeedPercent);
Serial.print(actualFanSpeedRpm);
Serial.println("RPM");
singleLed->fill(Color(0,128,128));
singleLed->setBrightness(fanSpeedPercent);
singleLed->show();
}