Skip to content

Instantly share code, notes, and snippets.

@1271
Last active January 23, 2018 12:32
Show Gist options
  • Save 1271/ae3838b4e9382713992bab8ab5af5775 to your computer and use it in GitHub Desktop.
Save 1271/ae3838b4e9382713992bab8ab5af5775 to your computer and use it in GitHub Desktop.
PCdisplay_v_1.3_1602
#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;
}
}
#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;
}
}
@MisTERR0000
Copy link

Доработал 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;
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment