Аналоговый индикатор загруженности компьютера

Встретил я как-то пост от ClusterM где он сделал виджет в виде старых индикаторов. Мне эта идея безумно понравилась так как есть приятное чувство винтажа в этом проекте. Но вот незадача — я никогда не работал с самим микроконтроллером и программирую я так себе, поэтому идею долго откладывал. Но недавно я натолкнулся на видео где Алекс доработал с помощью знакомых Open source программу и разработал алгоритм обработки данных со стороны Ардуино. В этой статье я хочу показать как я реализовал эту задачу.


Этап I. Как я разбирался с кодом монитора загрузки



После скачивания программы мониторинга я подключил ардуино с дисплеем, в которую был зашит код из библиотеки примеров analogRead, он просто выводит все, что получает ардуино по ком порту. Как можно увидеть я получил массив символов, сначала я экспериментальным путем старался понять, но потом плюнул решил поступить профессиональнее и открыл с помощью ридера кода предоставленный исходник. С помощью я нашел часть которая отправляет все данные в виде массива, для своего удобства выписал их на бумажку, так как код дописывал Алекс с его командой я ничего не менял, а просто взял значения загруженности процессора, видеокарты, и RAM, это значения PCdata[4], PCdata[5], PCdata[6]. После этого я смог дальше работать только с Ардуино.


Этап II. Разбираемся с парсингом данных и их обработкой


Честно говоря, я бы не сказал, что я разобрался, в стиле начинающего гика я просто понял, что код, написанный Алексом, нужен мне без доработок, поэтому я добавил его в свой код. Парсинг выглядит так:


  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;
      isDataExist = true;
    }
   }
  }

Для пущей уверенности через команду lcd.Write я поочередно выводил значения PCdata[4], чтобы убедиться, что принимаю те данные, которые мне нужно.


Дальше я занялся переводом данных в процентах в шим сигнал. Зная, что шим сигнал это значения от 0 до 255, а принимаем мы значения от 0 до 100 (это загруженность в процентах) с помощью функции map и ограничение значений с помощью функции constrain, пишу простой код:


  cpu = map(cpu, 0, 100, 0, 255);
  cpu = constrain(cpu, 0, 255);
  analogWrite(9, cpu);

  gpu= PCdata[5];
  gpu = map(gpu, 0, 100, 0, 255);
  gpu = constrain(gpu, 0, 255);
  analogWrite(3, gpu);

  mem= PCdata[6];
  mem = map(mem, 0, 100, 0, 255);
  mem = constrain(mem, 0, 255);
  analogWrite(5, mem);

Этап III. Как подключить 3 индикатора к одной ардуино?


Когда я только начинал — я подключал только один индикатор и так действительно все прекрасно, но как только появляется второй — начинаются проблемы. Ардуино не может "раскачать" два вместе, я подозреваю, что это из-за платы ардуино, там очень много вещей которые жрут потребляют энергию (всякие светодиоды, стабилизаторы, защиты от дураков итд) если использовать как ClusterM саму Атмегу — должно хватить, на два уж точно. Я решал проблему с помощью мосфет транзисторов, у меня был IRF520 на плате-конструктор с АлиЭкспресс, подключил один индикатор через мосфет а второй напрямую в ардуино и все заработало. Так как плата с Али чрезмерно огромна, решил паять сам, разводить плату не хотел совсем, поэтому рисовал маркером по текстолиту.



Вышло компактно, а для меня это главное.


Схема подключения такая же как и у платы с Али, ну почти, я убрал светодиод так-как индикация работы тут не нужна.



Этап IV. Дизайн задников для индикатора


Специально сохранял свой дизайн для публикации, но конечный эскиз я успешно потерял, но остался увеличенный прототип. Позже я понял, что это не большая проблема, так как надо будет подгонять к размером ваших индикаторов, я делал в paint photoshop 2020, поэтому уверен, что доработать сможете и вы.



Мне кажется, что вышло очень интересно, осталось вырезать место для саморезов и стрелочки — готово!




Этап V. Подсветка RGB


Так как я в процессе понял, что мне некуда впихнуть светодиод — в итоге я отказался, но начальный код сделал, он очень простой — справится каждый, просто дописать для всех цветов для трех индикаторов. Проектировал на бредборде — работает как часы:


 void led()
   {
   if (PCdata[4] < 20 ) 
         {
    digitalWrite (6, HIGH);//например, на этом пине висит зеленая нога rgb
         }
  else{
   digitalWrite (6, LOW);
      }
   if (PCdata[4] > 20 && PCdata[4] < 60 );//не забываем, что это значения в 
                                          //процентах а не значения шим
         {
    digitalWrite(5, HIGH);//на этом пине - синяя
         }
    //и так далее для всех светодиодов
  }

Итог
Получился интересный виджет, который полезен при играх, редактировании видео и фото так как можно оценить не перегружен ли компьютер.


