Commit b8539cd6 authored by Oleg Nikulin's avatar Oleg Nikulin

Изменения в обмене, теперь можно получать данные от ардуины, добавлен файл прошивки ардуины

parent f58a8a6e
#include <Wire.h>
#define BAUDRATE 57600 //Скорость serial порта
#define BEEP_INTERVAL 1000 //Частота пищания во время потери связи или перегрева
#define BEEP_STRENGTH 100 //Уровень шима для пищалки. (При 255 не работает)
#define BLINK_INTERVAL 200 //Частота мигания светодиода во время ожидания ответа от пк
#define CHECK_TEMP_DELAY 500 //Задержка перед очередным получением температуры от пк
#define GET_TEMP_TIMEOUT 1000 //таймаут получения температуры от пк
#define ZERO_RPM_TIMEOUT 500 //таймаут обнуления RPM при отсутствии сигналов от вентилятора
#define DEFAULT_RPM_VALUE 255 //Величина которая устанавливается сразу после загрузки (до подключения к пк)
#define SOUND_PIN 10
#define LED_PIN 13
#define pwmpinA 3 //Выход ШИМ 1
#define pwmpinB 5 //Выход ШИМ 2
#define pwmpinC 6 //Выход ШИМ 3
int tachPins[6] = {14, 15, 16, 17, 18, 19};
int rpms[6] = {};
uint32_t lastSignalTimes[6] = {};
bool rpm_states[6] = {};
int temp, rpmValue; //целочисленные переменные для расчетов
uint32_t lastSignalTime;
typedef struct { // Вводим новый тип переменных для вентиляторов
char fantype;
unsigned int fandiv;
} fanspec;
fanspec fanspace[3] = {{0, 1}, {1, 2}, {2, 8}}; //Массив переменных нового типа
char fan = 1; //Переменная, отвечающая за выбор типа датчика вентилятора (1 – униполярный датчик Холла, 2 –биполярный датчик Холла)
uint32_t last_beep_time = 0;
uint32_t last_check_time = 0;
void rpm_interrupt(){
if(rpm_states[1] == 0){
rpm_states[1] = 1;
}
else{
rpm_states[1] = 0;
return;
}
rpms[1] = 60000000 / (micros() - lastSignalTimes[1]);
lastSignalTimes[1] = micros();
}
void rpmcalc() { //Считывание оборотов
for (int i = 0; i < 6; i ++) {
if (digitalRead(tachPins[i]) == 0) {
if (rpm_states[i] == 0){
rpm_states[i] = 1;
}
else{
rpm_states[i] = 0;
continue;
}
if (millis() - lastSignalTimes[i] != 0) {
rpms[i] = 60000 / (millis() - lastSignalTimes[i]);
}
else {
rpms[i] = 9999;
}
lastSignalTimes[i] = millis();
}
else if (millis() >= lastSignalTimes[i] + ZERO_RPM_TIMEOUT) {
rpms[i] = 0;
}
}
}
void wait_for_connection(bool beep) { //функция, которая мигает светодиодом и пищит (если beep == true) до тех пор, пока не будет установлено соединение с ПК
Serial.println("start_transmission");
digitalWrite(LED_PIN, 1);
unsigned long last_blink_time = millis();
while (Serial.available() == 0) {//ждем ответа
if (millis() >= last_blink_time + BLINK_INTERVAL * 2) {
digitalWrite(LED_PIN, 1);
last_blink_time = millis();
}
else if (millis() >= last_blink_time + BLINK_INTERVAL) {
digitalWrite(LED_PIN, 0);
}
if (beep) {
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);
}
}
}
digitalWrite(LED_PIN, 0); //гасим светодиод
analogWrite(SOUND_PIN, 0); //и выключаем пищалку
while (Serial.available()) {// очистка буфера
Serial.readString();
}
}
void tempFromPc()// получаем температуру от пк
{
String rpm_string = "send_rpm_";
for (int i = 0; i < 6; i++) {
rpm_string += String(rpms[i]);
if (i < 5) {
rpm_string += "_";
}
}
Serial.println("req_temperature_" + rpm_string); //запрос к пк
unsigned long query_time = millis();
while (Serial.available() == 0) { //ждем пока ответит
if (millis() >= query_time + GET_TEMP_TIMEOUT) { //если слишком долго не отвечает
//Венитялторы на максимум
analogWrite(pwmpinA, 255);
analogWrite(pwmpinB, 255);
analogWrite(pwmpinC, 255);
wait_for_connection(true);//снова ждем подключения
break;
}
}
String response = Serial.readStringUntil('\n');
temp = response.substring(12).toInt();
}
void autocontrol()//Автоконтроль температуры
{
tempFromPc();//получаем температуру от пк
if (temp < 20) { //<20
rpmValue = 50;
}
else if (temp < 40) { //20-39
rpmValue = 100;
}
else if (temp < 60) { //40-59
rpmValue = 150;
}
else if (temp < 80) { //60-79
rpmValue = 200;
}
else { //>=80
rpmValue = 255;
}
analogWrite(pwmpinA, rpmValue);//задаем скорость вращения кулера 1
analogWrite(pwmpinB, rpmValue);//задаем скорость вращения кулера 2
analogWrite(pwmpinC, rpmValue);//задаем скорость вращения кулера 3
}
void setup() {
attachInterrupt(0, rpm_interrupt, FALLING);
pinMode(LED_PIN, OUTPUT);
pinMode(pwmpinA, OUTPUT);
pinMode(pwmpinB, OUTPUT);
pinMode(pwmpinC, OUTPUT);
analogWrite(pwmpinA, DEFAULT_RPM_VALUE);
analogWrite(pwmpinB, DEFAULT_RPM_VALUE);
analogWrite(pwmpinC, DEFAULT_RPM_VALUE);
for (int i = 1; i < 6; i++) {
pinMode(tachPins[i], INPUT_PULLUP); // Настраиваем pin на получение прерывания
}
Serial.begin(BAUDRATE);
pinMode(SOUND_PIN, OUTPUT);
wait_for_connection(false); //Ждем установленя связи с ПК
}
void loop() {
if (millis() >= last_check_time + CHECK_TEMP_DELAY) {
last_check_time = millis();
autocontrol(); //Получаем температуру от ПК, устанавливаем соотв. скорость вращения
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 в то время, как пищалка включена
}
}
//rpmcalc();
}
......@@ -7,10 +7,10 @@ from argparse import RawTextHelpFormatter
import datetime
import threading
POLL_SLEEP_TIME = 0.05
RECONNECT_SLEEP_TIME = 1
TIMEOUT_TIME = 3
SERIAL_SPEEDS = [300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000, 500000, 1000000, 2000000]
POLL_SLEEP_TIME = 0.05 #Задержка между проверками наличия запроса от ардуины
RECONNECT_SLEEP_TIME = 1 #Задержка между попытками открыть serial порт при потере связи
TIMEOUT_TIME = 3 #Считается что ардуина перестала отвечать, если от нее не было запросов в течение этого времени
SERIAL_SPEEDS = [300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000, 500000, 1000000, 2000000] #Тут только те, которые доступны в arduino IDE
PORT:str = None
SPEED:int = None
......@@ -123,23 +123,27 @@ except OSError:
exit()
print('Connecting to the serial device...')
serial_port.reset_input_buffer()
while True:
try:
if serial_port.in_waiting > 0:
if not connected:
print('Connected. Starting transmission')
connected = True
if args.manual and not input_thread_running:
input_thread.start()
input_thread_running = True
if serial_port.read().decode() == '1':
if serial_port.readline().decode()[:-2] == 'start_transmission':
last_serial_input_time = datetime.datetime.now().timestamp()
serial_port.write('starting_transmission\n'.encode())
print('Connected. Starting transmission')
connected = True
if args.manual and not input_thread_running:
input_thread.start()
input_thread_running = True
incoming_line = serial_port.readline().decode()[:-2]
if 'req_temperature' in incoming_line:
last_serial_input_time = datetime.datetime.now().timestamp()
if args.manual:
serial_port.write('a'.encode())
serial_port.write(temp.encode()) #отправка значения
serial_port.write(('temperature_' + temp + '\n').encode()) #отправка значения
else:
output = str(subprocess.Popen(['netcat', 'localhost', '7634'], stdout = subprocess.PIPE, stderr = subprocess.STDOUT).communicate()[0]) #получаем output от hddtemp
#b'|/dev/sda2|ST340014A|41|C|'
......@@ -154,13 +158,16 @@ while True:
try:
int(temp)
#print(temp + ' C')
serial_port.write('a'.encode())
serial_port.write(temp.encode()) #отправка значения
serial_port.write(('temperature_' + temp + '\n').encode()) #отправка значения
except ValueError:
print('Error: Failed to get a temperature value from hddtemp output')
else:
print('Unknown query from serial device')
if 'send_rpm' in incoming_line:
send_rpm_pos = incoming_line.find('send_rpm')
rpm_str = incoming_line[send_rpm_pos + 9:]
if args.manual: print()
print('Fan RPMs: ' + rpm_str)
if args.manual: print('Enter the temperature value: ')
except OSError:
if connected:
......@@ -181,4 +188,4 @@ while True:
print('Serial device is not responding')
connected = False
time.sleep(POLL_SLEEP_TIME)
\ No newline at end of file
#time.sleep(POLL_SLEEP_TIME)
\ No newline at end of file
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