Главная » Компьютерная электроника
Призовой фонд
на июль 2019 г.
1. 1000 руб
Паяльник
2. Регулируемый паяльник 60 Вт
Паяльник
3. 100 руб.
От пользователей

LED индикатор загруженности ЦП

Схем различных индикаторов, отображающих загруженность ЦП и памяти достаточно много. Но в основном они отображают информацию с помощью LCD дисплея, который или слишком мал, или размеры нормальные, но дорогой. Именно по этой причине я решил собрать индикатор загруженности ЦП на светодиодах.

Эта статья является логическим продолжением для применения кода, описанного в третьем видеоуроке о mikroPascal.

Исходя из того, что у меня нет лазерного принтера (ЛУТ отпадает), двухъядерный процессор и один светодиод стоит примерно 0.8 гривны, было решено делать 3 строки светодиодов по 10  штук в каждой. Две - под индикацию загрузки процессора, и оставшаяся под память или третье ядро (не сталкивался, но слышал).

Основная информация об устройстве:

  1. Напряжение питания: 5 V
  2. Потребляемый ток: < 50 mA 
  3. Частота обновления данных: 0,5

Теперь можно перейти к схеме. 

Как видите, она достаточно простая. Основа схемы - микроконтроллер ATmega8 (в корпусе DIP-28). Общее количество деталей - 40 шт., из них : светодиодов - 31, транзисторов - 5, остальное микроконтроллер и обвязка генератора.

Не столько для экономии выводов, сколько для удобства обращения к портам я использовал такое включение светодиодов для динамической индикации:

Рис.2 (схема включения светодиодов).

Таким способом мне удалось "уложиться" в два порта МК (PORTB - 6 пин, PORTC - 5 пин). Можно было конечно использовать сдвиговые регистры, но это повлекло бы за собой усложнение программы, а так же занятое место на плате. По-этому решил обойтись без них. 

На схеме нет токоограничительных резисторов (применительно к светодиодам), так как они работают в импульсном режиме. Я использовал светодиоды красного, желтого и белого цветов. Красный и желтый - ЦП, белый же для дополнительной строки.

После всех манипуляций со схемой, взялся за разводку печатной платы. Вот тут то и был зарыт кирпич....Если схема была набросана минут за 5 то с платой пришлось возитсья около получаса. В итоге она получилась двухсторонней. 

Как видите, разводка платы не самая простая. В этом виновата прежде всего динамическая индикация. Из-за нее пришлось часть проводников перенести на обратную сторону платы, а так же использовать большое количество переходных отверстий (в основном  для подключения светодиодов). Но, тем не менее эту плату возможно сделать и без ЛУТа. И последнее относительно платы - я использовал текстолит толщиной 0,5 мм, так как другого с двухсторонним покрытием в наличии не оказалось.

Рассмотрев аппаратную часть можно перейти к программной.

Программу для МК я как всегда писал в среде mikroPascal for AVR (v 6.01). Так как в микропаскале нет библиотеки для микроконтроллера Atmega8, которая позволяет работать с USB, то выбор пал на UART. Но так как последний видеоурок по mikroPascal был про прерывания, то решил и сюда их всунуть. И вот что в итоге получилось:

program iCPU_t;

uses AADL;

var dat:array [0..2] of byte;
    rec,i,c,enbl:byte;
    rcit,rci,ti:integer;

    
const pc: array [0..10] of byte = (31,30,28,24,16,0,30,28,24,16,0);             //Объявляем константы
const pb0: array [0..10] of byte = (0,254,254,254,254,254,253,253,253,253,253); //Они будут использоваться, как вы уже поняли из
const pb1: array [0..10] of byte = (0,251,251,251,251,251,247,247,247,247,247); //из названий, для отправки заданных значений
const pb2: array [0..10] of byte = (0,239,239,239,239,239,223,223,223,223,223); //в порт.



procedure usart_c(); iv IVT_ADDR_USART__RXC;                                    //Функция, которая вызывается по прерыванию UART
begin                                                                           //(если в буфере приема есть данные).
     rec:=UART_Read();                                                          //
     if rec=47 then enbl:=1;                                                    //Тут мы ищем нужные нам символы, и сразу их
     if enbl=1 then inc(enbl) else                                              //переводим.
     if enbl=2 then begin                                                       //
     case rec of                                                                //
     48: rec:=0;
     49: rec:=1;
     50: rec:=2;
     51: rec:=3;
     52: rec:=4;
     53: rec:=5;
     54: rec:=6;
     55: rec:=7;
     56: rec:=8;
     57: rec:=9;
     end;
     ti:=rec;
     inc(i);
     case i of
     1: rci:=ti*10;
     2: rci:=rci+(ti);
     end;
     if i>=2 then begin i:=0; enbl:=0; end;
     end;
