Commit e254348a authored by Oleg Nikulin's avatar Oleg Nikulin

3 прошивки: для указания скважности шим, для поддержания указаных оборотовб и…

3 прошивки: для указания скважности шим, для поддержания указаных оборотовб и для поддержания температуры. Небольшие изменения в скрипте
parent 750c1fd4
#epmi pip
#pip install pyserial
import subprocess import subprocess
import time import time
import serial import serial
import os
import argparse import argparse
from argparse import RawTextHelpFormatter from argparse import RawTextHelpFormatter
import datetime import datetime
import threading import threading
import sys
POLL_SLEEP_TIME = 0.05 #Задержка между проверками наличия запроса от ардуины (cек) POLL_SLEEP_TIME = 0.1 #Задержка между проверками наличия запроса от ардуины (cек)
RECONNECT_SLEEP_TIME = 1 #Задержка между попытками открыть serial порт при потере связи (cек) RECONNECT_SLEEP_TIME = 1 #Задержка между попытками открыть serial порт при потере связи (cек)
TIMEOUT_TIME = 3 #Считается что ардуина перестала отвечать, если от нее не было запросов в течение этого времени (cек) TIMEOUT_TIME = 3 #Считается что ардуина перестала отвечать, если от нее не было запросов в течение этого времени (cек)
SERIAL_SPEEDS = [300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000, 500000, 1000000, 2000000] #Тут только те, которые доступны в arduino IDE
PORT:str = None PORT:str = None
SPEED:int = None SPEED:int = None
...@@ -67,11 +67,6 @@ parser = argparse.ArgumentParser( ...@@ -67,11 +67,6 @@ parser = argparse.ArgumentParser(
formatter_class=RawTextHelpFormatter formatter_class=RawTextHelpFormatter
) )
parser.add_argument('-l', '--list',
required = False,
action='store_true',
help = 'show a list of available serial devices',
)
parser.add_argument('-m', '--manual', parser.add_argument('-m', '--manual',
required = False, required = False,
action='store_true', action='store_true',
...@@ -81,41 +76,19 @@ parser.add_argument('-m', '--manual', ...@@ -81,41 +76,19 @@ parser.add_argument('-m', '--manual',
parser.add_argument('device', parser.add_argument('device',
type = str, type = str,
nargs = '?', nargs = '?',
help = 'serial device to commuicate with. Example: ttyUSB0', help = 'serial device to commuicate with. Example: /dev/ttyUSB0',
metavar = 'SERIAL' metavar = 'SERIAL'
) )
parser.add_argument('speed', parser.add_argument('speed',
type = int, type = int,
nargs = '?', nargs = '?',
help = 'serial port baud rate. Supported rates: ' + str(SERIAL_SPEEDS)[1:-1], help = 'serial port baud rate',
metavar = 'SPEED' metavar = 'SPEED'
) )
args = parser.parse_args() args = parser.parse_args()
#получаем список serial устройств
dev_contents = os.listdir('/dev/')
serial_devices:str = []
for file in dev_contents:
if file.startswith('ttyUSB'):
serial_devices.append(file)
if args.list != False: #вывод списка serial устройств
if len(serial_devices) == 0:
print('No serial devices found')
else:
print('Available serial devices:')
for device in serial_devices:
print(device)
exit()
#проверка наличия аргументов #проверка наличия аргументов
if args.device == None: if args.device == None:
print('Serial device was not specified') print('Serial device was not specified')
...@@ -127,25 +100,12 @@ if args.manual: ...@@ -127,25 +100,12 @@ if args.manual:
input_thread = threading.Thread(target = temp_input) input_thread = threading.Thread(target = temp_input)
temp = '50,51,52' temp = '50,51,52'
#ищем указанное serial устройство PORT = args.device
if args.device in serial_devices: SPEED = args.speed
PORT = args.device
else:
print('Serial device "{dev}" was not found. Use --list option to see a list of available serial devices'.format(dev = args.device))
exit()
#ищем указанную скорость
if args.speed in SERIAL_SPEEDS:
SPEED = args.speed
else:
print('Specified baud rate is unsupported. Use -h option to see a list of supported rates')
exit()
try: #пытаемся открыть serial порт try: #пытаемся открыть serial порт
serial_port = serial.Serial( serial_port = serial.Serial(
port = '/dev/' + PORT, port = PORT,
baudrate = SPEED, baudrate = SPEED,
parity = serial.PARITY_NONE, parity = serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE, stopbits=serial.STOPBITS_ONE,
...@@ -180,7 +140,7 @@ while True: ...@@ -180,7 +140,7 @@ while True:
output = str(subprocess.Popen(['netcat', 'localhost', '7634'], stdout = subprocess.PIPE, stderr = subprocess.STDOUT).communicate()[0]) #получаем output от hddtemp output = str(subprocess.Popen(['netcat', 'localhost', '7634'], stdout = subprocess.PIPE, stderr = subprocess.STDOUT).communicate()[0]) #получаем output от hddtemp
#b'|/dev/sda2|ST340014A|41|C|' #b'|/dev/sda2|ST340014A|41|C|'
if output == "b''": if output == "b''":
print('Hddtemp output is empty, make sure it is running. If not, launch it with $sudo hddtemp -d') print('Hddtemp output is empty, make sure it is running. If not, launch it with #hddtemp -d')
exit() exit()
#вычленяем значение температуры: #вычленяем значение температуры:
...@@ -198,7 +158,6 @@ while True: ...@@ -198,7 +158,6 @@ while True:
send_rpm_pos = incoming_line.find('send_rpm_') send_rpm_pos = incoming_line.find('send_rpm_')
rpm_string = incoming_line[send_rpm_pos + 9:] rpm_string = incoming_line[send_rpm_pos + 9:]
rpm_string = rpm_string.replace('_', ' ') rpm_string = rpm_string.replace('_', ' ')
rpm_string = rpm_string.replace('debug', 'debug:')
rpm_string = 'Fan RPMs: ' + rpm_string rpm_string = 'Fan RPMs: ' + rpm_string
#сохранение положения курсора, перервод в начало строки, перевод на 59 символов вправо, очистка всего перед курсором, курсор в начало строки, вывод оборотов, загрузка положения строки #сохранение положения курсора, перервод в начало строки, перевод на 59 символов вправо, очистка всего перед курсором, курсор в начало строки, вывод оборотов, загрузка положения строки
print('\0337' + '\033[255D' +'\033[59C' + '\033[1K' + '\033[255D' + rpm_string + '\0338', end = '', flush=True) print('\0337' + '\033[255D' +'\033[59C' + '\033[1K' + '\033[255D' + rpm_string + '\0338', end = '', flush=True)
......
...@@ -99,7 +99,7 @@ fan fans[FAN_COUNT] = { ...@@ -99,7 +99,7 @@ fan fans[FAN_COUNT] = {
}, },
{ {
19, 19,
2, 1,
0, 0,
0, 0,
0 0
...@@ -115,7 +115,6 @@ fan &fan_6 = fans[5]; ...@@ -115,7 +115,6 @@ fan &fan_6 = fans[5];
int temps[3] = {}; //Температуры, полученные от пк int temps[3] = {}; //Температуры, полученные от пк
int target_rpms[3] = {}; //Обороты, которые нужно держать (в этой прошивке target_rpms и temps это одно и то же)
uint32_t last_beep_time = 0; uint32_t last_beep_time = 0;
uint32_t last_check_time = 0; uint32_t last_check_time = 0;
...@@ -125,14 +124,12 @@ float p[3] = {}; ...@@ -125,14 +124,12 @@ float p[3] = {};
float i[3] = {}; float i[3] = {};
float d[3] = {}; float d[3] = {};
float k_p = 0.03; float k_p = 0.04;
float k_i = 0.0002; float k_i = 0.0001;
float k_d = 20; float k_d = 3;
float i_max = 255; float i_max = 255;
bool flag = 0;
void wait_for_connection(bool beep) { //функция, которая мигает светодиодом и пищит (если beep == true) до тех пор, пока не будет установлено соединение с ПК void wait_for_connection(bool beep) { //функция, которая мигает светодиодом и пищит (если beep == true) до тех пор, пока не будет установлено соединение с ПК
Serial.println("start_transmission"); Serial.println("start_transmission");
digitalWrite(LED_PIN, 1); digitalWrite(LED_PIN, 1);
...@@ -184,13 +181,13 @@ void tempFromPc()// получаем температуру от пк ...@@ -184,13 +181,13 @@ void tempFromPc()// получаем температуру от пк
} }
} }
Serial.println("req_temperature_" + rpm_string + "_debug_" + String(OCR1A) + "_" + String(OCR2A) + "_" + String(OCR2B)); //запрос к пк Serial.println("req_temperature_" + rpm_string + "_debug(pwm values):_" + String(OCR1A) + "_" + String(OCR2A) + "_" + String(OCR2B)); //запрос к пк
unsigned long query_time = millis(); unsigned long query_time = millis();
while (Serial.available() == 0) { //ждем пока ответит while (Serial.available() == 0) { //ждем пока ответит
if (millis() >= query_time + GET_TEMP_TIMEOUT) { //если слишком долго не отвечает if (millis() >= query_time + GET_TEMP_TIMEOUT) { //если слишком долго не отвечает
//Венитялторы на максимум //Венитялторы на максимум
for (int i = 0; i < CONTROL_COUNT; i++) { for (int i = 0; i < CONTROL_COUNT; i++) {
controls[i].dutyCycle = MAX_PWM_DUTY_CYCLE; //установка скважности по умолчанию controls[i].dutyCycle = DEFAULT_PWM_DUTY_CYCLE; //установка скважности по умолчанию
} }
wait_for_connection(true);//снова ждем подключения wait_for_connection(true);//снова ждем подключения
break; break;
...@@ -247,17 +244,6 @@ void tempFromPc()// получаем температуру от пк ...@@ -247,17 +244,6 @@ void tempFromPc()// получаем температуру от пк
void autocontrol()//Автоконтроль температуры
{
tempFromPc();//получаем температуру от пк
for (int i = 0; i < 3; i++) {
target_rpms[i] = temps[i];
}
}
void rpm_control() { void rpm_control() {
...@@ -270,11 +256,10 @@ void rpm_control() { ...@@ -270,11 +256,10 @@ void rpm_control() {
} }
for (int group = 0; group < 3; group++) { //PID управление скоростью 3-х групп вентиляторов for (int group = 0; group < 3; group++) {//управление скоростью 3-х групп вентиляторов
/*
uint8_t duty_cycle = 0; uint8_t duty_cycle = 0;
if (target_rpms[group] > 0) { if (temps[group] > 0) {
uint32_t avg_rpm = 0; uint32_t avg_rpm = 0;
//вычисление средних rpm из нескольких значений, записанных для фильтра //вычисление средних rpm из нескольких значений, записанных для фильтра
...@@ -283,8 +268,8 @@ void rpm_control() { ...@@ -283,8 +268,8 @@ void rpm_control() {
} }
avg_rpm /= RPM_VALUES_COUNT; avg_rpm /= RPM_VALUES_COUNT;
d[group] = (target_rpms[group] - int(avg_rpm) - p[group]) / float(millis() - lastRpmCheck); d[group] = (temps[group] - int(avg_rpm) - p[group]) / float(millis() - lastRpmCheck);
p[group] = target_rpms[group] - int(avg_rpm); p[group] = temps[group] - int(avg_rpm);
i[group] = i[group] + p[group] * (millis() - lastRpmCheck); i[group] = i[group] + p[group] * (millis() - lastRpmCheck);
if (fabs(i[group] * k_i) >= i_max) { if (fabs(i[group] * k_i) >= i_max) {
...@@ -307,8 +292,7 @@ void rpm_control() { ...@@ -307,8 +292,7 @@ void rpm_control() {
else { else {
duty_cycle = 0; duty_cycle = 0;
} }
*/
uint8_t duty_cycle = target_rpms[group];
if (duty_cycle < MIN_PWM_DUTY_CYCLE) { if (duty_cycle < MIN_PWM_DUTY_CYCLE) {
controls[group].mode = 0; //всегда выкл controls[group].mode = 0; //всегда выкл
...@@ -323,7 +307,6 @@ void rpm_control() { ...@@ -323,7 +307,6 @@ void rpm_control() {
} }
controls[group].dutyCycle = duty_cycle; controls[group].dutyCycle = duty_cycle;
} }
...@@ -359,7 +342,7 @@ ISR(TIMER1_OVF_vect) { //Функция, вызываемая при переп ...@@ -359,7 +342,7 @@ ISR(TIMER1_OVF_vect) { //Функция, вызываемая при переп
if (control_a.mode > 0) { //если режим шим или всегда вкл if (control_a.mode > 0) { //если режим шим или всегда вкл
digitalWrite(control_a.pin, 1); digitalWrite(control_a.pin, 1);
} }
delayMicroseconds(15); //delayMicroseconds(15);
for (int i = 0; i < 2; i++) { //проверка тахометров 0-1 for (int i = 0; i < 2; i++) { //проверка тахометров 0-1
if (digitalRead(fans[i].pin) == 0 && fans[i].state == 0) { //сигнал тахометра появился if (digitalRead(fans[i].pin) == 0 && fans[i].state == 0) { //сигнал тахометра появился
fans[i].state = 1; fans[i].state = 1;
...@@ -425,7 +408,6 @@ void setup() { ...@@ -425,7 +408,6 @@ void setup() {
//таймер 2 сравнение A - пин 5 //таймер 2 сравнение A - пин 5
//таймер 2 сравнение B - пин 6 //таймер 2 сравнение B - пин 6
//Пины 5 и 6: скважность от 7 до 254. Если меньше 2, то немного штырит.
//Пины 5 и 6: скважность от 8 до 255. //Пины 5 и 6: скважность от 8 до 255.
//режим таймера 1 (fast pwm 8 бит): //режим таймера 1 (fast pwm 8 бит):
...@@ -459,22 +441,21 @@ void setup() { ...@@ -459,22 +441,21 @@ void setup() {
void loop() { void loop() {
if (uint32_t(millis() - last_check_time) >= CHECK_TEMP_DELAY) { if (uint32_t(millis() - last_check_time) >= CHECK_TEMP_DELAY) {
last_check_time = millis(); last_check_time = millis();
autocontrol(); //Получаем температуру от ПК, устанавливаем соотв. скорость вращения tempFromPc();//получаем температуру от пк
// if (temp >= 80) { //Если перегрев, включается пищалка
// if (millis() >= last_beep_time + BEEP_INTERVAL * 2) {
// analogWrite(SOUND_PIN, BEEP_STRENGTH);
// last_beep_time = millis();
// }
// else if (millis() >= last_beep_time + BEEP_INTERVAL) {
// analogWrite(SOUND_PIN, 0);
// }
// }
// else {
// analogWrite(SOUND_PIN, 0); //Чтобы постоянно не пищал, если температура станет < 80 в то время, как пищалка включена
// }
/*
if (temp >= 80) { //Если перегрев, включается пищалка
if (millis() >= last_beep_time + BEEP_INTERVAL * 2) {
analogWrite(SOUND_PIN, BEEP_STRENGTH);
last_beep_time = millis();
}
else if (millis() >= last_beep_time + BEEP_INTERVAL) {
analogWrite(SOUND_PIN, 0);
}
}
else {
analogWrite(SOUND_PIN, 0); //Чтобы постоянно не пищал, если температура станет < 80 в то время, как пищалка включена
}
*/
} }
if (uint32_t(millis() - lastRpmCheck) >= RPM_CHECK_INTERVAL) { if (uint32_t(millis() - lastRpmCheck) >= RPM_CHECK_INTERVAL) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment