pwm with delay

Hello,

In order to try to get my head around the "blink without delay" concept, I have run into a wall. I am trying to use pwm to turn on the led and modify the blink without delay example to replace the "delay (50);" I think you can see what I'm trying to do through the code. Unfortunately the light never comes on and I always get 0 in the serial monitor. Can anybody shed some light for me? Thanks in advance.
I'm trying to replace this:

int led = 3;

void setup()
{
  Serial.begin (9600);
  pinMode (led, OUTPUT);
}
void loop()
{
  for (int i = 0; i <=255; i++){
    analogWrite (led, i);
    delay (50);  
    Serial.println (i);
  }
}

with this:

int led = 3;

long interval = 50;
long previousMillis = 0;

void setup()
{
  Serial.begin (9600);
  pinMode (led, OUTPUT);
}
void loop()
{
  unsigned long currentMillis = millis();

  for (int i = 0; i <=255; i++){
    if (currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;
      analogWrite (led, i);

      Serial.println (i);
    }
  }
}

How long do you think it takes to rip through that for loop?

You need to ditch that whole for loop, and completely rethink how you fade an LED. There are plenty of examples around of fading without delay.

You need a variable that defines the PWM value for the pin. Each pass through loop, you see if it is time to change that value. If it is, change and apply the value, and record when you did that.

It doesn't take long at all to "rip" through the loop. The point isn't fading the led. The point is trying to understand "blink without delay" in a concept other than blinking a light.

It doesn't take long at all to "rip" through the loop.

That's exactly why nothing happens in the loop. The first pass through the loop, enough time has elapsed to see some output. On no other pass through loop has enough time passed for the if test to evaluate to true.

You don't want to loop when you aren't delaying.

You're close. Paul is right, lose the for loop. Don't worry, loop() will be called again real soon. More like this:

void loop()
{
  unsigned long currentMillis = millis();

//  for (int i = 0; i <=255; i++){                     //<-- delete this line
    if (currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;
      analogWrite (led, i++);     // <-- increment i here
      Serial.println (i);
    }
//  }          // <-- delete this line
}

-br

I am trying to slow the loop down by trying to use the "blink without delay." Are you saying that there is no way to slow the for loop down without using delay()?
It does work without any delay() like this:

for (int i = 0; i <=255; i++){
    analogWrite (led, i); 
    Serial.println (i);

TeslaIaint:
I am trying to slow the loop down by trying to use the "blink without delay." Are you saying that there is no way to slow the for loop down without using delay()?
It does work without any delay() like this:

for (int i = 0; i <=255; i++){

analogWrite (led, i);
    Serial.println (i);

Get rid of your for loop, that's what everyone is trying to say. You already have built in iteration by the mere nature of loop(), so an additional one is not needed. At every interval, you need to be thinking what you should be doing. Last interval you wrote 2 as the PWM value, perhaps the next interval should be 3, then 4, etc.

Thanks Billroy. That works. I had to add a line to constrain i to a maximum of 255.

int led = 3;
int i = 0;
long interval = 10;
long previousMillis = 0;

void setup()
{
  Serial.begin (9600);
  pinMode (led, OUTPUT);
}
void loop()
{
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    i = min (i, 254);            sets pwm to 255 maximum
    analogWrite (led, i++);
    Serial.println (i);
  }
}

Although this works to turn the light on, I am still curious how to fix my origional code. Fading the light is just something I picked to try to get to understand the "blink without delay." That really was the origional question. I suppose the question is: how do I use the "blink without delay" with a for loop? Any ideas would be greatly appreciated

TeslaIaint:
I suppose the question is: how do I use the "blink without delay" with a for loop? Any ideas would be greatly appreciated

I discuss that concept here:

TeslaIaint:
Although this works to turn the light on, I am still curious how to fix my origional code. Fading the light is just something I picked to try to get to understand the "blink without delay." That really was the origional question. I suppose the question is: how do I use the "blink without delay" with a for loop? Any ideas would be greatly appreciated

I'm not sure why "don't use a for loop" isn't sticking. I can't think of a single situation where this code shell would be usefull:

for (int i=0;i<sum_num;i++)
{
  if (millis() - last_check > interval)
  {
    last_check = millis();
    // do stuff
  }
}
int led = 3;
int i = 0;
long interval = 10;
long previousMillis = 0;
int lastcheck = 0;

void setup()
{
  Serial.begin (9600);
  pinMode (led, OUTPUT);
}
void loop()
{
  unsigned long currentMillis = millis();
 for (int i=0;i<=255;i++)
{
  if (millis() - lastcheck > interval)
  {
    lastcheck = millis();
    analogWrite (led, i);
  }
  Serial.println (i);
}
}

The above code works as intended. It resets the led to 0 every time through the loop. The following code works in a different way. Once the led reaches 255, it stays there constantly lit. As I said a few times, I'm trying to learn different ways of implementing a delay without "delay()." That's why it "wasn't sticking."

int led = 3;
int i = 0;
long interval = 10;
long previousMillis = 0;

void setup()
{
  Serial.begin (9600);
  pinMode (led, OUTPUT);
}
void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    analogWrite (led, i++);
    i = constrain (i,0,255);
    Serial.println (i);
  }
 // analogWrite (led, 0);
  //Serial.println (i);
}

Your first example in the previous post looks OK to me. Every 10 mS you are increasing the brightness by 1.

Thanks, Nick. That's what I'm trying to do. In my previous post I said that the first bit example of code that I modified from arrch was working correctly. It isn't. I doesn't increment every 10ms; It increments as fast as it can. The "delay" functions aren't working. I'll play with it a bit and see if I can get it to work. I know I shouldn't worry about it as the second posted code in my previous post works, but I just like to try to understand things. Maybe there will be a situation where I could modify the code into something useful.

You had duplicate declarations if "i" there. This is a cut-down version:

int LED = 3;
unsigned long interval = 100;
unsigned long lastcheck = 0;

void setup()
  {
  }  // end of setup

void loop()
  {
  for (int i = 0; i <= 255; i++)
    {
    if (millis() - lastcheck > interval)
      {
      lastcheck = millis();
      analogWrite (LED, i);
      }  // end if time up
    }  // end of for
  }  // end of loop

Although I must confess that on my test board at least it isn't quite doing what I expect. The duty cycle seems to be jumping in a strange way.

Ach! I have it! The loops are the wrong way around. In your code you are adding to i, even if you don't send that value to the LED. In other words, you only send the updated "i" at intervals of "interval". Hence it jumps in brightness in large gaps.

This fades up nicely, relying on the byte value in "brightness" to wrap around at 255:

const int LED = 3;
const unsigned long interval = 10;
unsigned long lastcheck = 0;
byte brightness;

void setup()
  {
  }  // end of setup

void loop()
  {
  if (millis() - lastcheck > interval)
    {
    lastcheck = millis();
    analogWrite (LED, brightness++);
    }  // end if time up
  }  // end of loop

Thanks Nick,
Good work. You explained that well. I know I can use this down the road when I get my robot going again. It will be useful for ramping up the motors among other things. The sensors won't be interrupted by the "delay()."

How is Melbs? I was there at this time last year. I wish I was there now haha.

Getting warmer. Particularly where I am sitting.