Pages: [1]   Go Down
Author Topic: made a PWM without PWM ports  (Read 849 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey there!

so I was bored and testing my PWM skills and with no attachments but an arduino board, trying to get LED13 to accept PWM settings, eventually I hacked for an hour or so trying to use the example "Fade" and I wasn't getting closer to understanding it.

so I made my own Pulse Width Modifier code for digital outputs (specifically LED13).

I hope you liekss.

(probably should be in a different location because I dont need help [I dont know where], I am just so proud of some of my first arduino codings and first coding in years and years and years, compliments to the chef - language and reference and even randoms on forums discussing code are very easy to read and understand!)

Quote
void setup() {
  Serial.begin(9600);
//I like to talk to my arduino and have it report back to me
}

void loop(){
  Serial.println("start");
  int ledPin=13;                // uses arduino D13 LED
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  float DelayValue = .5;        // increment of power
  float TimeofFade = 25;        // width of one pulse
  // total length of time from 0 to 100% is (TimeofFade/DelayValue)*TimeofFade (TOF/DV is the number of times the loop is completed, * length of time in the loop)
  //  in this case 25/.5 = 50/1 = 50*25 = 1250ms
  // total loop time is 2500 + the two delays between increase and decrease the middle to add smoothness
  
  //this is going from 0->100
  for(float FadeValue=0; FadeValue <= TimeofFade; FadeValue += DelayValue) {
   digitalWrite(ledPin, HIGH);
   delay(FadeValue);           // ON for the incrementing FadeValue
   digitalWrite(ledPin, LOW); 
   delay(TimeofFade-FadeValue); // OFF for the decrementing remaining "pulse width"
    //  Serial.println(FadeValue);
  }
  digitalWrite(ledPin, HIGH); delay (TimeofFade);
  
  //this is going from 100->0
  for(float FadeValue=TimeofFade; FadeValue >=0; FadeValue -=DelayValue){
   digitalWrite(ledPin, HIGH);
   delay(FadeValue);           // ON for the decrementing FadeValue
   digitalWrite(ledPin, LOW);
   delay(TimeofFade-FadeValue); // OFF for the incrementing remaining "pulse width"
 //  Serial.println(FadeValue);
  }
  digitalWrite(ledPin, LOW); delay (TimeofFade);
}

what do you think?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48556
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
Why do you feel it necessary to tell the Arduino over and over that this pin is an OUTPUT pin? Don't you trust it to remember that?

Code:
   delay(FadeValue);           // ON for the incrementing FadeValue
delay() takes an unsigned long. That is an integer value. Your float is going to be truncated, eliminating the value of using a float.


Logged

Wisconsin
Offline Offline
Edison Member
*
Karma: 4
Posts: 1001
I LOVE THIS STUFF!!!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

As PaulS said, you don't need to have the
Code:
pinMode(ledPin, OUTPUT);
in the loop section.  It will keep on setting it like that.
You could move it over to the setup section.

Code:
int ledPin=13;                // uses arduino D13 LED
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  float DelayValue = .5;        // increment of power
  float TimeofFade = 25;        // width of one pulse

All of that should be moved out of the loop section

Also this should be moved out as well, since each time that it goes through a loop, you'll be seeing "Start" on the serial monitor and, trust me, that'll get annoying
Code:
  Serial.println("start");

Also the last part of your first for loop is confusing
Code:
FadeValue += DelayValue
That last element of a for loop is for the incrementing factor, such as i++ or in your case, FadeValue++ or FadeValue = FadeValue + (any number)
Are you trying to increment by the DelayValue?  if so then you'll need to do this
Code:
FaceValue = FadeValue+DelayValue
Logged

Accelerate to 88 miles per hour.

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 604
Posts: 33419
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Also the last part of your first for loop is confusing
Code:
FadeValue += DelayValue
No that is fine, that will add DelayValue to FadeValue
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

initialisations in the wrong loop - good point.  I tried to have them inside void Setup() {...}  but I ended up with errors that the variables did not exist in that scope.  just some rusty and lack of C knowledge.  (my bad...  how do you initialise a global variable?)  [did I get it right? - see below]

+= and -= are compound addition and subtraction.  is it good practice to use "x = x + y"  not "x += y"  I used to know a healthy amount of basic and never got any C education, so I figured I would use the += functions when available

the trouble is that I am using fadeValue as both the delay time and the counter in the for-loop.  should I not?

I guess I do know that my increment is 1/50th of total power, so I could just make fadeValue into a counter and make the delay look like

for (counter = 1 to 50; counter ++) {
digitalWrite(ledPin, HIGH);
delay(fadeValue*2) ;
digitalWrite(ledPin, LOW);
delay (TimeofFade - fadeValue*2);
}
etc etc.
which way is neater//better coding practice?

I didnt realise that delay takes an unsigned long...  I was working in DelayMicroseconds() but I thought I just had too many zeros.  guess I will move back to that.  save me a decimal point...  oh also I was getting worried about overflow from the (I think) 32000 or so limit of a normal interger.  working with 25000us...  (and now I am using long)

here is what we got:  didn't get a chance to test it just yet.  but the last one was working and this one compiles fine..
Quote
  int ledPin=13;                // uses arduino D13 LED
  long DelayValue = 500;       // increment of power
  long TimeofFade = 25000;     // width of one pulse

void setup() {
  Serial.begin(9600);           //I like to talk to my arduino and have it report back to me
  Serial.println("start");
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
}

void loop(){
  // total length of time from 0 to 100% is (TimeofFade/DelayValue)*TimeofFade (TOF/DV is the number of times the loop is completed, * length of time in the loop)
  //  in this case 25000/500 = 50/1 = 50*25000 = 1250000us = 1250ms
  // total loop time is 2500 + the two delays between increase and decrease the middle to add smoothness
  
  //this is going from 0->100%
  for(long FadeValue=0; FadeValue <= TimeofFade; FadeValue += DelayValue) {
   digitalWrite(ledPin, HIGH);
   delayMicroseconds(FadeValue);           // ON for the incrementing FadeValue
   digitalWrite(ledPin, LOW); 
   delayMicroseconds(TimeofFade-FadeValue); // OFF for the decrementing remaining "pulse width"
    //  Serial.println(FadeValue);
  }
  digitalWrite(ledPin, HIGH); delayMicroseconds (TimeofFade);
  
  //this is going from 100->0%
  for(long FadeValue=TimeofFade; FadeValue >=0; FadeValue -=DelayValue){
   digitalWrite(ledPin, HIGH);
   delayMicroseconds(FadeValue);           // ON for the decrementing FadeValue
   digitalWrite(ledPin, LOW);
   delayMicroseconds(TimeofFade-FadeValue); // OFF for the incrementing remaining "pulse width"
 //  Serial.println(FadeValue);
  }
  digitalWrite(ledPin, LOW); delayMicroseconds (TimeofFade);
}

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

actually I kinda liked my:
Serial.println("start");
to repeat every loop, that way I was sure that it didnt get stuck somewhere in the loop.  especially with the other two serial prints awake.

I moved it, but I would probably put it back if I were fiddling with the time lengths of the pulses, just to make sure that it was looping cleanly.

opinions?
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 604
Posts: 33419
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The compound += operator is fine, the other way is NOT good practice.

Can you use the # icon when posting code not the quote one.
Logged

Wisconsin
Offline Offline
Edison Member
*
Karma: 4
Posts: 1001
I LOVE THIS STUFF!!!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay well then you can keep it there if you like, all it is a serial print, it isn't really affecting anything. 
Logged

Accelerate to 88 miles per hour.

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Serial output takes milliseconds of time.  Think of it as an added delay of a varying amount - meaning it does affect your code timing.
Logged

Wisconsin
Offline Offline
Edison Member
*
Karma: 4
Posts: 1001
I LOVE THIS STUFF!!!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

everything takes time, although if its just for development purposes, it doesn't matter.

As long as it gets taken out later.  It doesn't take 12 ms to do, maybe, maaaybe 1.2 ms
Logged

Accelerate to 88 miles per hour.

Pages: [1]   Go Up
Jump to: