基于 HT16K33 的十四段控件并不总是显示 Windows 10 IoT Core 上给定位掩码的正确字符

HT16K33-based fourteen-segment control does not always show the correct characters for given bitmask on Windows 10 IoT Core

我想在我的 Pimoroni RainbowHAT 上为我的 Raspberry 运行 Microsoft Windows 10 IoT Core 在十四段控制显示器(4 个并排)上显示一个字符。

对于某些消息,如“HELL”(来自 "Hello) does my source work as expected but for others like "DEMO”,它显示垃圾。这对我来说很奇怪, 因为两条消息都包含字母 "E"。但它只有效一次。

我的最后一个想法是,如果我们假设没有拆分位掩码,bitmask[1] & 0xFF; 与位移位 (bitmask[0] >> 8) && 0xFF 不同。

示例消息(输入 -> 显示在显示屏上)

来源示例(完整来源: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},
      .... 
    }
};

获取字符的位掩码:

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);

链接

根据您的 post 中的代码,设置 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);
    }

解决方案

这是一个多步骤错误修正。

  1. @michael-xu-msft的尖端直接进入右边。我更新了源代码以使用默认 bit-shifting 而不是拆分数组。

  2. 我忘了在Show()方法中添加0x00的缓冲区偏移量。

更新后的源代码现已发布到 GitHub。