Skip to content
Go back

Driving the Max 7219 7-Segment Display Module from ASP.NET Core on the Raspberry Pi

By Michael Earls

Edit page

![Driving the Max 7219 7-Segment Display Module from ASP.NET Core on the Raspberry Pi](/assets/images/2017/11/7-segment-bad-food— 2-.jpg)

In a [previous blog post](/posts/running-a-net- core-2-0-webapi-app-on-the-raspberry-pi-raspbian/), I discussed how to create a dotnet core 2.0 WebApi application to run on the Raspberry Pi and trigger an LED. This post will build upon that by outlining the steps I took to connect a [Max 7219 7-Segment Display Module](http://pdf1.alldatasheet.com/datasheet- pdf/view/73745/MAXIM/MAX7219.html) to the Pi and extend my WebApi to display numbers on the display.

I recently purchased a [Max 7219 7-Segment Display Module on eBay](https://www.ebay.com/itm/8-Digit-LED-Display-MAX7219-7-Segment-Digital- Tube-For-Arduino-Raspberry- Pi/222402956185?hash=item33c83fcb99:m:mLqbQN_R2aqypsbjSK3rn4Q). It came in the mail today and I got right to work interfacing it with my Raspberry Pi. I used the excellent instructions found in this post on Plingboot:

[Driving the Max7219 with the Raspberry Pi](http://www.plingboot.com/2013/01/driving-the-max7219-with-the-raspberry- pi/).

I had to convert the C++ code to C# to get it to work with dotnet core, but that didn’t take too long. I also added a hex decoder and the ability to use multiple digits.

I hooked up my Pi using the following pin configuration:

I used the same Cake code and foundation WebApi code and added a new Controller for the Max7219. Here is the code:

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using Microsoft.AspNetCore.Mvc;  
    using Unosquare.RaspberryIO;  
    using Unosquare.RaspberryIO.Gpio;
    
    namespace WebApi.Controllers  
    {
        [Route("api/[controller]")]
        public class Max7219Controller : Controller
        {
            private GpioPin DataPin = Pi.Gpio.Pin00; // GPIO 17 (WiringPi pin num 0)  header pin 11
            private GpioPin ClockPin = Pi.Gpio.Pin03; // GPIO 22 (WiringPi pin num 3)   header pin 15
            private GpioPin LoadPin = Pi.Gpio.Pin04; // GPIO 23 (WiringPi pin num 4)   header pin 16
    
            private Dictionary Characters = new Dictionary 
            {
                {'-', 0b01000000},
                {'0', 0b01111110},
                {'1', 0b00110000},
                {'2', 0b01101101},
                {'3', 0b01111001},
                {'4', 0b00110011},
                {'5', 0b01011011},
                {'6', 0b01011111},
                {'7', 0b01110000},
                {'8', 0b01111111},
                {'9', 0b01111011},
                {'A', 0b01110111},
                {'B', 0b00011111},
                {'C', 0b01001110},
                {'D', 0b00111101},
                {'E', 0b01001111},
                {'F', 0b01000111},
                {'O', 0b00011101},
                {'R', 0b00000101},
                {' ', 0b00000000}
            };
            private int DECODE_MODE = 0x09;
            private int INTENSITY = 0x0a;
            private int SCAN_LIMIT = 0x0b;
            private int SHUTDOWN = 0x0c;
            private int DISPLAY_TEST = 0x0f;
    
            public Max7219Controller()
            {
                //We need 3 output pins to control the Max7219: Data, Clock and Load
                DataPin.PinMode = GpioPinDriveMode.Output;
                ClockPin.PinMode = GpioPinDriveMode.Output;
                LoadPin.PinMode = GpioPinDriveMode.Output;
            }
    
            // GET api/values
            [HttpGet]
            public IEnumerable Get()
            {
                Max7219Send(DISPLAY_TEST, 1);
                Max7219Send(DECODE_MODE, 0);   // Set BCD decode mode off
                Max7219Send(INTENSITY, 1);     // set brightness 0 to 15
                Max7219Send(SHUTDOWN, 1);      // come out of shutdown mode    / turn on the digits
                return new string[] { "Test mode. Call Max7219/{number} to show a number on the display" };
            }
    
            [HttpGet("{value}")]
            public string Get(int value)
            {
                /* 
                BCD decode mode off : data bits correspond to the segments (A-G and DP) of the seven segment display.
                BCD mode on :  0 to 15 =  0 to 9, -, E, H, L, P, and ' '
                */
    
                Max7219Send(DECODE_MODE, 1);   // Set BCD decode mode on
                Max7219Send(INTENSITY, 1);     // set brightness 0 to 15
                Max7219Send(SHUTDOWN, 1);      // come out of shutdown mode    / turn on the digits
                Max7219Send(1,value);
    
                /*
                var pin = Pi.Gpio.Pin00;
                pin.PinMode = GpioPinDriveMode.Output;
                pin.Write(value);
                return $"pin {pin.BcmPinNumber} set to {value}";
                */
    
                return $"sent {value} to Max7219";
            }
    
    
            /*
            GetFormatted() will set the value based on the first argument passed in. It will either display the hex or the decimal/integer value.
            <http://servername/api/max7219/hex/10>
            will display an "A"
             */
            [HttpGet("{format}/{value}")]
            public string GetFormatted(string format, int value)
            {
                Max7219Send(DISPLAY_TEST, 0);  // Disable test mode
                Max7219Send(INTENSITY, 0x01);     // set brightness 0 to 15
                Max7219Send(SHUTDOWN, 0x01);      // come out of shutdown mode    / turn on the digits
                Max7219Send(SCAN_LIMIT, 0x07);    // use all digits
                /* 
                BCD decode mode off : data bits correspond to the segments (A-G and DP) of the seven segment display.
                BCD mode on :  0 to 15 =  0 to 9, -, E, H, L, P, and ' '
                */
    
                Max7219Send(DECODE_MODE, 0);   // Set BCD decode mode off
    
                var outValue = format.ToLower() == "hex" ? value.ToString("X") : value.ToString();
    
                if (outValue.Length > 8)
                {
                    // send error message
                    outValue = "ERROR";
                }
    
                // make sure we have enough characters to work with
                outValue = outValue.PadLeft(8, ' ');
                var values = outValue.Reverse().Take(8).ToArray();
    
                for (int i = 0; i < 8; i++)
                {
                    var outChar = values[i];
                    Max7219Send(i + 1, Characters[outChar]);
                }
    
                return $"sent {outValue.Trim()} to Max7219 in {format} format.";
            }
    
            private void Max7219Send(int regNumber, int dataOut)
            {
                LoadPin.Write(GpioPinValue.High); // set LOAD High to start
                Send16Bits((regNumber << 8) + dataOut);   // send 16 bits ( reg number + dataout )
                LoadPin.Write(GpioPinValue.Low); // LOAD Low to latch
                LoadPin.Write(GpioPinValue.High); // set LOAD high to finish
            }
    
            private void Send16Bits(int output)
            {
                for(short i = 16; i > 0; i--)
                {
                    int mask = 1 << (i - 1); // calculate bitmask
    
                    ClockPin.Write(GpioPinValue.Low);
    
                    // send one bit on the data pin
                    if (Convert.ToBoolean(output & mask))
                    {
                        DataPin.Write(GpioPinValue.High);
                    }
                    else
                    {
                        DataPin.Write(GpioPinValue.Low);
                    }
    
                    ClockPin.Write(GpioPinValue.High);
                }
            }
        }
    }

This code will allow you to use either decimal(integer) or hexadecimal values depending on how you call the method.

http://servername/api/max7219/hex/42

will display “2A” on the display, while

http://servername/api/max7219/decimal/42

will display “42”.

Also, if the output data is more than 8 characters in length, it will display “Error” (line 113).
Driving the Max 7219 7-Segment Display Module from ASP.NET Core on the
Raspberry Pi ERROR on the Max7219 8-character 7-segment display

Update - November 29, 2017 - Here are the hexadecimal digits for versions of C# prior to 7 that do not support the binary literals:

private Dictionary Characters = new Dictionary  
{
    {'0', 0x7e},
    {'1', 0x30},
    {'2', 0x6d},
    {'3', 0x79},
    {'4', 0x33},
    {'5', 0x5b},
    {'6', 0x5f},
    {'7', 0x70},
    {'8', 0x7f},
    {'9', 0x7b},
    {'A', 0x77},
    {'B', 0x1f},
    {'C', 0x4e},
    {'D', 0x3d},
    {'E', 0x4f},
    {'F', 0x47},
    {'O', 0x1d},
    {'R', 0x05},
    {'-', 0x40},
    {' ', 0x00}
};

Edit page
Share this post on:

Previous Post
FPGA for Fun #1 (Part 1) - Driving the MAX 7219 LED Display Module
Next Post
Is the feedback loop the key to a learning computer?