end;


begin
Uart1_init(9600);                                                               //Инициализация UART

UCSRB.B7:=1;                                                                    //Прерывание по приему данных UART
SREG_I_bit:=1;                                                                  //Разрешаем прерывания


DDRC:=0xFF;
DDRB:=0xFF;
DDD7_bit:=1;

PORTD7_bit:=0;

for c:=0 to 2 do dat[c]:=0;

While TRUE do begin
        rcit:=rci;
        if (rcit>30) and (rcit<40) then dat[2]:=rcit-30;                        //Присваиваем значение различным
        if (rcit>20) and (rcit<30) then dat[1]:=rcit-20;                        //элементам массива dat, в зависимости от того,
        if (rcit>10) and (rcit<20) then dat[0]:=rcit-10;                        //какому ядру они соответствуют.
             for c:=0 to 2 do begin
                 case c of
                      0: if dat[c]<=5 then begin                                //Дальше обеспечиваем индикацию.
                            PORTC:=pc[dat[c]];
                            PORTB:=pb0[dat[c]];
                            delay_ms(1);
                         end else begin
                             PORTC:=pc[5];
                             PORTB:=pb0[dat[c]-5];
                             delay_ms(1);
                             PORTC:=pc[dat[c]];
                             PORTB:=pb0[dat[c]];
                             delay_ms(1);
                         end;
                      1: if dat[c]<=5 then begin
                            PORTC:=pc[dat[c]];
                            PORTB:=pb1[dat[c]];
                            delay_ms(1);
                         end else begin
                             PORTC:=pc[5];
                             PORTB:=pb1[dat[c]-5];
                             delay_ms(1);
                             PORTC:=pc[dat[c]];
                             PORTB:=pb1[dat[c]];
                             delay_ms(1);
                         end;
                      2: if dat[c]<=5 then begin
                            PORTC:=pc[dat[c]];
                            PORTB:=pb2[dat[c]];
                            delay_ms(1);
                         end else begin
                             PORTC:=pc[5];
                             PORTB:=pb2[dat[c]-5];
                             delay_ms(1);
                             PORTC:=pc[dat[c]];
                             PORTB:=pb2[dat[c]];
                             delay_ms(1);
                         end;
                 end;
             end;
    end;
end.

В программе тоже ничего сложного нет. Константы в самом начале программы использовались для того, что бы не писать в порт "ручками" каждый раз. В процедуре , вызываемой по прерыванию, используется такой алгоритм:

  1. Анализируем принятые данные, если они соответствуют "/", то разрешаем в следующий раз программе пройти дальше.
  2. Расшифровываем из ANCII кодировки.
  3. Рассчитываем и записываем в переменную

Далее, в основном цикле программы мы сначала сопоставляем, к какому ядру относятся полученные данные, а потом их присваиваем соответствующему элементу массива dat. 

Вот и весь алгоритм программы.

Если вас интересует, как данные отображаются, то все так же просто:

  1. Смотрим, какая строка сейчас должна обновиться.
  2. Выбираем из массива dat нужный элемент.
  3. Если нужно зажечь пять или меньше светодиодов в строке, то просто оправляем значение в порт. Если же больше пяти (число n), то сначала зажигаем первые пять, а потом то что осталось (n-5). Все это крутится в цикле.

Из фузов нужно выставить только внешний кварц (8 MHz).

В Khazama AVR Programmer это выглядит следующим образом:

Рис. 4(фузы).

Вот и все! Но если у вас нет каких-то деталей, но есть их аналоги.... Светодиоды можно взять любые, подходящие по току и размерам. Микроконтроллер заменить нельзя. Только взять такой же но с любым другим индексом (например, вместо ATmega8 - ATmega8L и т.д.). Транзисторы так же можно взять любые маломощные структуры p-n-p. Я использовал КТ361Г (работают нормально, хотя еще 1987 г. выпуска :) ). Резисторы - с разбросом от указанного номинала до +/- 20 %.

И напоследок, о программе для Windows, которая управляет индикацией. Она написана в Delphi xe5 и называется iCPU. 

Рис.5(iCPU).\

Рассчитана на 2 ядра. В настройках выбирается порт, к которому подключено устройство. Возможно использовать как встроенный COM порт (через преобразователь уровней на MAX232), так и через виртуальный COM порт, с использованием переходника на базе PL2303 и подобных. У меня в городе можно купить такой кабель для старых моделей NOKIA.

