Отображение температуры процессора ПК с помошью аналоговых стрелочных приборов

Вот наткнулся на эту тему и за выходной с помощью работ Alex Gyver
исходники ino и программа MADS = MSI Afterburner Data Server с хорошей документацией

Я вывел показания стрелкой на серво SG90

любого параметра который видит MSI Afterburner
далее в MADS указываешь ком порт(своей ардуинки), скорость, send mode=stream,
на каждый параметр свой префикс a b с .
проще всего менять загрузку CPU используя кнопку stress программы CPU-Z

при работе в IDE Arduino останавливайте в MADS serial server

серво нельзя питать от USB компа и нужен для этого отдельный USB зарядник
на момент написания используется 1602 чтобы отслеживать ошибки (потом закомментить все команды lcd)

// project Alex Gyver
// edit LLK44
//Парсинг разных пакетов по ключевым "префиксам", чуть более оптимальный вариант без использования строк
#define TIMEOUT 100  // таймаут в миллисекундах на отработку неправильно посланных данных
int a, b, c, cc;
int intValue;
char header;
boolean recievedFlag, startParse;
unsigned long parseTime;
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
// scl =A4 sda =A5
#include <Servo.h>
Servo myservo;

void setup(void) {
  Serial.begin(115200);
  myservo.attach(9); // желтый провод от серво на пин D9
  myservo.write(180);
  lcd.init();  // initialize the lcd
  lcd.print("AlexGyver");
  lcd.setCursor(10, 0);
  lcd.print("LLK44");
  lcd.setCursor(3, 1);
  lcd.print("02/06/2025");
  delay(5000);
  lcd.clear();
}

void parsing() {
  if (Serial.available() > 0) {     // если есть что то на вход
    char thisChar = Serial.read();  // принимаем байт
    if (startParse) {               // если парсим
      if (!isDigit(thisChar)) {     // если приходит НЕ ЦИФРА
        switch (header) {           // раскидываем по переменным
          case 'a':                 // если заголовок а
            a = intValue;
            break;
          case 'b':  // если заголовок b, и так далее
            b = intValue;
            break;
          case 'c':
            c = intValue;
            break;
        }
        recievedFlag = true;                          // данные приняты
        startParse = false;                           // парсинг завершён
      } else {                                        // если принятый байт всё таки цифра
        intValue = intValue * 10 + (thisChar - '0');  // с каждым принятым число растёт слева направо
      }
    }
    if (isAlpha(thisChar) && !startParse) {  // если префикс БУКВА и парсинг не идёт
      header = thisChar;                     // запоминаем префикс
      intValue = 0;                          // обнуляем
      startParse = true;                     // флаг на парсинг
      parseTime = millis();                  // запоминаем таймер
    }
  }
  if (startParse && (millis() - parseTime > TIMEOUT)) {
    startParse = false;  // парсинг завершён по причине таймаута
  }
}

void loop() {
  parsing();
  if (recievedFlag) {
    // выводим для отладки на lcd1602
    lcd.setCursor(0, 0);
    lcd.print(a);
    lcd.print(" ");
    lcd.print(b);
    lcd.print(" ");
    lcd.print(c);
    lcd.print(" ");
    cc = c * 180 / 100;// угол поворота стрелки
    myservo.write(180 - cc);
    recievedFlag = false;
  }
}