For loop 减慢Arduino FOR循环的速度

For loop 减慢Arduino FOR循环的速度,for-loop,arduino,delay,For Loop,Arduino,Delay,我正在试验以下代码。我希望我的LED灯在2秒/2000毫秒的时间内慢慢变暗。正如所写的,此代码与循环digitalWrite(2,高)和digitalWrite(2,低)无法区分。我怀疑处理器在255个步骤中的速度如此之快,以至于淡入淡出的持续时间难以察觉 void setup () { # set pin 2 as output pinMode = (2,OUTPUT); } void loop () { (for int fi=

我正在试验以下代码。我希望我的LED灯在2秒/2000毫秒的时间内慢慢变暗。正如所写的,此代码与循环
digitalWrite(2,高)
digitalWrite(2,低)
无法区分。我怀疑处理器在255个步骤中的速度如此之快,以至于淡入淡出的持续时间难以察觉

void setup () {                        # set pin 2 as output
    pinMode = (2,OUTPUT);
}

void loop () {
    (for int fi=0;fi<255;fi++) {   # fade IN pin2 from 0-254
    analogWrite(2,fi)
    }
    (for int fo=0;fo<255;fo--) {   # fade OUT pin2 from 0-254
    analogWrite(2,fo)
    }
}
void setup(){#将引脚2设置为输出
pinMode=(2,输出);
}
空循环(){

(对于int-fi=0;fi我将使用micros函数来更好地控制何时发出写入:

它不是延迟,只是返回自线路板联机以来经过的微秒数,使用它可以执行如下逻辑:

setup()
{
     t0 = micros()
}


loop()
{
    t1 = micros();
    dt = t1 - t0;
    if (dt > SOME_SMALL_TIME_DELTA)
    {
         increment_or_decrement_led_value_by_one();
         t0 = t1
    }
}

我会使用micros函数来更好地控制何时发出写入:

它不是延迟,只是返回自线路板联机以来经过的微秒数,使用它可以执行如下逻辑:

setup()
{
     t0 = micros()
}


loop()
{
    t1 = micros();
    dt = t1 - t0;
    if (dt > SOME_SMALL_TIME_DELTA)
    {
         increment_or_decrement_led_value_by_one();
         t0 = t1
    }
}

是的,您是正确的,使用微控制器不可能创建真正的线性衰减。输出将始终具有一些最小步长或分辨率。对于您来说,问题是“PWM是否具有足够的分辨率,以至于不会察觉到这些步长?”

PWN可以在255个步骤中输出0到100%。这与监视器上每个像素的8位分辨率相同。查看任何监视器校准页面,您可能会确信8位分辨率提供了基本上平滑的比例

这是一个示例,它每4秒使LED灯熄灭一次。这展示了几种在后台执行任务的方法

4秒的“打开”到“关闭”的更改使用了闪烁中描述的方法,没有延迟。每次通过循环()都会检查自上次更改以来经过的时间是否超过指定的时间间隔——如果是,则更改状态并标记当前时间

淡入淡出的完成方式略有不同。您会留下下一次更改发生的时间。每次旋转循环()都会检查是否是下一次操作的时间。如果是,则进行更改,并存储何时进行下一次更改

/* unfortunately standard LED on pin 13 does not have PWM
You will need to connect an LED and resistor */
const int pin = 3;

/* this is your step time between changes in light 
output in milliseconds */
const unsigned int tstep = 8;

/* this is the time then next change can be made.
The change will happen at or after this value. */
unsigned int tnext = 0;

/* this is the current and target light level 
The output will slowly ramp until the current value
meets the target.  So to request that the change start,
the code just sets a new target. */
unsigned int target = 0;
unsigned int current = 0;

/* These are from Blink without Delay 
Shows another way to execute delays. */
unsigned long previousMillis = 0;
unsigned long interval = 4000;

void setup() {
   pinMode(pin,OUTPUT);
   tnext = millis() + tstep;
   analogWrite(pin, current);
}

/* something in the code calls this
to request a change in the LED state 
Pass what you want to be the new value
and the LED will slowly change to that value. */
void newTarget(int value) {
   tnext = millis() + tstep;
   target = value;
}

/* call this frequently to update the LED 
If the time of the next action has been reached,
execute the change and setup when the following
change will occur. */
void driveLed() {
   unsigned int tnow = millis();

   if(target != current) {
      if(tnow >= tnext) {
         if(target > current) {
            current += 1;
         }
         else {
            current -= 1;
         }
         analogWrite(pin, current);
         tnext += tstep;
      }
   }
}


/* Note that the main loop has no delays.
Execution will spin rapidly through this, most times
checking and finding nothing to to.
You would add your other functionality here, and this 
LED would continue to happen.  As long as you don't pack 
anything that takes on the order of 8 ms, you won't notice
a change in the LED fade behavior.
void loop() {
   unsigned int tnow = millis();

   // some other logic here would decide when to change the LED state
   // For this sample, just toggle every 4 seconds
   if((tnow - previousMillis) >= interval) {        
      if(0 == target) {
         newTarget(255);
      }
      else {
         newTarget(0);
      }
      previousMillis = tnow;
   }

   driveLed();
}

是的,您是正确的,使用微控制器不可能创建真正的线性衰减。输出将始终具有一些最小步长或分辨率。对于您来说,问题是“PWM是否具有足够的分辨率,以至于不会察觉到这些步长?”

PWN可以在255个步骤中输出0到100%。这与监视器上每个像素的8位分辨率相同。查看任何监视器校准页面,您可能会确信8位分辨率提供了基本上平滑的比例

这是一个示例,它每4秒使LED灯熄灭一次。这展示了几种在后台执行任务的方法

4秒的“打开”到“关闭”的更改使用了闪烁中描述的方法,没有延迟。每次通过循环()都会检查自上次更改以来经过的时间是否超过指定的时间间隔——如果是,则更改状态并标记当前时间

淡入淡出的完成方式略有不同。您会留下下一次更改发生的时间。每次旋转循环()都会检查是否是下一次操作的时间。如果是,则进行更改,并存储何时进行下一次更改

/* unfortunately standard LED on pin 13 does not have PWM
You will need to connect an LED and resistor */
const int pin = 3;

/* this is your step time between changes in light 
output in milliseconds */
const unsigned int tstep = 8;

/* this is the time then next change can be made.
The change will happen at or after this value. */
unsigned int tnext = 0;

/* this is the current and target light level 
The output will slowly ramp until the current value
meets the target.  So to request that the change start,
the code just sets a new target. */
unsigned int target = 0;
unsigned int current = 0;

/* These are from Blink without Delay 
Shows another way to execute delays. */
unsigned long previousMillis = 0;
unsigned long interval = 4000;

void setup() {
   pinMode(pin,OUTPUT);
   tnext = millis() + tstep;
   analogWrite(pin, current);
}

/* something in the code calls this
to request a change in the LED state 
Pass what you want to be the new value
and the LED will slowly change to that value. */
void newTarget(int value) {
   tnext = millis() + tstep;
   target = value;
}

/* call this frequently to update the LED 
If the time of the next action has been reached,
execute the change and setup when the following
change will occur. */
void driveLed() {
   unsigned int tnow = millis();

   if(target != current) {
      if(tnow >= tnext) {
         if(target > current) {
            current += 1;
         }
         else {
            current -= 1;
         }
         analogWrite(pin, current);
         tnext += tstep;
      }
   }
}


/* Note that the main loop has no delays.
Execution will spin rapidly through this, most times
checking and finding nothing to to.
You would add your other functionality here, and this 
LED would continue to happen.  As long as you don't pack 
anything that takes on the order of 8 ms, you won't notice
a change in the LED fade behavior.
void loop() {
   unsigned int tnow = millis();

   // some other logic here would decide when to change the LED state
   // For this sample, just toggle every 4 seconds
   if((tnow - previousMillis) >= interval) {        
      if(0 == target) {
         newTarget(255);
      }
      else {
         newTarget(0);
      }
      previousMillis = tnow;
   }

   driveLed();
}