简体   繁体   English

在Arduino中制作更好的循环

[英]Making a better loop in Arduino

I've written code in Arduino that cycles through 3 LED color lights but it seems (code) bug prone so I'm trying to come up with a new way to write it. 我已经在Arduino中编写了循环3个LED彩色灯的代码,但似乎(代码)容易出错,所以我试图提出一种新的编写方式。 Due to the complexity I'm going to stick with the phesdo code of what I'm trying to do. 由于复杂性,我将坚持使用我想做的phesdo代码。 Here it is: 这里是:

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;

Note: For a visual it's a color wheel going red->orange->green->teal->blue->pink->repeat 注意:从视觉上看,它是一个色轮,呈红色->橙色->绿色->蓝绿色->蓝色->粉红色->重复

The caveat is, all this is in a loop that is only run once before exiting to fetch other data. 需要注意的是,所有这些都处于循环中,该循环在退出以获取其他数据之前仅运行一次。 It then has to return to this loop and remember the color location it left off. 然后,它必须返回到此循环并记住它保留的颜色位置。 Other wise it would be very easy to wrap all this in for loops and execute it linearly. 否则,将所有这些包装在for循环中并线性执行将非常容易。 As it is it has to inc or dec one color, understand it's color position if you will, update the led driver and then come back to inc or dec remembering where it left off. 因为它必须增​​加或减少一种颜色,所以请先了解它的颜色位置,更新LED驱动程序,然后再返回以增加或减少颜色来记住它停止的位置。 So does anyone have a better code methodologically, pseudo style, I can use besides this complex if statements style. 因此,有人会在方法上有更好的代码吗,伪样式,除了这种复杂的if语句样式之外,我还可以使用。

yeah that is not great... I would do something like.. 是的,那不是很好...我会做类似的事情..

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
}

At least as I read your if statements, you have 7 distinct states (maybe it should be 8?), and when you reach the last, it wraps back around to the first. 至少当我阅读您的if语句时,您有7个不同的状态(也许应该是8个),当您到达最后一个状态时,它会回绕到第一个状态。

That's pretty easy to implement as a counter with a small lookup table to map from a state number to which LED(s) should be lit for a state. 这很容易实现为带有小的查找表的计数器,以从状态编号映射到状态应该点亮的LED。

With a simple drawing of the situation you are able to find a formula that applies the intensity directly to the single component according to a global counter that you increment on every tick, the code is the following (I wrote it just now and haven't tested but should be enough for you to understand how it works): 通过简单绘制情况,您可以找到一个公式,该公式根据您在每个刻度上递增的全局计数器将强度直接应用于单个组件,代码如下(我刚才写过,但还没有经过测试,但足以让您了解其工作原理):

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

The idea follows from this: 这个想法来自于此:

在此处输入图片说明

The shift is needed because by adding an increment to the current phase for a different color component it is possible to consider always phase 0, 1, 2 and 3 to understand is intensity should be raising, dropping or set to max for each component. 之所以需要进行这种偏移,是因为通过为不同的颜色分量在当前相位上增加一个增量,可以始终考虑相位0、1、2和3,以了解每个分量的强度应该提高,下降还是设置为最大值。

This should be adaptable to whatever step of intensity you want to apply easily. 这应该适合您想要轻松应用的强度的任何步骤。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM