2013-04-04 35 views
4

我已经使用Arduino,移位寄存器和TLC5940s制作了24 x 15 LED矩阵。寻找不需要阵列的炫酷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设定从1 LED以15到一定的颜色之一,val偏移波向右每次迭代。

因此,我正在寻找这样简单的图形例程,以获得很酷的动画,而不必将所有内容都存储在阵列中,因为15 x 24 x RGB快速使用了所有32   KB的RAM。

我会尝试获得Arduino Mega,但让我们假设现在不是一个选项。

我该怎么办?

回答

1

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

你有使用算法来生成效果的一般想法,所以你应该继续前进,写出更疯狂的功能。

你可以打包你的功能,并使它们可供所有人使用。

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

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

+0

我在沙漠中的汽车电池上运行它,所以很不幸我不能使用电脑。但是,如果我想出特别好的东西,我会在某处发布代码。 – djb 2013-04-04 13:56:20

+0

燃烧的男人风格? – zaf 2013-04-04 14:09:32

+0

确实,Afrika Burn :)这就像燃烧的人,但尺寸的1/10 – djb 2013-04-04 14:35:06

2

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

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

+0

我看到有人发布了一些Perlin噪声Arduino代码。我会通读您的链接并尝试一下。谢谢! – djb 2013-04-04 14:41:48

1

我会回答相关问题,但不完全是你问,因为我不是一个图形专家的问题....

首先,不要忘了PROGMEM,它允许你存储在闪存中的数据。实际上,闪存比闪存有更多的闪存,而实际上通常的做法是将额外的数据存储在闪存中。

其次,有压缩技术可以减少你的内存消耗。而这些“压缩”技术对于你正在做的任务来说是很自然的,所以“压缩”这个词有点误导。首先,我们观察到,因为人类对光强度的感知是指数级的(无耻地链接到我自己的answer关于此主题),取决于您使用LED驱动程序的准确程度,您不需要存储确切的强度。看起来您在TLC5940上只使用了8位亮度,而不是全部亮度12.对于8位LED驱动强度,您只有8或9种不同的亮度值(因为您告诉LED驱动器使用的亮度为2^perceptible_intensity) 。只有三位可以存储8个不同的值。以字节为单位存储三位块可能有点痛苦,但仍然可以将阵列中的每个“像素”视为uint16_t,但存储整个颜色信息。所以你可以将你的内存消耗降低到原来的2/3。此外,您可以调色您的图像:每个像素是一个字节(uint8_t),并在调色板中索引一个位置,如果您愿意,可以为三个字节。调色板不需要很大,事实上,你根本不需要调色板,这就意味着在代码中有一个调色板:你的代码知道如何将一个字节转换成一组强度。然后,您可以在将它们移出之前生成TLC5940所需的实际强度值。

+1

例如,当我编译时,它说“二进制草图大小:14,234字节(最大32,256字节)”。那么,它不是已经在使用32KB闪存了吗? SRAM只有2KB。感谢压缩建议;我不确定如何将24位颜色压缩为16位。我使用3个无符号字符来保存R/G/B;所以相反,它索引调色板?你可以扩展这个吗?对于彩虹代码的强度,k只是递增,然后进入sin()函数以获得1-256之间的值,该值在1-4096之间变化。不要以为我会在强度值压缩上节省很多空间。 – djb 2013-04-05 11:50:37

+0

啊好的,所以像Philipp的链接中描述的调色板,使用HSBtoRGB ...只有256色左右,没有不连续性。 – djb 2013-04-05 12:54:06

+0

不,你正在使用15K(32K),所以你有超过一半的免费闪光。 – angelatlarge 2013-04-05 16:10:12

2

我一直对类似的图形样式项目Arduino的,并已考虑了各种策略应对有限的。就我个人而言,我发现算法动画相当平庸和通用,除非它们与其他事物相结合或以某种方式进行指导。

在任何速率,这两种方法我已经工作:

  • 定义自定义格式打包该数据作为位,然后用bitshifting到它解

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

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

+0

有趣;所以绘制SVG到LED ...有关如何做到这一点的任何提示? – djb 2013-04-06 15:59:11

+0

@djb:SVG只是一种存储路径点或基元(矩形,圆等)的XML格式。使用(非常)简单的形状,我存储数据点(x/y)并使用线路例程(Bresenham,DDA)在它们之间插值 - 执行精灵动画:从PROGMEM中拉出形状数据,基于插值数据打开LED ,等一下,将形状数据移动一些x/y,重新绘制新的位置。要点是只存储简单的形状数据 - 不是每个动画帧 - 并通过代码进行动画。 – 2013-04-06 19:26:04