Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Committer:
Bigcheese
Date:
Sun Mar 02 06:33:08 2014 +0000
Revision:
3:f151d08d335c
Parent:
2:1df0b61d3b5a
Bunch of stuff. Need to locally merge in updated USB changes.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Michael J. Spencer 2:1df0b61d3b5a 1 #include "Pwm.h"
Michael J. Spencer 2:1df0b61d3b5a 2
Michael J. Spencer 2:1df0b61d3b5a 3 #include "nuts_bolts.h"
Michael J. Spencer 2:1df0b61d3b5a 4
Michael J. Spencer 2:1df0b61d3b5a 5 #define PID_PWM_MAX 256
Michael J. Spencer 2:1df0b61d3b5a 6
Michael J. Spencer 2:1df0b61d3b5a 7 // What ?
Michael J. Spencer 2:1df0b61d3b5a 8
Michael J. Spencer 2:1df0b61d3b5a 9 Pwm::Pwm()
Michael J. Spencer 2:1df0b61d3b5a 10 {
Michael J. Spencer 2:1df0b61d3b5a 11 _max = PID_PWM_MAX - 1;
Michael J. Spencer 2:1df0b61d3b5a 12 _pwm = -1;
Michael J. Spencer 2:1df0b61d3b5a 13 }
Michael J. Spencer 2:1df0b61d3b5a 14
Michael J. Spencer 2:1df0b61d3b5a 15 void Pwm::pwm(int new_pwm)
Michael J. Spencer 2:1df0b61d3b5a 16 {
Michael J. Spencer 2:1df0b61d3b5a 17 _pwm = confine(new_pwm, 0, _max);
Michael J. Spencer 2:1df0b61d3b5a 18 }
Michael J. Spencer 2:1df0b61d3b5a 19
Michael J. Spencer 2:1df0b61d3b5a 20 Pwm* Pwm::max_pwm(int new_max)
Michael J. Spencer 2:1df0b61d3b5a 21 {
Michael J. Spencer 2:1df0b61d3b5a 22 _max = confine(new_max, 0, PID_PWM_MAX - 1);
Michael J. Spencer 2:1df0b61d3b5a 23 _pwm = confine( _pwm, 0, _max);
Michael J. Spencer 2:1df0b61d3b5a 24 return this;
Michael J. Spencer 2:1df0b61d3b5a 25 }
Michael J. Spencer 2:1df0b61d3b5a 26
Michael J. Spencer 2:1df0b61d3b5a 27 int Pwm::max_pwm()
Michael J. Spencer 2:1df0b61d3b5a 28 {
Michael J. Spencer 2:1df0b61d3b5a 29 return _max;
Michael J. Spencer 2:1df0b61d3b5a 30 }
Michael J. Spencer 2:1df0b61d3b5a 31
Michael J. Spencer 2:1df0b61d3b5a 32 void Pwm::set(bool value)
Michael J. Spencer 2:1df0b61d3b5a 33 {
Michael J. Spencer 2:1df0b61d3b5a 34 _pwm = -1;
Michael J. Spencer 2:1df0b61d3b5a 35 Pin::set(value);
Michael J. Spencer 2:1df0b61d3b5a 36 }
Michael J. Spencer 2:1df0b61d3b5a 37
Michael J. Spencer 2:1df0b61d3b5a 38 uint32_t Pwm::on_tick(uint32_t dummy)
Michael J. Spencer 2:1df0b61d3b5a 39 {
Michael J. Spencer 2:1df0b61d3b5a 40 if ((_pwm < 0) || (_pwm >= PID_PWM_MAX))
Michael J. Spencer 2:1df0b61d3b5a 41 return dummy;
Michael J. Spencer 2:1df0b61d3b5a 42
Michael J. Spencer 2:1df0b61d3b5a 43 /*
Michael J. Spencer 2:1df0b61d3b5a 44 * Sigma-Delta PWM algorithm
Michael J. Spencer 2:1df0b61d3b5a 45 *
Michael J. Spencer 2:1df0b61d3b5a 46 * This Sigma-Delta implementation works by increasing _sd_accumulator by _pwm until we reach _half_ of max,
Michael J. Spencer 2:1df0b61d3b5a 47 * then decreasing by (max - target_pwm) until we hit zero
Michael J. Spencer 2:1df0b61d3b5a 48 *
Michael J. Spencer 2:1df0b61d3b5a 49 * While we're increasing, the output is 0 and while we're decreasing the output is 1
Michael J. Spencer 2:1df0b61d3b5a 50 *
Michael J. Spencer 2:1df0b61d3b5a 51 * For example, with pwm=128 and a max of 256, we'll see the following pattern:
Michael J. Spencer 2:1df0b61d3b5a 52 * ACC ADD OUT
Michael J. Spencer 2:1df0b61d3b5a 53 * 0 128 1 // after the add, we hit 256/2 = 128 so we change direction
Michael J. Spencer 2:1df0b61d3b5a 54 * 128 -128 0 // after the add, we hit 0 so we change direction again
Michael J. Spencer 2:1df0b61d3b5a 55 * 0 128 1
Michael J. Spencer 2:1df0b61d3b5a 56 * 128 -128 0
Michael J. Spencer 2:1df0b61d3b5a 57 * as expected
Michael J. Spencer 2:1df0b61d3b5a 58 *
Michael J. Spencer 2:1df0b61d3b5a 59 * with a pwm value of 192 (75%) we'll see this:
Michael J. Spencer 2:1df0b61d3b5a 60 * ACC ADD OUT
Michael J. Spencer 2:1df0b61d3b5a 61 * 0 192 0 // after the add, we are beyond max/2 so we change direction
Michael J. Spencer 2:1df0b61d3b5a 62 * 192 -64 1 // haven't reached 0 yet
Michael J. Spencer 2:1df0b61d3b5a 63 * 128 -64 1 // haven't reached 0 yet
Michael J. Spencer 2:1df0b61d3b5a 64 * 64 -64 1 // after this add we reach 0, and change direction
Michael J. Spencer 2:1df0b61d3b5a 65 * 0 192 0
Michael J. Spencer 2:1df0b61d3b5a 66 * 192 -64 1
Michael J. Spencer 2:1df0b61d3b5a 67 * 128 -64 1
Michael J. Spencer 2:1df0b61d3b5a 68 * 64 -64 1
Michael J. Spencer 2:1df0b61d3b5a 69 * 0 192 0
Michael J. Spencer 2:1df0b61d3b5a 70 * etcetera
Michael J. Spencer 2:1df0b61d3b5a 71 *
Michael J. Spencer 2:1df0b61d3b5a 72 * with a pwm value of 75 (about 29%) we'll see this pattern:
Michael J. Spencer 2:1df0b61d3b5a 73 * ACC ADD OUT
Michael J. Spencer 2:1df0b61d3b5a 74 * 0 75 0
Michael J. Spencer 2:1df0b61d3b5a 75 * 75 75 0
Michael J. Spencer 2:1df0b61d3b5a 76 * 150 -181 1
Michael J. Spencer 2:1df0b61d3b5a 77 * -31 75 0
Michael J. Spencer 2:1df0b61d3b5a 78 * 44 75 0
Michael J. Spencer 2:1df0b61d3b5a 79 * 119 75 0
Michael J. Spencer 2:1df0b61d3b5a 80 * 194 -181 1
Michael J. Spencer 2:1df0b61d3b5a 81 * 13 -181 1
Michael J. Spencer 2:1df0b61d3b5a 82 * -168 75 0
Michael J. Spencer 2:1df0b61d3b5a 83 * -93 75 0
Michael J. Spencer 2:1df0b61d3b5a 84 * -18 75 0
Michael J. Spencer 2:1df0b61d3b5a 85 * 57 75 0
Michael J. Spencer 2:1df0b61d3b5a 86 * 132 -181 1
Michael J. Spencer 2:1df0b61d3b5a 87 * -49 75 0
Michael J. Spencer 2:1df0b61d3b5a 88 * 26 75 0
Michael J. Spencer 2:1df0b61d3b5a 89 * 101 75 0
Michael J. Spencer 2:1df0b61d3b5a 90 * 176 -181 1
Michael J. Spencer 2:1df0b61d3b5a 91 * -5 75 0
Michael J. Spencer 2:1df0b61d3b5a 92 * 70 75 0
Michael J. Spencer 2:1df0b61d3b5a 93 * 145 -181 1
Michael J. Spencer 2:1df0b61d3b5a 94 * -36 75 0
Michael J. Spencer 2:1df0b61d3b5a 95 * etcetera. This pattern has 6 '1's over a total of 21 lines which is on 28.57% of the time. If we let it run longer, it would get closer to the target as time went on
Michael J. Spencer 2:1df0b61d3b5a 96 */
Michael J. Spencer 2:1df0b61d3b5a 97
Michael J. Spencer 2:1df0b61d3b5a 98 // this line should never actually do anything, it's just a sanity check in case our accumulator gets corrupted somehow.
Michael J. Spencer 2:1df0b61d3b5a 99 // If we didn't check and the accumulator is corrupted, we could leave a heater on for quite a long time
Michael J. Spencer 2:1df0b61d3b5a 100 // the accumulator is kept within these limits by the normal operation of the Sigma-Delta algorithm
Michael J. Spencer 2:1df0b61d3b5a 101 _sd_accumulator = confine(_sd_accumulator, -PID_PWM_MAX, PID_PWM_MAX << 1);
Michael J. Spencer 2:1df0b61d3b5a 102
Michael J. Spencer 2:1df0b61d3b5a 103 // when _sd_direction == false, our output is 0 and our accumulator is increasing by _pwm
Michael J. Spencer 2:1df0b61d3b5a 104 if (_sd_direction == false)
Michael J. Spencer 2:1df0b61d3b5a 105 {
Michael J. Spencer 2:1df0b61d3b5a 106 // increment accumulator
Michael J. Spencer 2:1df0b61d3b5a 107 _sd_accumulator += _pwm;
Michael J. Spencer 2:1df0b61d3b5a 108 // if we've reached half of max, flip our direction
Michael J. Spencer 2:1df0b61d3b5a 109 if (_sd_accumulator >= (PID_PWM_MAX >> 1))
Michael J. Spencer 2:1df0b61d3b5a 110 _sd_direction = true;
Michael J. Spencer 2:1df0b61d3b5a 111 }
Michael J. Spencer 2:1df0b61d3b5a 112 // when _sd_direction == true, our output is 1 and our accumulator is decreasing by (MAX - _pwm)
Michael J. Spencer 2:1df0b61d3b5a 113 else
Michael J. Spencer 2:1df0b61d3b5a 114 {
Michael J. Spencer 2:1df0b61d3b5a 115 // decrement accumulator
Michael J. Spencer 2:1df0b61d3b5a 116 _sd_accumulator -= (PID_PWM_MAX - _pwm);
Michael J. Spencer 2:1df0b61d3b5a 117 // if we've reached 0, flip our direction
Michael J. Spencer 2:1df0b61d3b5a 118 if (_sd_accumulator <= 0)
Michael J. Spencer 2:1df0b61d3b5a 119 _sd_direction = false;
Michael J. Spencer 2:1df0b61d3b5a 120 }
Michael J. Spencer 2:1df0b61d3b5a 121 Pin::set(_sd_direction);
Michael J. Spencer 2:1df0b61d3b5a 122
Michael J. Spencer 2:1df0b61d3b5a 123 return dummy;
Michael J. Spencer 2:1df0b61d3b5a 124 }