Go Down

Topic: adding a delay? (Read 170 times) previous topic - next topic

mbartolucci

Dec 04, 2016, 02:30 am Last Edit: Dec 04, 2016, 02:39 am by mbartolucci
Hello,
I am new to the programming and arduino world...
i managed to get an LED to fade in and out. but once it is completely off (at 0?), it startsturning on again immediately. How do I tell it to wait 1 second before starting again? or better yet, how to I get it to fade in and out equally like a wave) The code I am using is below. Please explain as much as possible! thank you!

int ledPin = 9;   

void setup() {
}

void loop() {
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
    analogWrite(ledPin, fadeValue);
    delay(30);
  }

  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
    analogWrite(ledPin, fadeValue);
    delay(30);
  }
}

LarryD

#1
Dec 04, 2016, 02:33 am Last Edit: Dec 04, 2016, 02:34 am by LarryD
If you must use delay()
Code: [Select]
delay(1000);   // 1000 milli seconds


.
No technical PMs.
The last thing you did is where you should start looking.

mbartolucci

If you must use delay()
Code: [Select]
delay(1000);   // 1000 milli seconds


im sorry.. I cant figure out where to pt that in the code... Where would I put that?



Jimmy60

You've got loops inside a loop. You can do what you want with a single loop. Consider what you might do with fadeValue inside this loop. Then find a way to do it without using delay().

ChrisTenone

Put it right after your looped statements:

Code: [Select]


...
    delay(30);
  }

  delay(1000);

...


Oh, and quote my reply so you can see the better way of expressing your code in the forum.
Wubba lubba dub dub!

xniinja

#5
Dec 04, 2016, 04:45 am Last Edit: Dec 04, 2016, 04:57 am by xniinja
You said you wanted the light to fade like a wave, in this case you probably want to approach this a bit differently.

Think of the sin function. For some x value, it outputs a y value. We can think of this in terms of your program. In the case of your program, time is the x value. So, we can say that

Code: [Select]
brightness = sin(time)

However, if we want to put this into code, we have to take some considerations about how your program treats numbers.

First, you have different types of numbers. I see that you already know how to use the int type. The type that we will need is called float. A float type is just a decimal. If you want to deal with precision, you'll need floats. There are even more precise version of floats called double. We will be using double in this program.

Next, we need to know how to use the sin() function in code. Arduino makes this really easy, it's just sin(). Some programming languages make you call Math.sin() or something of that nature. You can forget all of that on Arduino. It's just sin().

The next part is time. In Arduino, we figure out the time by using millis(). This will give the total number of milliseconds since the Arduino was turned on.

Now, I'm going to throw a piece of code at you, don't panic.

Code: [Select]
brightness = (sin( ((double)millis()/1000.0f ) * 2.0f * 3.14159265f )/2 + 0.5) * 255

Here is the same code color-coded for easier explanation:

brightness = (sin(((double)millis()/1000.0f ) * 2.0f * 3.14159265f )/2 + 0.5) * 255

Okay, starting with the blue part:

Code: [Select]
(double)millis()/1000.0f

millis() is good, however if we feed only millis() into the sin() function, we will have a very rapidly blinking light, and that's not what we want. So, we are scaling it back by dividing by 1000. The whole of this piece of code will be outputting the number of seconds since startup. Not only that, but we also cast the millis() value to double. That what the (double) part is for. On top of that, the 1000 isn't just 1000. It says 1000.0f. That's telling the arduino to treat it as a float. All of this together means we get the number of seconds since startup in decimal seconds. Which gives us a lot of smoothness.

Next, the orange part:

Code: [Select]
2.0f * 3.14159265f

This is making the sin function normalized. The period is now 1 second instead of 2pi seconds. 2 pi doesn't really mean much to us, so normalizing this value is nice. This is basically like saying:

y = sin(x * 2 * pi)

You can also put another value in here like:

Code: [Select]
2.0f * 3.14159265f / period


This will directly affect the period and the period will be whatever number is in the "period" variable.

Now, we're onto the green part:

Code: [Select]
/2 + 0.5

So, this bit of code is dividing the output of the sin function by 2, so it goes from -0.5 to 0.5 and adds 0.5 to it so it goes from 0.0 to 1.0. Why did we do this? Well, that feeds into the next colored area.

The teal colored code:  

Code: [Select]
* 255

This takes the output of the value from 0 to 1 and multiplies it by 255. This ensures that the value is always somewhere between 0 to 255. We do this because AnalogWrite can only take a value from 0 to 255. So now your code looks like this:

Code: [Select]
int ledPin = 9;  

void setup() {
}

void loop() {
   double fadeValue;
   fadeValue = (sin( ((double)millis()/1000.0f ) * 2.0f * 3.14159265f )/2 + 0.5) * 255;
   analogWrite(ledPin, fadeValue);

 }




Great! Now we have a wave. But, if we ever use a delay in here, it will just stop. How do we make it stop every time it goes to 0? Well, 2 ways. The first way, we could just check if fade value is equal to 0 and delay. However, using delay() is generally frowned upon because it causes something called "busy waiting". Instead, we're going to find a way to continue running without changing the fade.

So, without getting way too complex with the math, we can do something like the following:

Code: [Select]

int ledPin = 9;  
int startFade = 0;
double period = 1.0; //period in seconds
void setup() {
}

void loop() {
  
   int fadeValue;
  
   if(millis() >= startFade)
   {
      double fadeValue;
      fadeValue = (cos( ((double)(millis() - startFade + (period/2.0f) * 1000)/1000.0f ) * 2.0f * 3.14159265f / period)/2 + 0.5) * 255;
      analogWrite(ledPin, fadeValue);
    
      if(millis() - startFade == period * 1000)
      {
         startFade = millis() + 1000;
         analogWrite(ledPin, 0);
      }
   }



 }




A couple things I did:
Changed the sin function to a cos function. It's just easier to work with because it peaks at 0. Then, I shifted the wave over by half of a period so it starts at 0, climbs to 1 by t = 0.5, and comes back to 0 at t = 1. I also added the code that can deal with adjusting the period length. However, the really important part is:

Code: [Select]
     if(millis() - startFade == period * 1000)
         startFade = millis() + 1000;


This part is saying that once the time is right about the time that the led should be off, turn it off and set a new time where the fade should start again. Before it becomes that time, the fading code just won't run at all. Then, once it does we make sure to start the cos() at 0 again with:

Code: [Select]
millis() - startFade + (period/2.0f) * 1000

This is saying, take the millis and subtract off the time we start at, so we start at 0. Then, make sure to shift over by half of a period so the cos() value starts at 0.

So, that was a huge mouthful. However, I hope it helps you a ton. Honestly, using delay() at all is probably a bad idea and it will make you use it as a crutch. Think creatively and try to avoid delay whenever possible.

Also, if my code doesn't work, please tell me. I simulated it, so it should work. No guarantees though.

lastchancename

Just aside...
This is a great example of why some beginners should have paid attention in maths class at school.  AND why schools should start teaching STEM subjects again!

No offence suggested to the OP, he may well be across xniinja's explanation, but I fear for many others that might still have trouble opening the cardboard package.  They should start trying harder, or take up knitting (!)... that takes practice too!

I was lucky, and caught just enough back then, but many newbies expect the logic and maths to fall out of the Arduino experimenters box along with the AC adapter.
Q: How many searches did you make before posting this question?      A: none
At the very least, take a guess at the solution, then we can help move forward from what you know already.

ChrisTenone

...
  AND why schools should start teaching STEM subjects again!
...
IMO, too much "STEM" is where the problem lies. On the other hand, if science and math were taught outside of the 'touchy-feeley' STEM umbrella, perhaps students would learn this stuff. But it all needs to be made palpable to the various 'boards', who decide based on their 'gut', what subjects get taught, and which are not funded. Thus STEM was born. Crunch everything hard into a single category, to what purpose? To save money.

Remember "tracking"? Back in the 1960s it was believed that some students could grasp science and math, while others should go into retail or food service. So they gave us a test. Pass and you got science education. Fail, and the highest math you ever saw (until you got to the university) was arithmetic. And maybe something called "Earth Science".

STEM is the same thing, repackaged. STEM considers robotics, rudimentary biology (cutting planaria in half kind of thing, or measuring the amount of plastic in waste), are presented as Science subjects. Without any understanding of the scientific method (thanks post-modernism) students are left with the impression that STEM is actually a game of Trivial Pursuit.

But of course, it is far harder to control the outcome of real scientific study. So we now have STEM. Watered down, but controllable.
Wubba lubba dub dub!

lastchancename

Chris, maybe you're being a bit harsh.

Kids need some exposure - even at the battery, switch and bulb level - to see if those type of things 'float their boat' in grade 6, then as they stream into higher years, they can identify which direction they 'might' be interested.  Physics, chemistry, geology, biology, maths etc were all study options when i was in year 8... a long time ago!

But many/most schools at the moment would rather teach gender equality, anti-bullying and job-seeking methods than the actual skills needed to get and hold a job.
Q: How many searches did you make before posting this question?      A: none
At the very least, take a guess at the solution, then we can help move forward from what you know already.

ChrisTenone

For kids, yeah, but I work at a college. Granted, it's a two year college, but we are still using the same techniques as you would for fifth graders. Even at the university level, teaching has been dumbed down to appeal to short attention spans, and unexercised memories.

In physics class (that I help to produce) for example, they DO the battery, wire, bulb experiment! Why? Because the kids have never been exposed to that. I thought that was grade school stuff. So for one, we have a bit of catch-up to achieve.

Perhaps I am harsh. I strongly believe in gender, ethnic, and racial equality. But in a science class, we should go into it with equality already established. And the basic tennents of science should not need to be re-established over and over. But the concept that all opinions are equal has been interwoven with the ideals of general equality. And so sciencetific observations have become "just your opinion, man."

The teacher presents an opinion, and the student is then free to compare that opinion to other opinions. Ideally the student comes to a conclusion that is consistant with their observations and uses science to understand the world. Not necessarily though. The ideas are filtered through social, political and entertainment values. When it's called guided discovery (a STEM based method) the teacher is there to gently nudge the student toward understanding. We dare not tell them they are wrong though.
Wubba lubba dub dub!

lastchancename

Chris,
That's an interesting and valid observation.
Many of the posters on here are from non-English speaking, and other regions of the world.
In many cases (I lived over there for 10+ years), the interesting thing that pushes their competitive learning streak - is they aren't told 'what you can't do'!

Yes, they blow things up and occasionally kill someone, but if you put those students into a richly resourced STEM/tech education system, the good ones will flourish - possibly better than the home-grown students'.  Look at the best Chinese and Indian graduates... they're hungry and willing to take risks.
Q: How many searches did you make before posting this question?      A: none
At the very least, take a guess at the solution, then we can help move forward from what you know already.

ChrisTenone

Chris,
That's an interesting and valid observation.
Many of the posters on here are from non-English speaking, and other regions of the world.
In many cases (I lived over there for 10+ years), the interesting thing that pushes their competitive learning streak - is they aren't told 'what you can't do'!

Yes, they blow things up and occasionally kill someone, but if you put those students into a richly resourced STEM/tech education system, the good ones will flourish - possibly better than the home-grown students'.  Look at the best Chinese and Indian graduates... they're hungry and willing to take risks.
I'm not interested in helping anyone who is going to use their knowledge to kill people. That goes equally for "terrorists" and the military. But what you say is true, good students who are willing to put in the work and enjoy learning are a joy to work with. If that weren't the case, I would not have lasted in this business for 29 years (and counting.)
Wubba lubba dub dub!

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy