RockPi4_FanControl/pwmfan.cpp

160 lines
3.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Author: Thomas Ingleby <thomas.c.ingleby@intel.com>
* 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 <iostream>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fstream>
#include <string>
#include <cstring>
#include <fstream>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <getopt.h>
/* mraa headers */
#include "mraa/common.hpp"
#include "mraa/pwm.hpp"
/* для HDD*/
#include <sys/ioctl.h>
#include <linux/hdreg.h>
#include <cstdio>
#include <memory>
#include <stdexcept>
#include <array>
#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<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, decltype(&pclose)> 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;
}