| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

LT1054_voltage_mode_buck_DC_ctrl.ino
Go to the documentation of this file.
1 /*
2 Control system for a simple voltage-mode buck converter based on
3 the LT1054. ATMega-based Arduinos (such as the Linduino) only.
4
5 Reads an analog input pin, compares to desired setpoint, integrates the error,
6 maps the integral to a range from 0 to 255 and uses
7 the result to set the pulse width modulation (PWM) of an output pin.
8 Also prints the results to the Serial Monitor.
9
10 The circuit:
11 - LT1054 clock overdrive circuit, driven by Digital Pin 3 (PWM capable)
12 - Analog Input 0 connected to buck converter output.
13
14
15 Derived from AnalogInOutSerial example:
16 http://www.arduino.cc/en/Tutorial/AnalogInOutSerial
17 PWM frequency adjustment function from:
18 https://playground.arduino.cc/Code/PwmFrequency
19
20 Copyright 2018(c) Analog Devices, Inc.
21
22 All rights reserved.
23
24 Redistribution and use in source and binary forms, with or without
25 modification, are permitted provided that the following conditions are met:
26 - Redistributions of source code must retain the above copyright
27 notice, this list of conditions and the following disclaimer.
28 - Redistributions in binary form must reproduce the above copyright
29 notice, this list of conditions and the following disclaimer in
30 the documentation and/or other materials provided with the
31 distribution.
32 - Neither the name of Analog Devices, Inc. nor the names of its
33 contributors may be used to endorse or promote products derived
34 from this software without specific prior written permission.
35 - The use of this software may or may not infringe the patent rights
36 of one or more patent holders. This license does not release you
37 from the requirement that you obtain separate licenses from these
38 patent holders to use this software.
39 - Use of the software either in source or binary form, must be run
40 on or directly connected to an Analog Devices Inc. component.
41
42 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
43 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
44 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
46 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
48 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
51 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52
53 */
54
55 // These constants won't change. They're used to give names to the pins used:
56 const int analogInPin = A0; // Analog input pin that the potentiometer is attached to
57 const int analogOutPin = 3; // Analog output pin that the LED is attached to
58 #define fixed 0
59 #define closed_loop 1
60
61 float vout = 3.3; // Floating poiont output voltage.
62 int setpoint = int (vout * 1024.0 / 5.0);
63 //int setpoint = 512; // 1.25V
64 int feedback = 0; // value read from the pot
65 int outputValue = 0; // value output to the PWM (analog out)
66 int error = 0;
67 int integral = 128;
68
69 #define verbose
70
71 void setup()
72 {
73 // initialize serial communications at 115200 bps:
74 #ifdef verbose
75 Serial.begin(115200);
76 #endif
77 setPwmFrequency(analogOutPin, 1);
78 }
79
80 uint8_t state = closed_loop;
81 void loop()
82 {
83 char ch;
84 float fbv, dc;
85 if (Serial.available())
86 {
87 ch = Serial.read();
88 switch (ch)
89 {
90 case '0':
91 state = fixed;
92 outputValue = 0 ;
93 break;
94 case '1':
95 state = fixed;
96 outputValue = 26 ;
97 break;
98 case '2':
99 state = fixed;
100 outputValue = 51 ;
101 break;
102 case '3':
103 state = fixed;
104 outputValue = 77 ;
105 break;
106 case '4':
107 state = fixed;
108 outputValue = 102;
109 break;
110 case '5':
111 state = fixed;
112 outputValue = 128;
113 break;
114 case '6':
115 state = fixed;
116 outputValue = 153;
117 break;
118 case '7':
119 state = fixed;
120 outputValue = 179;
121 break;
122 case '8':
123 state = fixed;
124 outputValue = 204;
125 break;
126 case '9':
127 state = fixed;
128 outputValue = 230;
129 break;
130 case 'A':
131 state = fixed;
132 outputValue = 255;
133 break;
134 case '\r':
135 break;
136 case '\n':
137 break;
138 default:
139 state = closed_loop;
140 }
141 if (ch != '\r' && ch != '\n')
142 {
143 Serial.print("Setting PWM to ");
144 Serial.print(outputValue);
145 Serial.println("/255");
146 }
147 analogWrite(analogOutPin, outputValue);
148 }
149 if (state == closed_loop)
150 {
151 // read the analog in value:
152 feedback = analogRead(analogInPin);
153 error = setpoint - feedback;
154 integral = integral + error/4; //kI = 0.25
155 if (integral > 1023) integral = 1023;
156 if (integral < 0) integral = 0;
157
158 // map it to the range of the analog out
159 // (could probably just right-shift by two...)
160 // outputValue = map(integral, 0, 1023, 0, 255);
161 outputValue = integral >> 2; // Map 10 bit integral to 8 bit output, maintainting integral precision
162 // change the analog out value:
163 analogWrite(analogOutPin, outputValue);
164 #ifdef verbose
165 // print the results to the Serial Monitor:
166 Serial.print("feedback = ");
167 fbv = (float) feedback * (5.0 / 1024.0);
168 Serial.print(fbv, 2);
169 Serial.print("\t PWM duty cycle = ");
170 dc = (float) outputValue * (100.0 / 256.0);
171 Serial.println(dc, 1);
172 #endif
173 // wait some milliseconds before the next loop for the analog-to-digital
174 // converter to settle after the last reading:
175 delay(10);
176 }
177 }
178
179
180 /**
181 * Divides a given PWM pin frequency by a divisor.
182 *
183 * The resulting frequency is equal to the base frequency divided by
184 * the given divisor:
185 * - Base frequencies:
186 * o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
187 * o The base frequency for pins 5 and 6 is 62500 Hz.
188 * - Divisors:
189 * o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
190 * 256, and 1024.
191 * o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
192 * 128, 256, and 1024.
193 *
194 * PWM frequencies are tied together in pairs of pins. If one in a
195 * pair is changed, the other is also changed to match:
196 * - Pins 5 and 6 are paired on timer0
197 * - Pins 9 and 10 are paired on timer1
198 * - Pins 3 and 11 are paired on timer2
199 *
200 * Note that this function will have side effects on anything else
201 * that uses timers:
202 * - Changes on pins 3, 5, 6, or 11 may cause the delay() and
203 * millis() functions to stop working. Other timing-related
204 * functions may also be affected.
205 * - Changes on pins 9 or 10 will cause the Servo library to function
206 * incorrectly.
207 *
208 * Thanks to macegr of the Arduino forums for his documentation of the
209 * PWM frequency divisors. His post can be viewed at:
210 * http://forum.arduino.cc/index.php?topic=16612#msg121031
211 */
212 void setPwmFrequency(int pin, int divisor)
213 {
214 byte mode;
215 if (pin == 5 || pin == 6 || pin == 9 || pin == 10)
216 {
217 switch (divisor)
218 {
219 case 1:
220 mode = 0x01;
221 break;
222 case 8:
223 mode = 0x02;
224 break;
225 case 64:
226 mode = 0x03;
227 break;
228 case 256:
229 mode = 0x04;
230 break;
231 case 1024:
232 mode = 0x05;
233 break;
234 default:
235 return;
236 }
237 if (pin == 5 || pin == 6)
238 {
239 TCCR0B = TCCR0B & 0b11111000 | mode;
240 }
241 else
242 {
243 TCCR1B = TCCR1B & 0b11111000 | mode;
244 }
245 }
246 else if (pin == 3 || pin == 11)
247 {
248 switch (divisor)
249 {
250 case 1:
251 mode = 0x01;
252 break;
253 case 8:
254 mode = 0x02;
255 break;
256 case 32:
257 mode = 0x03;
258 break;
259 case 64:
260 mode = 0x04;
261 break;
262 case 128:
263 mode = 0x05;
264 break;
265 case 256:
266 mode = 0x06;
267 break;
268 case 1024:
269 mode = 0x07;
270 break;
271 default:
272 return;
273 }
274 TCCR2B = TCCR2B & 0b11111000 | mode;
275 }
276 }
loop
static void loop()
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:81
vout
static float vout
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:61
setpoint
static int setpoint
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:62
fixed
#define fixed
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:58
outputValue
static int outputValue
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:65
analogInPin
const int analogInPin
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:56
closed_loop
#define closed_loop
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:59
error
static int error
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:66
integral
static int integral
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:67
setPwmFrequency
static void setPwmFrequency(int pin, int divisor)
Divides a given PWM pin frequency by a divisor.
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:212
setup
static void setup()
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:71
state
static uint8_t state
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:80
feedback
static int feedback
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:64
analogOutPin
const int analogOutPin
Definition: LT1054_voltage_mode_buck_DC_ctrl.ino:57