| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

LT1054_voltage_mode_buck.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
59 float vout = 3.3; // Floating poiont output voltage.
60 int setpoint = int (vout * 1024.0 / 5.0);
61 //int setpoint = 512; // 1.25V
62 int feedback = 0; // value read from the pot
63 int outputValue = 0; // value output to the PWM (analog out)
64 int error = 0;
65 int integral = 128;
66
67 #define verbose
68
69 void setup()
70 {
71 // initialize serial communications at 115200 bps:
72 #ifdef verbose
73 Serial.begin(115200);
74 #endif
75 setPwmFrequency(analogOutPin, 1);
76 }
77
78 void loop()
79 {
80 // read the analog in value:
81 feedback = analogRead(analogInPin);
82 error = setpoint - feedback;
83 integral = integral + error/4; //kI = 0.25
84 if (integral > 1023) integral = 1023;
85 if (integral < 0) integral = 0;
86
87 // map it to the range of the analog out
88 // (could probably just right-shift by two...)
89 outputValue = map(integral, 0, 1023, 0, 255);
90 // change the analog out value:
91 analogWrite(analogOutPin, outputValue);
92 #ifdef verbose
93 // print the results to the Serial Monitor:
94 Serial.print("feedback = ");
95 Serial.print(feedback);
96 Serial.print("\t output = ");
97 Serial.println(outputValue);
98 #endif
99 // wait some milliseconds before the next loop for the analog-to-digital
100 // converter to settle after the last reading:
101 delay(10);
102 }
103
104
105 /**
106 * Divides a given PWM pin frequency by a divisor.
107 *
108 * The resulting frequency is equal to the base frequency divided by
109 * the given divisor:
110 * - Base frequencies:
111 * o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
112 * o The base frequency for pins 5 and 6 is 62500 Hz.
113 * - Divisors:
114 * o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
115 * 256, and 1024.
116 * o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
117 * 128, 256, and 1024.
118 *
119 * PWM frequencies are tied together in pairs of pins. If one in a
120 * pair is changed, the other is also changed to match:
121 * - Pins 5 and 6 are paired on timer0
122 * - Pins 9 and 10 are paired on timer1
123 * - Pins 3 and 11 are paired on timer2
124 *
125 * Note that this function will have side effects on anything else
126 * that uses timers:
127 * - Changes on pins 3, 5, 6, or 11 may cause the delay() and
128 * millis() functions to stop working. Other timing-related
129 * functions may also be affected.
130 * - Changes on pins 9 or 10 will cause the Servo library to function
131 * incorrectly.
132 *
133 * Thanks to macegr of the Arduino forums for his documentation of the
134 * PWM frequency divisors. His post can be viewed at:
135 * http://forum.arduino.cc/index.php?topic=16612#msg121031
136 */
137 void setPwmFrequency(int pin, int divisor)
138 {
139 byte mode;
140 if (pin == 5 || pin == 6 || pin == 9 || pin == 10)
141 {
142 switch (divisor)
143 {
144 case 1:
145 mode = 0x01;
146 break;
147 case 8:
148 mode = 0x02;
149 break;
150 case 64:
151 mode = 0x03;
152 break;
153 case 256:
154 mode = 0x04;
155 break;
156 case 1024:
157 mode = 0x05;
158 break;
159 default:
160 return;
161 }
162 if (pin == 5 || pin == 6)
163 {
164 TCCR0B = TCCR0B & 0b11111000 | mode;
165 }
166 else
167 {
168 TCCR1B = TCCR1B & 0b11111000 | mode;
169 }
170 }
171 else if (pin == 3 || pin == 11)
172 {
173 switch (divisor)
174 {
175 case 1:
176 mode = 0x01;
177 break;
178 case 8:
179 mode = 0x02;
180 break;
181 case 32:
182 mode = 0x03;
183 break;
184 case 64:
185 mode = 0x04;
186 break;
187 case 128:
188 mode = 0x05;
189 break;
190 case 256:
191 mode = 0x06;
192 break;
193 case 1024:
194 mode = 0x07;
195 break;
196 default:
197 return;
198 }
199 TCCR2B = TCCR2B & 0b11111000 | mode;
200 }
201 }
setup
static void setup()
Definition: LT1054_voltage_mode_buck.ino:69
analogInPin
const int analogInPin
Definition: LT1054_voltage_mode_buck.ino:56
loop
static void loop()
Definition: LT1054_voltage_mode_buck.ino:78
analogOutPin
const int analogOutPin
Definition: LT1054_voltage_mode_buck.ino:57
setpoint
static int setpoint
Definition: LT1054_voltage_mode_buck.ino:60
feedback
static int feedback
Definition: LT1054_voltage_mode_buck.ino:62
outputValue
static int outputValue
Definition: LT1054_voltage_mode_buck.ino:63
integral
static int integral
Definition: LT1054_voltage_mode_buck.ino:65
vout
static float vout
Definition: LT1054_voltage_mode_buck.ino:59
error
static int error
Definition: LT1054_voltage_mode_buck.ino:64
setPwmFrequency
static void setPwmFrequency(int pin, int divisor)
Divides a given PWM pin frequency by a divisor.
Definition: LT1054_voltage_mode_buck.ino:137