Совет — старайтесь не ронять ваши индикаторы, у меня случайно упал с RAM и стрелочка не приходит в состояние ноль, оно чинится но это жуткие костыли.


Целый код для ардуино


//#include <Wire.h>               // библиотека для соединения
//#include <LiquidCrystal.h>

// оставил с момента отладки, может кому надо будет
//LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

char inData[82];       // массив входных значений (СИМВОЛЫ)
int PCdata[20];        // массив численных значений показаний с компьютера
byte index = 0;
String string_convert;
bool isDataExist = false;
int cpu;
int mem;
int gpu;

void setup() {
   Serial.begin(9600);
}

void loop() {
  parsing();
  //led(); для тех кто захочет подключить подсветку 

  cpu = PCdata[4];
  cpu = map(cpu, 0, 100, 0, 255);
  cpu = constrain(cpu, 0, 255);
  analogWrite(9, cpu);

  gpu= PCdata[5];
  gpu = map(gpu, 0, 100, 0, 255);
  gpu = constrain(gpu, 0, 255);
  analogWrite(3, gpu);

  mem= PCdata[6];
  mem = map(mem, 0, 100, 0, 255);
  mem = constrain(mem, 0, 255);
  analogWrite(5, mem);
}

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;
      isDataExist = true;
    }
   }
  }
  /*void led()
   {
   if (PCdata[4] < 20 ) 
         {
    digitalWrite (6, HIGH);//например на этом пине висит зеленая нога rgb
         }
  else{
   digitalWrite (6, LOW);
      }
   if (PCdata[4] > 20 && PCdata[4] < 60 );//не забываем, что это значения в процентах, а не значения шим
         {
    digitalWrite(5, HIGH);//на этом пине - синяя
         }
    //и так далее для всех светодиодов
  }
  */

Программа Мониторинга лежит в архиве у Алекса
Я использовал старую версию, она прекрасно работает, поэтому и вам советую.


Хотел бы выразить благодарности Алексу и его команде за доработку Open Source кода, а также пользователю ClusterM за демонстрацию своего гаджета и моему папе за помощь в дешифровке кода.

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 30

    +2
    Неужели ардуина не тянет 2-3 индикатора на 2-3 вольта?
      0
      Вот после вашего комментария полез искать их потребление. До даташитов не добрался, но если верить
      http://go-radio.ru/strelochniy-voltmetr.html
      Как то странно выглядит решение браться сразу за мосфеты.
        0
        Может я сам испортил что-то, но я проверял и действительно не тянет (УНО точно не тянет)
          0
          Проверьте сопротивление головок.
          У головки без шунта ток полного отклонения до 200 микроАмпер.
          От тока GPIO стрелка должна биться об ограничитель так, что ее деформирует.
            0
            Ардуина Уно тянет в сумме на выходах 40 мА (если не изменяет память), что предостаточно для работы с полсотни вольтметров(если бы хватало выходов).
            Может у вас индикаторы не вольтметры, а амперметры? (какое сопротивление головок показывает тестер?)
            Когда вы подключали напрямую в ардуину, то использовали общий минус или общий плюс? Если общий плюс, то куда его подключали: на входные 5 В или 3.3 В с ардуины?
              0

              Я подключал минус к gnd а плюс к шим выводу Ардуино, сопротивление не замерял, приду домой — замерю

                0
                Может стоит добавить конденсатор параллельно вольтметру? И постараться увеличить частоту ШИМа. Насколько помню, штатно она составляет ~500Гц, что для поставленной задачи может быть маловато.
                Ведь данные вольтметры всё таки ориентированны на аналог, а вы ему скармливаете импульсный сигнал довольно низкой частоты.
                  –1
                  Может не стоит?
                  У головки индуктивное сопротивление, ведь там электромагнит, отклоняющий ротор.
                  И вы лихо предлагает превратить это в параллельный резонансный контур, подключенный напрямую к выходу микроконтроллера.
                  Правильный вариант — резистор+конденсатор, т.е. классический RC-снаббер, с сопротивлением равнім резистивному сопротивлению головки, и емкостью, обратной индуктивности. Ну и резистор между выходом контроллера и головкой не помешает.
                  В зависимости от настроек выхода — открытый выход или обоими активными транзисторами, головку цеплять или на землю, или на плюс питания.

                  Насчет малой частоты — вы видели стрелку, колеблющуюся с частотой 500Гц?
                    0
                    Нужен не снаббер а ФНЧ на RC. Да, это разные схемы.


                      0
                      Сама голова из-за своей механической сути является ФНЧ как минимум первого порядка.
                      Для ШИМа — нужен именно снаббер.
                  0
                  Это не тот уровень абстракции.
                  Например, мосфет с затвором, прилепленным напрямую к выходу мк приведет к ВЧ колебаниям. Ибо у проводов индуктивность, а у транзистора — входная емкость.
                  Туда таки нужен резистор ом на 100, а лучше на Vпитания/Iмаксимальный одного выхода.

                  Так же и с головкой в стоке мосфета. Если частота станет достаточно высокой, то у вас транзистор пробъет выбросом от закрывания при работе на индуктивность.
                  Параллельно обмотке головки явно не помешает диод.

                  Проверьте оммическое сопротивление головки, оно должно быть несколько килоом.
                  Вы сейчас перезаряжая ломовую входную емкость мосфета в ТО-220 тратите больше энергии, чем на отклонение самой стрелки.
            +2
            Получился интересный виджет, который полезен при играх, редактировании видео и фото так как можно оценить не перегружен ли компьютер.


            Я не стебусь, а просто интересуюсь. Ну вот перегружен комп и что дальше?
              0

              Иногда бывает, что какое-то приложение где-то внутри создает поток с бесконечным busy loop, который отъедает 100% CPU. На ноуте это иногда можно заметить без индикатора по постоянно крутящемуся вентилятору.


              Чаще всего это веб-браузер (либо ошибка в коде самого браузера, либо какая-нибудь страница с гигабайтами js-кода, делающего непонятно что 100% времени), либо IDE.

                0
                поток с бесконечным busy loop, который отъедает 100% CPU
                Он отъест не 100% CPU, а загрузит только одно ядро, что будет примерно 25% общей загрузки при 4-ядерном CPU(без HT).
                0
                Ну он ещё может быть и недогружен — и можно запустить ещё одну задачу, например. Ну или выполняется несколько задач и при перегрузке можно одну приостановить. Или видно что память заканчивается и можно выключить одно из приложений. У меня вообще на втором мониторе, когда он свободен, диспетчер задач для этих целей развернут на весь экран — позволяет оптимизировать загрузку ресурсов.

                А тут, конечно, не хватает ещё загрузки сети и нагрузки на жесткие диски по отдельности для полного комплекта, но это уже какая-то приборная панель получается)
                  0
                  Значит, под текущие задачи его уже не хватает. Пора на апгрейд или на новый копить! :)
                    0
                    и для этого одноразового вывода нужно городить панель с индикаторами? о_0
                  +4
                  Аналоговая характеристика «температура» преобразовывается в цифру, отдаётся в другую цифру и преобразовывается обратно в аналог для мониторинга аналоговым индикатором… Киберпанк, который мы заслужили.(с)
                    0
                    Я реализовал только процент загрузки, плюс это виджет только для наглядности, это же не научное оборудование, это как раз таки киберпанк который мы заслужили, как мне кажется
                      +1
                      Я и не критикую :)
                      «Just for fun» неплохо, атмосфера и интерьер очень важны.
                        0
                        Спасибо, просто я хотел разъяснить, так как люблю когда мне разъясняют :)
                    0
                    Взять в руки паяльник и начать что то новое для себя это конечно похвально. Но во всём этом полотне меток актуальна только одна лишь Ардуинка. Вот в каком месте раскрывается суть темы "аналоговые вычисления", затронуты любопытные особенности мосфетов, о которых знает далеко не каждый?
                      0
                      Хмм, его суть была сделать просто виджет а не рассказать о мосфетах, использовал их так как у них удобное напряжение открытия, я не претендую на то что это лучшее решение, но такое я нашел. Я пробовал сделать это на транзисторах BC547 если я не ошибаюсь так они не корректно отображали
                        0
                        Вот и зачем тогда статье выставлять эти метки? Давайте тогда уж засунем туда «резисторы, проводники...» и прочее, что на глаза попало.
                        И что бы донести претензию к оформлению окончательно, переходя по метке этих несчастных аналоговых вычислений, ожидалось увидеть статью уровня
                        https://habr.com/post/132702/
                        , не меньше.
                          0
                          Cпокойствие, скажу честно я не помню чтобы осознано это вставлял, уже убрал
                        +1
                        слово аналоговый я использовал не в том смысле, может плохо выбрал слово(хотел сказать что это реальное приспособление, а не программа), извиняюсь за дезинформацию.
                        0
                        Хотел бы выразить благодарности… моему папе за помощь в дешифровке кода.

                        Папе низкий поклон!

                          0
                          еще есть интересная идея — механический счетчик трафика — взять механизм от счетчика воды, убрать крыльчатку (он отлично располовинивается и вся интересующая часть остается в передней половинке), шаговый двигатель (можно попробовать плоский от жесткого диска) укомплектовываем магнитиком и по «тактам» от чего нибудь, что может получать данные о переданных данных толкаем шаговый двигатель заставляя вращаться циферки )
                            0
                            Вот вы дошутитесь. Будет потом Ростелеком ходить пломбы на интернет-счётчиках проверять!
                              0

                              Я видел схему на электросчетчик старого формата, там есть светодиоды который моргает 1000 рыз за киловатт или как то так, а с водой нужно подумать, но интересно !

                            Only users with full accounts can post comments. Log in, please.