Рис.6(кабель).

Внутри платка, которая с успехом может использоваться как USB-COM переходник.

Вот несколько фотографий готового устройства.

Обновление от 20.07.2014:
Доработал программу, теперь можно выводить на 3-ю строку загруженность памяти. А так же мелкие исправления.

Обновление от 01.05.2015:

Полностью переписан код как прошивки для МК, так и программы для Windows. Теперь есть отдельная версия для Windows x64.

Для МК прошивка писалась в WinAVR (Cpp).

ВНИМАНИЕ! Старая прошивка + новая версия программы НЕСОВМЕСТИМЫ, как и новая прошивка + старая версия программы.

При прошивке фузы указывать те же, что и для старой версии, за исключением (выставлять как на скрине):

.

Из "нововведений":

  • Возможность применять "выравнивание" (по левому краю, по центру и по правому краю).
  • Автоматическое отключение индикации через 10с (например, если комп погрузили "в сон").
  • Теперь есть "тестовый" режим, в котором включаются все светодиоды (например, при первых включениях уст-ва, для выявления неполадок).
  • Если у вас в системе многоядерный процессор, то будут отображаться только первые 2 ядра (на уст-ве, в программе будет видно загрузку всех ядер). В противном случае, на уст-ве будут активными только 1-я и 3-я строки (1 ядро и память соответственно).

Так же хочу заметить, что перед первым запуском программы, впишите номер ком порта, к которому подключено устройство, в файл "settings.ini". Он лежит в папке с exe-шником. Иначе, скорее всего, будете через каждые 0.5с получать окна с ошибками!

В аппаратную часть устройства никакие правки не вносились.

Немного фотографий:

Обновление от 16.05.2015:

Оптимизирован код. Добавлена возможность регулировки яркости (программный ШИМ на таймере T2). Внесены некоторые правки в программу для Windows (теперь, если COM порт выбран неверно (порта с таким номером в системе нет), не будет +100500 окон с ошибками).

Список радиоэлементов

Обозначение Тип Номинал Количество ПримечаниеМагазинМой блокнот
U1 МК AVR 8-бит
ATmega8
1 DIP-28Поиск в Utsource В блокнот
D1-D30 СветодиодHL-A-3528H308W-S1-1330 Любые светодиоды 0805, подходящие по токуПоиск в Utsource В блокнот
C1, C2 Конденсатор27 пФ2 0805Поиск в Utsource В блокнот
X1 Кварцевый резонатор8 МГц1 НизкопрофильныйПоиск в Utsource В блокнот
R2-R6 Резистор
1 кОм
5 0805Поиск в Utsource В блокнот
R1, R7-R10 Резистор
30 кОм
5 0805Поиск в Utsource В блокнот
Q1-Q4 Транзистор2N37025 Или КТ361Поиск в Utsource В блокнот
Добавить все

Скачать список элементов (PDF)

Прикрепленные файлы:

Теги:

Опубликована: Изменена: 16.05.2015 0 0
Я собрал 0 1
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 4.3 Проголосовало: 1 чел.

Комментарии (8) | Я собрал (0) | Подписаться

0
BARS_ #
Плату поменьше раза в 3 и будет очень даже неплохо
Ответить
0

[Автор]
zeconir #
Да вот, первый опыт так сказать. Раньше как-то не приходилось с таким кол-вом светодиодов маяться.
Ответить
+1
civil #
Интересно.
А исходник на Дельфях покажете? И хорошо бы отрабатывать ситуацию отсутствия ком-портов, а то я программу еле прибил через диспетчер задач.
Ответить
0

[Автор]
zeconir #
Да, скиньте в ЛС почту. А программу я еще допиливать буду (на присутствие портов + индикация загрузки в трее).
Ответить
0
Artos5 #
Рассмешили. Эту ситуацию надо учитывать .. и обрабатывать подобные исключения.
Ответить
0

[Автор]
zeconir #
Изначально, если прочитать статью, то понятно, что на ПК без COM порта (виртуального или физического) устройство по определению работать не будет, соответственно, программа там тоже не нужна.
А если 6 ядер, то будет брать только первые два (или три. В программе правку внести).
Ответить
0
Artos5 #
Уважаемый автор! А если у меня 6 ядер, как устройство будет себя вести?
Ответить
+1
Глеб #
Собрал данное устройство, все работает, спасибо автору.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется сила тока?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

МиниПК MK809V - 4 ядра, Android 4.4.2
МиниПК MK809V - 4 ядра, Android 4.4.2
Печатная плата для усилителя "LM3886 + AD825" Набор начинающего радиолюбителя
вверх