wwtwxlwjh 发表于 2013-12-7 11:03:33

arduino RGB led 代码问题 急急急

我用的是RGB led灯 想整一个呼吸灯的效果,代码如下,简单的代码:

// left to rightred blue green
int redpin=11;
int bluepin=10;
int greenpin=9;
void setup()
{
pinMode(redpin,OUTPUT);
pinMode(bluepin,OUTPUT);
pinMode(greenpin,OUTPUT);
}
void loop()
{
yellow();
white();
lightred();
lightred();

}
void yellow()
{
for(int a=0;a<=255;a++)
{
analogWrite(redpin,a);
analogWrite(greenpin,a);
delay(20);
}
}

void white()
{
for(int a=0;a<=255;a++)
{
analogWrite(redpin,a);
analogWrite(bluepin,a);
analogWrite(greenpin,a);
delay(20);
}
}

void lightred()
{
for(int a=0;a<=255;a++)
{
analogWrite(redpin,a);
analogWrite(bluepin,a);
delay(10);
}
}

单独分别执行 yellow white lighted 颜色都正确,也跑得对,但放在一起我想让他们无线循环就不行了,颜色就紊乱了,不再是我设置的那三个颜色的循环,求问高手 如何解决。。。

zoologist 发表于 2013-12-7 11:50:48

建议你用 serial print 看一下debug信息是什么地方错了

isilcala 发表于 2013-12-7 14:01:12

这是老生常谈得很的问题了。

不要用delay,用millis()。具体请google吧。

wwtwxlwjh 发表于 2013-12-7 15:20:10

isilcala 发表于 2013-12-7 14:01 static/image/common/back.gif
这是老生常谈得很的问题了。

不要用delay,用millis()。具体请google吧。

为什么不能用delay,减小延时就可以了呢?

isilcala 发表于 2013-12-7 15:29:57

wwtwxlwjh 发表于 2013-12-7 15:20 static/image/common/back.gif
为什么不能用delay,减小延时就可以了呢?

如果你有去google过,就知道为什么了。网上有系统而完整得多的解释,以及各种示例代码。比在这里问答有帮助得多。

zoologist 发表于 2013-12-7 16:16:30

http://playground.arduino.cc/Code/AvoidDelay

关于 Delay 的limitation

换成 millis 看看吧

Estel 发表于 2013-12-7 18:49:26

定时器中断才是正解。
millis这个函数很有用,但用来实现延时之类的功能,绝对不合适!

zoologist 发表于 2013-12-7 19:38:24

Estel 发表于 2013-12-7 18:49 static/image/common/back.gif
定时器中断才是正解。
millis这个函数很有用,但用来实现延时之类的功能,绝对不合适!

为什么说millis 用来做延时不合适?

Estel 发表于 2013-12-8 11:17:27

延时比较适合一些对时序要求很高的操作,us级别的。


不管是millis,还是delay,都是在不断的执行一些毫无意义的代码,消耗大量的机器周期来实现。

在一个相对资源丰富的系统里(电源,flash,sram)执行比较简单的程序,比如Blink,奢侈的使用任何库函数任何命令都不为过。
但如果系统复杂一点呢?你要不断的处理外部资源发来的中断消息,比如ad,按键,你要不断的向外部做好几路pwm,同时在一定周期对数码管,点阵之类的设备扫描,外部中断不够你还要在主循环里疯狂的while io口检测。 这样的情况,你就要节省每一点资源。

另外,最重要的一点:不是每一刻都有稳定的5V供电。如果用锂电或者干电池的话,更要节省。
同样的Blink,定时器中断里执行代码,主程序执行进入空闲模式。每个1秒周期来临时,系统会醒来闪烁LED,其他时间会休息来节省电量。

以上完全是经验之谈,吃透后,写起程序更是得心应手。

