1

设置

我有几百个 Sparkfun LED 像素(类似于https://www.sparkfun.com/products/11020)连接到 Arduino Uno,并希望使用内置的 Serial-over-USB 连接从 PC 控制像素的阿杜诺。

像素是可单独寻址的,每个像素都有 24 位颜色 (RGB)。由于我希望能够非常快速地更改每个像素的颜色,因此从 pc 到 Arduino 的数据传输必须非常高效(从 Arduino 到像素的数据进一步传输已经非常快了)。

问题

我试过直接将所需的 RGB 值直接发送到 Arduino,但这会导致明显的延迟,例如,当我想同时打开所有 LED 时。我最小化数据量的直接想法是将可用颜色从 24 位减少到 8 位,这对于我的应用程序来说已经绰绰有余了。

如果我这样做,我必须将 PC 上的 8 位值扩展为 Arduino 上的 24 位值,以设置像素的实际颜色。这里明显的解决方案是一个调色板,它包含所有可用的 8 位值和相应的 24 位颜色。不过,我希望有一个没有调色板的解决方案,主要是出于内存空间的原因。

问题

将 8 位颜色扩展到 24 位颜色的有效方法是什么,最好是准确保留颜色信息的方法?这个任务有标准算法吗?

可能的解决方案

我正在考虑一种格式,每个 R 和 B 2 位,G 3 位。这些值将被打包成一个字节,然后传输到 Arduino,然后使用位移解包并使用 map() 进行插值功能(http://arduino.cc/en/Reference/Map)。

对该解决方案有任何想法吗?有什么更好的方法来做到这一点?

4

4 回答 4

1

R2B2G3 会给你很少的颜色(实际上还剩下一点)。我不知道这是否足以满足您的申请。您可以使用抖动技术使 8 位图像看起来更好一些。

或者,如果您有任何首选的颜色集,您可以将已知的调色板存储在您的设备上,并且永远不要通过网络发送它。您还可以为不同的情况存储多个调色板,并指定哪一个与小整数索引一起使用。

最重要的是,可以实现一些简单的压缩算法,如RLELZW并在接收后解压缩。

您可以使用一些占用空间很小的非常快速的压缩库:SnappyminiLZO

于 2012-10-12T15:57:51.567 回答
1

关于您的问题“什么是更好的方法来做到这一点?”,首先要做的事情之一(如果尚未完成)是提高串行数据速率。一个Arduino 论坛建议使用 115200 bps 作为标准速率,并尝试使用 230400 bps。在这些速率下,您需要编写接收软件,以便它将数据从相对较小的接收缓冲区快速传输到较大的缓冲区,而不是尝试处理来自小型接收缓冲区的数据。

第二种可能性是将激活时间放入您的数据包中。假设 F1、F2、F3... 是您将在 LED 阵列上显示的一系列帧。提前从 PC 发送这些帧,或者在空闲或等待时间内发送这些帧,并让 Arduino 缓冲它们直到它们被安排出现。当给定帧的激活时间到达时,让 Arduino 打开它。如果您事先知道帧但不知道激活时间,请发送和缓冲帧并在适当的时间仅发送激活码。

第三,您可以拥有多个即时更改的调色板和动态调色板,并且可以使用像素地址或像素列表以及像素图。也就是说,您可能会在不同的时间使用不同的协议。协议 3 可能会下载整个调色板,协议 4 可能会更改调色板的一个元素,协议 5 可能会发送一个 24 位值 v、时间 t、计数 n,以及在时间 t 设置为 v 的 n 个像素的列表, 6 可能会发送像素设置的位图,等等。位图可以是指示开或关的简单的每像素 1 位图,也可以是每像素 k 位图,其中 k 位条目可以指定像素的调色板编号或帧编号。这有点模糊,因为有很多可能性;但简而言之,定义适用于您所显示的任何内容的协议。

第四,鉴于 ATmega328P 的 RAM 较小 (2KB) 但闪存较大 (32KB),请考虑将多个调色板、帧和宏硬编码到程序中。通过宏,我的意思是生成图形元素的例程,如弧线、线条、开放或填充的矩形。任何预先知道的显示元素都是闪存而不是 RAM 存储的候选者。

于 2012-10-12T17:49:48.313 回答
0

您的 (2, 3, 2) 位想法是“在野外”使用的。尝试起来应该非常简单。质量会很低,但请尝试一下,看看它是否满足您的需求。

如果查找表随时间保持不变,那么与 256 色查找表相比,任何其他解决方案似乎都不太可能节省大量内存。我认为任何成功的事情都必须利用您发送到像素的图像类型中的模式。

于 2012-10-12T15:54:16.623 回答
0

不管你怎么看,你真正想要的是图像压缩。因此,我建议您查看 PNG 和 JPG 压缩之类的方法,看看它们是否足够快,适合您的应用程序。

如果没有,那么您可以考虑自己滚动。到目前为止,您只能进行逐像素压缩;在尺寸方面,您的 (2,3,2) 想法与您预期的一样好。您可以尝试使用四叉树类型的格式:取 4 像素块的平均值,传输差异的压缩(有损)表示,然后将相同的操作应用于平均值的半分辨率图像......

正如其他人指出的那样,抖动将使您的图像在 (2,3,2) 处看起来更好。对您的应用程序进行抖动的最简单方法可能是为每个像素的每种颜色选择不同的(随机或准随机)固定量化阈值偏移。PC 和 Arduino 都会有这个阈值表的副本;阈值的分布将防止分色,而 Arduino 边桌将有助于保持准确性。

于 2012-10-12T18:44:41.190 回答