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
76 }
77 
78 void loop()
79 {
80  // read the analog in value:
81  feedback = analogRead(analogInPin);
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 }
static void setup()
const int analogInPin
static void loop()
const int analogOutPin
static int setpoint
static int feedback
static int outputValue
static int integral
static float vout
static int error
static void setPwmFrequency(int pin, int divisor)
Divides a given PWM pin frequency by a divisor.