c# - 在 Windows 10 IoT Core 上,基于 HT16K33 的十四段控制并不总是显示给定位掩码的正确字符
问题描述
我想在我的Pimoroni RainbowHAT上为运行 Microsoft Windows 10 IoT Core 的 Raspberry上的 14 段控制显示器(并排 4 个)显示一个字符。
对于像“ HELL ”(来自“Hello”)这样的消息,我的源是否按预期工作,但对于像“ DEMO ”这样的其他消息,它显示垃圾。这对我来说很奇怪,因为两条消息都包含字母“E”。但它只工作一次。
我的最后一个想法是,如果我们假设一个未拆分的位掩码,这bitmask[1] & 0xFF;
与位移不同。(bitmask[0] >> 8) && 0xFF
示例消息(输入 -> 显示在显示屏上)
- “地狱”-> 地狱
- "DEMO" -> " ,"(3 个空格,逗号)
源代码示例(完整源代码:GitHub)
将写入设备的段缓冲区:
private readonly byte[] segmentBuffer = Enumerable.Repeat(Convert.ToByte(0b00000000), BUFFER_SIZE).ToArray();
字母 D 的位掩码:
private static readonly Dictionary<char, byte[]> BITMASK_DICTIONARY = new Dictionary<char, byte[]>{
{ 'D', new byte[]{0b00010010, 0b00001111},
....
}
};
获取 char 的位掩码:
private byte[] ConvertCharToBitmask(char character)
{
// Check if char is available.
if(BITMASK_DICTIONARY.Keys.Contains(character))
{
return BITMASK_DICTIONARY[character];
}
// If not, return default (spaces).
...
}
将更改写入设备(消息 =“ DEMO ”):
for (int i = 0; i < message.Length; i++)
{
var bitmask = ConvertCharToBitmask(message[i]);
segmentBuffer[i * 2] = Convert.ToByte(bitmask[0] & 0xFF);
segmentBuffer[i * 2 + 1] = Convert.ToByte(bitmask[1] & 0xFF);
}
// Write buffer to device.
ht16k33.Write(segmentBuffer);
链接
- 我在 GitHub 上的 C#源代码
- Pimoroni的原始python源码
解决方案
从您帖子中的代码来看,设置segmentBuffer似乎不正确。请尝试以下代码。
for (int i = 0; i < message.Length; i++)
{
var bitmask = ConvertCharToBitmask(message[i]);
Logger.Log(this, $"Writing char: '{message[i]}' at index: {i}.");
segmentBuffer[i * 2] = Convert.ToByte(bitmask[1] & 0xFF);
segmentBuffer[i * 2 + 1] = Convert.ToByte(bitmask[0] & 0xFF);
}
你转移'D': 0b0001001000001111
到{ 'D', new byte[]{0b00010010, 0b00001111}
,根据python中的代码,segmentBuffer[i * 2]
应该是较低的位置字节,而segmentBuffer[i * 2 + 1]
应该是较高的。
我没有设备来测试这个问题。如果它不起作用,请随时让我知道。
更新:
下面的代码似乎更符合python中的代码。
private static readonly Dictionary<char, int> BITMASK_DICTIONARY = new Dictionary<char, int>
{
{ ' ', 0b0000000000000000 },
{ 'D', 0b0001001000001111 },
};
private int ConvertCharToBitmask(char character)
{
// Check if char is available.
if (BITMASK_DICTIONARY.Keys.Contains(character))
{
return BITMASK_DICTIONARY[character];
}
// If not, return default.
return GetDefaultCharBitmask();
}
private int GetDefaultCharBitmask()
{
return BITMASK_DICTIONARY[DEFAULT_BITMASK_CHAR];
}
public void Show(string message)
{
// Ensure message has valid length.
if(message.Length > NUMBER_OF_SEGMENTS)
{
throw new OperationCanceledException($"Maximum message length is {NUMBER_OF_SEGMENTS} characters.");
}
// Update buffer
Logger.Log(this, $"Show for {message}");
for (int i = 0; i < message.Length; i++)
{
var bitmask = ConvertCharToBitmask(message[i]);
Logger.Log(this, $"Writing char: '{message[i]}' at index: {i}.");
segmentBuffer[i * 2] = Convert.ToByte(bitmask & 0xFF);
segmentBuffer[i * 2 + 1] = Convert.ToByte(bitmask >> 8 & 0xFF);
}
// Write buffer to device.
ht16k33.Write(segmentBuffer);
}
推荐阅读
- cloud - PaaS 云 (PCF) 上的客户端负载平衡 (Ribbon) 和服务发现 (Eureka)
- sql-server - CONCAT 函数在兼容级别为 100 (2008) 的 SQL Server 数据库上工作
- scala - 将从可变映射中删除的元素收集到第二个可变映射中的惯用方法
- linux - 健康的线程和任务数量?
- javascript - 王牌编辑器 - 传递模式以形成输入
- arrays - 使用 Golang 修改 xml 文件中的数据
- javascript - Array.from 与 map 如何产生密钥
- jquery - 以增量方式隐藏其他 div
- android - Gradle 构建失败:找不到方法 'org.gradle.api.tasks.testing.Test.getTestClassesDirs()Lorg/gradle/api/file/FileCollection;'
- c# - 在自定义队列包装器中实现平均方法