你这个问题,正解应该是:
单独执行时,正确,而放一起执行时不正确,是因为你在每个单独的调色函数结束后,没有对三个灯进行初始化。
yellow() 是红绿亮,蓝色灭。
lightred() 是红蓝亮,绿色灭。
发现错误了吗? yellow结束后,绿色一直是亮的。lightred() 就变成三个灯都亮了

解决方法,每个单独的函数,比如 yellow(),进去第一句就执行 r g b 三个灯都熄灭!

zoologist 发表于 2013-12-8 12:40:40

Estel 发表于 2013-12-8 11:17 static/image/common/back.gif
延时比较适合一些对时序要求很高的操作,us级别的。




受教了,意思是如果有可能,我们尽量使用 delay() 这样能省电?

isilcala 发表于 2013-12-8 13:39:54

本帖最后由 isilcala 于 2013-12-8 14:00 编辑

Estel 发表于 2013-12-8 11:17 static/image/common/back.gif
延时比较适合一些对时序要求很高的操作,us级别的。




“延时比较适合一些对时序要求很高的操作,us级别的。”

不知道这句是不是说的millis和delay,这两者返回的值都是毫秒为单位。微妙单位的是micros和delayMicroseconds。另外严格说来,millis和micros并不是“延时”函数。

“不管是millis,还是delay,都是在不断的执行一些毫无意义的代码,消耗大量的机器周期来实现。”

这句描述用来形容delay还算可以。但要放在millis身上则是个谬误。millis和delay本质上是完全不同的东西。

另外不知道对于millis“耗费大量资源”一说是否有实际的数据支撑?


定时器中断是个好东西,但它和millis一类也并非是替代而是共存关系。两者各有优劣之处。只是各自适用的场合不一样罢了。大家做的东西千百万种,以一概全未免有些偏颇。对于楼主这个case,一来连millis都还不知道,就跳跃到定时中断,怕是也不好消化;二来这个case也没有复杂到那个程度。还是先吃透了基础,再一步步深入比较好。

Estel 发表于 2013-12-8 17:30:42

isilcala 发表于 2013-12-8 13:39 static/image/common/back.gif
“延时比较适合一些对时序要求很高的操作,us级别的。”

不知道这句是不是说的millis和delay,这两者 ...

你说的很对,定时器中断因为Arduino本身并不提供核心支持。所以相对来讲,很难。如果直接调用AVR,操作寄存器,哪还不如不使用Arduino。感谢层主提醒,对一些新手灌输定时器中断确实不太合适。

还有一些内容,我写的比较含糊,表达错误了:


delay比较适合一些时序要求很高的地方。us级别。我个人尽量避免用delay来做100ms以上的延时。除非是非常非常简单的一些实验。


millis本身不消耗资源,用millis来作延时这种不断等待,不断的和millis比较,是很消耗资源的。

在一个loop里如果只有一个blink需要执行,那么无所谓,可往往还有许多任务。那么不管是millis还是delay都很影响效率。

在这里我本人不厌其烦的不断说delay的“坏话”,是给大家提醒,使用delay,一定要慎重!

isilcala 发表于 2013-12-8 18:13:37

Estel 发表于 2013-12-8 17:30 static/image/common/back.gif
你说的很对,定时器中断因为Arduino本身并不提供核心支持。所以相对来讲,很难。如果直接调用AVR,操作寄 ...

同意,delay有它的用处,但一般都是用在非常短的延时里需要紧跟后一个操作的。其他大部分情况都应该极力避免使用。

但是新手一定要掌握millis等函数。重要的不是该函数本身,而是由它去理解这个平台的程序执行逻辑究竟是怎样的,随后再去设计程序的结构,才会正确和有效(新手一定要知道的一件事是,BLINK只是一个演示,而绝非设计准则。可惜没有地方强调这一点。)。这也是为什么我不直接给一个millis的调用,而是建议去google的原因。

比如待楼主理解了这一点,自然也就知道自己的程序哪儿有问题,该怎么改了。
页: [1]
查看完整版本: arduino RGB led 代码问题 急急急