controlling multipal LED using PWM Channels for power saving

hellow…

need a small help TIA…

i have four PWM channels with 1000 Hz freq. each

what i need to do is given in attachment …can any one guide me for that

BTW i m beginner

Screenshot_3.png

OP’s pic:

How to inline an image

You could surely do that with 4 blink with delays?

At t=0, write pinA high.

At t= whatever (you do the maths* ;) ) set it low, turn pinB high

etc etc....

  • hint: read the 'scope...

Above assumes blink WITH delay would be ok: you didn't say if the skecth needs to do anything else.

Otherwise, use blink withOUT delay thinking, stick the leds in an array, and just "walk" across them. Every blink interval, turn the current led off, increment the led index, and turn that one on.

blomcrestlight:
Above assumes blink WITH delay would be ok: you didn’t say if the skecth needs to do anything else.

Otherwise, use blink withOUT delay thinking, stick the leds in an array, and just “walk” across them. Every blink interval, turn the current led off, increment the led index, and turn that one on.

The 4 outputs of the micro controller will be connected to 4 light outputs
of the hardware that can handle a maximum of 200W of power each.
• The actual light fixture can only handle a total of 200W of power.
• This means that if all 4 outputs were on 100% each would use 200W of
power and the complete fixture would use 800W of power. This will
destroy the fixture because the fixture can only handle 200W.
• This means that the recipe created on the app has to be converted in the
micro to ensure the fixture never uses more than 200W. This feature in the
micro is like a basic “encryption” of the light recipe which does not allow
any other light to work off our controller and vice versa.

Well the code below produces the waveforms in your 'scope trace at the top of the thread.

My 'scope has only 2 channels, so there’s a 2x250us “gap” between the end of ch2 (blue) and the start of ch1 (yellow) where the other 2 channels would be if I had a 4 channel scope.

If that’s what you actually want I have no idea, but it matches your trace.

// 671664 WITH delay
// 19 mar 2020

const byte ch1 = 2;
const byte ch2 = 3;
const byte ch3 = 4;
const byte ch4 = 5;

bool debug = false;

void setup()
{
  Serial.begin(9600);
  Serial.println("setup()...");
  Serial.println("250us x 4 channels");
  pinMode(ch1, OUTPUT);
  pinMode(ch2, OUTPUT);
  pinMode(ch3, OUTPUT);
  pinMode(ch4, OUTPUT);

  Serial.println("setup() done");
} //setup

void loop()
{
  if (debug) Serial.print("a");
  digitalWrite(ch1, HIGH);
  digitalWrite(ch2, LOW);
  digitalWrite(ch3, LOW);
  digitalWrite(ch4, LOW);
  delayMicroseconds(250);  //full speed... scope only
  //delay(250); //milliseconds to make leds visible as test

  if (debug) Serial.print("b");
  digitalWrite(ch1, LOW);
  digitalWrite(ch2, HIGH);
  digitalWrite(ch3, LOW);
  digitalWrite(ch4, LOW);
  delayMicroseconds(250);  //full speed... scope only
  //delay(250); //milliseconds to make leds visible as test

  if (debug) Serial.print("c");
  digitalWrite(ch1, LOW);
  digitalWrite(ch2, LOW);
  digitalWrite(ch3, HIGH);
  digitalWrite(ch4, LOW);
  delayMicroseconds(250);   //full speed... scope only
  //delay(250); //milliseconds to make leds visible as test

  if (debug) Serial.println("d");
  digitalWrite(ch1, LOW);
  digitalWrite(ch2, LOW);
  digitalWrite(ch3, LOW);
  digitalWrite(ch4, HIGH);
  delayMicroseconds(250);  //full speed... scope only
  //delay(250); //milliseconds to make leds visible as test

} //loop

250MIC.jpg

