Let me preface this by saying I'm an arduino novice. I've read a lot of posts about phase-correct PWM stuff, but most of it went over my head.
I have a project where I control 4 LEDs individually so I can create some unique patterns. I use the time LED is on (OnTime) and two different phases to calculate LED OffTime. The LED activation is thus heavily based on what activation time and patterns I put in. See attached file "Quad_LED_1_backup.ino".
I have another code, "regulatorTest_backup.ino", that controls 2 LEDs using phase-corrected PWM. The problem is that I don't really know what the activation frequency is. I can of course speed it up and down by changing maxvalue and fadeValue, but I'm not sure what this corresponds to in terms of seconds.
I'd like to merge the two codes such that I can set OnTime, phase_A, phase_B, and OffTime like I do in the first code, but have the LEDs operated using PWM. In my head, it looks something like this:
For OnTime (one second):
start ramping LED brightness from 0 to 100 over the course of that one second (gradual increase over the OnTime duration).
For OffTime:
decrease LED brightness from 100 to 0 either quickly or slowly (for various reasons, I may need it to decrease very quickly and then stay off for the remainder of OffTime, rather than take all of OffTime to go to 0).
Can someone please walk me through how to achieve this? I'd greatly appreciate the help.
zaneywolf:
Using analogWrite(ledA, HIGH/LOW) results in very dim flickering and (ledA, 100/0) results in it being on all the time.
So using analogWrite incorrect results in incorrect LED operation, who would have guessed.
The file "Quad_LED_1_backup.ino" is very odd, you seem to be updating the previous millis from a base of zero not from a base of the current millis time in the setup function. You can not assume that this value is zero by the time the code reaches the setup function because it has been running for some time before that in the bootloader.
The problem is that I don't really know what the activation frequency is.
The quad_led_1_backup is a modified version of the code available of the Demonstration Code for several things at the same time code pinned to the top of this forum. I just took out the bits I didn't need and put in the bits I did.
And I wasn't quite clear. When I say activation frequency, I don't mean the PWM frequency. I mean, I want the LED to turn on for one second and turn off for one second, so 1cycle/2 seconds = 0.5Hz. I want to set this "LED activation" frequency by hand and have the PWM follow suit. Is this possible?
So using analogWrite incorrect results in incorrect LED operation, who would have guessed.
Oh yeah, no, I was just being super lazy. I used analogWrite(ledA, HIGH).....analogWrite(ledA, LOW) and analogWrite(ledA, 100)....analogWrite(ledA, 0) in the appropriate loops, but didn't want to type all that out in the first post. Sorry you didn't seem to catch that.
No, it shouldn't. LagA is zero, and it's just a remnant from troubleshooting. Trust me, that code works exactly like I want it to. The regulatorTest code works like I want it to. Now I need to merge the two. For regulatorTest code, the value that is iterated over is fadevalue until maxvalue is reached. How long it takes to reach maxvalue depends on what fadevalue is, the pwm frequency, and how long analogWrite takes to work. What I want to do is say, I want this entire process, from fadeValue = 0 to fadeValue = maxvalue, to take exactly 1 second (or some other unit of time--1/2 of the LED activation frequency I explained above. This would be analogous to OnTime). When turning the LED off, I would like it to turn off (either quickly or slowly) and remain off for OffTime. Then after OffTime and whatever Lags, turn back on again. Is this possible? And if so, could you please tell me how?
I am NOT recommending this as a solution but it is my attempt to express clearly my understanding of what you are trying to achieve. If I have the concept all wrong (quite likely) then please try to explain it again
byte ledBrightness = 0;
for (byte n = 0; n < 20; n++) {
analogWrite(ledPin, ledBrightness);
ledBrightness += 12;
delay(50);
}
Wait, so...it is probably safe to say that updating the LED brightness will take less than 50ms. By inserting that delay, you can specify exactly how long each round lasts, and if you know the stepsize and maxvalue, you can essentially know the entire frequency loop.
The problem with the delay is that I have 3 other loops that are running individually and delay, of course, would interrupt whatever they're doing.
zaneywolf:
The problem with the delay is that I have 3 other loops that are running individually and delay, of course, would interrupt whatever they're doing.
Is there another option?
Well I did specifically say I was not recommending that solution - precisely because it uses delay().
Have a look at how millis() is used to manage timing without blocking in several things at a time
updating the LED brightness will take less than 50ms
The quad_led_1_backup is a modified version of the code available of the Demonstration Code for several things at the same time code pinned to the top of this forum. I just took out the bits I didn't need and put in the bits I did.
Sorry. It is hard to remember all the circumstances of many completely different Threads.
On the other hand, if you are familiar I am not clear about what you need assistance with when you say, in Reply #10 "The problem with the delay is that I have 3 other loops that are running individually"
This image shows the different patterns I would like to achieve in the activation of each pink pneunet, using the PWM-based regulatorTest_backup code. Right now, that code acts like a simple on/off switch, but I need it to be able to control each pneunet individually just as Quad_LED_1_backup is able to code each LED individually, using activation frequency as an input rather than as a byproduct. Quad_LED_1_backup can achieve all these different patterns using the variables OnTime, phase_A, and phase_B. I would like to achieve the same patterns of activation in regulatorTest_backup using the same variables.
That looks fascinating. However I still don't get the drawing with the coloured squares. Can you post it here (see this Image Guide) so that others can see it more easily.
I think the problem I have with the coloured squares is that they convey an ON-OFF pattern to me but you seem to be looking for something else.
You said the code in Reply #8 reflects the sort of thing you want - except that you need 4 of them at the same time. Maybe you an produce a piece of pseudo code in that style ignoring the fact that (because it uses delay() ) it won;t actually work. But it might convey your requirement more clearly. Alternatively write the requirement down as a series of steps, one on each line like this (which is probably far off the mark)
blow bag 1
wait 5
blow bag 2
wait 5
deflate bag 1
blow bag 3
wait 5
etc etc
Is there another way besides delay to control how fast the fade occurs?
int led = 9; // the PWM pin the LED is attached to
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
// the setup routine runs once when you press reset:
void setup() {
// declare pin 9 to be an output:
pinMode(led, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
// set the brightness of pin 9:
analogWrite(led, brightness);
// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;
// reverse the direction of the fading at the ends of the fade:
if (brightness <= 0 || brightness >= 255) {
fadeAmount = -fadeAmount;
}
// wait for 30 milliseconds to see the dimming effect
delay(30);
}
Sorry, I didn't say the page 2 replies. I drew the 'colored squares' guide when I was trying to figure out exactly how the Quad_LED_1_backup code could be made. You're right, R, they're not quite accurate when it comes to PWM because of the ramp up. I can redraw it to better reflect the code I want to achieve.
There's a corresponding image that explains what 1R, 2L, 2R, and 1L correspond to in a dropbox folder somewhere that might help it make more sense, in general. If you have the little swimming pneufish with the four blocks, two on each side, then 1R is the right block in the first set, 1L is the left block in the first set, 2R and 2L, the right and left blocks in the second set. So the colored squares indicate how they are activated in relation to each other.
For example the very first block with Phase_A and Phase_B equal zero, the pattern would be a simple alternating pattern. 1R and 2L would both activate at the same time, forming an S shape in the pneufish. Then 1L and 2R would activate, forming the S in the other direction. Simple nearly-sinusoidal motion. Having Phase_A and Phase_B allows for more complicated (and hopefully realistic) patterns.
int led = 9; // the PWM pin the LED is attached to
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
unsigned long lastChangeTime;
unsigned long changeInterval = 30;
// the setup routine runs once when you press reset:
void setup() {
// declare pin 9 to be an output:
pinMode(led, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
// set the brightness of pin 9:
analogWrite(led, brightness);
if (millis() - lastChangeTime > changeInterval)
{
lastChangeTime += changeInterval;
// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;
// reverse the direction of the fading at the ends of the fade:
if (brightness <= 0 || brightness >= 255) {
fadeAmount = -fadeAmount;
}
// wait for 30 milliseconds to see the dimming effect
//delay(30);
}
}