【问题标题】:Making a better loop in Arduino在 Arduino 中制作更好的循环
【发布时间】:2013-04-26 17:53:53
【问题描述】:

我在 Arduino 中编写了循环通过 3 个 LED 彩色灯的代码,但它似乎(代码)容易出错,所以我试图想出一种新的方式来编写它。由于复杂性,我将坚持使用我正在尝试做的 phesdo 代码。这里是:

If (red LED isn't max and green LED is 0 and blue LED is 0)
  {inc red LED; update dot matrix}
If (red LED is max and green LED isn't max and blue LED is 0)
  {inc green LED; update dot matrix}
If ((red LED is/has-been max but not 0 ) and green LED is max and blue LED is 0)
  {dec red; update dot matrix}
If (red LED is 0 and green LED is max and blue LED isn't max)
  {inc blue; update dot matrix}
If (red LED is 0 and (green LED is/has-been max but not 0) and blue LED is max)
  {dec green; update dot matrix}
If (red LED isn't Max and green LED is 0 and blue is Max )
  {inc red; update dot matrix}
If (red LED is Max and green LED is 0 and (blue LED is/has-been Max but not 0))
  {dec blue; update dot matrix}

Update LED Driver;

注意:对于视觉来说,它是一个红色->橙色->绿色->蓝绿色->蓝色->粉色->重复的色轮

需要注意的是,所有这些都在一个循环中,该循环仅在退出以获取其他数据之前运行一次。然后它必须返回到这个循环并记住它离开的颜色位置。否则,将所有这些包装在 for 循环中并线性执行它会很容易。因为它必须增​​加或减少一种颜色,如果您愿意,请了解它的颜色位置,更新 LED 驱动程序,然后返回增加或减少记住它停止的位置。那么有没有人有更好的代码方法,伪风格,除了这种复杂的 if 语句风格,我还可以使用。

【问题讨论】:

  • “所有这些都在一个循环中,只运行一次”那么它在循环中的意义何在?
  • 不抱歉这个循环,但我必须在我不能只是坐在它更新颜色之前和之后做一些事情。我需要稍微改变颜色,更新 LED 驱动器,然后做其他事情,然后再回到这个,再更新一点,重复。
  • 不要使用循环,使用计时器。

标签: c++ c loops arduino


【解决方案1】:

通过简单的情况图,您可以找到一个公式,该公式根据您在每个刻度上递增的全局计数器将强度直接应用于单个组件,代码如下(我刚刚写了它并且尚未测试,但应该足以让您了解它的工作原理):

int counter = 0; // counter you should increment on each tick
int phases = 6; // total phases in a cycles
int cycleLength = max_steps * phases; // total ticks in a cycle

int currentStepOfCycle = counter % cycleLength;
int currentPhase = currentStepOfCycle / max_steps;
int currentStepOfPhase = currentStepOfCycle % max_steps;

// this is how much phase shifts are performed for each primary color to have the raising line in phase 0
int phase_shifts[3] = {2, 0, 4}; 

// for each color component
for (int i = 0; i < 3; ++i) {
  // shift the phase so that you have / at phase 0
  int shiftedPhase = (currentPhase+phase_shifts[i])%phases;

  if (shiftedPhase == 1 || shiftedPhase == 2)
    intensity[i] = MAX;
  else if (shiftedPhase == 0)
    intensity[i] = currentStepOfPhase;
  else if (shiftedPhase == 3)
    intensity[i] = MAX - currentStepOfPhase;
  else
    intensity[i] = 0;
}

想法由此而来:

之所以需要这种转变,是因为通过为不同颜色分量添加当前相位的增量,可以始终考虑相位 0、1、2 和 3,以了解强度应该提高、下降还是设置为最大值组件。

这应该可以适应您想要轻松应用的任何强度步骤。

【讨论】:

  • 我喜欢这种方法,但什么时候会 (shiftedPhase == 1 && shiftPhase == 2)?
  • @GradyPlayer:这是一个||,抱歉
  • 超高速千斤顶,感谢绘制。它确实有助于解释你是如何想出你所做的代码的。这很有帮助。
【解决方案2】:

至少在我阅读您的 if 声明时,您有 7 个不同的状态(也许应该是 8 个?),当您到达最后一个时,它会返回到第一个。

这很容易实现为带有小型查找表的计数器,以将状态编号映射到应为某个状态点亮的 LED。

【讨论】:

    【解决方案3】:

    是的,那不是很好......我会做类似的事情......

    typedef struct{ //maybe stick this in a union, depending on what the compiler does to it.
        unsigned char r:2;
        unsigned char g:2;
        unsigned char b:2;
    }color;
    const int numOfColors = 3;
    color colors[numOfColors] = {
        {2,0,0},//r
        {1,1,0},//o
        {0,2,0}//g
    };
    
    for(int i = 0 ; 1 ; i++)
    {
        color c = colors[i%numOfColors];
        //set color
        //update
        //wait
    }
    

    【讨论】:

    • 至少在我读到它的时候,LED 不只是开或关——我相信他每个都有两个“开”级别(但我可能误读了真正的组合意图LED 数)。
    • @JerryCoffin 是的,我不确定...我想您可以使用 2 位并具有开/半/关状态,但您仍然可以以相同的基本方式操作...具有缓存/查找而不是容易出错的多枝性。
    • 是的——它仍然是状态计数器,并且在某个级别上驱动每个 LED 以适应任何给定状态。
    • 是的,抱歉,每种 LED 颜色的值都在 0 到 4095 之间,我每次通过都加/减 5。
    • 哦@nimjox ...这有点不同...我想我会进入状态机并具有红色填充状态和红色减少状态,然后是绿色填充状态...我猜...但是我不知道这只是我的想法...我想这取决于您想要颜色做什么...您基本上在色彩空间中绘制了一个多边形并进行了跟踪它......但你如何做到这一点取决于哪个多边形。
    猜你喜欢
    • 2022-01-10
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多