... but that version uses delay() so is going to block your sketch from doing anything else (you didn't say if it needs to or not.)

blomcrestlight:
Well the code below produces the waveforms in your 'scope trace at the top of the thread.

My 'scope has only 2 channels, so there’s a 2x250us “gap” between the end of ch2 (blue) and the start of ch1 (yellow) where the other 2 channels would be if I had a 4 channel scope.

If that’s what you actually want I have no idea, but it matches your trace.

// 671664 WITH delay

// 19 mar 2020

const byte ch1 = 2;
const byte ch2 = 3;
const byte ch3 = 4;
const byte ch4 = 5;

bool debug = false;

void setup()
{
 Serial.begin(9600);
 Serial.println(“setup()…”);
 Serial.println(“250us x 4 channels”);
 pinMode(ch1, OUTPUT);
 pinMode(ch2, OUTPUT);
 pinMode(ch3, OUTPUT);
 pinMode(ch4, OUTPUT);

Serial.println(“setup() done”);
} //setup

void loop()
{
 if (debug) Serial.print(“a”);
 digitalWrite(ch1, HIGH);
 digitalWrite(ch2, LOW);
 digitalWrite(ch3, LOW);
 digitalWrite(ch4, LOW);
 delayMicroseconds(250);  //full speed… scope only
 //delay(250); //milliseconds to make leds visible as test

if (debug) Serial.print(“b”);
 digitalWrite(ch1, LOW);
 digitalWrite(ch2, HIGH);
 digitalWrite(ch3, LOW);
 digitalWrite(ch4, LOW);
 delayMicroseconds(250);  //full speed… scope only
 //delay(250); //milliseconds to make leds visible as test

if (debug) Serial.print(“c”);
 digitalWrite(ch1, LOW);
 digitalWrite(ch2, LOW);
 digitalWrite(ch3, HIGH);
 digitalWrite(ch4, LOW);
 delayMicroseconds(250);   //full speed… scope only
 //delay(250); //milliseconds to make leds visible as test

if (debug) Serial.println(“d”);
 digitalWrite(ch1, LOW);
 digitalWrite(ch2, LOW);
 digitalWrite(ch3, LOW);
 digitalWrite(ch4, HIGH);
 delayMicroseconds(250);  //full speed… scope only
 //delay(250); //milliseconds to make leds visible as test

} //loop

thank you so muchhh @blomcrestlight but what if i want custom duty cycle?

something like given below

Screenshot_4.png

using smartphone app i need something like that…

• The calculation in the app is simple. The total percentage of power to the outputs
cannot go over 100%. Below are a few examples to better understand:
• Full Spectrum (A,B,C,D = 100%) – All 4 channels cannot be at 100% all at the same
time so the app will only allow each channel to be set to 25% equaling 100%. The
app will send to the ESP 25% for all 4 channels. The combined LED lights will be at
their maximum, but each light is only using 25% of its maximum.
• Vegi (A=100%, B=50%, C=0%, D=0%) – The app will send to the ESP 66.6% for A, 33.3% for B and 0% for C and D. The total will be 100% to the LED lights.
• The equation is: Multiplication factor for A,B,C,D on app = (100/A+B+C+D (on the
app)) * decimal of A, B, C, D
• Vegi equation: App A=100 or 1, App B=50% or .5, App C,D=0. Set to ESP for A = 1*(100/100+50+0+0) = 1*(100/150) = 1*.667 = .667 or 66.7%. Sent to ESP for B =
.5*(100/100+50+0+0) = .5*(100/150) = .5*.667 = .333 or 33.3%.

I showed you in #1 how to inline an image :(

|500x353

You would have different delays so instead of each "block" ending with:

delayMicroseconds(250);

.. with the 250 hardcoded, you would need:

..
delayMicroseconds(ch1_time); 
..
delayMicroseconds(ch2_time); 
..
delayMicroseconds(ch3_time); 
..
delayMicroseconds(ch4_time);

...where the chn_time would be variables.

Then you would need to get those calculated numbers from the 'phone to the Arduino, perhaps with BT, into each variable. (Or have the phone send the % and calc the actual time in the Arduino.)

If in the meantime you hardcode a few values other than 250 into the delay()s you should get the right output as PoC.

You haven't said yet if using delay() is ok for this; if not you have a lot more learning to do.

blomcrestlight:
I showed you in #1 how to inline an image :frowning:

You would have different delays so instead of each “block” ending with:

delayMicroseconds(250);

… with the 250 hardcoded, you would need:

..

delayMicroseconds(ch1_time);

delayMicroseconds(ch2_time);

delayMicroseconds(ch3_time);

delayMicroseconds(ch4_time);




...where the chn_time would be variables.

Then you would need to get those calculated numbers from the 'phone to the Arduino, perhaps with BT, into each variable. (Or have the phone send the % and calc the actual time in the Arduino.)

If in the meantime you hardcode a few values other than 250 into the delay()s you should get the right output as PoC.

You haven't said yet if using delay() is ok for this; if not you have a lot more learning to do.

you are right sir…

using delay() block my sketch from reading RTC time and many more things !!!

i think we need to use blinkwithoutdelay but how can i do that
a m totally beginner for that
as you said i need lot more learning to do.
and sorry for inline image!!!

Please stop quoting a whole post. If you need to quote anything, just grab a bit out like this:

i think we need to use blinkwithoutdelay but how can i do that

"We" meaning "you".... :o

If you have a look at #7 in this thread, I posted some delay()-less code to "walk" through 4x leds for that OP's Lego hotel sign.

no we means me and you sir..and i m student :)

and i saw that OP's Lego hotel sign thread i try to understand it that something like state machine

but what for duty cycle changing? :confused:

haresh_007: no we means me and you sir..and i m student :)

But that doesn't make some random helper on an internet forum part of a "we". The "we" is you and the faculty.

haresh_007: and i saw that OP's Lego hotel sign thread i try to understand it that something like state machine

No, it just uses the blink without delay idea. But instead of just toggling one led when the interval expires, it turns "this" led off and increments the array index to go to the "next" led and turns it on.

