SHARE
TWEET

Arduino Software PWM with mills Example

baldengineer Oct 6th, 2015 1,474 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //pwm-with-millis.ino
  2.  
  3. // macros for LED state
  4. #define ON true
  5. #define OFF false
  6.  
  7. // variables for pattern timing
  8. unsigned long currentMillis = millis();
  9. unsigned long previousMillis = 0;
  10. unsigned long millisInterval = 100;
  11.  
  12. // variables for software PWM
  13. unsigned long currentMicros = micros();
  14. unsigned long previousMicros = 0;
  15. // this is the frequency of the sw PWM
  16. // frequency = 1/(2 * microInterval)
  17. unsigned long microInterval = 250;
  18.  
  19. const byte pwmMax = 100;
  20.  
  21. // fading (for the timing)
  22. int fadeIncrement = 1;
  23.  
  24. // typedef for properties of each sw pwm pin
  25. typedef struct pwmPins {
  26.   int pin;
  27.   int pwmValue;
  28.   bool pinState;
  29.   int pwmTickCount;
  30. } pwmPin;
  31.  
  32. // create the sw pwm pins
  33. // these can be any I/O pin
  34. // that can be set to output!
  35. const int pinCount = 8;
  36. const byte pins[pinCount] = {2,3,5,6,9,10,11,12};
  37.  
  38. pwmPin myPWMpins[pinCount];
  39.  
  40. // function to "setup" the sw pwm pin states
  41. // modify to suit your needs
  42. // this creates an alternating fade pattern
  43. void setupPWMpins() {
  44.   for (int index=0; index < pinCount; index++) {
  45.     myPWMpins[index].pin = pins[index];
  46.  
  47.     // mix it up a little bit
  48.     // changes the starting pwmValue for odd and even
  49.     if (index % 2)
  50.       myPWMpins[index].pwmValue = 25;
  51.     else
  52.       myPWMpins[index].pwmValue = 75;
  53.  
  54.     myPWMpins[index].pinState = ON;
  55.     myPWMpins[index].pwmTickCount = 0;
  56.  
  57.     // unlike analogWrite(), this is necessary
  58.     pinMode(pins[index], OUTPUT);
  59.   }
  60. }
  61.  
  62. void pwmFadePattern() {
  63.   // go through each sw pwm pin, and increase
  64.   // the pwm value. this would be like
  65.   // calling analogWrite() on each hw pwm pin
  66.   for (int index=0; index < pinCount; index++) {
  67.     myPWMpins[index].pwmValue += fadeIncrement;
  68.     if (myPWMpins[index].pwmValue > 100)
  69.       myPWMpins[index].pwmValue = 0;
  70.   }
  71. }
  72.  
  73. void handlePWM() {
  74.   currentMicros = micros();
  75.   // check to see if we need to increment our PWM counters yet
  76.     if (currentMicros - previousMicros >= microInterval) {
  77.     // Increment each pin's counter
  78.     for (int index=0; index < pinCount; index++) {
  79.     // each pin has its own tickCounter
  80.       myPWMpins[index].pwmTickCount++;
  81.  
  82.     // determine if we're counting on or off time
  83.       if (myPWMpins[index].pinState == ON) {
  84.         // see if we hit the desired on percentage
  85.         // not as precise as 255 or 1024, but easier to do math
  86.         if (myPWMpins[index].pwmTickCount >= myPWMpins[index].pwmValue) {
  87.           myPWMpins[index].pinState = OFF;
  88.         }
  89.       } else {
  90.         // if it isn't on, it is off
  91.         if (myPWMpins[index].pwmTickCount >= pwmMax) {
  92.           myPWMpins[index].pinState = ON;
  93.           myPWMpins[index].pwmTickCount = 0;
  94.         }
  95.       }
  96.       // could probably use some bitwise optimization here, digitalWrite()
  97.       // really slows things down after 10 pins.
  98.       digitalWrite(myPWMpins[index].pin, myPWMpins[index].pinState);
  99.     }
  100.     // reset the micros() tick counter.
  101.     digitalWrite(13, !digitalRead(13));
  102.     previousMicros = currentMicros;
  103.   }
  104. }
  105.  
  106. void setup() {
  107.   setupPWMpins();
  108.   pinMode(13, OUTPUT);
  109. }
  110.  
  111. void loop() {
  112.   // this is the magic for sw pwm
  113.   // need to call this anytime you
  114.   // have a long operation
  115.   handlePWM();
  116.  
  117.   // check timer for fading pattern
  118.   // this would be the same
  119.   // if we used analogWrite()
  120.   currentMillis = millis();
  121.   if (currentMillis - previousMillis >= millisInterval) {
  122.     // moved to own funciton for clarity
  123.     pwmFadePattern();
  124.  
  125.     // setup clock for next tick
  126.     previousMillis = currentMillis;
  127.   }
  128. }
  129.  
  130. // Code from james@baldengineer.com
  131. // email | twitter | www
  132. // See more at: https://www.baldengineer.com/software-pwm-with-millis.html
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top