Hardware components | ||||||
![]() |
| × | 1 | |||
| × | 1 |
/*
Author : KIRAN KUMAR BOLLUKONDA
Email : BK.KIRAN.KUMAR@GMAIL.COM
BK.KIRAN.KUMAR@HOTMAIL.COM
Created : 21-JUNE-2015
Comments : Please note that this code is written only for beginners
and I tried to keep as simple as possible. This code allows
the beginner to understand the MAX7219 via Raspberry Pi 2
SPI with Windows 10. I will try to post full version when
I find free time
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Devices.Enumeration;
using Windows.Devices.Spi;
using Windows.Devices.Gpio;
using System.Threading.Tasks;
namespace ScrollingDisplay
{
public sealed partial class MainPage : Page
{
private const string SPI_CONTROLLER_NAME = "SPI0"; // Use SPI0.
private const Int32 SPI_CHIP_SELECT_LINE = 0; // Line 0 is the CS0 pin which is
// the physical pin 24 on the Rpi2.
// private const UInt32 MAX_DISPLAYS = 1;
// private const UInt32 DISPLAY_ROWS = 8;
private const UInt32 DISPLAY_COLUMNS = 8;
// private byte[] DisplayBuffer = new byte[DISPLAY_COLUMNS * 2]; // Including address byte. 1 Address byte, 1 Data byte.
private string Message; // Message to be displayed on the LED display.
private byte[] MessageBuffer; // Message Buffer to hold total character font.
private int ScrollDelay = 40; // In milliseconds. Use this field to change dynamically for scroll speed.
private byte[] SendBytes = new byte[2]; // Send to Spi Display without drawing memory.
// COMMAND MODES for MAX7219. Refer to the table in the datasheet.
private static readonly byte[] MODE_DECODE = { 0x09, 0x00 }; // , 0x09, 0x00 };
private static readonly byte[] MODE_INTENSITY = { 0x0A, 0x00 }; // , 0x0A, 0x00 };
private static readonly byte[] MODE_SCAN_LIMIT = { 0x0B, 0x07 }; // , 0x0B, 0x07 };
private static readonly byte[] MODE_POWER = { 0x0C, 0x01 }; // , 0x0C, 0x01 };
private static readonly byte[] MODE_TEST = { 0x0F, 0x00 }; // , 0x0F, 0x00 };
private static readonly byte[] MODE_NOOP = { 0x00, 0x00 }; // , 0x00, 0x00 };
private SpiDevice SpiDisplay; // SPI device on Raspberry Pi 2
private GpioController IoController; // GPIO Controller on Raspberry Pi 2
private int uCtr, rCtr; // Counter variables for updating message.
public MainPage()
{
this.InitializeComponent();
// Initialize Scrolling Message
InitScrollMessage(); // You can override the default message by providing some string here.
Initialize(); // Initialize SPI and GPIO on the current system.
}
/// <summary>
/// Initialize Scroll Message.
/// </summary>
/// <param name="msg">Message to scroll.</param>
private void InitScrollMessage(string msg = "KIRAN KUMAR BOLLUKONDA * ")
{
Message = msg; // Scroll Message.
MessageBuffer = new byte[Message.Length * 8]; // Message Buffer containing the character font.
// Fill message buffer with the character font.
for (int i = 0; i < Message.Length; i++)
{
Array.Copy(Character.Get(Message[i]), // Source array.
0, // Source start index.
MessageBuffer, // Destination array.
(i * 8), // Destination array index.
8); // Length of bytes to copy.
}
}
/// <summary>
/// Initialize SPI, GPIO and LED Display
/// </summary>
private async void Initialize()
{
try
{
InitGpio();
await InitSpi();
await InitDisplay();
}
catch (Exception ex)
{
txtStatus.Text = "Error Occurred: \r\n" + ex.Message;
if (ex.InnerException != null)
{
txtStatus.Text += "\r\nInner Exception: " + ex.InnerException.Message;
}
return;
}
}
/// <summary>
/// Initialize SPI.
/// </summary>
/// <returns></returns>
private async Task InitSpi()
{
try
{
var settings = new SpiConnectionSettings(SPI_CHIP_SELECT_LINE);
settings.ClockFrequency = 100000;
settings.Mode = SpiMode.Mode0;
string spiAqs = SpiDevice.GetDeviceSelector(SPI_CONTROLLER_NAME); /* Find the selector string for the SPI bus controller */
var devicesInfo = await DeviceInformation.FindAllAsync(spiAqs); /* Find the SPI bus controller device with our selector string */
SpiDisplay = await SpiDevice.FromIdAsync(devicesInfo[0].Id, settings); /* Create an SpiDevice with our bus controller and SPI settings */
}
/* If initialization fails, display the exception and stop running */
catch (Exception ex)
{
throw new Exception("SPI Initialization Failed", ex);
}
}
/// <summary>
/// Initialize LED Display. Refer to the datasheet of MAX7219
/// </summary>
/// <returns></returns>
private async Task InitDisplay()
{
SpiDisplay.Write(MODE_SCAN_LIMIT);
await Task.Delay(10);
SpiDisplay.Write(MODE_INTENSITY);
await Task.Delay(10);
SpiDisplay.Write(MODE_POWER);
await Task.Delay(10);
SpiDisplay.Write(MODE_TEST); // Turn on all LEDs.
await Task.Delay(10);
}
/// <summary>
/// Initiazlie GPIO.
/// </summary>
private void InitGpio()
{
IoController = GpioController.GetDefault();
if (IoController == null)
{
throw new Exception("Unable to find GPIO on the current system.");
}
}
// Use the below method to debug or test if the font character is correct.
//private async void DisplayChar(char ch)
//{
// byte[] c = Character.Get(ch);
// for (int i = 0; i < 8; i++)
// {
// SpiDisplay.Write(new byte[] { (byte)(i + 1), c[i] });
// await Task.Delay(10);
// }
//}
/// <summary>
/// Update Message to LED display.
/// </summary>
/// <returns></returns>
private async Task UpdateMessage()
{
for (uCtr = 0; uCtr < 8; uCtr++)
{
SendBytes[0] = (byte)(uCtr + 1); // Address
SendBytes[1] = MessageBuffer[uCtr];
// SpiDisplay.Write(new byte[] { (byte)(uCtr + 1), MessageBuffer[uCtr] });
SpiDisplay.Write(SendBytes);
}
await Task.Delay(ScrollDelay);
}
/// <summary>
/// Rotate message by one column in the message buffer.
/// </summary>
private void RotateDisplay()
{
byte tmpByte = MessageBuffer[0];
for (rCtr = 1; rCtr < MessageBuffer.Length; rCtr++)
{
MessageBuffer[rCtr - 1] = MessageBuffer[rCtr];
}
MessageBuffer[MessageBuffer.Length - 1] = tmpByte;
}
/// <summary>
/// Start scrolling forever.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void btnScroll_Click(object sender, RoutedEventArgs e)
{
btnScroll.IsEnabled = false;
while (true)
{
await UpdateMessage(); // Update message in LED display.
RotateDisplay(); // Rotate message in buffer.
}
}
}
}
<Page
x:Class="ScrollingDisplay.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ScrollingDisplay"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="#FF7C88FF">
<TextBlock x:Name="txtStatus" HorizontalAlignment="Left" Margin="10,58,0,0" TextWrapping="Wrap" Text="Click Scroll to start scrolling" VerticalAlignment="Top" Width="965" Height="150"/>
<Button x:Name="btnScroll" Content="Scroll" HorizontalAlignment="Left" Margin="437,497,0,0" VerticalAlignment="Top" Click="btnScroll_Click" Width="102"/>
</Grid>
</Page>
/*
Author : KIRAN KUMAR BOLLUKONDA
Email : BK.KIRAN.KUMAR@GMAIL.COM
BK.KIRAN.KUMAR@HOTMAIL.COM
Created : 21-JUNE-2015
Comments : Please note that this code is written only for beginners
and I tried to keep as simple as possible. This code allows
the beginner to understand the MAX7219 via Raspberry Pi 2
SPI with Windows 10.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ScrollingDisplay
{
public static class Character
{
public static byte[] Get(char ch)
{
switch (ch)
{
case ' ': return new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
case '!': return new byte[] { 0x00, 0x06, 0x5F, 0x5F, 0x06, 0x00, 0x00, 0x00 };
case '"': return new byte[] { 0x00, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00, 0x00 };
case '#': return new byte[] { 0x14, 0x7F, 0x7F, 0x14, 0x7F, 0x7F, 0x14, 0x00 };
case '$': return new byte[] { 0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00 };
case '%': return new byte[] { 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, 0x00 };
case '&': return new byte[] { 0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x7A, 0x48, 0x00 };
case '\'': return new byte[] { 0x04, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 };
case '(': return new byte[] { 0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00, 0x00, 0x00 };
case ')': return new byte[] { 0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x00 };
case '*': return new byte[] { 0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08 };
case '+': return new byte[] { 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00, 0x00 };
case ',': return new byte[] { 0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00 };
case '-': return new byte[] { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 };
case '.': return new byte[] { 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 };
case '/': return new byte[] { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 };
case '0': return new byte[] { 0x3E, 0x7F, 0x71, 0x59, 0x4D, 0x7F, 0x3E, 0x00 };
case '1': return new byte[] { 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00 };
case '2': return new byte[] { 0x62, 0x73, 0x59, 0x49, 0x6F, 0x66, 0x00, 0x00 };
case '3': return new byte[] { 0x22, 0x63, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 };
case '4': return new byte[] { 0x18, 0x1C, 0x16, 0x53, 0x7F, 0x7F, 0x50, 0x00 };
case '5': return new byte[] { 0x27, 0x67, 0x45, 0x45, 0x7D, 0x39, 0x00, 0x00 };
case '6': return new byte[] { 0x3C, 0x7E, 0x4B, 0x49, 0x79, 0x30, 0x00, 0x00 };
case '7': return new byte[] { 0x03, 0x03, 0x71, 0x79, 0x0F, 0x07, 0x00, 0x00 };
case '8': return new byte[] { 0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 };
case '9': return new byte[] { 0x06, 0x4F, 0x49, 0x69, 0x3F, 0x1E, 0x00, 0x00 };
case ':': return new byte[] { 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 };
case ';': return new byte[] { 0x00, 0x80, 0xE6, 0x66, 0x00, 0x00, 0x00, 0x00 };
case '<': return new byte[] { 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x00 };
case '=': return new byte[] { 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00 };
case '>': return new byte[] { 0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00 };
case '?': return new byte[] { 0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00, 0x00 };
case '@': return new byte[] { 0x3E, 0x7F, 0x41, 0x5D, 0x5D, 0x1F, 0x1E, 0x00 };
case 'A': return new byte[] { 0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00, 0x00 };
case 'B': return new byte[] { 0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00 };
case 'C': return new byte[] { 0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00 };
case 'D': return new byte[] { 0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00 };
case 'E': return new byte[] { 0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00 };
case 'F': return new byte[] { 0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00 };
case 'G': return new byte[] { 0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00 };
case 'H': return new byte[] { 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00 };
case 'I': return new byte[] { 0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00, 0x00 };
case 'J': return new byte[] { 0x30, 0x70, 0x40, 0x41, 0x7F, 0x3F, 0x01, 0x00 };
case 'K': return new byte[] { 0x41, 0x7F, 0x7F, 0x08, 0x1C, 0x77, 0x63, 0x00 };
case 'L': return new byte[] { 0x41, 0x7F, 0x7F, 0x41, 0x40, 0x60, 0x70, 0x00 };
case 'M': return new byte[] { 0x7F, 0x7F, 0x0E, 0x1C, 0x0E, 0x7F, 0x7F, 0x00 };
case 'N': return new byte[] { 0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00 };
case 'O': return new byte[] { 0x1C, 0x3E, 0x63, 0x41, 0x63, 0x3E, 0x1C, 0x00 };
case 'P': return new byte[] { 0x41, 0x7F, 0x7F, 0x49, 0x09, 0x0F, 0x06, 0x00 };
case 'Q': return new byte[] { 0x1E, 0x3F, 0x21, 0x71, 0x7F, 0x5E, 0x00, 0x00 };
case 'R': return new byte[] { 0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00 };
case 'S': return new byte[] { 0x26, 0x6F, 0x4D, 0x59, 0x73, 0x32, 0x00, 0x00 };
case 'T': return new byte[] { 0x03, 0x41, 0x7F, 0x7F, 0x41, 0x03, 0x00, 0x00 };
case 'U': return new byte[] { 0x7F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00 };
case 'V': return new byte[] { 0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x00 };
case 'W': return new byte[] { 0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00 };
case 'X': return new byte[] { 0x43, 0x67, 0x3C, 0x18, 0x3C, 0x67, 0x43, 0x00 };
case 'Y': return new byte[] { 0x07, 0x4F, 0x78, 0x78, 0x4F, 0x07, 0x00, 0x00 };
case 'Z': return new byte[] { 0x47, 0x63, 0x71, 0x59, 0x4D, 0x67, 0x73, 0x00 };
case '[': return new byte[] { 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00 };
case '\\': return new byte[] { 0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00 };
case ']': return new byte[] { 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00 };
case '^': return new byte[] { 0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00 };
case '_': return new byte[] { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
case '`': return new byte[] { 0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00 };
case 'a': return new byte[] { 0x20, 0x74, 0x54, 0x54, 0x3C, 0x78, 0x40, 0x00 };
case 'b': return new byte[] { 0x41, 0x7F, 0x3F, 0x48, 0x48, 0x78, 0x30, 0x00 };
case 'c': return new byte[] { 0x38, 0x7C, 0x44, 0x44, 0x6C, 0x28, 0x00, 0x00 };
case 'd': return new byte[] { 0x30, 0x78, 0x48, 0x49, 0x3F, 0x7F, 0x40, 0x00 };
case 'e': return new byte[] { 0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00, 0x00 };
case 'f': return new byte[] { 0x48, 0x7E, 0x7F, 0x49, 0x03, 0x02, 0x00, 0x00 };
case 'g': return new byte[] { 0x98, 0xBC, 0xA4, 0xA4, 0xF8, 0x7C, 0x04, 0x00 };
case 'h': return new byte[] { 0x41, 0x7F, 0x7F, 0x08, 0x04, 0x7C, 0x78, 0x00 };
case 'i': return new byte[] { 0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00, 0x00 };
case 'j': return new byte[] { 0x60, 0xE0, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00 };
case 'k': return new byte[] { 0x41, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00 };
case 'l': return new byte[] { 0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x00 };
case 'm': return new byte[] { 0x7C, 0x7C, 0x18, 0x38, 0x1C, 0x7C, 0x78, 0x00 };
case 'n': return new byte[] { 0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00 };
case 'o': return new byte[] { 0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00 };
case 'p': return new byte[] { 0x84, 0xFC, 0xF8, 0xA4, 0x24, 0x3C, 0x18, 0x00 };
case 'q': return new byte[] { 0x18, 0x3C, 0x24, 0xA4, 0xF8, 0xFC, 0x84, 0x00 };
case 'r': return new byte[] { 0x44, 0x7C, 0x78, 0x4C, 0x04, 0x1C, 0x18, 0x00 };
case 's': return new byte[] { 0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00, 0x00 };
case 't': return new byte[] { 0x00, 0x04, 0x3E, 0x7F, 0x44, 0x24, 0x00, 0x00 };
case 'u': return new byte[] { 0x3C, 0x7C, 0x40, 0x40, 0x3C, 0x7C, 0x40, 0x00 };
case 'v': return new byte[] { 0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x00 };
case 'w': return new byte[] { 0x3C, 0x7C, 0x70, 0x38, 0x70, 0x7C, 0x3C, 0x00 };
case 'x': return new byte[] { 0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00 };
case 'y': return new byte[] { 0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00, 0x00 };
case 'z': return new byte[] { 0x4C, 0x64, 0x74, 0x5C, 0x4C, 0x64, 0x00, 0x00 };
case '{': return new byte[] { 0x08, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00, 0x00 };
case '|': return new byte[] { 0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x00 };
case '}': return new byte[] { 0x41, 0x41, 0x77, 0x3E, 0x08, 0x08, 0x00, 0x00 };
case '~': return new byte[] { 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, 0x00 };
default:
return new byte[] { };
}
}
}
}
1 project • 2 followers
I am working as a Technical Architect. Electronics+Computers is my hobby.
Comments