Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
DC1785A.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1785 Demonstration Board.
3 LTC2991: 14-bit ADC Octal I2C Voltage, Current, and Temperature monitor.
4 
5 @verbatim
6 
7  Setup:
8  Set the terminal baud rate to 115200 and select the newline terminator.
9  A precision voltage source (preferably low-noise) may be used to apply a voltage
10  to input terminals V1-V8. A precision voltmeter may be used to verify applied
11  voltages. An oscilloscope may be used to view the PWM output. Ensure JP5, JP6
12  and JP7 are in the LOW position. Refer to Demo Manual DC1785A
13 
14  Explanation of Commands:
15 
16  1 - Single-Ended Voltage - Selects the Single-Ended Voltage Menu.
17  1-8: Displays the measured single-ended voltage at one of the V1-V8
18  inputs. When measuring V1 and V8, ensure jumpers are set to VOLT
19  position.
20  9: Vcc - Displays the measured Vcc voltage.
21  10: ALL - Displays the measured voltages at all of the V1-V8 inputs
22  and Vcc.
23 
24  2 - Differential Voltage - Selects the Differential Voltage Menu.
25  Maximum full scale differential voltage is 0.300V.
26 
27  1-4: Displays the measured differential voltage across one of the V1-V8
28  input pairs. The input common-mode range is 0V to Vcc. It is
29  easiest to ground the lower input. When measuring V1 and V8,
30  ensure jumpers are set to VOLT position.
31  5: ALL - Displays the measured differential voltages at all terminals.
32 
33  3 - Temperature - Selects the Temperature Menu
34  To measure temperature using onboard transistors, set JP1, JP2, JP3 and JP4
35  to TEMP position.
36  1: V1-V2 - Measure temperature of Q1 (mounted to demo board) when JP1
37  and JP2 are in TEMP position.
38  2: V3-V4 - Measure temperature of external transistor connected to V3
39  and V4 terminals.
40  3: V5-V6 - Measure temperature of external transistor connected to V5
41  and V6 terminals.
42  4: V7-V8 - Measure temperature of Q2 (mounted to demo board) when JP3
43  and JP4 are in TEMP position.
44  5: Internal - Measure temperature using the internal temperature
45  sensor.
46  6: All - Displays temperatures at all connections as well as the
47  internal temperature sensor.
48 
49  4 - Settings - Selects the Settings Menu
50  Enable/disable the on-chip digital filters. Also toggle temperature units
51  between degrees Celsius or degrees Kelvin.
52  1-5: Entering these one can enable/disable various channel filters.
53  6: Toggle temperature units between degrees Celsius and degrees
54  Kelvin.
55 
56  5 - PWM - Selects the PWM Menu
57  Generates Proportional PWM output using remote diode connected to pins 7 and
58  8. When JP3 and JP4 are in TEMP positions, Q2 is used as the temperature
59  sensing diode (mounted on demo board).
60  1: Set Threshold Temperature - Enter temperature corresponding to 0%
61  (100% in Inverted Mode) duty cycle.
62  2: Inverted/Non-Inverted PWM - Toggles between Inverted/Non-Inverted
63  modes
64  3: Enable/Disable - Enables or Disables PWM (Toggle)
65 
66 USER INPUT DATA FORMAT:
67  decimal : 1024
68  hex : 0x400
69  octal : 02000 (leading 0 "zero")
70  binary : B10000000000
71  float : 1024.0
72 
73 @endverbatim
74 
75 http://www.linear.com/product/LTC2991
76 
77 http://www.linear.com/product/LTC2991#demoboards
78 
79 
80 Copyright 2018(c) Analog Devices, Inc.
81 
82 All rights reserved.
83 
84 Redistribution and use in source and binary forms, with or without
85 modification, are permitted provided that the following conditions are met:
86  - Redistributions of source code must retain the above copyright
87  notice, this list of conditions and the following disclaimer.
88  - Redistributions in binary form must reproduce the above copyright
89  notice, this list of conditions and the following disclaimer in
90  the documentation and/or other materials provided with the
91  distribution.
92  - Neither the name of Analog Devices, Inc. nor the names of its
93  contributors may be used to endorse or promote products derived
94  from this software without specific prior written permission.
95  - The use of this software may or may not infringe the patent rights
96  of one or more patent holders. This license does not release you
97  from the requirement that you obtain separate licenses from these
98  patent holders to use this software.
99  - Use of the software either in source or binary form, must be run
100  on or directly connected to an Analog Devices Inc. component.
101 
102 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
103 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
104 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
105 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
106 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
107 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
108 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
109 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
110 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
111 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
112 */
113 
114 /*! @file
115  @ingroup LTC2991
116 */
117 
118 #include <Arduino.h>
119 #include <stdint.h>
120 #include "Linduino.h"
121 #include "UserInterface.h"
122 #include "LT_I2C.h"
123 #include "QuikEval_EEPROM.h"
124 #include "LTC2991.h"
125 #include <Wire.h>
126 #include <SPI.h>
127 
128 // Function Declaration
129 void print_title(); // Print the title block
130 void print_prompt(); // Prompt the user for an input command
131 
132 int8_t menu_1_single_ended_voltage(); //Sub-menu functions
134 int8_t menu_3_read_temperature();
135 int8_t menu_4_settings();
136 int8_t menu_5_pwm_options();
137 
138 // Global variables
139 static uint8_t demo_board_connected; //!< Set to 1 if the board is connected
140 
141 const uint16_t LTC2991_TIMEOUT=1000; //!< Configures the maximum timeout allowed for an LTC2991 read.
142 
143 //! Initialize Linduino
144 void setup()
145 {
146  char demo_name[] = "DC1785"; // Demo Board Name stored in QuikEval EEPROM
147  int8_t ack=0;
148  quikeval_I2C_init(); //! Initializes Linduino I2C port.
149  quikeval_I2C_connect(); //! Connects I2C port to the QuikEval connector
150  Serial.begin(115200); //! Initialize the serial port to the PC
151  print_title();
152  demo_board_connected = discover_demo_board(demo_name); //! Checks if correct demo board is connected.
154  {
155  print_prompt();
157  ack |= LTC2991_register_write(LTC2991_I2C_ADDRESS, LTC2991_CONTROL_V1234_REG, 0x00); //! Sets registers to default starting values.
159  ack |= LTC2991_register_write(LTC2991_I2C_ADDRESS, LTC2991_CONTROL_PWM_Tinternal_REG, LTC2991_REPEAT_MODE); //! Configures LTC2991 for Repeated Acquisition mode
160  }
161 }
162 
163 //! Repeats Linduino loop
164 void loop()
165 {
166  int8_t ack=0;
167 
168  uint8_t user_command;
169  if (demo_board_connected) //! Does nothing if the demo board is not connected
170  {
171  if (Serial.available()) // Checks for user input
172  {
173  user_command = read_int(); //! Reads the user command
174  if (user_command != 'm')
175  Serial.println(user_command);
176  ack = 0;
177  switch (user_command) //! Prints the appropriate submenu
178  {
179  case 1:
180  ack |= menu_1_single_ended_voltage(); // Print single-ended voltage menu
181  break;
182  case 2:
183  ack |= menu_2_read_differential_voltage(); // Differential voltage menu
184  break;
185  case 3:
186  ack |= menu_3_read_temperature(); // Temperature menu
187  break;
188  case 4:
189  ack |= menu_4_settings(); // Settings menu
190  break;
191  case 5:
192  ack |= menu_5_pwm_options(); // PWM options menu
193  break;
194  default:
195  Serial.println("Incorrect Option");
196  break;
197  }
198  if (ack != 0)
199  {
200  Serial.print(F("Error: No Acknowledge. Check I2C Address.\n"));
201  }
202  print_prompt();
203  }
204  }
205 }
206 
207 // Function Definitions
208 
209 //! Prints the title block when program first starts.
211 {
212  Serial.print(F("\n*****************************************************************\n"));
213  Serial.print(F("* DC1785A Demonstration Program *\n"));
214  Serial.print(F("* *\n"));
215  Serial.print(F("* This program demonstrates how to send and receive data from *\n"));
216  Serial.print(F("* the LTC2991 14-Bit Octal I2C Voltage, Current, and *\n"));
217  Serial.print(F("* Temperature Monitor. *\n"));
218  Serial.print(F("* *\n"));
219  Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
220  Serial.print(F("* *\n"));
221  Serial.print(F("*****************************************************************\n"));
222 }
223 
224 //! Prints main menu.
226 {
227  Serial.print(F("\n 1-Single-Ended Voltage\n"));
228  Serial.print(F(" 2-Differential Voltage\n"));
229  Serial.print(F(" 3-Temperature\n"));
230  Serial.print(F(" 4-Settings\n"));
231  Serial.print(F(" 5-PWM\n\n"));
232  Serial.print(F("Enter a command:"));
233 }
234 
235 //! Read single-ended voltages
236 //! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
238 {
239  int8_t ack=0;
240  uint8_t user_command;
241  do
242  {
243  //! Displays the single-ended voltage menu
244  Serial.print(F("\nSingle-Ended Voltage\n\n"));
245  Serial.print(F(" 1-V1\n"));
246  Serial.print(F(" 2-V2\n"));
247  Serial.print(F(" 3-V3\n"));
248  Serial.print(F(" 4-V4\n"));
249  Serial.print(F(" 5-V5\n"));
250  Serial.print(F(" 6-V6\n"));
251  Serial.print(F(" 7-V7\n"));
252  Serial.print(F(" 8-V8\n"));
253  Serial.print(F(" 9-Vcc\n"));
254  Serial.print(F(" 10-ALL\n"));
255  Serial.print(F(" m-Main Menu\n"));
256  Serial.print(F("\n\nEnter a command: "));
257 
258  user_command = read_int(); //! Reads the user command
259  if (user_command == 'm') // Print m if it is entered
260  {
261  Serial.print(F("m\n"));
262  }
263  else
264  Serial.println(user_command); // Print user command
265 
266  int16_t code;
267  int8_t data_valid;
268  float voltage;
269 
270  //! Enables single-ended mode.
271  //! Flushes one reading following mode change.
272  //! Reads single-ended voltage from ADC and prints it.
273  switch (user_command)
274  {
275  case 1:
276  // Enable Single-Ended Mode by clearing LTC2991_V1_V2_DIFFERENTIAL_ENABLE bit in LTC2991_CONTROL_V1234_REG
278  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
281  Serial.print(F("\n V1: "));
282  Serial.print(voltage, 4);
283  Serial.print(F(" V\n"));
284  break;
285  case 2:
286  // Enable Single-Ended Mode by clearing LTC2991_V1_V2_DIFFERENTIAL_ENABLE bit in LTC2991_CONTROL_V1234_REG
288  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
291  Serial.print(F("\n V2: "));
292  Serial.print(voltage, 4);
293  Serial.print(F(" V\n"));
294  break;
295  case 3:
296  // Enable Single-Ended Mode by clearing LTC2991_V3_V4_DIFFERENTIAL_ENABLE bit in LTC2991_CONTROL_V1234_REG
298  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
301  Serial.print(F("\n V3: "));
302  Serial.print(voltage, 4);
303  Serial.print(F(" V\n"));
304  break;
305  case 4:
306  // Enable Single-Ended Mode by clearing LTC2991_V3_V4_DIFFERENTIAL_ENABLE bit in LTC2991_CONTROL_V1234_REG
308  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
311  Serial.print(F("\n V4: "));
312  Serial.print(voltage, 4);
313  Serial.print(F(" V\n"));
314  break;
315  case 5:
317  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
320  Serial.print(F("\n V5: "));
321  Serial.print(voltage, 4);
322  Serial.print(F(" V\n"));
323  break;
324  case 6:
326  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
329  Serial.print(F("\n V6: "));
330  Serial.print(voltage, 4);
331  Serial.print(F(" V\n"));
332  break;
333  case 7:
335  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
338  Serial.print(F("\n V7: "));
339  Serial.print(voltage, 4);
340  Serial.print(F(" V\n"));
341  break;
342  case 8:
344  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
347  Serial.print(F("\n V8: "));
348  Serial.print(voltage, 4);
349  Serial.print(F(" V\n"));
350  break;
351  case 9:
352  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
355  Serial.print(F("\n Vcc: "));
356  Serial.print(voltage, 4);
357  Serial.print(F(" V\n"));
358  break;
359  case 10:
362  // Reads and displays all single-ended voltages
363  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
366  Serial.print(F("\n V1: "));
367  Serial.print(voltage, 4);
368  Serial.print(F(" V\n"));
369  if (ack)
370  break;
371  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
374  Serial.print(F(" V2: "));
375  Serial.print(voltage, 4);
376  Serial.print(F(" V\n"));
377  if (ack)
378  break;
379  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
382  Serial.print(F(" V3: "));
383  Serial.print(voltage, 4);
384  Serial.print(F(" V\n"));
385  if (ack)
386  break;
387  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
390  Serial.print(F(" V4: "));
391  Serial.print(voltage, 4);
392  Serial.print(F(" V\n"));
393  if (ack)
394  break;
395  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
398  Serial.print(F(" V5: "));
399  Serial.print(voltage, 4);
400  Serial.print(F(" V\n"));
401  if (ack)
402  break;
403  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
406  Serial.print(F(" V6: "));
407  Serial.print(voltage, 4);
408  Serial.print(F(" V\n"));
409  if (ack)
410  break;
411  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
414  Serial.print(F(" V7: "));
415  Serial.print(voltage, 4);
416  Serial.print(F(" V\n"));
417  if (ack)
418  break;
419  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
422  Serial.print(F(" V8: "));
423  Serial.print(voltage, 4);
424  Serial.print(F(" V\n"));
425  if (ack)
426  break;
427  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
430  Serial.print(F(" Vcc: "));
431  Serial.print(voltage, 4);
432  Serial.print(F(" V\n"));
433  break;
434  default:
435  if (user_command != 'm')
436  Serial.println(" Incorrect Option");
437  break;
438  }
439  }
440  while ((user_command != 'm') && (ack != 1));
441  return(ack);
442 }
443 
444 //! Read differential voltages.
445 //! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
447 {
448  int8_t ack=0;
449  uint8_t user_command;
450  do
451  {
452  //! Display differential voltage menu.
453  Serial.print(F("\nDifferential Voltage\n\n"));
454  Serial.print(F(" 1-V1-V2\n"));
455  Serial.print(F(" 2-V3-V4\n"));
456  Serial.print(F(" 3-V5-V6\n"));
457  Serial.print(F(" 4-V7-V8\n"));
458  Serial.print(F(" 5-ALL\n"));
459  Serial.print(F(" m-Main Menu\n"));
460  Serial.print(F("\n\nEnter a command: "));
461 
462  user_command = read_int(); //! Reads the user command
463  if (user_command == 'm') // Print m if it is entered
464  {
465  Serial.print(F("m\n"));
466  }
467  else
468  Serial.println(user_command); // Print user command
469 
470  int8_t data_valid;
471  int16_t code;
472  float voltage;
473 
474  //! Enables differential mode.
475  //! Flushes one reading following mode change.
476  //! Reads differential voltage from ADC and prints it.
477  switch (user_command)
478  {
479  case 1:
481  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
484  Serial.print(F("\n V1-V2: "));
485  Serial.print(voltage, 4);
486  Serial.print(F(" V\n"));
487  break;
488  case 2:
490  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
493  Serial.print(F("\n V3-V4: "));
494  Serial.print(voltage, 4);
495  Serial.print(F(" V\n"));
496  break;
497  case 3:
499  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
502  Serial.print(F("\n V5-V6: "));
503  Serial.print(voltage, 4);
504  Serial.print(F(" V\n"));
505  break;
506  case 4:
508  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
511  Serial.print(F("\n V7-V8: "));
512  Serial.print(voltage, 4);
513  Serial.print(F(" V\n"));
514  break;
515  case 5:
516  // reads all differential voltages
519  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
522  Serial.print(F("\n V1-V2: "));
523  Serial.print(voltage, 4);
524  Serial.print(F(" V\n"));
525  if (ack)
526  break;
527  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
530  Serial.print(F(" V3-V4: "));
531  Serial.print(voltage, 4);
532  Serial.print(F(" V\n"));
533  if (ack)
534  break;
535  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
538  Serial.print(F(" V5-V6: "));
539  Serial.print(voltage, 4);
540  Serial.print(F(" V\n"));
541  if (ack)
542  break;
543  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
546  Serial.print(F(" V7-V8: "));
547  Serial.print(voltage, 4);
548  Serial.print(F(" V\n"));
549  break;
550  default:
551  if (user_command != 'm')
552  {
553  Serial.print(F("Incorrect Option\n"));
554  }
555  break;
556  }
557  }
558  while ((user_command != 'm') && (ack != 1));
559  return(ack);
560 }
561 
562 //! Read temperatures
563 //! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
565 {
566  int8_t ack=0;
567  boolean isKelvin = false; //!Keeps track of the unit of measurement
568  uint8_t user_command;
569  do
570  {
571  //! Displays temperature menu
572  Serial.print(F("\nTemperature\n\n"));
573  Serial.print(F(" 1-V1-V2\n"));
574  Serial.print(F(" 2-V3-V4\n"));
575  Serial.print(F(" 3-V5-V6\n"));
576  Serial.print(F(" 4-V7-V8\n"));
577  Serial.print(F(" 5-Internal\n"));
578  Serial.print(F(" 6-ALL\n"));
579  Serial.print(F(" m-Main Menu\n"));
580  Serial.print(F("\n\nEnter a command: "));
581  user_command = read_int(); //! Reads the user command
582  if (user_command == 'm') // Print m if it is entered
583  {
584  Serial.print(F("m\n"));
585  }
586  else
587  Serial.println(user_command); // Print user command
588 
589  // Read Temperature
590  int8_t data_valid;
591  int16_t adc_code;
592  uint8_t reg_data;
593  float temperature;
594 
595  //! Enables temperature mode.
596  //! Flushes one reading following mode change.
597  //! Reads temperature from ADC and prints it.
598  switch (user_command)
599  {
600  case 1:
601 
605  if (reg_data & LTC2991_V1_V2_KELVIN_ENABLE) isKelvin= true;
606  else isKelvin=false;
607  temperature = LTC2991_temperature(adc_code, LTC2991_TEMPERATURE_lsb, isKelvin);
608  Serial.print(F("\n V1-V2: "));
609  Serial.print(temperature, 2);
610  if (isKelvin) Serial.print(F(" K\n"));
611  else Serial.print(F(" C\n"));
612  break;
613  case 2:
614 
616  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
619  if (reg_data & LTC2991_V3_V4_KELVIN_ENABLE) isKelvin=true;
620  else isKelvin = false;
621  temperature = LTC2991_temperature(adc_code, LTC2991_TEMPERATURE_lsb, isKelvin);
622  Serial.print(F("\n V3-V4: "));
623  Serial.print(temperature, 2);
624 
625  if (isKelvin) Serial.print(F(" K\n"));
626  else Serial.print(F(" C\n"));
627  break;
628 
629  case 3:
630 
631 
633  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
636  if (reg_data & LTC2991_V5_V6_KELVIN_ENABLE) isKelvin=true;
637  else isKelvin=false;
638  temperature = LTC2991_temperature(adc_code, LTC2991_TEMPERATURE_lsb, isKelvin);
639  Serial.print(F("\n V5-V6: "));
640  Serial.print(temperature, 2);
641 
642  if (isKelvin) Serial.print(F(" K\n"));
643  else Serial.print(F(" C\n"));
644  break;
645  case 4:
646 
648  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
651  if (reg_data & LTC2991_V7_V8_KELVIN_ENABLE) isKelvin = true;
652  else isKelvin = false;
653  temperature = LTC2991_temperature(adc_code, LTC2991_TEMPERATURE_lsb, isKelvin);
654  Serial.print(F("\n V7-V8: "));
655  Serial.print(temperature, 2);
656 
657  if (isKelvin) Serial.print(F(" K\n"));
658  else Serial.print(F(" C\n"));
659  break;
660  case 5:
661 
662 
663 
664  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
667  if (reg_data & LTC2991_INT_KELVIN_ENABLE) isKelvin=true;
668  else isKelvin=false;
669  temperature = LTC2991_temperature(adc_code, LTC2991_TEMPERATURE_lsb,isKelvin);
670  Serial.print(F("\n Internal: "));
671  Serial.print(temperature, 2);
672 
673  if (isKelvin) Serial.print(F(" K\n"));
674  else Serial.print(F(" C\n"));
675  break;
676  case 6:
677  // All Temperatures
678 
679 
680 
683  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
686  if (reg_data & LTC2991_V1_V2_KELVIN_ENABLE) isKelvin = true;
687  else isKelvin=false;
688 
689  temperature = LTC2991_temperature(adc_code, LTC2991_TEMPERATURE_lsb,isKelvin);
690  Serial.print(F("\n V1-V2: "));
691  Serial.print(temperature, 2);
692 
693  if (isKelvin) Serial.print(F(" K\n"));
694  else Serial.print(F(" C\n"));
695  if (ack)
696  break;
697 
698 
699  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
702  if (reg_data & LTC2991_V3_V4_KELVIN_ENABLE) isKelvin = true;
703  else isKelvin=false;
704  temperature = LTC2991_temperature(adc_code, LTC2991_TEMPERATURE_lsb, isKelvin);
705  Serial.print(F(" V3-V4: "));
706  Serial.print(temperature, 2);
707  if (isKelvin) Serial.print(F(" K\n"));
708  else Serial.print(F(" C\n"));
709  if (ack)
710  break;
711 
712 
713  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
716  if (reg_data & LTC2991_V5_V6_KELVIN_ENABLE) isKelvin = true;
717  else isKelvin=false;
718  temperature = LTC2991_temperature(adc_code, LTC2991_TEMPERATURE_lsb,isKelvin);
719  Serial.print(F(" V5-V6: "));
720  Serial.print(temperature, 2);
721  if (isKelvin) Serial.print(F(" K\n"));
722  else Serial.print(F(" C\n"));
723  if (ack)
724  break;
725 
726 
727  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
730  if (reg_data & LTC2991_V7_V8_KELVIN_ENABLE) isKelvin = true;
731  else isKelvin=false;
732  temperature = LTC2991_temperature(adc_code, LTC2991_TEMPERATURE_lsb, isKelvin);
733  Serial.print(F(" V7-V8: "));
734  Serial.print(temperature, 2);
735  if (isKelvin) Serial.print(F(" K\n"));
736  else Serial.print(F(" C\n"));
737  if (ack)
738  break;
739 
740 
741  // Flush one ADC reading in case it is stale. Then, take a new fresh reading.
744  if (reg_data & LTC2991_INT_KELVIN_ENABLE) isKelvin = true;
745  else isKelvin = false;
746  temperature = LTC2991_temperature(adc_code, LTC2991_TEMPERATURE_lsb, isKelvin);
747  Serial.print(F(" Internal: "));
748  Serial.print(temperature, 2);
749  if (isKelvin) Serial.print(F(" K\n"));
750  else Serial.print(F(" C\n"));
751  break;
752  default:
753  if (user_command != 'm')
754  Serial.println("Incorrect Option");
755  break;
756  }
757  }
758  while ((user_command != 'm') && (ack == 0));
759  return(ack);
760 }
761 
762 //! Configure settings
763 //! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
765 {
766  uint8_t user_command;
767  int8_t ack=0;
768  uint8_t reg_data;
769 
770  do
771  {
772  Serial.print(F("\nSettings\n")); //! Displays Setting menu
773  Serial.print(F("************************\n"));
774  Serial.print(F("* Filter *\n"));
775  Serial.print(F("************************\n"));
776  Serial.print(F("* 1-V1/V2: "));
777 
778  //! Displays present status of all settings by reading from LTC2991 registers.
780  if (reg_data & LTC2991_V1_V2_FILTER_ENABLE) Serial.print(F("Enabled *\n"));
781  else Serial.print(F("Disabled *\n"));
782 
783  Serial.print(F("* 2-V3/V4: "));
784 
785  if (reg_data & LTC2991_V3_V4_FILTER_ENABLE) Serial.print(F("Enabled *\n"));
786  else Serial.print(F("Disabled *\n"));
787 
789  Serial.print(F("* 3-V5/V6: "));
790 
791  if (reg_data & LTC2991_V5_V6_FILTER_ENABLE) Serial.print(F("Enabled *\n"));
792  else Serial.print(F("Disabled *\n"));
793 
794  Serial.print(F("* 4-V7/V8: "));
795 
796  if (reg_data & LTC2991_V7_V8_FILTER_ENABLE) Serial.print(F("Enabled *\n"));
797  else Serial.print(F("Disabled *\n"));
798 
799  Serial.print(F("* 5-Internal: "));
800 
802  if (reg_data & LTC2991_INT_FILTER_ENABLE) Serial.print(F("Enabled *\n"));
803  else Serial.print(F("Disabled *\n"));
804 
805  Serial.print(F("************************\n"));
806  Serial.print(F("* 6-Deg C/K:"));
807 
808  //Only looks at the internal temperature sensor's setting for Celsius/Kelvin, but all channels should be the same in this program.
810  if (reg_data & LTC2991_INT_KELVIN_ENABLE) Serial.print(F(" Kelvin *\n"));
811  else Serial.print(F(" Celsius*\n"));
812 
813  Serial.print(F("* m-Main Menu *\n"));
814  Serial.print(F("************************\n\n"));
815  Serial.print(F("Enter a command: "));
816 
817  user_command = read_int(); //! Reads the user command
818 
819  if (user_command == 'm') Serial.print(F("m\n")); // Print m if it is entered
820  else Serial.println(user_command); // Print user command
821 
822  //! Toggles the setting selected by user.
823  switch (user_command)
824  {
825  case 1:
826  // Toggle Filter bit
828  ack |= LTC2991_register_write(LTC2991_I2C_ADDRESS, LTC2991_CONTROL_V1234_REG, reg_data ^ LTC2991_V1_V2_FILTER_ENABLE);
829  break;
830  case 2:
831  // Toggle Filter bit
833  ack |= LTC2991_register_write(LTC2991_I2C_ADDRESS, LTC2991_CONTROL_V1234_REG, reg_data ^ LTC2991_V3_V4_FILTER_ENABLE);
834  break;
835  case 3:
836  // Toggle Filter bit
838  ack |= LTC2991_register_write(LTC2991_I2C_ADDRESS, LTC2991_CONTROL_V5678_REG, reg_data ^ LTC2991_V5_V6_FILTER_ENABLE);
839  break;
840  case 4:
841  // Toggle Filter bit
843  ack |= LTC2991_register_write(LTC2991_I2C_ADDRESS, LTC2991_CONTROL_V5678_REG, reg_data ^ LTC2991_V7_V8_FILTER_ENABLE);
844  break;
845  case 5:
846  // Toggle Filter bit
848  ack |= LTC2991_register_write(LTC2991_I2C_ADDRESS, LTC2991_CONTROL_PWM_Tinternal_REG, reg_data ^ LTC2991_INT_FILTER_ENABLE);
849  break;
850  case 6:
851  // Toggle Kelvin/Celsius bits
857  ack |= LTC2991_register_write(LTC2991_I2C_ADDRESS, LTC2991_CONTROL_PWM_Tinternal_REG, reg_data ^ LTC2991_INT_KELVIN_ENABLE);
858  break;
859  default:
860  if (user_command != 'm')
861  Serial.print(F("Incorrect Option\n"));
862  break;
863  }
864  }
865  while ((user_command != 'm') && (ack != 1));
866  return(ack);
867 }
868 
869 //! Configure PWM options
870 //! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
872 {
873  int8_t ack=0;
874 
875  uint8_t user_command;
876  int16_t pwm_temp = 0;
877  uint8_t reg_data, reg_data_msb;
878 
879  do
880  {
881  Serial.print(F("\n\nPWM Settings - Select to Toggle\n\n")); //! Displays PWM Settings menu
882  Serial.print(F(" 1-Temp Threshold: "));
883  // Check if V7-V8 are configured for temperature mode
884 
885  //! Print present status of all PWM settings based on LTC2991 register contents.
887  if (reg_data & LTC2991_V7_V8_TEMP_ENABLE)
888  {
889  // Print the configured PWM temperature threshold
892  // Combine temperature threshold's upper 8 MSB's from LTC2991_PWM_THRESHOLD_MSB_REG with the 1 LSB in the upper bit of LTC2991_CONTROL_PWM_Tinternal_REG
893  pwm_temp = (int16_t)((reg_data_msb << 1) | (reg_data & LTC2991_PWM_0) >> 7);
894  Serial.print(pwm_temp);
895  //Print degrees C or K configured for V7/V8
897  if (reg_data & LTC2991_V7_V8_KELVIN_ENABLE) Serial.print(F(" K\n"));
898  else Serial.print(F(" C\n"));
899  }
900  else
901  {
902  Serial.print(F("Not Configured"));
903  }
905  if (reg_data & LTC2991_PWM_INVERT) Serial.print(F(" 2-Inverted\n"));
906  else Serial.print(F(" 2-Noninverted\n"));
907 
908  if (reg_data & LTC2991_PWM_ENABLE) Serial.print(F(" 3-Enabled\n"));
909  else Serial.print(F(" 3-Disabled\n"));
910 
911  Serial.print(F(" m-Main Menu\n"));
912  Serial.print(F("\n\nEnter a command: "));
913  user_command = read_int(); //! Reads the user command
914  if (user_command == 'm') // Print m if it is entered
915  {
916  Serial.print(F("m\n"));
917  }
918  else
919  {
920  Serial.println(user_command); // Print user command
921  }
922 
923  //! Modify PWM threshold or toggle a PWM setting based on user input.
924  switch (user_command)
925  {
926  case 1:
928  if (reg_data & LTC2991_V7_V8_KELVIN_ENABLE) Serial.print(F("\nEnter Temperature Threshold in Kelvin: "));
929  else Serial.print(F("\nEnter Temperature Threshold in Celsius: "));
930  pwm_temp = (int16_t)read_int(); // read the user command
931  Serial.println(pwm_temp);
932  ack |= LTC2991_register_set_clear_bits(LTC2991_I2C_ADDRESS, LTC2991_CONTROL_V5678_REG, LTC2991_V7_V8_TEMP_ENABLE, 0x00); // Enables V7-V8
935  break;
936  case 2:
938  ack |= LTC2991_register_write(LTC2991_I2C_ADDRESS, LTC2991_CONTROL_PWM_Tinternal_REG, reg_data ^ LTC2991_PWM_INVERT);
939  break;
940  case 3:
941  // Enable temperature mode for V7-V8 in case it was in voltage mode
942  ack |= LTC2991_register_set_clear_bits(LTC2991_I2C_ADDRESS, LTC2991_CONTROL_V5678_REG, LTC2991_V7_V8_TEMP_ENABLE, 0x00);
943  // Toggle PWM Enable
945  ack |= LTC2991_register_write(LTC2991_I2C_ADDRESS, LTC2991_CONTROL_PWM_Tinternal_REG, reg_data ^ LTC2991_PWM_ENABLE);
946  break;
947  default:
948  if (user_command != 'm')
949  Serial.println("Incorrect Option");
950  break;
951  }
952  }
953  while ((user_command != 'm') && (ack != 1));
954  return(ack);
955 }
const float LTC2991_TEMPERATURE_lsb
Typical temperature LSB weight in degrees Celsius (and Kelvin).
Definition: LTC2991.h:143
static void print_title()
Prints the title block when program first starts.
Definition: DC1785A.ino:210
unsigned char user_command
#define LTC2991_ENABLE_ALL_CHANNELS
Use to enable all LTC2991 channels.
Definition: LTC2991.h:211
const float LTC2991_DIFFERENTIAL_lsb
Typical differential LSB weight in volts.
Definition: LTC2991.h:138
int8_t LTC2991_register_set_clear_bits(uint8_t i2c_address, uint8_t register_address, uint8_t bits_to_set, uint8_t bits_to_clear)
Used to set and clear bits in a control register.
Definition: LTC2991.cpp:173
#define LTC2991_V7_V8_DIFFERENTIAL_ENABLE
Enable V7-V8 differential mode.
Definition: LTC2991.h:238
#define LTC2991_V5_V6_KELVIN_ENABLE
Enable V5-V6 for Kelvin.
Definition: LTC2991.h:240
#define LTC2991_PWM_0
PWM threshold Least Significant Bit.
Definition: LTC2991.h:250
#define LTC2991_V5_V6_DIFFERENTIAL_ENABLE
Enable V5-V6 differential mode.
Definition: LTC2991.h:242
#define LTC2991_V1_V2_TEMP_ENABLE
Enable V1-V2 temperature mode.
Definition: LTC2991.h:226
#define LTC2991_V5_V6_FILTER_ENABLE
Enable filters on V5-V6.
Definition: LTC2991.h:239
#define LTC2991_Vcc_MSB_REG
Vcc MSB.
Definition: LTC2991.h:197
static int8_t menu_2_read_differential_voltage()
Read differential voltages.
Definition: DC1785A.ino:446
#define LTC2991_INT_FILTER_ENABLE
Enable Internal Temperature Filter.
Definition: LTC2991.h:254
float LTC2991_code_to_vcc_voltage(int16_t adc_code, float LTC2991_single_ended_lsb)
Calculates the LTC2991 Vcc voltage.
Definition: LTC2991.cpp:201
Header File for Linduino Libraries and Demo Code.
#define LTC2991_V3_V4_DIFFERENTIAL_ENABLE
Enable V3-V4 differential mode.
Definition: LTC2991.h:223
#define LTC2991_V1_V2_FILTER_ENABLE
Enable filters on V1-V2.
Definition: LTC2991.h:224
#define LTC2991_V5_MSB_REG
V5, or T_R3 T MSB.
Definition: LTC2991.h:187
const uint16_t LTC2991_TIMEOUT
Configures the maximum timeout allowed for an LTC2991 read.
Definition: DC1785A.ino:141
#define LTC2991_PWM_THRESHOLD_MSB_REG
PWM Threshold.
Definition: LTC2991.h:178
static uint8_t demo_board_connected
Set to 1 if the board is connected.
Definition: DC1785A.ino:139
#define LTC2991_V1_V2_DIFFERENTIAL_ENABLE
Enable V1-V2 differential mode.
Definition: LTC2991.h:227
#define LTC2991_CONTROL_V5678_REG
V5, V6, V7, AND V8 Control Register.
Definition: LTC2991.h:176
const float LTC2991_SINGLE_ENDED_lsb
Typical single-ended LSB weight in volts.
Definition: LTC2991.h:136
#define LTC2991_CONTROL_PWM_Tinternal_REG
PWM Threshold and T_internal Control Register.
Definition: LTC2991.h:177
int8_t LTC2991_register_write(uint8_t i2c_address, uint8_t register_address, uint8_t register_data)
Write one byte to an LTC2991 register.
Definition: LTC2991.cpp:163
float LTC2991_code_to_differential_voltage(int16_t adc_code, float LTC2991_differential_lsb)
Calculates the LTC2991 differential input voltage.
Definition: LTC2991.cpp:216
#define LTC2991_I2C_ADDRESS
I2C address of the LTC2991.
Definition: LTC2991.h:156
#define LTC2991_V7_V8_KELVIN_ENABLE
Enable V7-V8 for Kelvin.
Definition: LTC2991.h:236
float LTC2991_code_to_single_ended_voltage(int16_t adc_code, float LTC2991_single_ended_lsb)
Calculates the LTC2991 single-ended input voltages.
Definition: LTC2991.cpp:186
#define LTC2991_PWM_INVERT
Invert PWM.
Definition: LTC2991.h:251
QuikEval EEPROM Library.
static int8_t menu_3_read_temperature()
Read temperatures.
Definition: DC1785A.ino:564
#define LTC2991_V4_MSB_REG
V4, V3-V4, or T_R2 Voltage MSB.
Definition: LTC2991.h:185
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
#define LTC2991_PWM_ENABLE
Enable PWM.
Definition: LTC2991.h:252
#define LTC2991_V2_MSB_REG
V2, V1-V2, or T_R2 Voltage MSB.
Definition: LTC2991.h:181
#define LTC2991_V7_MSB_REG
V7, or T_R4 T MSB.
Definition: LTC2991.h:191
#define LTC2991_V7_V8_FILTER_ENABLE
Enable filters on V7-V8.
Definition: LTC2991.h:235
#define LTC2991_V3_V4_TEMP_ENABLE
Enable V3-V4 temperature mode.
Definition: LTC2991.h:222
#define LTC2991_V5_V6_TEMP_ENABLE
Enable V5-V6 temperature mode.
Definition: LTC2991.h:241
#define LTC2991_V3_V4_FILTER_ENABLE
Enable filters on V3-V4.
Definition: LTC2991.h:220
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
#define LTC2991_V7_V8_TEMP_ENABLE
Enable V7-V8 temperature mode.
Definition: LTC2991.h:237
int8_t LTC2991_adc_read_new_data(uint8_t i2c_address, uint8_t msb_register_address, int16_t *adc_code, int8_t *data_valid, uint16_t timeout)
Reads new data (even after a mode change) by flushing old data and waiting for the data_valid bit to ...
Definition: LTC2991.cpp:142
int8_t LTC2991_register_read(uint8_t i2c_address, uint8_t register_address, uint8_t *register_data)
Reads an 8-bit register from the LTC2991 using the standard repeated start format.
Definition: LTC2991.cpp:153
static int8_t menu_5_pwm_options()
Configure PWM options.
Definition: DC1785A.ino:871
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
static int8_t menu_1_single_ended_voltage()
Read single-ended voltages.
Definition: DC1785A.ino:237
int32_t read_int()
#define LTC2991_REPEAT_MODE
Enable Repeated Aquisition Mode.
Definition: LTC2991.h:253
#define LTC2991_T_Internal_MSB_REG
T_Internal MSB.
Definition: LTC2991.h:195
static int8_t menu_4_settings()
Configure settings.
Definition: DC1785A.ino:764
static void loop()
Repeats Linduino loop.
Definition: DC1785A.ino:164
#define LTC2991_V1_V2_KELVIN_ENABLE
Enable V1-V2 for Kelvin.
Definition: LTC2991.h:225
#define LTC2991_V1_MSB_REG
V1, or T_R1 T MSB.
Definition: LTC2991.h:179
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
#define LTC2991_CONTROL_V1234_REG
V1, V2, V3, and V4 Control Register.
Definition: LTC2991.h:175
void quikeval_I2C_connect(void)
Switch MUX to connect I2C pins to QuikEval connector.
Definition: LT_I2C.cpp:401
#define LTC2991_V3_MSB_REG
V3, or T_R2 T MSB.
Definition: LTC2991.h:183
#define LTC2991_CHANNEL_ENABLE_REG
Channel Enable, Vcc, T_internal Conversion Status, Trigger.
Definition: LTC2991.h:174
static float voltage
Definition: DC2289AA.ino:71
#define LTC2991_V8_MSB_REG
V8, V7-V8, or T_R4 Voltage MSB.
Definition: LTC2991.h:193
#define LTC2991_V6_MSB_REG
V6, V5-V6, or T_R3 Voltage MSB.
Definition: LTC2991.h:189
float LTC2991_temperature(int16_t adc_code, float LTC2991_temperature_lsb, boolean unit)
Calculates the LTC2991 temperature.
Definition: LTC2991.cpp:230
#define LTC2991_INT_KELVIN_ENABLE
Enable internal temperature for Kelvin.
Definition: LTC2991.h:255
static void print_prompt()
Prints main menu.
Definition: DC1785A.ino:225
static void setup()
Initialize Linduino.
Definition: DC1785A.ino:144
LTC2991: 14-bit ADC octal I2C voltage, current, and temperature monitor.
#define LTC2991_V3_V4_KELVIN_ENABLE
Enable V3-V4 for Kelvin.
Definition: LTC2991.h:221
static uint32_t adc_code
Definition: DC2071AA.ino:113