Using an I2C OLED to display Pi-Hole stats

disclaimer #

This is actually a re-write of an older tutorial I posted on github about a year and a half ago with some cleaner code and working pictures (original can be found here)

Final result #

stats

prerequisites #

*other sizes of i2c displays should work but I haven’t tested it

Steps #

  1. Wire up the display like so:

    Layout

  2. Now install the i2c-tools package and run the following command:
    $ sudo apt install i2c-tools
    $ sudo i2cdetect -y 1
    

    This allows us to get the i2c address of the display we just wired up. Once running the command you should see a grid like so:

    i2cdetect

    Copy the address for later, For this example the address was “0x3C”.

  3. Now install the required npm packages:
    $ npm install i2c-bus oled-i2c-bus oled-font-5x7 axios
    

    This will install the i2c-bus, oled-i2c-bus, oled-i2c-bus and axios packages

  4. Now we get to write some code! Create a new file called “oled.js” and add the boilerplate code:
     const i2c = require('i2c-bus'),
           i2cBus = i2c.openSync(1),
           oledBus = require('oled-i2c-bus');
    
     const font = require('oled-font-5x7');
    
     var opts = {
         width: 128,   // width of display
         height: 64,   // height of display
         address: 0x3C // change to what you got in step 2
     };
    
     var oled = new oledBus(i2cBus, opts);
    

    This creates the “oled” object which will allow us to communicate with the display, remember to change the address in “opts” to the one you got in step 2.

    If you are using a different size of display, also change the width and heights to match your display.

    Now to actually display something we’ll add the following:

     oled.turnOnDisplay();
     oled.clearDisplay();
     oled.setCursor(0,0);
     oled.writeString(font, 2, "Hello world!", 1, false);
    
  5. Now to check if the display works!

    Save the code and run the following:

    $ sudo node oled.js
    

    Sudo is needed in order to access the IO pins on the pi. You should now see “Hello world!” on the screen:

    helloworld

    Very nice.

  6. Now to display some Pi-Hole stats!

    To do this replace the code we just wrote with the following:

     const i2c = require('i2c-bus'),
         i2cBus = i2c.openSync(1),
         oledBus = require('oled-i2c-bus');
    
     const font = require('oled-font-5x7'),
         axios = require("axios");
    
     var opts = {
         width: 128,   // width of display
         height: 64,   // height of display
         address: 0x3C // change to what you got in step 2
     };
    
     const api_url = 'http://localhost/admin/api.php';
    
     var oled = new oledBus(i2cBus, opts);
    
     async function updateOLED() {
    
         try {
             var res = await axios.get(api_url);
             var piholedata = res.data;
         } catch (err) {
             console.error(err);
         }
    
    
         var toprint =   `Pi-Hole stats\n` +
                         `DNS Queries:\n   - ${piholedata.dns_queries_today}\n` +
                         `DNS blocked:\n   - ${piholedata.ads_blocked_today}(${Math.round(piholedata.ads_percentage_today)}%)\n` +
                         `Blocklist:\n   - ${piholedata.domains_being_blocked}`;
            
         oled.clearDisplay();
         oled.setCursor(0, 0);
         oled.writeString(font, 1, toprint, 1, false);
    
     }
    
     setInterval(() => {
         updateOLED();
     }, 5000);
    

    To go over what we just copied, basically what is happening is the function “updateOLED” runs every 5 seconds. When it runs it first queries the pihole API and puts the results into a string before then displaying the string on the display.

    However, the stats displayed are not the only ones that Pi-Hole gives you access to, if we query the API we can see all the data we can dispaly on the screen:

    stats

  7. Finally, save and run the code and we should see the stats on the screen! display

conclusion #

Hopefully this tutorial was useful! Although displaying the Pi-Hole stats is pretty cool, it is far from what you can do with the i2c bus and the i2c displays.

Check out the oled-i2c-bus package to see what else you can do with it!