Introduction: Raspberry Pi CPU Load Indicator

When running Raspberry Pi (RPI) as headless without console monitor, no specific visual indications are available to recognize the RPI is actually doing something.

Even though remote terminal is used with SSH, time to time execution of Linux command is required to check how much system load is burdening CPU now

So this circuit is made to help immediately recognizing the real activity of CPU (maybe semi-real or near real manner) to execute currently applied system loads.

Although only python programming and much simpler circuit can support the same functionality, a little bit complex python codes will be required to simulate the sophisticate LED control logic required by this circuit.

Also paradoxically increased complexity of python code will burden CPU more with increased system load.

Therefore, off-loading any indication functionality as much as possible to external hardware circuit will be reasonable as this service should be running all time and frequently such as per each 5 seconds.

And this circuit will add a little bit funny feature to headless running RPI.

Step 1: CPU Load Checking Linux Command

There are diverse CPU load checking Linux commands are available such as top, iostat, sysstat, and uptime.

Each command has specific advantageous features in terms of information diversity and displaying data simplicity.

Top command is the most information rich and very detail data is available for immediately recognizing system load.

But it operating as iteration mode (displaying data continuously on screen) and information format is quite complex to extract only required CPU load data simply.

The iostat command provide in-depth system load information by separating user and system running queue jobs which are burdening CPU currently.

But it also unnecessarily complex to get current CPU load as prompt and intuitive manner.

In case of uptime, very simple system load data are available in term of 1 minute average, 5 minutes average and 15 minutes summarized average.

As mentioned above, simplifying python code is necessary because it should be executed quite often such as per each 5 seconds or 10 seconds.

When python code become complex, it will burden CPU much.

It’s kind of paradox that you burdening RPI to monitor its system load.

Therefore, I’m choosing uptime command to gather CPU load and interoperating with indicator circuit because it is the simplest.

But as uptime shows 1 minute average of system load, indicator circuit shall be operated not as strictly real time mode.

Still this circuit can provide helpful visual hint which shows how RPI is doing now.

Step 2: Schematics

This circuit will receive 4 different levels (e.g. 00->LOW, 01->LIGHT, 10->MEDIUM, 11->HIGH) of current CPU load from RPI via two opto-coupler inputs.

74LS139 (2 to 4 decoder and de-multiplexer) is decoding two bit inputs into one of single output among 4 possible ways such as 00(LOW)->B0, 01(LIGHT)->B1, 10(MEDIUM)->B2, 11(HIGH)->B3.

As 74LS139 output is reverse level (00 input -> B0 become LOW and other 3 output HIGH), 74HC04 inverter is used to make output reverse one more time.

When output of 74LS139 is normal HIGH, 74HC04 will not necessary.

But somehow 74LS139 is made like that way. (Please check truth table of 74LS139)

When any of 74LS139 output is selected, it will activate one certain analog switch among 4 switches included in CD4066 IC.

CD4066 can support 4 analog switches and each switch consists with 1 control input and 2 analog outputs.

When control input become HIGH, two outputs connection become low impedance (Resistance become 0) and others become HIGH impedance (Resistance between two output path become several hundreds mega ohm) level.

Simply control 1 (pin 13) of CD4066 become HIGH, path between output 1 (pin 1) and output 2 (pin 2) connected meanwhile other outputs are not connected (in high impedance state).

Likewise HIGH input of control 2 (pin 5) make output 1 (pin 4) and output 2 (pin 3) connected while other outputs are disconnected.

Then LM555 is blinking two LEDs in different blinking rate.

As you can see in the schematic above, NE555 will operate with one of resistance value among 4 (12k, 24k, 51k, 100k) possible resistance levels.

Step 3: NE555 Different Clock Generation

As shown in the schematic, NE555 will operate one of possible resistance value such as 12k, 24l, 51k and 100k.

Actually NE555 timing circuit portion is major visual indication supporting part of the circuit.

Circuit operation scheme is like follows.

- When there is no significant CPU load, python program installed in RPI will send 00 outputs to indicator circuit. Then two outputs path of CD4066 is activating and NE555 is operating with 12k resistor value. Therefore, LEDs blinking 1.5 times per second (blinking quite rapidly)

- CPU is lightly loaded (Then uptime queue length become 0.1 ~ 0.9 level), python will send 01 to circuit. Then CD4066 activated with outputs connected with 24k resistor. As a result, LED blinking decreased 1.2 times per second (LED blinking slightly decreased but still a little bit fast)

- When CPU load increased significantly (Then uptime run-queue length become 1.0 ~ 1.9 level), python will output 10 to circuit. Then 51k resistor connection path is opened and NE555 is operating 0.8 times per second. Now blinking rate becomes significantly reduced.

- Heavy loads burdening CPU and uptime run-queue length become longer (more than 2 jobs will wait to be executed by CPU and uptime will report more than 2.0). As 100k resistor connection is selected, NE555 will blink LED 0.5 times per second (Blink speed become very slow)

***

Along with increased system loads, LED blinking speed will be reduced accordingly.

When LED blinks quite slow, then RPI surely overloaded significantly.

This way is the load indication circuit report you current load level of RPI.

Step 4: Parts

For making this circuit, various IC chips are utilized.

Although I’m mentioning 74LSxx, CD40xx type of old IC chips, you can utilize recent types of TTL and CMOS chips such as 74HC4066, and 74ASxx when selected IC chip is DIP type.

Surface mount type of tiny IC package also can be used when you can solder the small ones properly on the universal PCB.

Others are common parts you can easily buying from internet e-stores.

- 74LS139 (2 to 4 decoder, de-multiplexer) x 1

- 74HC04 (6 inverter) x 1

- CD4066 (4 analog switches IC) x 1

- NE555 Timer IC x 1

- Capacitors: 10uF x 1, 0.1uF x 1

- PC817 opto-coupler x 2 (Any common 4 pin opto-coupler can be used)

- Resistors: 220ohm x 4 (LED current limiting), 4.7K (Opto-coupler interface) x 2, 12K,/24K/51K/100K (Clock timing control) x 1

- LED x 2 (Any different colors such as Yellow, Green or Red, Green)

- Universal board 30(W) by 20(H) holes size (You can cut any size of universal board to fit this circuit)

- Tin wire (For making wiring patterns on the universal PCB)

- pin head (3 pins) x 3

- IC pin head (4 pins) x 4

- red/blue color wiring cables

***

Step 5: Making PCB Drawing

Although I’m showing PCB drawing in each project, the wiring design is just reference which will guide you correct soldering each part on universal PCB.

But you are not necessarily stick on this wiring scheme.

As you can see the wiring diagram above, it is quite complex and requires significantly large PCB.

You can use common cable to connect parts instead of tin wire to reduce size of soldering completed PCB.

Only utilize the PCB drawing for checking and confirming the correct soldering between parts.

When number of TTL or CMOS ICs are increased, usually PCB drawing become quite complex beyond proper integration on single side of PCB.

Therefore, multi-layer of PCB is commonly utilized for industrial grade of digital circuits which including a lot of TTL, CMOS and micro-processor.

Step 6: Soldering

I’m using tin wire and common wiring cable together to minimizing PCB size as much as possible.

When comparing with PCB drawing, location of each part is completely changed.

But still PCB drawing is utilized to verify correct connection between parts while soldering.

You can see 12k/24k/51k/100k resistors are inserted on the IC pin head without soldering.

Therefore, you can replace resistors to other values for conveniently changing circuit operational scheme later.

Step 7: Assembling

Completed load indicator circuit (Hereinafter as INDICATOR) is installed to the music player RPI box as shown in the picture above.

This music player is installed with DAC and I’m using this one recently for playing music video.

About this RPI box, I’ll explain later and now let’s focus on INDICATOR as the circuit is main subject of this project.

I bought Raspberry Pi 4 Model B 2GB (Hereinafter RPI 4B) recently to support video playing application.

As RPI 4B has increased performance of 4 cores CPU, system loads handling is enhanced quite significantly from RPI 3B+.

Therefore uptime run-queue length output should be treated differently from RPI 3B+.

- For the very conventional system load such as playing video, run-queue length usually less than 0.5 (So the LOW system load will be 0.0 ~ 0.5 level)

- When slight additional system load is added such as playing video and copying files from and to local directory kind of works result in slight burden on CPU. (So the LIGHT load level will be 0.5 ~ 1.0)

- When significant loads are applied such as playing video on browser at Youtube site and web surfing on another browser, running speed of RPI 4 become slightly sluggish (So the MEDIUM load level shall be 1.0 ~ 2.0)

- Finally RPI 4 system load become HIGH when running multiple web browsers and copying large volume of files to another RPI server through network (Then run-queue length become more than 2.0)

***

This load level data will be utilized by shall be developed python code in the next step.

Step 8: Revising Original Circuit

Due to several defects of original circuit design, I’m modifying the circuit as shown in the picture above.

The reasons for changing are as follows.

- NE555 clock pulse is consists with HIGH and LOW waveform. But usually HIGH and LOW signal duration (t=1/f) is not same (for example HIGH is 70% and LOW is 30% in original circuit). Therefore, blinking rate of two LEDs (Green/Yellow LED in original design) is not same (One LED turn on longer than other). By this reason, visual indication by LED blinking is not much easily recognizable.`

- Therefore, I’m adding more LEDs and making circular iteration pattern with CD4017 for ensuring easy recognition of operational state

- Also changing LED blinking scheme reversely such as slow blinking at LOW load and faster blinking with HIGH load. (Original circuit is made to blink faster in LOW load and slow blinking at HIGH load). In the HIGH load situation, any RPI actions become sluggish. And showing slow LED blinking will not make you happy. (In the psychological aspect, I’m choosing more positive display scheme)

***

Although LED display part is significantly modified, overall change level with the original circuit is not much as you can see in the next step.

Step 9: Original Schematic Change

Addition of CD4017 and 8 LEDs are major modification.

Also to change NE555 clocking frequency and reverse LED blinking scheme, resistors values are changed as shown in the schematics above.

As added circuit portion is simple CD4017 based chaser circuit, I’ll skip other detail explanations of the modified circuit.

All changed circuit portion can be made as daughter PCB board to which CD4017 and 8 LEDs are soldered.

The daughter board can be attached to main-board (mother board) as shown picture in step 8.

Step 10: Testing

Testing video of all operational stages (LOW, LIGHT, MEDIUM and HIGH load state) are shown by the file stored in the google drive below.

***

<Video Link>

https://drive.google.com/file/d/1CNScV2nlqtuH_CYSW...

***

According to the current system load, blinking rate will be changed among one of 4 states shown in the video.

Step 11: Python Code

As the most of controlling logics are included to external hardware circuit, operational logic of python code is relatively simple including the following steps.

- Getting CPU temperature data to compare relativity between system load and raising of temperature

- Gathering 1 minute average system load from uptime output

- Making time stamp like yy-mm-dd hh:mm:ss format

- Writing temperature, system load along with time-stamp

- According to the current system load output data (00, 01, 10, 11) to INDICATOR circuit

- Sleep 5 second before starting steps mentioned above

As python program need strict indentation within source code, please download source file from google drive by following the link below.

***

<Python code download link>

https://drive.google.com/file/d/1BdaRVXyFmQrRHkxY8...

***

As I’m not using RPI as desktop computer, running Libre office applications or web browser is very rare.

Usually I’m playing music video, file copy/moving or python programming with newly purchased RPI 4B 2GB.

Therefore, average load is usually less than 1.0 in my case and accordingly I’m changing LOW/LIGHT/MEDIUM/HIGH levels in my code. (You can change test conditions otherwise)

But when you’re commonly viewing Youtube videos with RPI, more than 2.0 of system loads will be commonly happen.

Step 12: Relativity Between System Load and CPU Temperature

Usually I’m guessing and certain that increasing system load will raise CPU temperature.

But until now I don’t have clear image of the mutual inter-operation between them.

As you can see in the graph above, they are very strong co-relation as follows.

- For easy comparison, I’m multiply 10 to average system load. Otherwise scale of system load is very small (0.0 ~ 2.0), direct comparison become difficult.

- As cooling FAN circuit is installed to the music playing Pi box, CPU temperature never exceeding more than 50C

- When system load is within range of 0.0 ~ 1.0, temperature within range of 45 ~ 48C (CPU metal cover is slightly warming up)

- But heavy load is applied (Usually web browser and playing Youtube videos), load soaring and so the temperature

***

As RPI 4B is installed with 4 core CPU, theoretically performance will not much be degraded up to load level (uptime running queue) 4.

But still less than average load level 4, appropriate temperature control will be necessary.

Step 13: Finalization

I’m finishing this project by installing INDICATOR to Pi box like picture above.

During the casual use of this Pi box, INDICATOR rarely shows HIGH level and dynamic LED blinking.

Usually it remained in slow blinking LEDs states (so LOW or LIGHT level).

Anyway added visual indicator make a little bit funny at least it shows RPI doing something right now.

Thank you for reading this story…..