# Question about connecting digispark pin P1 to led driver board with PWM pin...

#### hoghunter

##### Member
You need braces after while statement.
I don't know if the compiler accepts the while statement as it is now.
Probably the statements in pwm_up and pwm_dn are executed only once

Should be something like this:
---------------
void PWM_UP()
{
//for (int i=0; i <= 60; i++) //need to add .333 sec delay somewhere for a 20 sec overall fade down duration

while( delay1 > 0 && delay1< 10000)
{
digitalWrite(ledPin,HIGH);
delayMicroseconds(delay1); //increase duty cycle at 100Hz - delay #1 - HIGH
digitalWrite(ledPin,LOW);
delayMicroseconds(delay2); //delay #2 - LOW
delay1=delay1-delayValue;
delay2=delay2+delayValue;
}
}

Same for PWM_DN()
Hi jjw,
I'm quite sure the actual fade sequences, UP & DN, are looping properly. They are simply looping too fast so it appears as a blink on/off approx 7 times per second. The entire sketch loops 7 times per second, continuously. My problem now is, I need to create a 1/3 second pause every 55 (changes in pulse width) loops of the UP & DN functions, which would take approx 60 seconds. 60/.33=180, 10000/180=55.55
I'm working on implementing this scenario now. MikeMI has been a huge help over the last few days, but I just can't grasp specifically what he is conveying and that is on me, of course.
Maybe he'll chime in later....
I did a bit more testing using the 500Hz PWM signal (analog 1-255) to my led driver and although there is fading, it is obviously not fading smoothly and does not like the 500Hz so I do need to get this Hz coding figured out so regardless of an IC or modules requirement, I'll be able to adjust for it.

Last edited:

#### MikeMl

##### Well-Known Member
Possibly a better idea:

I have been assuming that your PWM function has two delays in it that add up to the period. Say the PWM freq is 100Hz; that means that the PWM period is 10ms = 0.01s. If you put the loop inside the PWM function, and you looped 50 times before exiting, that would mean you spend 0.5s looping inside the PWM function.

The third argument to the PWM function could be the number of times you do the loop before exiting (e.g. 50), or it could be the actual time spend inside the PWM loop (e.g. 0.5 seconds) if you calculate the number of loops on the fly from the passed-in argument (e.g. index=time/per = 0.5/0.01=50).

Last edited:

#### hoghunter

##### Member
Sorry, but I dont have the time to check your code right now, but if you want (say) 100 different steps of PWM duty cycle, each lasting the same duration, then if the index in the for loop runs from 0 to 99, the duty cycle % can also run 0% to 99%. The actual delay times (in us) would be computed from the index value (0 to 99) passed to the PWM sub by the loop...
Thank you so much Mike !! I will study that and try to implement it. I will post it too for you to take a look at whenever you get time.
Thanks again, I really do appreciate your help. .........MOVING FORWARD

#### hoghunter

##### Member
I have been assuming that your PWM function has two delays in it that add up to the period. Say the PWM freq is 100Hz; that means that the PWM period is 10ms = 0.01s
Is this not correct?
Code:
 */
int sensorPin = 2;  //motion sensor out pin connected to digital pin 2 (P2 on digispark)
int ledPin = 1;    // LED driver module's PWM pin is connected to digital pin 1 (P1 on digispark)
int delay1 = 9999; //HIGH pulse
int delay2 = 0; //LOW pulse
const int delayValue = 20;

while(0<delay1>10000)
digitalWrite(ledPin,LOW);
delayMicroseconds(delay1); //decrease duty cycle at 100Hz - delay #1 - LOW
digitalWrite(ledPin,HIGH);
delayMicroseconds(delay2); //delay #2 - HIGH
delay1=delay1-delayValue;
delay2=delay2+delayValue;

#### MikeMl

##### Well-Known Member
Your while() is not correct. Look at this for an example. Note the missing {
}.

If checking a variable against a limit in a while statement like while(1000<delay1) {...}, there needs to be something that modifies the variable inside the while statement (e.g. delay1++, and something that initializes delay1 like delay1=0; before you enter the while statement. That is why I showed you the for loop, because the initialization, the incrementing, and the testing against a limit of the loop variable is intrinsic in the definition.

#### hoghunter

##### Member
I think a lightbulb has came on finally. The .01 second of time for high & low at 100hz, then looping makes much more sense to me. I have noted the sketch on a note pad and will edit in the morning. I plan to have the pwm function loop 33 times, then call a function to change the delay variable by 55, then loop back incrementing the main FOR loop variable by one until it reaches 180... in a nutshell.
180x.3 sec = 1 min
and
10000 microsecs ÷ 180 = 55

Thanks for cleaning up my while statement also. I knew I had to clean that up.

#### hoghunter

##### Member
Mike,
Here is the revised sketch. After testing, it appears to start to run PWM_UP, but hangs after setting pin1 very dim.... I have more studying to do as it relates to calling functions and looping obviously. Other than that, how does it look?
Code:
   /*

The circuit:
* LED (+) attached to pin 1.
* motion sensor 'signal' will be attached to pin 2
* digispark microcontroller

last edit 8/17/2017
By John A. Austin

//IMPORTANT NOTE: reverse logic is required based on LED driver board's PWM pin functionality
//REVERSE LOGIC - CHANGE AFTER TESTING

*/
//*******************************************************************************************

int sensorPin = 2;  //motion sensor out pin connected to digital pin 2 (P2 on digispark)
int ledPin = 1;    // LED driver module's PWM pin is connected to digital pin 1 (P1 on digispark)
int delay1 = 9999; //HIGH pulse
int delay2 = 1; //LOW pulse
const int incrValue_up = 55;
const int incrValue_dn = 167;
int y = 1;
int x = 1;

//********************************************************************************************

void setup()
{
// initialize the sensorPin as an input:
pinMode(sensorPin, INPUT);
// initialize the ledPin as an output:
pinMode(ledPin, OUTPUT);
}
void INCR_UP()
{
delay1=delay1-incrValue_up; //incremental change to pulse width value
delay2=delay2+incrValue_up; //increment change to pulse width value
}
void INCR_DN()
{
delay1=delay1-incrValue_dn; //incremental change to pulse width value
delay2=delay2+incrValue_dn; //increment change to pulse width value
}
void PWM_UP() //loops 33 times for a total of 1/3 second at 100Hz
{
while(x < 33)
digitalWrite(ledPin,LOW);
delayMicroseconds(delay1); //decrease duty cycle at 100Hz - delay #1 - LOW
digitalWrite(ledPin,HIGH);
delayMicroseconds(delay2); //delay #2 - HIGH
x++;

}

void PWM_DN() //loops 33 times for a total of 1/3 second at 100Hz
{
while(x < 33)
digitalWrite(ledPin,HIGH);
delayMicroseconds(delay1); //increase duty cycle at 100Hz - delay #1 - HIGH
digitalWrite(ledPin,LOW);
delayMicroseconds(delay2); //delay #2 - LOW
x++;
}

//"intended" SKETCH FLOW:
//motion sensor triggers pin2 on digispark
//PWM_UP is called and loops 33 times for a total of 1/3 seconds
//then back to main code and INCR() is called to change the pulse width (HIGH/LOW) values
//INCR() is called after each loop to change the pulse width (HIGH/LOW) values
//the looping increment is increased by one and the loop starts over
//after 180 loops and 60 seconds have passed, the loop count variable is set back to 1
//the LEDS are held at full brightness for 5 minutes (10 seconds for testing)
//PWM_DN is then called and loops 33 times for a total of 1/3 seconds
//then back to main code and INCR() is called to change the pulse width (HIGH/LOW) values
//INCR() is called after each loop to change the pulse width (HIGH/LOW) values
//the looping increment is increased by one and the loop starts over
//after 60 loops and 20 seconds have passed, the loop count variable is set back to 1
//*************************************************************************************************

void loop()
{
{
loop;
}
else
{
while(y < 180)
{
PWM_UP();
INCR_UP();
y++;
}
{
int y=1;
}
{
digitalWrite(ledPin, HIGH); //set leds at full brightness
delay(10000); //hold at full brightness for 10 seconds (for testing purposes)
}
while(y < 60)
{
PWM_DN();
INCR_DN();
y++;
}
{
int y=1;
}
}
}

#### jjw

##### Member
At least you should set x=1 before while(x<33)
in PWM_UP() and PWM_DN() functions.
Now x=33 after first run of PWM_UP() and they won't execute anymore.

#### hoghunter

##### Member
Success!! I have the PWM_UP sequence running properly and I have a smooth fade over a 1 min period.
However, as soon as it finishes the fade up to full brightness, it starts flashing rapidly, so I have more debugging to do. Just a matter of some flow control maintenance and I'll have it!!
I changed the 'while' loops to 'for' loops. I also changed the loop count for the 1 minute fade up sequence to 360 for a smoother fade.
Code:
   /*

The circuit:
* LED (+) attached to pin 1.
* motion sensor 'signal' will be attached to pin 2
* digispark microcontroller

last edit 8/17/2017
By John A. Austin

//FUNCTIONALITY: (WILL CHANGE TO REVERSE LOGIC FOR PWM ON DRIVER MODULE)
//read status of motion sensor (HIGH or LOW)
//If HIGH, fade leds from off to on over a one minute period
//then fade to off over a 32 second period
//wait 5 seconds and read sensor pin again

//IMPORTANT NOTE: reverse logic is required based on LED driver board's PWM pin functionality
//REVERSE LOGIC - CHANGE AFTER TESTING

*/
//*******************************************************************************************

int sensorPin = 2;  //motion sensor out pin connected to digital pin 2 (P2 on digispark)
int ledPin = 1;    // LED driver module's PWM pin is connected to digital pin 1 (P1 on digispark)
int delay1 = 9999; //HIGH pulse
int delay2 = 1; //LOW pulse
const int incrValue_up = 28;
const int incrValue_dn = 167;
int y = 1;
int x = 1;

//********************************************************************************************

void setup()
{
// initialize the sensorPin as an input:
pinMode(sensorPin, INPUT);
// initialize the ledPin as an output:
pinMode(ledPin, OUTPUT);
}
void INCR_UP()
{
delay1=delay1-incrValue_up; //incremental change to pulse width value
delay2=delay2+incrValue_up; //increment change to pulse width value
}

void INCR_DN()
{
delay1=delay1-incrValue_dn; //incremental change to pulse width value
delay2=delay2+incrValue_dn; //increment change to pulse width value
}

void PWM_UP() //loops 33 times for a total of 1/3 second at 100Hz
{
for (x = 0; x <= 17; x++)
{
digitalWrite(ledPin,LOW);
delayMicroseconds(delay1); //decrease duty cycle at 100Hz - delay #1 - LOW
digitalWrite(ledPin,HIGH);
delayMicroseconds(delay2); //delay #2 - HIGH
}}

void PWM_DN() //loops 33 times for a total of 1/3 second at 100Hz
{
for (x = 0; x <= 33; x++)
{
digitalWrite(ledPin,HIGH);
delayMicroseconds(delay1); //increase duty cycle at 100Hz - delay #1 - HIGH
digitalWrite(ledPin,LOW);
delayMicroseconds(delay2); //delay #2 - LOW
}}

//"intended" SKETCH FLOW:
//motion sensor triggers pin2 on digispark
//PWM_UP is called and loops 33 times for a total of 1/3 seconds
//then back to main code and INCR() is called to change the pulse width (HIGH/LOW) values
//INCR() is called after each loop to change the pulse width (HIGH/LOW) values
//the looping increment is increased by one and the loop starts over
//after 180 loops and 60 seconds have passed, the loop count variable is set back to 1
//the LEDS are held at full brightness for 5 minutes (10 seconds for testing)
//PWM_DN is then called and loops 33 times for a total of 1/3 seconds
//then back to main code and INCR() is called to change the pulse width (HIGH/LOW) values
//INCR() is called after each loop to change the pulse width (HIGH/LOW) values
//the looping increment is increased by one and the loop starts over
//after 60 loops and 20 seconds have passed, the loop count variable is set back to 1
//*************************************************************************************************

void loop()
{
{
loop;
}
else
{
for (y = 0; x <= 360; y++)
{
PWM_UP();
INCR_UP();
}}
{
int y = 1;
}
{
digitalWrite(ledPin, HIGH); //set leds at full brightness
delay(10000); //hold at full brightness for 10 seconds (for testing purposes)
}
{
for (y = 0; x <= 60; y++)
{
PWM_DN();
INCR_DN();
}}
{
int delay1 = 9999; //HIGH pulse
int delay2 = 1; //LOW pulse
int y = 1;
int x = 1;
}
}

#### hoghunter

##### Member
At least you should set x=1 before while(x<33)
in PWM_UP() and PWM_DN() functions.
Now x=33 after first run of PWM_UP() and they won't execute anymore.
jjw,
I noticed that and did make that change. It is going through the fade up sequence correctly now... (see my post #49)
Thank you

#### hoghunter

##### Member
Ok, here is what my sketch is doing:
• fade up sequence over 60 sec period is working fine
• then approx 3 seconds of rapid flashing/blinking
• then holding at full brightness for 10 seconds (as included in sketch)
I know it is a matter of controlling the program flow, but I have not found my error(s) yet.....

Code:
   /*
VISIBLE_FEEDER_LIGHT_SKETCH_700ma

The circuit:
* LED (+) attached to pin 1.
* motion sensor 'signal' will be attached to pin 2
* digispark microcontroller

last edit 8/17/2017
By John A. Austin

//FUNCTIONALITY: (WILL CHANGE TO REVERSE LOGIC FOR PWM ON DRIVER MODULE)
//read status of motion sensor (HIGH or LOW)
//If HIGH, fade leds from off to on over a one minute period
//then fade to off over a 32 second period
//wait 5 seconds and read sensor pin again

//IMPORTANT NOTE: reverse logic is required based on LED driver board's PWM pin functionality
//REVERSE LOGIC - CHANGE AFTER TESTING

*/
//*******************************************************************************************

int sensorPin = 2;  //motion sensor out pin connected to digital pin 2 (P2 on digispark)
int ledPin = 1;    // LED driver module's PWM pin is connected to digital pin 1 (P1 on digispark)
int delay1 = 9999; //HIGH pulse
int delay2 = 1; //LOW pulse
const int incrValue_up = 28;
const int incrValue_dn = 84;
int y = 1;
int x = 1;

//********************************************************************************************

void setup()
{
// initialize the sensorPin as an input:
pinMode(sensorPin, INPUT);
// initialize the ledPin as an output:
pinMode(ledPin, OUTPUT);
}
void INCR_UP()
{
delay1=delay1-incrValue_up; //incremental change to pulse width value
delay2=delay2+incrValue_up; //increment change to pulse width value
}

void INCR_DN()
{
delay1=delay1-incrValue_dn; //incremental change to pulse width value
delay2=delay2+incrValue_dn; //increment change to pulse width value
}

void PWM_UP() //loops 17 times for a total of 1/6 second at 100Hz
{
for (x = 0; x <= 17; x++)
{
digitalWrite(ledPin,LOW);
delayMicroseconds(delay1); //decrease duty cycle at 100Hz - delay #1 - LOW
digitalWrite(ledPin,HIGH);
delayMicroseconds(delay2); //delay #2 - HIGH
}}

void PWM_DN() //loops 17 times for a total of 1/6 second at 100Hz
{
for (x = 0; x <= 17; x++)
{
digitalWrite(ledPin,HIGH);
delayMicroseconds(delay1); //increase duty cycle at 100Hz - delay #1 - HIGH
digitalWrite(ledPin,LOW);
delayMicroseconds(delay2); //delay #2 - LOW
}}

//"intended" SKETCH FLOW:
//motion sensor triggers pin2 on digispark
//PWM_UP is called and loops 17 times for a total of 1/6 seconds
//then back to main code and INCR() is called to change the pulse width (HIGH/LOW) values
//INCR() is called after each loop to change the pulse width (HIGH/LOW) values
//the looping increment is increased by one and the loop starts over
//after 360 loops and 60 seconds have passed, the loop count variable is set back to 1
//the LEDS are held at full brightness for 5 minutes (10 seconds for testing)
//PWM_DN is then called and loops 17 times for a total of 1/6 seconds
//then back to main code and INCR() is called to change the pulse width (HIGH/LOW) values
//INCR() is called after each loop to change the pulse width (HIGH/LOW) values
//the looping increment is increased by one and the loop starts over
//after 120 loops and 20 seconds have passed, the loop count variable is set back to 1
//*************************************************************************************************

void loop()
{
{
loop;
}
else
{
for (y = 1; y <= 360; y++)
{
PWM_UP();
INCR_UP();
}}
{
digitalWrite(ledPin, HIGH); //set leds at full brightness
delay(10000); //hold at full brightness for 10 seconds (for testing purposes)
}
int delay1 = 9999;
int delay2 = 1;
int y = 1;
int x = 1;
{
for (y = 1; y <= 120; y++)
{
PWM_DN();
INCR_DN();
}}
{
int delay1 = 9999;
int delay2 = 1;
int y = 1;
int x = 1;
}
}

#### jjw

##### Member
Check the delays, they go out of boundaries.
360×28 = 10080
9999 - 10080 = -81, which is as unsigned integer over 65000

#### hoghunter

##### Member
I adjusted those numbers to come out evenly, but it made no difference with the flashing during the PWM_DN sequence. Everything is working properly up to and including OFF/ON/OFF sequence in the middle of the sketch. I have been making adjustments to the code all morning and cannot fix the 'flashing'.
It appears the led is lit at a certain lower brightness, say 50% maybe and flashing to full (possibly) in rapid pulses, continuously. I have added key comment lines into my code below:
Code:
   /*

The circuit:
* LED (+) attached to pin 1.
* motion sensor 'signal' will be attached to pin 2
* digispark microcontroller

last edit 8/17/2017
By John A. Austin

//IMPORTANT NOTE: reverse logic is required based on LED driver board's PWM pin functionality

*/
//*******************************************************************************************

int sensorPin = 2;  //motion sensor out pin connected to digital pin 2 (P2 on digispark)
int ledPin = 1;    // LED driver module's PWM pin is connected to digital pin 1 (P1 on digispark)
int delay1 = 9999;
int delay2 = 1;
const int incrValue_up = 10;
const int incrValue_dn = 30;
int y = 1;
int x = 1;

//********************************************************************************************

void setup()
{
// initialize the sensorPin as an input:
pinMode(sensorPin, INPUT);
// initialize the ledPin as an output:
pinMode(ledPin, OUTPUT);
}
void INCR_UP()
{
delay1=delay1-incrValue_up; //incremental change to pulse width value
delay2=delay2+incrValue_up; //increment change to pulse width value
}

void INCR_DN()
{
delay1=delay1-incrValue_dn; //incremental change to pulse width value
delay2=delay2+incrValue_dn; //increment change to pulse width value
}

void PWM_UP() //loops 6 times for a total of .06 seconds at 100Hz
{
for ( int x = 1; x <= 6; x++)
{
digitalWrite(ledPin,HIGH);
delayMicroseconds(delay1); //decrease duty cycle at 100Hz - delay #1 - LOW
digitalWrite(ledPin,LOW);
delayMicroseconds(delay2); //delay #2 - HIGH
}}

void PWM_DN() //loops 6 times for a total of .06 seconds at 100Hz
{
for ( int x = 1; x <= 6; x++)
{
digitalWrite(ledPin,LOW);
delayMicroseconds(delay1); //increase duty cycle at 100Hz - delay #1 - HIGH
digitalWrite(ledPin,HIGH);
delayMicroseconds(delay2); //delay #2 - LOW
}}

//SKETCH FLOW:
//motion sensor triggers pin2 on digispark
//PWM_UP is called and loops 6 times for a total of .06 seconds
//then back to main code and INCR() is called to change the pulse width (HIGH/LOW) values
//INCR() is called after each loop to change the pulse width (HIGH/LOW) values by 10
//the looping increment is increased by one and the loop starts over
//after 1000 loops and 60 seconds have passed, the loop count variable is set back to 1
//the LEDS are held at full brightness for 5 minutes (10 seconds for testing)
//PWM_DN is then called and loops 6 times for a total of .06 seconds
//then back to main code and INCR() is called to change the pulse width (HIGH/LOW) values by 30
//the looping increment is increased by one and the loop starts over
//after 333 loops and 20 seconds have passed, sketch should to go back to the start and read the sensor pin again
//*************************************************************************************************
// REVERSE LOGIC APPLIES BASED ON PWM PIN ON LED DRIVER BOARD (HIGH=OFF, LOW=ON)
void loop()
{
{
delay(5000); // wait 5 seconds, then check the sensorPin again
loop;
}
else
{
for (int y = 1; y <= 1000; y++) // 60 seconds to fade up
{
PWM_UP();
INCR_UP();
}
// LEDs fade up to full brightness as expected
{
digitalWrite(ledPin,HIGH); // led off
delay(2000); // 2 seconds
}
{
digitalWrite(ledPin,LOW); // led on
delay(10000); // 10 seconds
}
{
digitalWrite(ledPin,HIGH); // led off
delay(2000); // 2 seconds
}
// LEDs come on for 2 seconds then at full brightness for 10 seconds, then back off for 2 seconds.
// Good to this point
// moving on to the fade down sequence below, the leds start flashing rapidly in what appears
// to be an endless loop. Power has to be disconnected.
{
}
// flashing starts here
for (int y = 1; y <= 333; y++) // 20 seconds to fade down
{
PWM_DN();
INCR_DN();
}
{
digitalWrite(ledPin, HIGH);
}}}

#### hoghunter

##### Member
jjw,
I was assuming that one or more of my variables needed to be reset, but have been editing the code for hours trying to debug that and the flashing will not go away. Hopefully a 'second set of eyes' will see the error(s). Thanks for your help.

#### jjw

##### Member
There is still the delay problem.
After 1000 × PWM_UP() and INCR_UP() the delay1 = -1 and delay2 = 10000
PWM_DN() continues from these values, which should be reseted ? ( 9999 and 0 )
I don't know how Arduino reacts to negative delay values.

#### hoghunter

##### Member
There is still the delay problem.
After 1000 × PWM_UP() and INCR_UP() the delay1 = -1 and delay2 = 10000
PWM_DN() continues from these values, which should be reseted ? ( 9999 and 0 )
I don't know how Arduino reacts to negative delay values.
Thanks, I'll take a look at that. Your time is much appreciated.

#### jjw

##### Member
In INCR_DN() the delay1 should be increased and the delay2 decreased as you say in comments for PWM_DN() and then no need to reset the delay values.

Edit: and check also the order of the delays in PWM_DN(), delay2 first ?

Last edited:

#### hoghunter

##### Member
In INCR_DN() the delay1 should be increased and the delay2 decreased as you say in comments for PWM_DN() and then no need to reset the delay values.

Edit: and check also the order of the delays in PWM_DN(), delay2 first ?
I will try swapping the delay1/2 in PWM_DN.

I agree. However, after trying a dozen different ways to get the blinking to go away, I wanted to have code in there to be sure those values were reset correctly.

Also, keep in mind this sketch works with 'reverse logic', so increasing is dimming, up is down, forwards is backwards...........

#### jjw

##### Member
I will try swapping the delay1/2 in PWM_DN.

I agree. However, after trying a dozen different ways to get the blinking to go away, I wanted to have code in there to be sure those values were reset correctly.

Also, keep in mind this sketch works with 'reverse logic', so increasing is dimming, up is down, forwards is backwards...........
I read and write this with a tablet, so it is confusing enough to browse the program back and forth.
I think it would be easier to read if you put the the statements in INCR functions inside the PWMUP, PWMDN functions.

Also you could use #defines to make the logic clear.
For example
#define LedOn low
#define LedOff high
and then Digitalwrite(Ledpin,LedOn)

#### hoghunter

##### Member
Like Mike had said early on, I only needed a function called PWM(), not up/dn... The PWM function stays the same for both up and down, only the numbers change. I adjusted some numbers for the fade down sequence also. As it turns out, delay1 was 10 when PWM_DN tried to run and I was subtracting 33 from that so getting a neg# immediately. It took all this time for me to see it...
The sketch is working great now!!!! Thanks.

Last edited: