4

我使用 Arduino、移位寄存器和TLC5940s制作了一个 24 x 15 LED 矩阵。

Arduino Uno的内存只有区区 32 KB,因此图形不会事先存储到数组中。相反,我编写算法来使用数学方程式生成艺术动画。

彩虹正弦波的示例代码是:

for (int iterations = 0; iterations < times; iterations++)
{
    val += PI/500;

    for (int col = 0; col < NUM_COLS; col++)
    {
        digitalWrite(layerLatchPin, LOW);
        shiftOut(layerDataPin, layerClockPin, MSBFIRST, colMasks[col] >> 16 );
        shiftOut(layerDataPin, layerClockPin, MSBFIRST, colMasks[col] >> 8 );
        shiftOut(layerDataPin, layerClockPin, MSBFIRST, colMasks[col] );
        digitalWrite(layerLatchPin, HIGH);

        Tlc.clear();
        int rainbow1 = 7 + 7*sin(2*PI*col/NUM_COLS_TOTAL + val);
        setRainbowSinkValue(rainbow1, k);
        Tlc.update();
    }
}

其中 setRainbowSinkValue 将其中一个 LED 从 1 到 15 设置为某种颜色,并val在每次迭代时将波向右移动。

所以我正在寻找像这样的简单图形例程,以便获得很酷的动画,而不必将所有内容存储在数组中,因为 15 x 24 x RGB 很快就会用完所有 32 KB 的 RAM。

我会尝试买一个 Arduino Mega,但让我们假设现在这不是一个选择。

我该怎么做?

4

4 回答 4

2

我一直在使用 Arduino 从事类似的图形风格项目,并考虑了各种策略来处理有限的问题。就个人而言,我发现算法动画相当平庸和通用,除非它们与其他事物结合或以某种方式指导。

无论如何,我一直在研究的两种方法:

  • 定义自定义格式以将数据打包为位,然后使用位移位对其进行解包

  • 在 PROGMEM 中存储简单的 SVG 图形,然后使用精灵技术在屏幕上移动它们(屏幕环绕等)。通过使用布尔运算将多个图形合并在一起,可以获得动画层效果并建立复杂性/多样性。

我只使用单色 LED,因此在概念上和数据上都更简单。

于 2013-04-05T03:26:35.397 回答
2

如果您开始叠加简单的函数(如 sin 或 cos),您可以获得许多效果。这家伙创造了“等离子”效应,我认为这总是一件很酷的事情:)

另一种方法是使用噪声函数来计算像素的颜色。如果你在谷歌上搜索“Arduino Perlin noise”,你会得到很多例子(取决于你的 Arduino 模型,你可能无法获得高帧率,因为 Perlin 噪声需要一些 CPU 能力)。

于 2013-04-04T14:29:35.950 回答
1

我将回答相关问题,但不完全是您提出的问题,因为我不是图形专家....

首先,不要忘记PROGMEM,它允许您将数据存储在闪存中。闪存比 SRAM 多得多,实际上,通常要做的就是在闪存中存储额外的数据。

其次,有一些可用的压缩技术可以减少内存消耗。无论如何,这些“压缩”技术对于您正在执行的任务来说是很自然的,所以“压缩”这个词有点误导。

首先,我们观察到,因为人类对光强度的感知是指数级的(无耻链接到我自己关于这个主题的答案),取决于你如何准确地使用 LED 驱动器,你不需要存储确切的强度。看起来您在 TLC5940 上仅使用 8 位强度,而不是完整的 12 位。对于 8 位 LED 驱动器强度,您只有 8 或 9 个不同的强度值(因为您告诉 LED 驱动器使用的强度是2^perceptible_intensity)。8 个不同的值只能存储在三位中。以字节为单位存储三位块可能有点麻烦,但您仍然可以将数组中的每个“像素”视为uint16_t,但存储整个颜色信息。因此,您将内存消耗减少到原来的 2/3。此外,您可以对图像进行调色:每个像素都是一个字节(uint8_t),并索引调色板中的位置,如果您愿意,可以是三个字节。调色板不必很大,事实上,您根本不需要调色板,这只是意味着在代码中有调色板:您的代码知道如何将一个字节转换为一组强度。然后在将它们移出之前生成 TLC5940 需要的实际强度值。

于 2013-04-04T16:46:40.127 回答
1

一个很好的问题,但由于平台的性质,您可能不会找到任何东西。

您有使用算法生成效果的一般想法,因此您应该继续编写更多疯狂的函数。

你可以打包你的函数,让每个人都可以使用它们。

此外,如果您允许,请使用串行端口与拥有更多资源并可以提供无尽模式流的主机进行通信。

使用发射器和接收器也可以连接到另一台计算机。

于 2013-04-04T12:38:20.243 回答