Skip to content

Commit 405acf6

Browse files
schonbachlertarekgh
authored andcommitted
Added a MAX7219 device (#104)
* Added a simple implementation for a MAX7219 device * Add MatrixTextWriter and optimise Max7219 device * Fixes issues from pull request comments * Changes for pull request * More changes for pull request * refactoring: rename MatrixTextWriter to MatrixGraphics * Font implementation optimised
1 parent 87e0b20 commit 405acf6

16 files changed

+2208
-0
lines changed

src/devices/Max7219/FixedSizeFont.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Collections.Generic;
7+
8+
namespace Iot.Device.Max7219
9+
{
10+
/// <summary>
11+
/// Implementation of a <see cref="IFont"/> that uses a common array for all characters.
12+
/// The number of bytes per character is constant and zero values between the characters are trimmed.
13+
/// </summary>
14+
public class FixedSizeFont : IFont
15+
{
16+
17+
private readonly byte[] _data;
18+
private readonly int _bytesPerCharacter;
19+
private readonly byte[] _space;
20+
21+
public FixedSizeFont(int bytesPerCharacter, byte[] data, int spaceWidth = 3)
22+
{
23+
_data = data;
24+
_bytesPerCharacter = bytesPerCharacter;
25+
_space = new byte[spaceWidth];
26+
}
27+
28+
public IReadOnlyList<byte> this[char chr]
29+
{
30+
get
31+
{
32+
int start = chr * _bytesPerCharacter;
33+
int end = start + _bytesPerCharacter;
34+
if (end > _data.Length)
35+
return _space; //character is not defined
36+
37+
if (chr == ' ')
38+
return _space;
39+
40+
// trim the font
41+
while (start < end && _data[start] == 0)
42+
start++;
43+
while (end > start && _data[end - 1] == 0)
44+
end--;
45+
46+
return new ArraySegment<byte>(_data, start, end - start);
47+
}
48+
}
49+
}
50+
}

src/devices/Max7219/Fonts.cs

Lines changed: 1334 additions & 0 deletions
Large diffs are not rendered by default.

src/devices/Max7219/IFont.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Collections.Generic;
6+
7+
namespace Iot.Device.Max7219
8+
{
9+
/// <summary>
10+
/// A font contains one list of bytes per character which can be written to the matrix to represent the character.
11+
/// </summary>
12+
/// <remarks>
13+
/// Each character consists of a list of bytes where a single byte represents a column of the display.
14+
/// </remarks>
15+
///
16+
/// <example>
17+
/// This example shows how the 'A' char could by encoded:
18+
/// <code>
19+
/// var aBytes = new byte[] {
20+
/// 0b1111100,
21+
/// 0b1111110,
22+
/// 0b0010011,
23+
/// 0b0010011,
24+
/// 0b1111110,
25+
/// 0b1111100,
26+
/// 0b0000000,
27+
/// 0b0000000
28+
/// };
29+
/// </code>
30+
///
31+
/// </example>
32+
public interface IFont {
33+
34+
/// <summary>
35+
/// Returns a list of bytes for a given character to be written to a matrix.
36+
/// </summary>
37+
IReadOnlyList<byte> this[char chr]
38+
{
39+
get;
40+
}
41+
}
42+
}

src/devices/Max7219/MatrixGraphics.cs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
using System.Threading;
9+
10+
namespace Iot.Device.Max7219
11+
{
12+
13+
/// <summary>
14+
/// Graphical functions for a MAX7219 device
15+
/// </summary>
16+
public class MatrixGraphics
17+
{
18+
readonly Max7219 _device;
19+
20+
public MatrixGraphics(Max7219 device, IFont font)
21+
{
22+
if (device == null)
23+
throw new ArgumentNullException(nameof(device));
24+
if (font == null)
25+
throw new ArgumentNullException(nameof(font));
26+
_device = device;
27+
Font = font;
28+
}
29+
30+
public IFont Font { get; set; }
31+
32+
/// <summary>
33+
/// Writes a char to the given device with the specified font.
34+
/// </summary>
35+
public void WriteLetter(int deviceId, char chr, bool flush = true)
36+
{
37+
var charBytes = Font[chr];
38+
var end = Math.Min(charBytes.Count, Max7219.NumDigits);
39+
for (int col = 0; col < end; col++)
40+
{
41+
_device[deviceId, col] = charBytes[col];
42+
}
43+
if (flush)
44+
{
45+
_device.Flush();
46+
}
47+
}
48+
49+
/// <summary>
50+
/// Scrolls the underlying buffer (for all cascaded devices) up one pixel
51+
/// </summary>
52+
public void ScrollUp(bool flush = true)
53+
{
54+
for (var i = 0; i < _device.Length; i++)
55+
_device[i] = (byte)(_device[i] >> 1);
56+
if (flush)
57+
{
58+
_device.Flush();
59+
}
60+
}
61+
62+
/// <summary>
63+
/// Scrolls the underlying buffer (for all cascaded devices) down one pixel
64+
/// </summary>
65+
public void ScrollDown(bool flush = true)
66+
{
67+
for (var i = 0; i < _device.Length; i++)
68+
{
69+
_device[i] = (byte)((_device[i] << 1) & 0xff);
70+
}
71+
if (flush)
72+
{
73+
_device.Flush();
74+
}
75+
}
76+
77+
/// <summary>
78+
/// Scrolls the underlying buffer (for all cascaded devices) to the left
79+
/// </summary>
80+
public void ScrollLeft(byte value, bool flush = true)
81+
{
82+
for (var i = 1; i < _device.Length; i++)
83+
{
84+
_device[i - 1] = _device[i];
85+
}
86+
_device[_device.Length - 1] = value;
87+
if (flush)
88+
{
89+
_device.Flush();
90+
}
91+
}
92+
93+
/// <summary>
94+
/// Scrolls the underlying buffer (for all cascaded devices) to the right
95+
/// </summary>
96+
public void ScrollRight(byte value, bool flush = true)
97+
{
98+
for (var i = _device.Length - 1; i > 0; i--)
99+
{
100+
_device[i] = _device[i - 1];
101+
}
102+
_device[0] = value;
103+
if (flush)
104+
{
105+
_device.Flush();
106+
}
107+
}
108+
109+
/// <summary>
110+
/// Shows a message on the device.
111+
/// If it's longer then the total width (or <see paramref="alwaysScroll"/> == true),
112+
/// it transitions the text message across the devices from right-to-left.
113+
/// </summary>
114+
public void ShowMessage(string text, int delayInMilliseconds = 50, bool alwaysScroll = false)
115+
{
116+
IEnumerable<IReadOnlyList<byte>> textCharBytes = text.Select(chr => Font[chr]);
117+
int textBytesLength = textCharBytes.Sum(x => x.Count) + text.Length - 1;
118+
119+
bool scroll = alwaysScroll || textBytesLength > _device.Length;
120+
if (scroll)
121+
{
122+
var pos = _device.Length - 1;
123+
_device.ClearAll(false);
124+
foreach (var arr in textCharBytes)
125+
{
126+
foreach (byte b in arr)
127+
{
128+
ScrollLeft(b, true);
129+
Thread.Sleep(delayInMilliseconds);
130+
131+
}
132+
ScrollLeft(0, true);
133+
Thread.Sleep(delayInMilliseconds);
134+
135+
}
136+
for (; pos > 0; pos--)
137+
{
138+
ScrollLeft(0, true);
139+
Thread.Sleep(delayInMilliseconds);
140+
}
141+
}
142+
else
143+
{
144+
//calculate margin to display text centered
145+
var margin = (_device.Length - textBytesLength) / 2;
146+
_device.ClearAll(false);
147+
var pos = margin;
148+
foreach (var arr in textCharBytes)
149+
{
150+
foreach (byte b in arr)
151+
{
152+
_device[pos++] = b;
153+
}
154+
pos++;
155+
}
156+
_device.Flush();
157+
}
158+
}
159+
}
160+
}

0 commit comments

Comments
 (0)