You need to put your actual project on the back burner, and get to grips with some underlying techniques; like blink without delay.

haresh_007: but what for duty cycle changing? :confused:

With blink without delay I reckon the (eg) BT input can be interleaved, read the values from the phone into some variables. Then (off the top of my head here...) have those times in an array just like the pins are in an array, so when it's using pin[m] it also uses interval[m] kind of thing.

If it looks like BT will be in your solution, looks at Robin2's serial input tutorials, since that's what BT is. Although he doesn't mention BT, and BT wasn't his specific context, it's the way I would go about getting values out of a stream of stuff coming in over serial, regardless of the actual external source.

You're trying to answer too many things at once. It won't work that way. Do things one at a time; or at least in parallel but not interleaved to start. That will work as long as you're mindful of needing to interleave various things (like get the time you said) so do it delay-lessly right from the start.

blomcrestlight: You need to put your actual project on the back burner, and get to grips with some underlying techniques; like blink without delay.

great.....thanks for help.

now i find another help full information

Think of things as building blocks...

Get blink without delay under your belt, in its basic form with one led. Then figure out how to do 2 or 3. Then you'll think "whoa, there has to be an easier way than repeating loads of code" and meet arrays.

In the meantime you could get your rtc working in another sketch, and wonder "how can read and display the time while the leds are blinking". Figure that out...

Here's an excellent video on how to do two delay()-less blinks together.

And right from the start use functions and call everything in one-liners from loop() to keep it tidy, maybe like:

void loop()
{
readBT();
manageFourChannels();
readRTC();
readButtons();
if (time==1100) makeTheTea();
updateLCD();
}
#include <Arduino.h>

unsigned long currentMillis = 0;
long previousMillisled1 = 0;    //last time  LED1 was updated
long previousMillisled2 = 0;  //last time  LED2 was updated
long previousMillisled3 = 0;    //last time  LED3 was updated
long previousMillisled4 = 0;  //last time  LED4 was updated


long Led1_Intaraval = 1; //interval to blink  LED1 (milliseconds)
long Led2_Intarval = 1;    //interval to blink  LED2 (milliseconds)
long Led3_Intarval = 1; //interval to blink  LED3 (milliseconds)
long Led4_Intaraval = 1;    //interval to blink  LED4 (milliseconds)

int LedState1 = HIGH; //ledState for  LED1
int LedState2 = HIGH;   //ledState for  LED2
int LedState3 = HIGH; //ledState for LED3
int LedState4 = HIGH;   //ledState for  LED4

const byte ch1 = 16;
const byte ch2 = 17;
const byte ch3 = 18;
const byte ch4 = 19;

bool debug = false;


void manageLed1() {  //check if it's time to change the Red LED yet
  if(currentMillis - previousMillisled1 > Led1_Intaraval) {
    //store the time of this change
    previousMillisled1 = currentMillis;
    LedState1 = (LedState1 == HIGH) ? LOW : HIGH;
    digitalWrite(16, LedState1);
  }
}

void manageLed2() {
  //check if it's time to change the green LED yet 
  if(currentMillis - previousMillisled2 > Led2_Intarval) {
    //store the time of this change
    previousMillisled2 = currentMillis;
    LedState2 = (LedState2 == HIGH) ? LOW : HIGH;
    digitalWrite(17, LedState2);
  }
}
void manageLed3() {
  //check if it's time to change the green LED yet 
  if(currentMillis - previousMillisled3 > Led3_Intarval) {
    //store the time of this change
    previousMillisled3 = currentMillis;
    LedState3 = (LedState3 == HIGH) ? LOW : HIGH;
    digitalWrite(18, LedState3);
  }
}

void manageLed4() {
  //check if it's time to change the green LED yet 
  if(currentMillis - previousMillisled4 > Led4_Intaraval) {
    //store the time of this change
    previousMillisled4 = currentMillis;
    LedState4 = (LedState4 == HIGH) ? LOW : HIGH;
    digitalWrite(19, LedState4);
  }
}

void setup()
{
  Serial.begin(115200);
  pinMode(ch1, OUTPUT);
  pinMode(ch2, OUTPUT);
  pinMode(ch3, OUTPUT);
  pinMode(ch4, OUTPUT);

  currentMillis = millis();
  Serial.println("setup() done");



 

} //setup

void loop()
{
  
    currentMillis = millis();
    manageLed1();
    manageLed2();
    manageLed3();
    manageLed4();
     
    
} //loop

that what i make and get output given below

|500x163

Not sure if that's what you meant to do as a starting point?

But it's like that because you're not in any way making it only do ch2's high after ch1's is finished.

That's why my "hotel sign" code has the leds in an array, and cycles to the next pin each time it's time to off the current one.

as i used that code i manage to get given output…

but what for freq…?
that has been devided

i mean i can only manage to make intarval of 1 millisecond

where i need 250 microsecond delay for getting 1000 Hz each freq. for each channel

Screenshot_6.png

Please do your own inlining of the pics...