Introduction: System Monitor With Arduino and 7 Segment Display

Recently I got a new computer and started playing video games. I like to monitor my system while having the games full-screen : I want to see my GPU temperature and my amount of used RAM (Minecraft FTB eats a lot of, like 3-6 GB!).

I had a salvaged 7-segment 3-digit display that I already used to display the music playing on a Raspberry Pi.

How does it work ? - Computer side

My PC runs Linux Mint, so I can use the power of the UNIX command-line and scripting ability

This could run on Macs with very few modification - at least for the RAM monitor

I have a script started on login that parses information from the Nvidia drivers and from a linux utility for RAM usage.

How does it work ? - Arduino side

The computer send a string to the Arduino via the serial connection (included in the USB port of the Arduino). The Arduino reads it and converts it into electricity in the LEDs of the display.

I used a well-made library that sits in the Arduino and runs the 7-segment display.

The Arduino is set up so that it displays whatever you send on its serial port. That means you can type with your keyboard and display the text on the Arduino (funny but useless, and it doesn't look very good)

Step 1: Requirements

For this project you will need

  • the Arduino software configured correctly
  • an Arduino/Genuino board (My Arduino Uno Rev.3 worked fine)
  • a 7-segment display that you bough/salvaged or made yourself
  • if you salvaged your display, you'll need patience and precision !
  • a UNIX-based OS that recognizes your Arduino (FreeBSD could work then)

This could work on Windows with Processing, but you need a way to get the system informations you want to display. With Windows, only the Arduino part is working (meaning that you can write on your little display with your keyboard, just open the Serial Monitor)

Step 2: 7-segment Display

There are 2 main cases : you bought a 7segment display and so you know its pinout and characteristics, oryou salvaged it from unused/broken electronics - like me !

What we will need to know is if the display is common cathode or common anode.

Common anode means that the positive terminal is the digit one, so the negative terminals are the segments.

How does a 7-segment display works ?

Every segment - a LED - is wired to a digit pin (in case your display can multiple numbers) and a segment pin.

But there are only 7 or 8 segment pins (the last one is for the decimal point, DP) : they are name A,B,C,D,E,F,G,DP.

There is also (usually) one pin per digit - that's the common one (cathode or anode).

Take a look at this PDF - the guide included in the library.

By a combination of a digit pin and a segment pin, you can light a segment. The controller switches very fast between pins so that you see multiple segments at a time. That's the refresh frequency.

If you salvaged your display, what you will need is :

  • a low-voltage battery
  • jumper wires, with eventually a resistor attached to it

Now, you will need to test in order to get the digit pins and the segment pins : touch the display connectors with the wires of your battery until you got every segment to light. And don't forget to note what you found !

The first step is to find the common pin with 2 or more segment pins, and by reversing the wires you can deduce the display type. Then test all the pins. Good luck !

If you display has more than 1 digit, all its segment will already be wired together (A with A, B with B ...). They are multiplexed, like on the picture above


Wiring the Arduino

That is now the simple part. Just wire the pins to any digital or analog port (I only used digital but analog should work) and note down the wiring (ex : segment A on pin 13, digit 2 on pin A1 ...).

There is no need for any order, you can plug an anode next to a cathode, everything will be configured by the Arduino sketch.

The picture show how to wire : all segment pins (A with A, B with B..) on one pin; and the digit on a separate pin for each display/digit. You can have multiple displays, but they need to be of the same type if you want to wire their pins together.

Step 3: Programming

I used this library, which provides a very easy way to control our 7-segment display : it supports decimal point, letters (that doesn't look great on such a little screen)

There is even a PDF describing how to do it !

This sketch uses Interrupts so the Arduino can wait for Serial and use the display. Without that, the display would instantly turn back to black after displaying something.

If your display is Common Cathode, you need to replace disp.setCommonAnode(); with disp.setCommonCathode();

#include <sevenseg.h>
SevenSeg disp(12,8,4,6,7,11,3); // here you put the pins that are connected to the segments
// in alphabetical order : A,B,C,D,E,F,G
const int numOfDigits=3;
int digitPins[numOfDigits]={13,10,9};
String inputString = "";
boolean stringComplete = false
void setup() {
  disp.setDigitPins(numOfDigits,digitPins);
  disp.setDPPin(5); // set the pin for the Decimal Point, if you have one
  disp.setCommonAnode(); // REPLACE THIS WITH disp.setCommonCathode(); IF YOUR DISPLAY IS COMMON CATHODE
  disp.setTimer(2);
  disp.startTimer();
  Serial.begin(9600);
}
void loop() {
  if (stringComplete) {
   Serial.println(inputString);
    disp.write(inputString);
    inputString = "";
    // clear the string:
    stringComplete = false;
  }
}
void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read(); 
    // add it to the inputString:
    if(inChar != '\n') {
      inputString += inChar;
    }
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    else {
      stringComplete = true;
    } 
  }
}

ISR(TIMER2_COMPA_vect) {
    disp.interruptAction(); //attaches the timer to the interrupt
}

Step 4: Computer Scripting

To feed the Arduino with the informations we want to display on its new shiny screen, I used a few commands managed by a little script.

#!/bin/bash<br>if [ -e "/dev/ttyACM0" ]
then
    stty -F /dev/ttyACM0 10:0:8bd:0:3:1c:7f:15:4:0:0:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
    while [ 1 > 0 ]
    do
        if [ -e "/dev/ttyACM0" ]
        then
            free -h|head -n 3|tail -n 1|awk '{print $3}'|awk -F, '{print $1"."$2}' > /dev/ttyACM0
        fi
        sleep 1
        if [ -e "/dev/ttyACM0" ]
        then
            echo "$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader)C" > /dev/ttyACM0
        fi
        sleep 1
    done
fi

The script begins by checking if the Arduino is connected, and then configures its serial port. After that, it sends a formatted RAM usage and GPU temperature to the Arduino. If you do not have an Nvidia GPU with the Nvidia drivers installed, you can remove the corresponding part.

You can also put your own commands, but don't forget to add a "sleep " after, or the next command will be instantly executed and you won't have enough time to look at your display !

Step 5: Computer Setup

Fortunately, working with Serial is very easy on Linux !

Open a Terminal (on GNOME it's CTRL+ALT+T)

You should be able to write on your Arduino via the command-line

echo "123" > /dev/ttyACM0

replace "ttyACM0" with the port you use.

In order to use the script made in the last step, open a terminal in the directory of your script and make it executable

chmod +x file_name

Now you can go into your Computer Setup application and add this script to the list of auto-start programms (put in the field "command" the path of the script and its name.

Once you got there, the possibilities are endless ! You can monitor what you want.

Feel free to suggest improvement, typos and what you didn't understood in the comments !