diff --git a/pwmfan.cpp b/pwmfan.cpp new file mode 100644 index 0000000..2d1b4bd --- /dev/null +++ b/pwmfan.cpp @@ -0,0 +1,159 @@ +/* + * Author: Thomas Ingleby + * Copyright (c) 2014 Intel Corporation. + * + * SPDX-License-Identifier: MIT + * + * Example usage: Generates PWM at a step rate of 0.01 continuously. + * Press Ctrl+C to exit + */ + +/* standard headers */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* mraa headers */ +#include "mraa/common.hpp" +#include "mraa/pwm.hpp" +/* для HDD*/ +#include +#include +#include +#include +#include +#include + +#define PWM_PORT 13 +#define TEMPERATURE_FILE "/sys/class/thermal/thermal_zone0/temp" +#define T_MIN 30 +#define T_MAX 50 + + + + +volatile sig_atomic_t flag = 1; + +int readTempCPU(){ + std::fstream ftemp; + std::string raw; + + ftemp.open(TEMPERATURE_FILE,std::ios::in); + if (ftemp.is_open()){ + getline(ftemp, raw); + ftemp.close(); + return std::stoi(raw)/1000; + }else{ + std::cerr << "Read temperature error. Cannot open file.\n"; + } + + return -1; +} + +std::string exec(const char* cmd) { + std::array buffer; + std::string result; + std::unique_ptr pipe(popen(cmd, "r"), pclose); + if (!pipe) { + throw std::runtime_error("popen() failed!"); + } + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { + result += buffer.data(); + } + return result; +} + +int readTempHDD(const std::string& drive) { + std::string cmd = "smartctl -A " + drive + " | grep Temperature_Celsius | awk '{print $10}'"; + std::string output = exec(cmd.c_str()); + return std::stoi(output); +} + +int readTemp(){ + int T_CPU = readTempCPU(); + // std::cout << "Temperature CPU: " << T_CPU << " C" << std::endl; + + int T_HDD_1 = readTempHDD("/dev/sda"); + // std::cout << "Temperature /dev/sda: " << T_HDD_1 << " C" << std::endl; + + int T_HDD_2 = readTempHDD("/dev/sdb"); + // std::cout << "Temperature /dev/sdb: " << T_HDD_2 << " C" << std::endl; + + int T_HDD_3 = readTempHDD("/dev/sdc"); + // std::cout << "Temperature /dev/sdc: " << T_HDD_3 << " C" << std::endl; + + int T_HDD_4 = readTempHDD("/dev/sdd"); + // std::cout << "Temperature /dev/sdd: " << T_HDD_4 << " C" << std::endl; + + int max = T_CPU; + if (T_HDD_1 > max) { + max = T_HDD_1; + } + if (T_HDD_2 > max) { + max = T_HDD_2; + } + if (T_HDD_3 > max) { + max = T_HDD_3; + } + if (T_HDD_4 > max) { + max = T_HDD_4; + } + return max; +} + + +void +sig_handler(int signum) +{ + if (signum == SIGINT) { + std::cout << "Exiting..." << std::endl; + flag = 0; + } +} + +int +main(void) +{ + std::cout << " Control fan connected to RockPi4 pin " << PWM_PORT << " according to CPU&HDD temperature\n"; + float value = 0.0f; + int t = 0; + + signal(SIGINT, sig_handler); + + //! [Interesting] + mraa::Pwm pwm(PWM_PORT); + std::cout << "Cycling PWM on IO3 (pwm3)" << std::endl; + pwm.enable(true); + + while (flag) { + //value = value + 0.01f; + pwm.write(value); + usleep(2000000); + t = readTemp(); + if (t < T_MIN) { + value = 0.0f; + } + if (t >= T_MIN && t <= T_MAX) { + value = (float(t)-float(T_MIN))/(float(T_MAX)-float(T_MIN)); + if (value<0.25) { + value = 0.0f; + } + } + if (t > T_MAX) { + value = 1.0f; + } + std::cout << "T:" << t << "С power:"<< value << "%\n"; + } + //! [Interesting] + + return EXIT_SUCCESS; +}