Last active
January 23, 2018 12:32
-
-
Save 1271/ae3838b4e9382713992bab8ab5af5775 to your computer and use it in GitHub Desktop.
PCdisplay_v_1.3_1602
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define DRIVER_VERSION 1 // 0 - маркировка драйвера кончается на 4АТ, 1 - на 4Т | |
// ------------------------ НАСТРОЙКИ ---------------------------- | |
// ----------------------- ПИНЫ --------------------------- | |
#define BTN1 A3 // первая кнопка | |
#define BTN2 A2 // вторая кнопка | |
// ----------------------- ПИНЫ --------------------------- | |
// -------------------- БИБЛИОТЕКИ --------------------- | |
#include <OneWire.h> // библиотека протокола датчиков | |
#include <string.h> // библиотека расширенной работы со строками | |
#include <Wire.h> // библиотека для соединения | |
#include <LiquidCrystal_I2C.h> // библтотека дислея | |
#include <TimerOne.h> // библиотека таймера | |
// -------------------- БИБЛИОТЕКИ --------------------- | |
// -------- АВТОВЫБОР ОПРЕДЕЛЕНИЯ ДИСПЛЕЯ------------- | |
// Если кончается на 4Т - это 0х27. Если на 4АТ - 0х3f | |
#if (DRIVER_VERSION) | |
LiquidCrystal_I2C lcd(0x27, 16, 2); | |
#else | |
LiquidCrystal_I2C lcd(0x3f, 16, 2); | |
#endif | |
// -------- АВТОВЫБОР ОПРЕДЕЛЕНИЯ ДИСПЛЕЯ------------- | |
#define printByte(args) write(args); | |
// правый край полосы загрузки | |
byte right_empty[8] = {0b11111, 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b11111}; | |
// левый край полосы загрузки | |
byte left_empty[8] = {0b11111, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b11111}; | |
// центр полосы загрузки | |
byte center_empty[8] = {0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111}; | |
// блоки для построения графиков | |
byte row8[8] = {0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111}; | |
byte row7[8] = {0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111}; | |
byte row6[8] = {0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111}; | |
byte row5[8] = {0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111}; | |
byte row4[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111}; | |
byte row3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111}; | |
byte row2[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111}; | |
byte row1[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111}; | |
char inData[63]; // массив входных значений (СИМВОЛЫ) | |
int PCdata[20]; // массив численных значений показаний с компьютера | |
byte PLOTmem[6][16]; // массив для хранения данных для построения графика (16 значений для 6 параметров) | |
byte index = 0; | |
int display_mode = 6; | |
String string_convert; | |
unsigned long timeout, blink_timer, plot_timer; | |
boolean reDraw_flag = 1, updateDisplay_flag, timeOut_flag = 1; | |
int duty; | |
byte lines[] = {4, 5, 7, 6}; | |
byte plotLines[] = {0, 1, 4, 5, 6, 7}; // 0-CPU temp, 1-GPU temp, 2-CPU load, 3-GPU load, 4-RAM load, 5-GPU memory | |
String perc; | |
boolean btn1_sig, btn2_sig, btn1_flag, btn2_flag; | |
// Названия для легенды графиков | |
const char plot_0[] = "CPU"; | |
const char plot_1[] = "GPU"; | |
const char plot_2[] = "RAM"; | |
const char plot_3[] = "temp"; | |
const char plot_4[] = "load"; | |
const char plot_5[] = "mem"; | |
// названия ниже должны совпадать с массивами сверху и идти по порядку! | |
static const char *plotNames0[] = { | |
plot_0, plot_1, plot_0, plot_1, plot_2, plot_1 | |
}; | |
static const char *plotNames1[] = { | |
plot_3, plot_3, plot_4, plot_4, plot_4, plot_5 | |
}; | |
// 0-CPU temp, 1-GPU temp, 2-CPU load, 3-GPU load, 4-RAM load, 5-GPU memory | |
void setup() { | |
Serial.begin(9600); | |
Timer1.initialize(40); // поставить частоту ШИМ 25 кГц (40 микросекунд) | |
pinMode(BTN1, INPUT_PULLUP); | |
pinMode(BTN2, INPUT_PULLUP); | |
// инициализация дисплея | |
lcd.init(); | |
lcd.backlight(); | |
lcd.clear(); // очистить дисплей | |
PCdata[8] = 0; | |
PCdata[9] = 0; | |
PCdata[10] = 0; | |
PCdata[11] = 0; | |
} | |
// 8-maxFAN, 9-minFAN, 10-maxTEMP, 11-minTEMP, 12-mnlFAN | |
// ------------------------------ ОСНОВНОЙ ЦИКЛ ------------------------------- | |
void loop() { | |
parsing(); // парсим строки с компьютера | |
updatePlot(); // обновляем массив данных графика | |
buttonsTick(); // опрос кнопок и смена режимов | |
updateDisplay(); // обновить показания на дисплее | |
timeoutTick(); // проверка таймаута | |
} | |
// ------------------------------ ОСНОВНОЙ ЦИКЛ ------------------------------- | |
void buttonsTick() { | |
btn1_sig = !digitalRead(BTN1); | |
btn2_sig = !digitalRead(BTN2); | |
if (btn1_sig && !btn1_flag) { | |
display_mode++; | |
reDraw_flag = 1; | |
if (display_mode > 9) display_mode = 0; | |
btn1_flag = 1; | |
} | |
if (!btn1_sig && btn1_flag) { | |
btn1_flag = 0; | |
} | |
if (btn2_sig && !btn2_flag) { | |
display_mode--; | |
reDraw_flag = 1; | |
if (display_mode < 0) display_mode = 9; | |
btn2_flag = 1; | |
} | |
if (!btn2_sig && btn2_flag) { | |
btn2_flag = 0; | |
} | |
} | |
void parsing() { | |
while (Serial.available() > 0) { | |
char aChar = Serial.read(); | |
if (aChar != 'E') { | |
inData[index] = aChar; | |
index++; | |
inData[index] = '\0'; | |
} else { | |
char *p = inData; | |
char *str; | |
index = 0; | |
String value = ""; | |
while ((str = strtok_r(p, ";", &p)) != NULL) { | |
string_convert = str; | |
PCdata[index] = string_convert.toInt(); | |
index++; | |
} | |
index = 0; | |
updateDisplay_flag = 1; | |
} | |
timeout = millis(); | |
timeOut_flag = 1; | |
} | |
} | |
void updatePlot() { | |
if ((millis() - plot_timer) > (PCdata[17] * 1000)) { | |
for (int i = 0; i < 6; i++) { // для каждой строки параметров | |
for (int j = 0; j < 15; j++) { // каждый столбец параметров (кроме последнего) | |
PLOTmem[i][j] = PLOTmem[i][j + 1]; // сдвинуть весь массив на шаг ВЛЕВО | |
} | |
} | |
for (int i = 0; i < 6; i++) { | |
// запомнить общее число полосок графика в ПОСЛЕДНИЙ элемент массива | |
PLOTmem[i][15] = PCdata[plotLines[i]]; | |
} | |
plot_timer = millis(); | |
} | |
} | |
void updateDisplay() { | |
if (updateDisplay_flag) { | |
if (reDraw_flag) { | |
lcd.clear(); | |
switch (display_mode) { | |
case 0: | |
case 1: | |
case 2: | |
case 3: | |
case 4: | |
case 5: draw_plot_symb(); | |
break; | |
case 6: draw_labels_11(); | |
break; | |
case 7: draw_labels_12(); | |
break; | |
case 8: draw_labels_21(); | |
break; | |
case 9: draw_labels_22(); | |
break; | |
} | |
reDraw_flag = 0; | |
} | |
switch (display_mode) { | |
case 0: | |
case 1: | |
case 2: | |
case 3: | |
case 4: | |
case 5: draw_plot(); | |
break; | |
case 6: draw_stats_11(); | |
break; | |
case 7: draw_stats_12(); | |
break; | |
case 8: draw_stats_21(); | |
break; | |
case 9: draw_stats_22(); | |
break; | |
} | |
updateDisplay_flag = 0; | |
} | |
} | |
void draw_stats_11() { | |
lcd.setCursor(4, 0); lcd.print(PCdata[0]); lcd.write(223); | |
lcd.setCursor(13, 0); lcd.print(PCdata[4]); | |
if (PCdata[4] < 10) perc = "% "; | |
else if (PCdata[4] < 100) perc = "%"; | |
else perc = ""; lcd.print(perc); | |
lcd.setCursor(4, 1); lcd.print(PCdata[1]); lcd.write(223); | |
lcd.setCursor(13, 1); lcd.print(PCdata[5]); | |
if (PCdata[5] < 10) perc = "% "; | |
else if (PCdata[5] < 100) perc = "%"; | |
else perc = ""; lcd.print(perc); | |
for (int i = 0; i < 2; i++) { | |
byte line = ceil(PCdata[lines[i]] / 16); | |
lcd.setCursor(7, i); | |
if (line == 0) lcd.printByte(1) | |
else lcd.printByte(4); | |
for (int n = 1; n < 5; n++) { | |
if (n < line) lcd.printByte(4); | |
if (n >= line) lcd.printByte(2); | |
} | |
if (line == 6) lcd.printByte(4) | |
else lcd.printByte(3); | |
} | |
} | |
void draw_stats_12() { | |
lcd.setCursor(13, 0); lcd.print(PCdata[7]); | |
if (PCdata[7] < 10) perc = "% "; | |
else if (PCdata[7] < 100) perc = "%"; | |
else perc = ""; lcd.print(perc); | |
lcd.setCursor(13, 1); lcd.print(PCdata[6]); | |
if (PCdata[6] < 10) perc = "% "; | |
else if (PCdata[6] < 100) perc = "%"; | |
else perc = ""; lcd.print(perc); | |
for (int i = 0; i < 2; i++) { | |
byte line = ceil(PCdata[lines[i + 2]] / 16); | |
lcd.setCursor(7, i); | |
if (line == 0) lcd.printByte(1) | |
else lcd.printByte(4); | |
for (int n = 1; n < 5; n++) { | |
if (n < line) lcd.printByte(4); | |
if (n >= line) lcd.printByte(2); | |
} | |
if (line == 6) lcd.printByte(4) | |
else lcd.printByte(3); | |
} | |
} | |
void draw_stats_21() { | |
lcd.setCursor(13, 0); lcd.print(duty); | |
if ((duty) < 10) perc = "% "; | |
else if ((duty) < 100) perc = "%"; | |
else perc = ""; lcd.print(perc); | |
byte line = ceil(duty / 16); | |
lcd.setCursor(6, 0); | |
if (line == 0) lcd.printByte(1) | |
else lcd.printByte(4); | |
for (int n = 1; n < 5; n++) { | |
if (n < line) lcd.printByte(4); | |
if (n >= line) lcd.printByte(2); | |
} | |
if (line == 6) lcd.printByte(4) | |
else lcd.printByte(3); | |
} | |
void draw_stats_22() { | |
lcd.setCursor(2, 0); lcd.print(PCdata[2]); lcd.write(223); | |
lcd.setCursor(10, 0); lcd.print(PCdata[3]); lcd.write(223); | |
} | |
void draw_labels_11() { | |
lcd.createChar(1, left_empty); | |
lcd.createChar(2, center_empty); | |
lcd.createChar(3, right_empty); | |
lcd.createChar(4, row8); | |
lcd.setCursor(0, 0); | |
lcd.print("CPU:"); | |
lcd.setCursor(0, 1); | |
lcd.print("GPU:"); | |
} | |
void draw_labels_12() { | |
lcd.createChar(1, left_empty); | |
lcd.createChar(2, center_empty); | |
lcd.createChar(3, right_empty); | |
lcd.createChar(4, row8); | |
lcd.setCursor(0, 0); | |
lcd.print("GPUmem:"); | |
lcd.setCursor(0, 1); | |
lcd.print("RAMuse:"); | |
} | |
void draw_labels_21() { | |
lcd.createChar(1, left_empty); | |
lcd.createChar(2, center_empty); | |
lcd.createChar(3, right_empty); | |
lcd.createChar(4, row8); | |
lcd.setCursor(0, 0); | |
lcd.print("FANsp:"); | |
lcd.setCursor(0, 1); | |
lcd.print("T1: "); | |
lcd.setCursor(8, 1); | |
lcd.print("T2:"); | |
} | |
void draw_labels_22() { | |
lcd.createChar(1, left_empty); | |
lcd.createChar(2, center_empty); | |
lcd.createChar(3, right_empty); | |
lcd.createChar(4, row8); | |
lcd.setCursor(0, 0); | |
lcd.print("M:"); | |
lcd.setCursor(7, 0); | |
lcd.print("HM:"); | |
lcd.setCursor(0, 1); | |
lcd.print("UPTIME:"); | |
} | |
void draw_legend() { | |
byte data = PCdata[plotLines[display_mode]]; | |
lcd.setCursor(10, 0); lcd.print(data); | |
if (display_mode > 1) { | |
if (data < 10) perc = "% "; | |
else if (data < 100) perc = "%"; | |
else { | |
perc = ""; | |
} | |
lcd.print(perc); | |
} else { | |
if (data < 10) { | |
lcd.write(223); | |
lcd.print(" "); | |
} else if (data < 100) { | |
lcd.write(223); lcd.print(" "); | |
} else { | |
lcd.write(223); | |
} | |
} | |
} | |
void draw_plot() { | |
draw_legend(); | |
lcd.setCursor(0, 1); | |
for (int i = 0; i < 16; i++) { | |
lcd.printByte(constrain(map(PLOTmem[display_mode][i], 0, 100, 0, 7), 0, 7)); | |
} | |
} | |
void draw_plot_symb() { | |
lcd.createChar(0, row1); | |
lcd.createChar(1, row2); | |
lcd.createChar(2, row3); | |
lcd.createChar(3, row4); | |
lcd.createChar(4, row5); | |
lcd.createChar(5, row6); | |
lcd.createChar(6, row7); | |
lcd.createChar(7, row8); | |
lcd.setCursor(0, 0); | |
lcd.print(plotNames0[display_mode]); | |
lcd.setCursor(3, 0); | |
lcd.print(plotNames1[display_mode]); | |
lcd.print(": "); | |
} | |
void timeoutTick() { | |
if ((millis() - timeout > 5000) && timeOut_flag) { | |
lcd.clear(); | |
lcd.setCursor(3, 0); | |
lcd.print("CONNECT"); | |
lcd.setCursor(5, 1); | |
lcd.print("FAIL"); | |
timeOut_flag = 0; | |
reDraw_flag = 1; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define DRIVER_VERSION 1 // 0 - маркировка драйвера кончается на 4АТ, 1 - на 4Т | |
// ------------------------ НАСТРОЙКИ ---------------------------- | |
// ----------------------- ПИНЫ --------------------------- | |
#define BTN1 A3 // первая кнопка | |
#define BTN2 A2 // вторая кнопка | |
// ----------------------- ПИНЫ --------------------------- | |
// -------------------- БИБЛИОТЕКИ --------------------- | |
#include <OneWire.h> // библиотека протокола датчиков | |
#include <string.h> // библиотека расширенной работы со строками | |
#include <Wire.h> // библиотека для соединения | |
#include <LiquidCrystal_I2C.h> // библтотека дислея | |
#include <TimerOne.h> // библиотека таймера | |
// -------------------- БИБЛИОТЕКИ --------------------- | |
// -------- АВТОВЫБОР ОПРЕДЕЛЕНИЯ ДИСПЛЕЯ------------- | |
// Если кончается на 4Т - это 0х27. Если на 4АТ - 0х3f | |
#if (DRIVER_VERSION) | |
LiquidCrystal_I2C lcd(0x27, 20, 4); | |
#else | |
LiquidCrystal_I2C lcd(0x3f, 20, 4); | |
#endif | |
// -------- АВТОВЫБОР ОПРЕДЕЛЕНИЯ ДИСПЛЕЯ------------- | |
#define printByte(args) write(args); | |
// правый край полосы загрузки | |
byte right_empty[8] = {0b11111, 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b11111}; | |
// левый край полосы загрузки | |
byte left_empty[8] = {0b11111, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b11111}; | |
// центр полосы загрузки | |
byte center_empty[8] = {0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111}; | |
// блоки для построения графиков | |
byte row8[8] = {0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111}; | |
byte row7[8] = {0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111}; | |
byte row6[8] = {0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111}; | |
byte row5[8] = {0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111}; | |
byte row4[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111}; | |
byte row3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111}; | |
byte row2[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111}; | |
byte row1[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111}; | |
char inData[63]; // массив входных значений (СИМВОЛЫ) | |
int PCdata[20]; // массив численных значений показаний с компьютера | |
byte PLOTmem[6][16]; // массив для хранения данных для построения графика (16 значений для 6 параметров) | |
byte index = 0; | |
int display_mode = 6; | |
String string_convert; | |
unsigned long timeout, blink_timer, plot_timer; | |
boolean reDraw_flag = 1, updateDisplay_flag, timeOut_flag = 1; | |
int duty; | |
byte lines[] = {4, 5, 7, 6}; | |
byte plotLines[] = {0, 1, 4, 5, 6, 7}; // 0-CPU temp, 1-GPU temp, 2-CPU load, 3-GPU load, 4-RAM load, 5-GPU memory | |
String perc; | |
boolean btn1_sig, btn2_sig, btn1_flag, btn2_flag; | |
byte blocks, halfs; | |
// Названия для легенды графиков | |
const char plot_0[] = "CPU"; | |
const char plot_1[] = "GPU"; | |
const char plot_2[] = "RAM"; | |
const char plot_3[] = "temp"; | |
const char plot_4[] = "load"; | |
const char plot_5[] = "mem"; | |
// названия ниже должны совпадать с массивами сверху и идти по порядку! | |
static const char *plotNames0[] = { | |
plot_0, plot_1, plot_0, plot_1, plot_2, plot_1 | |
}; | |
static const char *plotNames1[] = { | |
plot_3, plot_3, plot_4, plot_4, plot_4, plot_5 | |
}; | |
// 0-CPU temp, 1-GPU temp, 2-CPU load, 3-GPU load, 4-RAM load, 5-GPU memory | |
void setup() { | |
Serial.begin(9600); | |
Timer1.initialize(40); // поставить частоту ШИМ 25 кГц (40 микросекунд) | |
pinMode(BTN1, INPUT_PULLUP); | |
pinMode(BTN2, INPUT_PULLUP); | |
// инициализация дисплея | |
lcd.init(); | |
lcd.backlight(); | |
lcd.clear(); // очистить дисплей | |
PCdata[8] = 0; | |
PCdata[9] = 0; | |
PCdata[10] = 0; | |
PCdata[11] = 0; | |
} | |
// 8-maxFAN, 9-minFAN, 10-maxTEMP, 11-minTEMP, 12-mnlFAN | |
// ------------------------------ ОСНОВНОЙ ЦИКЛ ------------------------------- | |
void loop() { | |
parsing(); // парсим строки с компьютера | |
updatePlot(); // обновляем массив данных графика | |
buttonsTick(); // опрос кнопок и смена режимов | |
updateDisplay(); // обновить показания на дисплее | |
timeoutTick(); // проверка таймаута | |
} | |
// ------------------------------ ОСНОВНОЙ ЦИКЛ ------------------------------- | |
void buttonsTick() { | |
btn1_sig = !digitalRead(BTN1); | |
btn2_sig = !digitalRead(BTN2); | |
if (btn1_sig && !btn1_flag) { | |
display_mode++; | |
reDraw_flag = 1; | |
if (display_mode > 7) display_mode = 0; | |
btn1_flag = 1; | |
} | |
if (!btn1_sig && btn1_flag) { | |
btn1_flag = 0; | |
} | |
if (btn2_sig && !btn2_flag) { | |
display_mode--; | |
reDraw_flag = 1; | |
if (display_mode < 0) display_mode = 7; | |
btn2_flag = 1; | |
} | |
if (!btn2_sig && btn2_flag) { | |
btn2_flag = 0; | |
} | |
} | |
void parsing() { | |
while (Serial.available() > 0) { | |
char aChar = Serial.read(); | |
if (aChar != 'E') { | |
inData[index] = aChar; | |
index++; | |
inData[index] = '\0'; | |
} else { | |
char *p = inData; | |
char *str; | |
index = 0; | |
String value = ""; | |
while ((str = strtok_r(p, ";", &p)) != NULL) { | |
string_convert = str; | |
PCdata[index] = string_convert.toInt(); | |
index++; | |
} | |
index = 0; | |
updateDisplay_flag = 1; | |
} | |
timeout = millis(); | |
timeOut_flag = 1; | |
} | |
} | |
void updatePlot() { | |
if ((millis() - plot_timer) > (PCdata[17] * 1000)) { | |
for (int i = 0; i < 6; i++) { // для каждой строки параметров | |
for (int j = 0; j < 15; j++) { // каждый столбец параметров (кроме последнего) | |
PLOTmem[i][j] = PLOTmem[i][j + 1]; // сдвинуть весь массив на шаг ВЛЕВО | |
} | |
} | |
for (int i = 0; i < 6; i++) { | |
// запомнить общее число полосок графика в ПОСЛЕДНИЙ элемент массива | |
PLOTmem[i][15] = ceil(PCdata[plotLines[i]] / 3); | |
} | |
plot_timer = millis(); | |
} | |
} | |
void updateDisplay() { | |
if (updateDisplay_flag) { | |
if (reDraw_flag) { | |
lcd.clear(); | |
switch (display_mode) { | |
case 0: | |
case 1: | |
case 2: | |
case 3: | |
case 4: | |
case 5: draw_plot_symb(); | |
break; | |
case 6: draw_labels_1(); | |
break; | |
case 7: draw_labels_2(); | |
break; | |
} | |
reDraw_flag = 0; | |
} | |
switch (display_mode) { | |
case 0: | |
case 1: | |
case 2: | |
case 3: | |
case 4: | |
case 5: draw_plot(); | |
break; | |
case 6: draw_stats_1(); | |
break; | |
case 7: draw_stats_2(); | |
break; | |
} | |
updateDisplay_flag = 0; | |
} | |
} | |
void draw_stats_1() { | |
lcd.setCursor(4, 0); lcd.print(PCdata[0]); lcd.write(223); | |
lcd.setCursor(17, 0); lcd.print(PCdata[4]); | |
if (PCdata[4] < 10) perc = "% "; | |
else if (PCdata[4] < 100) perc = "%"; | |
else perc = ""; lcd.print(perc); | |
lcd.setCursor(4, 1); lcd.print(PCdata[1]); lcd.write(223); | |
lcd.setCursor(17, 1); lcd.print(PCdata[5]); | |
if (PCdata[5] < 10) perc = "% "; | |
else if (PCdata[5] < 100) perc = "%"; | |
else perc = ""; lcd.print(perc); | |
lcd.setCursor(17, 2); lcd.print(PCdata[7]); | |
if (PCdata[7] < 10) perc = "% "; | |
else if (PCdata[7] < 100) perc = "%"; | |
else perc = ""; lcd.print(perc); | |
lcd.setCursor(17, 3); lcd.print(PCdata[6]); | |
if (PCdata[6] < 10) perc = "% "; | |
else if (PCdata[6] < 100) perc = "%"; | |
else perc = ""; lcd.print(perc); | |
for (int i = 0; i < 4; i++) { | |
byte line = ceil(PCdata[lines[i]] / 10); | |
lcd.setCursor(7, i); | |
if (line == 0) lcd.printByte(1) | |
else lcd.printByte(4); | |
for (int n = 1; n < 9; n++) { | |
if (n < line) lcd.printByte(4); | |
if (n >= line) lcd.printByte(2); | |
} | |
if (line == 10) lcd.printByte(4) | |
else lcd.printByte(3); | |
} | |
} | |
void draw_stats_2() { | |
lcd.setCursor(16, 0); lcd.print(duty); | |
if ((duty) < 10) perc = "% "; | |
else if ((duty) < 100) perc = "%"; | |
else perc = ""; lcd.print(perc); | |
lcd.setCursor(4, 2); lcd.print(PCdata[2]); lcd.write(223); | |
lcd.setCursor(16, 2); lcd.print(PCdata[3]); lcd.write(223); | |
byte line = ceil(duty / 10); | |
lcd.setCursor(6, 0); | |
if (line == 0) lcd.printByte(1) | |
else lcd.printByte(4); | |
for (int n = 1; n < 9; n++) { | |
if (n < line) lcd.printByte(4); | |
if (n >= line) lcd.printByte(2); | |
} | |
if (line == 10) lcd.printByte(4) | |
else lcd.printByte(3); | |
} | |
void draw_labels_1() { | |
lcd.createChar(1, left_empty); | |
lcd.createChar(2, center_empty); | |
lcd.createChar(3, right_empty); | |
lcd.createChar(4, row8); | |
lcd.setCursor(0, 0); | |
lcd.print("CPU:"); | |
lcd.setCursor(0, 1); | |
lcd.print("GPU:"); | |
lcd.setCursor(0, 2); | |
lcd.print("GPUmem:"); | |
lcd.setCursor(0, 3); | |
lcd.print("RAMuse:"); | |
} | |
void draw_labels_2() { | |
lcd.createChar(1, left_empty); | |
lcd.createChar(2, center_empty); | |
lcd.createChar(3, right_empty); | |
lcd.createChar(4, row8); | |
lcd.setCursor(0, 0); | |
lcd.print("FANsp:"); | |
lcd.setCursor(0, 1); | |
lcd.print("X: "); | |
lcd.setCursor(10, 1); | |
lcd.print("X:"); | |
lcd.setCursor(0, 2); | |
lcd.print("MOM:"); | |
lcd.setCursor(9, 2); | |
lcd.print("HDDmax:"); | |
lcd.setCursor(0, 3); | |
lcd.print("X:"); | |
} | |
void draw_legend() { | |
byte data = PCdata[plotLines[display_mode]]; | |
lcd.setCursor(16, 2); lcd.print(data); | |
if (display_mode > 1) { | |
if (data < 10) perc = "% "; | |
else if (data < 100) perc = "%"; | |
else { | |
perc = ""; | |
} | |
lcd.print(perc); | |
} else { | |
if (data < 10) { | |
lcd.write(223); | |
lcd.print(" "); | |
} else if (data < 100) { | |
lcd.write(223); lcd.print(" "); | |
} else { | |
lcd.write(223); | |
} | |
} | |
} | |
void draw_plot() { | |
draw_legend(); | |
for (byte i = 0; i < 16; i++) { // каждый столбец параметров | |
blocks = floor(PLOTmem[display_mode][i] / 8); // найти количество целых блоков | |
halfs = PLOTmem[display_mode][i] - blocks * 8; // найти число оставшихся полосок | |
for (byte n = 0; n < 4; n++) { | |
if (n < blocks) { | |
lcd.setCursor(i, (3 - n)); | |
lcd.printByte(0); | |
} | |
if (n >= blocks) { | |
if (n != 3) { | |
lcd.setCursor(i, (3 - n)); | |
if (halfs > 0) lcd.printByte(halfs); | |
for (byte k = n + 1; k < 4; k++) { | |
lcd.setCursor(i, (3 - k)); | |
lcd.print(" "); | |
} | |
break; | |
} | |
} | |
} | |
} | |
} | |
void draw_plot_symb() { | |
lcd.createChar(0, row8); | |
lcd.createChar(1, row1); | |
lcd.createChar(2, row2); | |
lcd.createChar(3, row3); | |
lcd.createChar(4, row4); | |
lcd.createChar(5, row5); | |
lcd.createChar(6, row6); | |
lcd.createChar(7, row7); | |
lcd.setCursor(16, 0); | |
lcd.print(plotNames0[display_mode]); | |
lcd.setCursor(16, 1); | |
lcd.print(plotNames1[display_mode]); | |
} | |
void timeoutTick() { | |
if ((millis() - timeout > 5000) && timeOut_flag) { | |
lcd.clear(); | |
lcd.setCursor(5, 1); | |
lcd.print("CONNECT"); | |
lcd.setCursor(7, 2); | |
lcd.print("FAIL"); | |
timeOut_flag = 0; | |
reDraw_flag = 1; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Доработал 2004. Убрал строки с X и строку с FanSP, так как она не работала
#define DRIVER_VERSION 1 // 0 - маркировка драйвера кончается на 4АТ, 1 - на 4Т
// ------------------------ НАСТРОЙКИ ----------------------------
// ----------------------- ПИНЫ ---------------------------
#define BTN1 A3 // первая кнопка
#define BTN2 A2 // вторая кнопка
// ----------------------- ПИНЫ ---------------------------
// -------------------- БИБЛИОТЕКИ ---------------------
#include <OneWire.h> // библиотека протокола датчиков
#include <string.h> // библиотека расширенной работы со строками
#include <Wire.h> // библиотека для соединения
#include <LiquidCrystal_I2C.h> // библтотека дислея
#include <TimerOne.h> // библиотека таймера
// -------------------- БИБЛИОТЕКИ ---------------------
// -------- АВТОВЫБОР ОПРЕДЕЛЕНИЯ ДИСПЛЕЯ-------------
// Если кончается на 4Т - это 0х27. Если на 4АТ - 0х3f
#if (DRIVER_VERSION)
LiquidCrystal_I2C lcd(0x27, 20, 4);
#else
LiquidCrystal_I2C lcd(0x3f, 20, 4);
#endif
// -------- АВТОВЫБОР ОПРЕДЕЛЕНИЯ ДИСПЛЕЯ-------------
#define printByte(args) write(args);
// правый край полосы загрузки
byte right_empty[8] = {0b11111, 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b11111};
// левый край полосы загрузки
byte left_empty[8] = {0b11111, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b11111};
// центр полосы загрузки
byte center_empty[8] = {0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111};
// блоки для построения графиков
byte row8[8] = {0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte row7[8] = {0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte row6[8] = {0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte row5[8] = {0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte row4[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111};
byte row3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111};
byte row2[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte row1[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111};
char inData[63]; // массив входных значений (СИМВОЛЫ)
int PCdata[20]; // массив численных значений показаний с компьютера
byte PLOTmem[6][16]; // массив для хранения данных для построения графика (16 значений для 6 параметров)
byte index = 0;
int display_mode = 6;
String string_convert;
unsigned long timeout, blink_timer, plot_timer;
boolean reDraw_flag = 1, updateDisplay_flag, timeOut_flag = 1;
int duty;
byte lines[] = {4, 5, 7, 6};
byte plotLines[] = {0, 1, 4, 5, 6, 7}; // 0-CPU temp, 1-GPU temp, 2-CPU load, 3-GPU load, 4-RAM load, 5-GPU memory
String perc;
boolean btn1_sig, btn2_sig, btn1_flag, btn2_flag;
byte blocks, halfs;
// Названия для легенды графиков
const char plot_0[] = "CPU";
const char plot_1[] = "GPU";
const char plot_2[] = "RAM";
const char plot_3[] = "temp";
const char plot_4[] = "load";
const char plot_5[] = "mem";
// названия ниже должны совпадать с массивами сверху и идти по порядку!
static const char *plotNames0[] = {
plot_0, plot_1, plot_0, plot_1, plot_2, plot_1
};
static const char *plotNames1[] = {
plot_3, plot_3, plot_4, plot_4, plot_4, plot_5
};
// 0-CPU temp, 1-GPU temp, 2-CPU load, 3-GPU load, 4-RAM load, 5-GPU memory
void setup() {
Serial.begin(9600);
Timer1.initialize(40); // поставить частоту ШИМ 25 кГц (40 микросекунд)
pinMode(BTN1, INPUT_PULLUP);
pinMode(BTN2, INPUT_PULLUP);
// инициализация дисплея
lcd.init();
lcd.backlight();
lcd.clear(); // очистить дисплей
PCdata[8] = 0;
PCdata[9] = 0;
PCdata[10] = 0;
PCdata[11] = 0;
}
// 8-maxFAN, 9-minFAN, 10-maxTEMP, 11-minTEMP, 12-mnlFAN
// ------------------------------ ОСНОВНОЙ ЦИКЛ -------------------------------
void loop() {
parsing(); // парсим строки с компьютера
updatePlot(); // обновляем массив данных графика
buttonsTick(); // опрос кнопок и смена режимов
updateDisplay(); // обновить показания на дисплее
timeoutTick(); // проверка таймаута
}
// ------------------------------ ОСНОВНОЙ ЦИКЛ -------------------------------
void buttonsTick() {
btn1_sig = !digitalRead(BTN1);
btn2_sig = !digitalRead(BTN2);
if (btn1_sig && !btn1_flag) {
display_mode++;
reDraw_flag = 1;
if (display_mode > 7) display_mode = 0;
btn1_flag = 1;
}
if (!btn1_sig && btn1_flag) {
btn1_flag = 0;
}
if (btn2_sig && !btn2_flag) {
display_mode--;
reDraw_flag = 1;
if (display_mode < 0) display_mode = 7;
btn2_flag = 1;
}
if (!btn2_sig && btn2_flag) {
btn2_flag = 0;
}
}
void parsing() {
while (Serial.available() > 0) {
char aChar = Serial.read();
if (aChar != 'E') {
inData[index] = aChar;
index++;
inData[index] = '\0';
} else {
char *p = inData;
char *str;
index = 0;
String value = "";
while ((str = strtok_r(p, ";", &p)) != NULL) {
string_convert = str;
PCdata[index] = string_convert.toInt();
index++;
}
index = 0;
updateDisplay_flag = 1;
}
timeout = millis();
timeOut_flag = 1;
}
}
void updatePlot() {
if ((millis() - plot_timer) > (PCdata[17] * 1000)) {
for (int i = 0; i < 6; i++) { // для каждой строки параметров
for (int j = 0; j < 15; j++) { // каждый столбец параметров (кроме последнего)
PLOTmem[i][j] = PLOTmem[i][j + 1]; // сдвинуть весь массив на шаг ВЛЕВО
}
}
for (int i = 0; i < 6; i++) {
// запомнить общее число полосок графика в ПОСЛЕДНИЙ элемент массива
PLOTmem[i][15] = ceil(PCdata[plotLines[i]] / 3);
}
plot_timer = millis();
}
}
void updateDisplay() {
if (updateDisplay_flag) {
if (reDraw_flag) {
lcd.clear();
switch (display_mode) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5: draw_plot_symb();
break;
case 6: draw_labels_1();
break;
case 7: draw_labels_2();
break;
}
reDraw_flag = 0;
}
switch (display_mode) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5: draw_plot();
break;
case 6: draw_stats_1();
break;
case 7: draw_stats_2();
break;
}
updateDisplay_flag = 0;
}
}
void draw_stats_1() {
lcd.setCursor(4, 0); lcd.print(PCdata[0]); lcd.write(223);
lcd.setCursor(17, 0); lcd.print(PCdata[4]);
if (PCdata[4] < 10) perc = "% ";
else if (PCdata[4] < 100) perc = "%";
else perc = ""; lcd.print(perc);
lcd.setCursor(4, 1); lcd.print(PCdata[1]); lcd.write(223);
lcd.setCursor(17, 1); lcd.print(PCdata[5]);
if (PCdata[5] < 10) perc = "% ";
else if (PCdata[5] < 100) perc = "%";
else perc = ""; lcd.print(perc);
lcd.setCursor(17, 2); lcd.print(PCdata[7]);
if (PCdata[7] < 10) perc = "% ";
else if (PCdata[7] < 100) perc = "%";
else perc = ""; lcd.print(perc);
lcd.setCursor(17, 3); lcd.print(PCdata[6]);
if (PCdata[6] < 10) perc = "% ";
else if (PCdata[6] < 100) perc = "%";
else perc = ""; lcd.print(perc);
for (int i = 0; i < 4; i++) {
byte line = ceil(PCdata[lines[i]] / 10);
lcd.setCursor(7, i);
if (line == 0) lcd.printByte(1)
else lcd.printByte(4);
for (int n = 1; n < 9; n++) {
if (n < line) lcd.printByte(4);
if (n >= line) lcd.printByte(2);
}
if (line == 10) lcd.printByte(4)
else lcd.printByte(3);
}
}
void draw_stats_2() {
lcd.setCursor(4, 0); lcd.print(PCdata[2]); lcd.write(223);
lcd.setCursor(17, 0); lcd.print(PCdata[3]); lcd.write(223);
}
void draw_labels_1() {
lcd.createChar(1, left_empty);
lcd.createChar(2, center_empty);
lcd.createChar(3, right_empty);
lcd.createChar(4, row8);
lcd.setCursor(0, 0);
lcd.print("CPU:");
lcd.setCursor(0, 1);
lcd.print("GPU:");
lcd.setCursor(0, 2);
lcd.print("GPUmem:");
lcd.setCursor(0, 3);
lcd.print("RAMuse:");
}
void draw_labels_2() {
lcd.createChar(1, left_empty);
lcd.createChar(2, center_empty);
lcd.createChar(3, right_empty);
lcd.createChar(4, row8);
lcd.setCursor(0, 0);
lcd.print("MOM:");
lcd.setCursor(9, 0);
lcd.print("HDDmax:");
}
void draw_legend() {
byte data = PCdata[plotLines[display_mode]];
lcd.setCursor(16, 2); lcd.print(data);
if (display_mode > 1) {
if (data < 10) perc = "% ";
else if (data < 100) perc = "%";
else {
perc = "";
}
lcd.print(perc);
} else {
if (data < 10) {
lcd.write(223);
lcd.print(" ");
} else if (data < 100) {
lcd.write(223); lcd.print(" ");
} else {
lcd.write(223);
}
}
}
void draw_plot() {
draw_legend();
for (byte i = 0; i < 16; i++) { // каждый столбец параметров
blocks = floor(PLOTmem[display_mode][i] / 8); // найти количество целых блоков
halfs = PLOTmem[display_mode][i] - blocks * 8; // найти число оставшихся полосок
for (byte n = 0; n < 4; n++) {
if (n < blocks) {
lcd.setCursor(i, (3 - n));
lcd.printByte(0);
}
if (n >= blocks) {
if (n != 3) {
lcd.setCursor(i, (3 - n));
if (halfs > 0) lcd.printByte(halfs);
for (byte k = n + 1; k < 4; k++) {
lcd.setCursor(i, (3 - k));
lcd.print(" ");
}
break;
}
}
}
}
}
void draw_plot_symb() {
lcd.createChar(0, row8);
lcd.createChar(1, row1);
lcd.createChar(2, row2);
lcd.createChar(3, row3);
lcd.createChar(4, row4);
lcd.createChar(5, row5);
lcd.createChar(6, row6);
lcd.createChar(7, row7);
lcd.setCursor(16, 0);
lcd.print(plotNames0[display_mode]);
lcd.setCursor(16, 1);
lcd.print(plotNames1[display_mode]);
}
void timeoutTick() {
if ((millis() - timeout > 5000) && timeOut_flag) {
lcd.clear();
lcd.setCursor(5, 1);
lcd.print("CONNECTION");
lcd.setCursor(8, 2);
lcd.print("FAIL");
timeOut_flag = 0;
reDraw_flag = 1;
}
}