| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

DC2574A_KIT.ino
Go to the documentation of this file.
1 /**
2 \date 6/17/2016
3
4 \brief
5 Linduino.INO File for DC2574A_KIT: Standalone power/energy monitor for evaluation of the LTC2947 monitor without a PC
6 Linear Technology DC2574A_KIT Demonstration Board: Standalone power/energy monitor for evaluation of the LTC2947 monitor without a PC.
7 LTC2947: high-precision power and energy monitor with an internal sense resistor supporting up to 30A.
8
9 NOTE:
10 The DC2574A-KIT includes the following items:
11 - DC2334A: LTC2947 Demo Circuit
12 - DC2026: Linduino with Pre-Programmed "LTC2947 - DC2574A_KIT Linduino.INO File" (THIS FILE!)
13 - LCD Keypad Shield
14 - USB Cable: Power Supply And Optional Communication Interface for Operating with the GUI
15 - 14-pin Ribbon Cable.
16
17 The DC2574A_KIT Linduino sketch contains a lot of code that is only necessary to operate with the
18 LCD, the serial ports and to allow compatibility with DC590 commands (see usage of GUI together with
19 the DC2574A-KIT). This code might not be of interest by the customer that wants to focuse on functionality
20 of the LTC2947. The focuse on LTC2947 relevant code only, just search for LTC2947_ within this source file.
21
22 Setup:
23 Set the terminal baud rate to 115200 and de-select the newline terminator. (That means
24 e.g. within the serial monitor of the Arduino IDE select "No line ending")
25 Refer to Demo Manual DC2574A_KIT.
26 Ensure all jumpers are installed in the factory default positions.
27 Especially make sure the board is configured to I2C mode with slave address set
28 to 0x5C (LL), see also below the define LTC2947_I2C_ADDRESS
29
30 Command Description:
31 After start-up the DC2574A_KIT Linduino sketch will send the following lines
32 on the connected serial com port:
33
34 Hello LTC2947
35 30A PowerMonitor
36 LCD found! Enter l or m for options.
37
38 - or in case no LCD Keypad Shield is plugged on top of the DC2334A demoboard -
39
40 No LCD found! Enter l or m for options.
41
42 In any case commands l or m can be send:
43 l-command: Status/Alert regsierts, the following submenu will be shown:
44 0:STATUS
45 1:STATVT
46 2:STATIP
47 3:STATC
48 4:STATE
49 5:STATCEOF
50 6:STATTB
51 7:STATVDVCC
52 8:CYCLE ALL
53 enter 0-8, any other to cancel
54
55 Select one out of 0-7 to report a single status/alert register or 8 to cycle
56 through all status/alert registers. In both cases new values will be reported
57 every second. E.g. for option 0 (STATUS) you will get the following output:
58 STAT:UPD,
59
60 STAT:UPD,
61 ...
62
63 The bits of the status/alert registers that are set to 1 will be reported, e.g. UPD
64 is the UPDATE bit of the STATUS register that tells a new conversion cycle
65 was performed.
66
67 Option 8 (CYCLE ALL) will show the following output:
68
69 STAT:UPD,
70
71 STATVT:
72
73 STATIP:
74
75 STATC:
76
77 STATE:
78
79 STATCEOF:
80
81 STATTB:
82
83 STATVDVCC:
84
85 In the example output above only the UPDATE bit was set
86
87 m-command: Measurement values, the following submenu will be shown:
88 0: I V
89 P TEMP
90 1:C1 VDVCC
91 E1 TB1
92 2:C2 VDVCC
93 E2 TB2
94 3:IMIN IMAX
95 PMIN PMAX
96 4:VMIN VMAX
97 TMIN TMAX
98 5:TMIN TMAX
99 VDMIN VDMAX
100 6:CYCLE ALL
101 measurements
102 enter 0-6, any other to cancel
103
104 Select one out of 0-5 to report a single set of measurement values or 8 to cycle
105 through all measurements. In both cases new values will be reported
106 every second. E.g. for option 0 (I V P TEMP) you will get the following output:
107
108 I V
109 P TEMP
110 0.012A -0.342V
111 0.000W 30.2°C
112 0.006A -0.342V
113 0.000W 30.2°C
114 0.012A -0.342V
115 0.000W 30.2°C
116 I V
117 P TEMP
118 0.012A -0.342V
119 0.000W 30.2°C
120 ....
121
122 Current, Voltage, Power and die temperature are reported every second.
123 Option 6 (CYCLE ALL) will show the following output:
124
125 I V
126 P TEMP
127 0.006A -0.342V
128 0.000W 30.2°C
129 0.012A -0.342V
130 0.000W 30.2°C
131 0.012A -0.342V
132 0.000W 30.2°C
133 C1 VDVCC
134 E1 TB1
135 4.83mAh 4.50V
136 0.00mWh 34m35s
137 4.83mAh 4.50V
138 0.00mWh 34m36s
139 4.83mAh 4.50V
140 0.00mWh 34m37s
141 C2 VDVCC
142 E2 TB2
143 4.84mAh 4.64V
144 0.00mWh 34m40s
145 4.84mAh 4.50V
146 0.00mWh 34m41s
147 4.85mAh 4.50V
148 0.00mWh 34m42s
149 ....
150
151 In case a LCD Keypad Shield is plugged on top of the DC2334A demoboard, all
152 output will also be shown on the LCD.
153
154 DC590B compatibility:
155 Appart from commands m and l the DC2574A_KIT sketch also supports a subset of the DC590B commands.
156 This way the LTC2947 GUI is also able to communicate with the DC2574A_KIT sketch which enables the
157 user to use the GUI to change LTC2947 configuration e.g. to set alarm thresholds etc.
158 The main limitations of this compatibility mode are:
159 - EEPROM read from the DC2334A demo board is faked (it will always report the right EEPROM string)
160 - SPI operation is not supported, due to incompatibility with the optional LCD Keypad Shield
161
162 See tinyDC590.cpp for details
163
164 http://www.linear.com/product/LTC2947
165
166 http://www.linear.com/product/LTC2947#demoboards
167
168
169 Copyright 2018(c) Analog Devices, Inc.
170
171 All rights reserved.
172
173 Redistribution and use in source and binary forms, with or without
174 modification, are permitted provided that the following conditions are met:
175 - Redistributions of source code must retain the above copyright
176 notice, this list of conditions and the following disclaimer.
177 - Redistributions in binary form must reproduce the above copyright
178 notice, this list of conditions and the following disclaimer in
179 the documentation and/or other materials provided with the
180 distribution.
181 - Neither the name of Analog Devices, Inc. nor the names of its
182 contributors may be used to endorse or promote products derived
183 from this software without specific prior written permission.
184 - The use of this software may or may not infringe the patent rights
185 of one or more patent holders. This license does not release you
186 from the requirement that you obtain separate licenses from these
187 patent holders to use this software.
188 - Use of the software either in source or binary form, must be run
189 on or directly connected to an Analog Devices Inc. component.
190
191 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
192 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
193 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
194 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
195 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
196 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
197 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
198 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
199 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
200 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
201 */
202
203 /*! @file
204 @ingroup LTC2947
205 Linduino .INO file for LTC2947 a high-precision power and energy monitor with an internal sense resistor supporting up to 30A.
206 */
207
208 #include <SPI.h>
209 #include <LT_SPI.h>
210 #include <LT_I2C.h>
211 #include <Linduino.h>
212 #include <LiquidCrystal.h>
213 #include "LCDKeypad.h"
214 #include "DC590_subset.ino"
215
216 //! DC590 busy check. Declared and controlled by DC590_subset.ino
217 //! true if DC590 is busy processing commands, false if not busy
218 extern boolean dc590Busy;
219
220 /** \brief Edit LTC2947.h to adjust the following settings:
221 Internal / External clock operation and frequency setting
222 I2C / SPI mode operation
223 In case of I2C: Slave address configuration
224 */
225 #include "LTC2947.h"
226
227 /** \brief
228 Define either LTC2947_I2C_MODE_ENABLE or LTC2947_SPI_MODE_ENABLE to set the communication interface to I2C or SPI
229 NOTE: It is not possible to operate in SPI mode together with the LCD due to pin conflicts. If you want to
230 operate in SPI mode you have to remove the LCD and connect DC2334A via the 14-pin ribbon cable to J1 of Linduino
231 instead of connecting DC2334A as a shield on top of Linduino.
232 */
233 #define LTC2947_I2C_MODE_ENABLE
234 //#define LTC2947_SPI_MODE_ENABLE
235
236 /** \brief Only one mode is possible at a time. If I2C and SPI are both enabled, I2C mode will be used! */
237 #ifdef LTC2947_I2C_MODE_ENABLE
238 #undef LTC2947_SPI_MODE_ENABLE
239 #endif
240
241 /** \brief update interval time in milli seconds */
242 #define SCREEN_UPDATE_TIME 1000UL
243 #define LABEL_DELAY 2000UL
244 #define SPLASH_SCREEN_DELAY 3000UL
245 /** \brief Menu Group 1 count: STATUS STATVT STATIP STATC STATE STATCEOF STATTB STATVDVCC "CYCLE stats" */
246 #define USER_SEL_GRP1_COUNT 9
247 /** \brief Menu Group 1 cycle count: STATUS STATVT STATIP STATC STATE STATCEOF STATTB STATVDVCC */
248 #define USER_SEL_GRP1_CYCLE_COUNT 8
249 /** \brief Menu group 2 count: RAW, ACCU1, ACCU2, Track1, Track2, Track3, "Cycle meas." */
250 #define USER_SEL_GRP2_COUNT 7
251 /** \brief Menu Group 2 cycle count: RAW, ACCU1, ACCU2, Track1, Track2, Track3 */
252 #define USER_SEL_GRP2_CYCLE_COUNT 6
253 /** \brief defines how many cycles a single measurement group will be displayed on the LCD in case of "cycle all" (2 means each measurement is shown 3 times) */
254 #define USERGROUPCYCLETIMERRELOAD 3
255
256 #define MEAS_LABEL00 F("I V")
257 #define MEAS_LABEL01 F("P TEMP")
258 #define MEAS_LABEL10 F("C1 VDVCC")
259 #define MEAS_LABEL11 F("E1 TB1")
260 #define MEAS_LABEL20 F("C2 VDVCC")
261 #define MEAS_LABEL21 F("E2 TB2")
262 #define MEAS_LABEL30 F("IMIN IMAX")
263 #define MEAS_LABEL31 F("PMIN PMAX")
264 #define MEAS_LABEL40 F("VMIN VMAX")
265 #define MEAS_LABEL41 F("TMIN TMAX")
266 #define MEAS_LABEL50 F("TMIN TMAX")
267 #define MEAS_LABEL51 F("VDMIN VDMAX")
268 #define MEAS_LABEL60 F("CYCLE ALL")
269 #define MEAS_LABEL61 F("measurements")
270
271 /** \brief The next update time. Stores the next time stamp (used for timing of update task) */
272 unsigned long nextUpdateTime = 0;
273
274 /** \brief pointer to the LCD keypad object */
275 LCDKeypad *lcd;
276 /** \brief The previous key. Stores previously pressed key*/
277 int8_t previousKey = KEYPAD_NONE;
278 /** \brief flag to store actions from user input. */
279 boolean flagClear = false;
280 /** \brief User selection of the first group. */
281 uint8_t userSelGroup1 = 0;
282 /** \brief group 1 cycle enable */
283 boolean userGroup1Cycle = false;
284 /** \brief User selection of the second group. */
285 uint8_t userSelGroup2 = 0;
286 /** \brief group 2 cycle enable */
287 boolean userGroup2Cycle = false;
288 /** \brief selected group 1: false, 2: true */
289 boolean userGroupSelect = true;
290 /** \brief flag is asserted once after all status registers were read. */
291 boolean statusRegsRead = false;
292 /** \brief array to store all status / alert registers */
293 byte statusRegs[8];
294 /** \brief The user group cycle timer. */
295 uint8_t userGroupCycleTimer = 0;
296
297 /** \fn void setup()
298 \brief general initialization */
299 void setup()
300 {
301 // init serial port
302 Serial.begin(115200);
303 // connect to LCD
304 lcd = new LCDKeypad(10);
305 #ifdef LTC2947_SPI_MODE_ENABLE
306 lcd->Disable4BitLCD();
307 LTC2947_InitSPI();
308 spi_enable(SPI_CLOCK_DIV16); // Configure the spi port for 1MHz SCK (16MHz / 16)
309 quikeval_SPI_connect();
310 #else
311 lcd->searchForLCD();
312 // set LTC2947 library to I2C mode
313 LTC2947_InitI2C(LTC2947_I2C_ADDR_LL);
314 // Initializes Linduino I2C port.
315 quikeval_I2C_init();
316 // Connects I2C to QuikEval port
317 quikeval_I2C_connect();
318 #endif
319 // make a reset of LTC2947
320 LTC2947_WR_BYTE(LTC2947_REG_OPCTL, LTC2947_BM_OPCTL_RST);
321 // give device some time to restart
322 DelayAndCheckSerialData(120);
323 // write PRE and DIV setting
324 LTC2947_WR_BYTE(LTC2947_REG_TBCTL,
325 LTC2947_PRE << BM2BITPOS(LTC2947_BM_TBCTL_PRE_0) |
326 LTC2947_DIV << BM2BITPOS(LTC2947_BM_TBCTL_DIV_0));
327 // enable continuous measurement on LTC2947
328 LTC2947_WR_BYTE(LTC2947_REG_OPCTL, LTC2947_BM_OPCTL_CONT);
329 CLEAR_SCREEN();
330 lcd->EnableSerialOutput = true;
331 PRINTSCREEN(F("Hello LTC2947"));
332 NEWLINE();
333 PRINTSCREEN(F("30A PowerMonitor"));
334 lcd->EnableSerialOutput = false;
335 Serial.println();
336 if (!lcd->foundLCD)
337 Serial.print(F("No "));
338 Serial.println(F("LCD found! Enter l or m for options."));
339 Serial.flush();
340 DelayAndProcessInputs(SPLASH_SCREEN_DELAY); //DelayAndCheckSerialData(SPLASH_SCREEN_DELAY);
341 }
342
343 /** \fn void update()
344 \brief update LTC2947 measurement results */
345 void update()
346 {
347 // general buffer to hold data from 2947
348 byte data[8];
349 // stores the last value or PGCTL
350 boolean lastPageSelect;
351 // 1st check if we will actually read values
352 // from the device or just show labels of
353 // measured values on the LCD
354 if (!flagClear && userGroupSelect)
355 {
356 // labels might only be shown if no clear is requested and measurement values will be shown
357 boolean showHeader = false;
358 if (userGroupCycleTimer == 0)
359 {
360 if (userGroup2Cycle)
361 userSelGroup2 = (userSelGroup2 + 1) % USER_SEL_GRP2_CYCLE_COUNT;
362 userGroupCycleTimer = USERGROUPCYCLETIMERRELOAD;
363 showHeader = true;
364 }
365 else
366 userGroupCycleTimer--;
367 if (showHeader)
368 {
369 CLEAR_SCREEN();
370 switch (userSelGroup2)
371 {
372 case 0:
373 PRINTSCREEN(MEAS_LABEL00);
374 NEWLINE();
375 PRINTSCREEN(MEAS_LABEL01);
376 DelayAndProcessInputs(LABEL_DELAY);
377 return;
378 case 1:
379 PRINTSCREEN(MEAS_LABEL10);
380 NEWLINE();
381 PRINTSCREEN(MEAS_LABEL11);
382 DelayAndProcessInputs(LABEL_DELAY);
383 return;
384 case 2:
385 PRINTSCREEN(MEAS_LABEL20);
386 NEWLINE();
387 PRINTSCREEN(MEAS_LABEL21);
388 DelayAndProcessInputs(LABEL_DELAY);
389 return;
390 case 3:
391 PRINTSCREEN(MEAS_LABEL30);
392 NEWLINE();
393 PRINTSCREEN(MEAS_LABEL31);
394 DelayAndProcessInputs(LABEL_DELAY);
395 return;
396 case 4:
397 PRINTSCREEN(MEAS_LABEL40);
398 NEWLINE();
399 PRINTSCREEN(MEAS_LABEL41);
400 DelayAndProcessInputs(LABEL_DELAY);
401 return;
402 default:
403 PRINTSCREEN(MEAS_LABEL50);
404 NEWLINE();
405 PRINTSCREEN(MEAS_LABEL51);
406 DelayAndProcessInputs(LABEL_DELAY);
407 return;
408 }
409 }
410 }
411 // check if we are in cont mode
412 LTC2947_RD_BYTE(LTC2947_REG_OPCTL, data);
413 if (bitMaskClrChk(data[0], LTC2947_BM_OPCTL_CONT))
414 {
415 // enable continuous measurement on LTC2947
416 LTC2947_WR_BYTE(LTC2947_REG_OPCTL, LTC2947_BM_OPCTL_CONT);
417 return; // we were in IDLE, so nothing todo here
418 }
419 // store page select
420 // this is needed to restore last selected page to avoid page missmatch
421 // if the LTC2947 GUI is also communicating with Linduino
422 lastPageSelect = LTC2947_GetCurrentPageSelect();
423 if (lastPageSelect)
424 LTC2947_SetPageSelect(false); // go to page 0 where the measuremnt results are stored
425 #ifdef LTC2947_AUTO_READ_STATUS
426 // reading the STATUS register would also affect the GUI as status register bits are CoR!!!
427 // for this reason the following code is not enabled!
428 // still KEYPAD_RIGHT allows read of STATUS on demand and print result on LCD
429 // read all status and alert (if alerts are used it is important to read all in a single burst of 8 bytes!)
430 LTC2947_RD_BYTES(LTC2947_REG_STATUS, 8, data);
431 // if UPDATE bit is set we have a new conversion result
432 if (bitMaskSetChk(data[0], LTC2947_BM_STATUS_UPDATE))
433 return; // UPDATE bit not set, so no new data
434 #endif
435 if (flagClear)
436 {
437 // clear everything
438 flagClear = false;
439 NEWLINE();
440 PRINTSCREEN(F("****CLEARED*****"));
441 LTC2947_WR_BYTE(LTC2947_REG_OPCTL, 0); // leave continuous mode and go to IDLE
442 DelayAndCheckSerialData(100);
443 LTC2947_WR_BYTE(LTC2947_REG_OPCTL, LTC2947_BM_OPCTL_CLR); // clear tracking registers and accumulators
444 DelayAndCheckSerialData(50);
445 LTC2947_WR_BYTE(LTC2947_REG_OPCTL, LTC2947_BM_OPCTL_CONT); // enable continuous
446 }
447 else
448 {
449 if (userGroupSelect)
450 {
451 switch (userSelGroup2)
452 {
453 case 0://PRINTSCREEN(F("I V P TEMP"));
454 {
455 // show RAW quantities like I,P,V,TEMP
456 float I, P, V, TEMP, VCC;
457 LTC2947_Read_I_P_V_TEMP_VCC(&I, &P, &V, &TEMP, &VCC);
458 CheckSerialData();// we execute CheckSerialData() from time to time here to make sure the uart rx buffer never overflows
459 // print current and limit decimal points for values -30.00 ... -10.00 (but -9.999 ... 30.000)
460 CLEAR_SCREEN();
461 PRINTSCREEN2(I, I > -10.0 ? 3 : 2);
462 PRINTSCREEN('A');
463 SCREENSETCURSOR(8, 0);
464 PRINTSCREEN2(V, 3);
465 PRINTSCREEN('V');
466 CheckSerialData();
467 NEWLINE();
468 PRINTSCREEN2(P, 3); // max characters: -450.000W = 9: 0..8
469 PRINTSCREEN('W');
470 boolean limitTempCharacters = P <= -100.0;
471 SCREENSETCURSOR(10, 1);
472 PRINTSCREEN2(TEMP, limitTempCharacters ? 0 : 1);
473 WRITE_DEGREE_C();
474 }
475 break;
476 case 1://PRINTSCREEN(F("C1 VDVCC E1 TB1"));
477 case 2://PRINTSCREEN(F("C2 VDVCC E2 TB2"));
478 {
479 double C, E, TB;
480 boolean signC = true, signE = true;
481 #ifndef LTC2947_READ_SIGNED_ACCUS
482 LTC2947_Read_Abs_C_E_TB(userSelGroup2 == 1, &C, &signC, &E, &signE, &TB); //Read either C1/2,E1/2,TB1/2
483 #else
484 // instead of using LTC2947_Read_Abs_C_E_TB we could also call LTC2947_Read_C_E_TB to
485 // get signed charge and energy values. But as the following code makes usage of
486 // LTC2947_Read_Abs_C_E_TB's separation in absolute values and sign, we won't use
487 // LTC2947_Read_C_E_TB here!
488 LTC2947_Read_C_E_TB(userSelGroup2 == 1, &C, &E, &TB); //Read either C1/2,E1/2,TB1/2
489 if (C < 0) C = -C;
490 else signC = false;
491 if (E < 0) E = -E;
492 else signE = false;
493 #endif
494 C = C * LTC2947_LSB_FACTOR_MILLI_HOURS; //! convert As to mAh
495 E = E * LTC2947_LSB_FACTOR_MILLI_HOURS; //! convert Ws to mWh
496 CLEAR_SCREEN();
497 // convert to reasonable units
498 if (C < 1e3)
499 {
500 // restore sign and print value in mAh
501 PRINTSCREEN2(signC ? -C : C, 2); // e.g. -999.99mAh: 10 chars
502 PRINTSCREEN(F("mAh"));
503 }
504 else if (C < 1e6)
505 {
506 // restore sign and print value in Ah
507 C = C * 1e-3;
508 PRINTSCREEN2(signC ? -C : C, 3); // e.g. -999.999Ah: 10 chars
509 PRINTSCREEN(F("Ah"));
510 }
511 else if (C < 1e9)
512 {
513 // restore sign and print value in kAh
514 C = C * 1e-6;
515 PRINTSCREEN2(signC ? -C : C, 2); // e.g. -999.99kAh: 10 chars
516 PRINTSCREEN(F("kAh"));
517 }
518 CheckSerialData();
519 SCREENSETCURSOR(11, 0);
520 LTC2947_RD_BYTES(LTC2947_VAL_VDVCC, 2, data); // read VDVCC[15:0]
521 double vcc = LTC2947_BytesToDouble(data, 2, true, LTC2947_LSB_VDVCC * 1e-3); // convert to real volts
522 PRINTSCREEN2(vcc, 2);
523 PRINTSCREEN('V'); // e.g. 4.65V: 5 chars
524 CheckSerialData();
525 NEWLINE();
526 // convert to reasonable units
527 if (E < 1e3)
528 {
529 // restore sign and print value in mWh
530 PRINTSCREEN2(signE ? -E : E, signE && (E >= 1e2) ? 1 : 2);
531 PRINTSCREEN(F("mWh"));
532 }
533 else if (E < 1e6)
534 {
535 // restore sign and print value in Wh
536 E = E * 1e-3;
537 PRINTSCREEN2(signE ? -E : E, signE && (E >= 1e5) ? 2 : 3);
538 PRINTSCREEN(F("Wh"));
539 }
540 else if (E < 1e9)
541 {
542 // restore sign and print value in kWh
543 E = E * 1e-6;
544 PRINTSCREEN2(signE ? -E : E, signE && (E >= 1e8) ? 1 : 2);
545 PRINTSCREEN(F("kWh"));
546 }
547 CheckSerialData();
548 SCREENSETCURSOR(10, 1);
549 // convert to reasonable units
550 if (TB < 60.0) // less than one minute
551 {
552 //print time in seconds
553 PRINTSCREEN2(TB, 2);
554 PRINTSCREEN('s');//e.g. 59.9s
555 }
556 else if (TB < 60.0 * 60.0) // less than one hour
557 {
558 //print time in minutes and seconds
559 uint16_t intSec = TB;
560 PRINTSCREEN(intSec / 60);
561 PRINTSCREEN('m');
562 PRINTSCREEN(intSec % 60);
563 PRINTSCREEN('s');//e.g. 59m59s
564 }
565 else if (TB < 60.0 * 60.0 * 24.0)
566 {
567 //print time in hours and minutes
568 uint16_t intMin = TB / 60.0;
569 PRINTSCREEN(intMin / 60);
570 PRINTSCREEN('h');
571 PRINTSCREEN(intMin % 60);
572 PRINTSCREEN('m');//e.g. 23h59m
573 }
574 else if (TB < 60.0 * 60.0 * 24.0 * 99.0)
575 {
576 //print time in days and hours
577 uint16_t inthour = TB / (60.0 * 60.0);
578 PRINTSCREEN(inthour / 24);
579 PRINTSCREEN('d');
580 PRINTSCREEN(inthour % 24);
581 PRINTSCREEN('h');//e.g. 99d23h
582 }
583 }
584 break;
585 case 3://IMIN IMAX / PMIN PMAX
586 {
587 float floatHelp;
588 LTC2947_RD_BYTES(LTC2947_VAL_IMAX, 8, data); // IMAX[15:0] IMIN[15:0] PMAX[15:0] PMIN[15:0] starting at data[0]
589 CheckSerialData();
590 floatHelp = LTC2947_2BytesToInt16(data + 2) * LTC2947_LSB_IMIN * 1e-3;// calc min current in amps
591 CLEAR_SCREEN();
592 PRINTSCREEN2(floatHelp, 2); //e.g. -30.00...30.00A..-30.00A
593 PRINTSCREEN(F("..."));
594 floatHelp = LTC2947_2BytesToInt16(data) * LTC2947_LSB_IMAX * 1e-3;
595 PRINTSCREEN2(floatHelp, 2);
596 PRINTSCREEN('A');
597 CheckSerialData();
598 floatHelp = LTC2947_2BytesToInt16(data + 6) * LTC2947_LSB_PMIN * 1e-3;// calc power in watts
599 NEWLINE();
600 PRINTSCREEN2(floatHelp, 1); // e.g. -450.0W
601 PRINTSCREEN(F("..."));
602 floatHelp = LTC2947_2BytesToInt16(data + 4) * LTC2947_LSB_PMAX * 1e-3;
603 PRINTSCREEN2(floatHelp, 1);
604 PRINTSCREEN('W');
605 }
606 break;
607 case 4://VMIN VMAX / TMIN TMAX
608 {
609 float floatHelp;
610 LTC2947_RD_BYTES(LTC2947_VAL_VMAX, 8, data); // VMAX[15:0] VMIN[15:0] TEMPMAX[15:0] TEMPMIN[15:0] starting at data[0]
611 CheckSerialData();
612 floatHelp = LTC2947_2BytesToInt16(data + 2) * LTC2947_LSB_VMIN * 1e-3;
613 CLEAR_SCREEN();
614 PRINTSCREEN2(floatHelp, 2);
615 PRINTSCREEN(F("..."));
616 floatHelp = LTC2947_2BytesToInt16(data) * LTC2947_LSB_VMAX * 1e-3;
617 PRINTSCREEN2(floatHelp, 2);
618 PRINTSCREEN('V');
619 CheckSerialData();
620 floatHelp = LTC2947_2BytesToInt16(data + 6) * LTC2947_LSB_TEMPMIN + LTC2947_OFFS_TEMPMIN;
621 boolean limitTempCharacters = floatHelp <= -100.0;
622 NEWLINE();
623 PRINTSCREEN2(floatHelp, limitTempCharacters ? 0 : 1);
624 PRINTSCREEN(F("..."));
625 floatHelp = LTC2947_2BytesToInt16(data + 4) * LTC2947_LSB_TEMPMAX + LTC2947_OFFS_TEMPMAX;
626 limitTempCharacters = floatHelp <= -100.0;
627 PRINTSCREEN2(floatHelp, limitTempCharacters ? 0 : 1);
628 WRITE_DEGREE_C();
629 }
630 break;
631 default://TMIN TMAX / VDMIN VDMAX
632 {
633 float floatHelp;
634 LTC2947_RD_BYTES(LTC2947_VAL_TEMPMAX, 8, data); // TEMPMAX[15:0] TEMPMIN[15:0] VDVCCMAX[15:0] VDVCCMIN[15:0] starting at data[0]
635 CheckSerialData();
636 floatHelp = LTC2947_2BytesToInt16(data + 2) * LTC2947_LSB_TEMPMIN + LTC2947_OFFS_TEMPMIN;
637 boolean limitTempCharacters = floatHelp <= -100.0;
638 CLEAR_SCREEN();
639 PRINTSCREEN2(floatHelp, limitTempCharacters ? 0 : 1);
640 PRINTSCREEN(F("..."));
641 floatHelp = LTC2947_2BytesToInt16(data) * LTC2947_LSB_TEMPMAX + LTC2947_OFFS_TEMPMAX;
642 limitTempCharacters = floatHelp <= -100.0;
643 PRINTSCREEN2(floatHelp, limitTempCharacters ? 0 : 1);
644 WRITE_DEGREE_C();
645 CheckSerialData();
646 floatHelp = LTC2947_2BytesToInt16(data + 6) * LTC2947_LSB_VDVCCMIN * 1e-3;
647 NEWLINE();
648 PRINTSCREEN2(floatHelp, 0);
649 PRINTSCREEN(F("..."));
650 floatHelp = LTC2947_2BytesToInt16(data + 4) * LTC2947_LSB_VDVCCMAX * 1e-3;
651 PRINTSCREEN2(floatHelp, 0);
652 PRINTSCREEN('V');
653 }
654 break;
655 }
656 }
657 else
658 {
659 if (userGroup1Cycle)
660 userSelGroup1 = (userSelGroup1 + 1) % USER_SEL_GRP1_CYCLE_COUNT;
661 else
662 statusRegsRead = false;// in case we don't cycle the status regs are read always
663 if (!statusRegsRead)
664 {
665 // read all status and alert (if alerts are used it is important to read all in a single burst of 8 bytes!)
666 LTC2947_RD_BYTES(LTC2947_REG_STATUS, 8, statusRegs);
667 // all status & alert regs are cleared-on-read. To make sure we report all bits correctly we
668 // only re-read them once we cycled through all of them (see last case STATVDVCC in which we clear
669 // statusRegsRead again.
670 statusRegsRead = true;
671 }
672 CLEAR_SCREEN();
673 switch (userSelGroup1)
674 {
675 case 0:
676 PRINTSCREEN(F("STAT:"));
677 if (bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_UPDATE))
678 PRINTSCREEN(F("UPD,"));
679 if (bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_ADCERR))
680 PRINTSCREEN(F("AER,"));
681 if (bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_TBERR))
682 PRINTSCREEN(F("TER"));
683 NEWLINE();
684 if (bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_UVLOA))
685 PRINTSCREEN(F("UVA,"));
686 if (bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_PORA))
687 PRINTSCREEN(F("POR,"));
688 if (bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_UVLOSTBY))
689 PRINTSCREEN(F("UVS,"));
690 if (bitMaskSetChk(statusRegs[0], LTC2947_BM_STATUS_UVLOD))
691 PRINTSCREEN(F("UVD"));
692 break;
693 case 1:
694 PRINTSCREEN(F("STATVT:"));
695 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATVT - LTC2947_REG_STATUS], LTC2947_BM_STATVT_VH))
696 PRINTSCREEN(F("VH,"));
697 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATVT - LTC2947_REG_STATUS], LTC2947_BM_STATVT_VL))
698 PRINTSCREEN(F("VL"));
699 NEWLINE();
700 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATVT - LTC2947_REG_STATUS], LTC2947_BM_STATVT_TEMPH))
701 PRINTSCREEN(F("TEH,"));
702 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATVT - LTC2947_REG_STATUS], LTC2947_BM_STATVT_TEMPL))
703 PRINTSCREEN(F("TEL,"));
704 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATVT - LTC2947_REG_STATUS], LTC2947_BM_STATVT_FANH))
705 PRINTSCREEN(F("FH,"));
706 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATVT - LTC2947_REG_STATUS], LTC2947_BM_STATVT_FANL))
707 PRINTSCREEN(F("FL"));
708 break;
709 case 2:
710 PRINTSCREEN(F("STATIP:"));
711 NEWLINE();
712
713 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATIP - LTC2947_REG_STATUS], LTC2947_BM_STATIP_IH))
714 PRINTSCREEN(F("IH,"));
715 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATIP - LTC2947_REG_STATUS], LTC2947_BM_STATIP_IL))
716 PRINTSCREEN(F("IL,"));
717 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATIP - LTC2947_REG_STATUS], LTC2947_BM_STATIP_PH))
718 PRINTSCREEN(F("PH,"));
719 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATIP - LTC2947_REG_STATUS], LTC2947_BM_STATIP_PL))
720 PRINTSCREEN(F("PL"));
721 break;
722 case 3:
723 PRINTSCREEN(F("STATC:"));
724 NEWLINE();
725 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATC - LTC2947_REG_STATUS], LTC2947_BM_STATC_C1H))
726 PRINTSCREEN(F("C1H,"));
727 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATC - LTC2947_REG_STATUS], LTC2947_BM_STATC_C1L))
728 PRINTSCREEN(F("C1L,"));
729 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATC - LTC2947_REG_STATUS], LTC2947_BM_STATC_C2H))
730 PRINTSCREEN(F("C2H,"));
731 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATC - LTC2947_REG_STATUS], LTC2947_BM_STATC_C2L))
732 PRINTSCREEN(F("C2L"));
733 break;
734 case 4:
735 PRINTSCREEN(F("STATE:"));
736 NEWLINE();
737 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATE - LTC2947_REG_STATUS], LTC2947_BM_STATE_E1H))
738 PRINTSCREEN(F("E1H,"));
739 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATE - LTC2947_REG_STATUS], LTC2947_BM_STATE_E1L))
740 PRINTSCREEN(F("E1L,"));
741 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATE - LTC2947_REG_STATUS], LTC2947_BM_STATE_E2H))
742 PRINTSCREEN(F("E2H,"));
743 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATE - LTC2947_REG_STATUS], LTC2947_BM_STATE_E2L))
744 PRINTSCREEN(F("E2L"));
745 break;
746 case 5:
747 PRINTSCREEN(F("STATCEOF:"));
748 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATCEOF - LTC2947_REG_STATUS], LTC2947_BM_STATCEOF_C1OF))
749 PRINTSCREEN(F("C1OF"));
750 NEWLINE();
751 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATCEOF - LTC2947_REG_STATUS], LTC2947_BM_STATCEOF_C2OF))
752 PRINTSCREEN(F("C2OF,"));
753 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATCEOF - LTC2947_REG_STATUS], LTC2947_BM_STATCEOF_E1OF))
754 PRINTSCREEN(F("E1OF,"));
755 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATCEOF - LTC2947_REG_STATUS], LTC2947_BM_STATCEOF_E2OF))
756 PRINTSCREEN(F("E2OF"));
757 break;
758 case 6:
759 PRINTSCREEN(F("STATTB:"));
760 NEWLINE();
761 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATTB - LTC2947_REG_STATUS], LTC2947_BM_STATTB_TB1OF))
762 PRINTSCREEN(F("1OF,"));
763 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATTB - LTC2947_REG_STATUS], LTC2947_BM_STATTB_TB2OF))
764 PRINTSCREEN(F("2OF,"));
765 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATTB - LTC2947_REG_STATUS], LTC2947_BM_STATTB_TB1TH))
766 PRINTSCREEN(F("1TH,"));
767 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATTB - LTC2947_REG_STATUS], LTC2947_BM_STATTB_TB2TH))
768 PRINTSCREEN(F("2TH"));
769 break;
770 default:
771 PRINTSCREEN(F("STATVDVCC:"));
772 NEWLINE();
773 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATVDVCC - LTC2947_REG_STATUS], LTC2947_BM_STATVDVCC_VDVCCH))
774 PRINTSCREEN(F("VDVCCH,"));
775 if (bitMaskSetChk(statusRegs[LTC2947_REG_STATVDVCC - LTC2947_REG_STATUS], LTC2947_BM_STATVDVCC_VDVCCL))
776 PRINTSCREEN(F("VDVCCL"));
777 statusRegsRead = false;// this will trigger a re-read of all status register in the next cycle
778 break;
779 }
780 }
781 }
782 // go back to page 1 if we initially had to switch to page 0
783 // this is only neccessary for compatibility with the GUI
784 if (lastPageSelect)
785 LTC2947_SetPageSelect(true); // go back to page 1
786 }
787
788 /** \fn void loop()
789 \brief main loop */
790 void loop()
791 {
792 DelayAndProcessInputs(0);
793 }
794
795 /** \fn void DelayAndProcessInputs(unsigned long ms)
796 \brief Delay and process input commands either from serial port or from keypad
797 \param ms delay in milliseconds
798 */
799 void DelayAndProcessInputs(unsigned long ms)
800 {
801 unsigned long currentMillis = millis();
802 ms += currentMillis; // calculate delay end time
803 do
804 {
805 if (dc590Busy || CheckSerialData())
806 {
807 // DC590 is still busy or new data available from serial port
808 char cmd = get_char();
809 if (!tinyDC590B(cmd))
810 processCommands(cmd); // no DC590B command so check for other commands
811 else if (cmd == 'i' || cmd == 'I') // check if one of the id commands was received (quikeval and GUI will send this command)
812 lcd->EnableSerialOutput = false; // disable any serial output
813 return;
814 }
815 if (currentMillis < ms)
816 {
817 currentMillis = millis();
818 continue;
819 }
820 if (currentMillis >= nextUpdateTime)
821 {
822 // make the periodic update of LTC2947 measurement results
823 nextUpdateTime = currentMillis + SCREEN_UPDATE_TIME;// calc next update time
824 if (!userInput())
825 update(); // update data from LTC2947
826 }
827 break;
828 }
829 while (true);
830 }
831
832 /** \fn boolean userInput()
833 \brief processes the user input from LCD keypad shield
834 \return true if any key was pressed on the LDC keypad shield */
835 boolean userInput()
836 {
837 if (!lcd->foundLCD)
838 return false;
839 int8_t key = lcd->button();// read pressed key
840 if (key != KEYPAD_NONE)
841 {
842 CLEAR_SCREEN();
843 // desable cyclic operation
844 userGroup1Cycle = false;
845 userGroup2Cycle = false;
846 userGroupCycleTimer = 0;
847 }
848 switch (key)
849 {
850 case KEYPAD_NONE:
851 break;
852 case KEYPAD_LEFT:
853 case KEYPAD_RIGHT:
854 if (previousKey == KEYPAD_LEFT)
855 {
856 if (userSelGroup2 == 0)
857 userSelGroup2 = USER_SEL_GRP2_COUNT - 1;
858 else
859 userSelGroup2--;
860 }
861 else if (previousKey == KEYPAD_RIGHT)
862 {
863 if (userSelGroup2 == USER_SEL_GRP2_COUNT - 1)
864 userSelGroup2 = 0;
865 else
866 userSelGroup2++;
867 }
868 userGroupSelect = true;
869 userGroupCycleTimer = 0;
870 switch (userSelGroup2)
871 {
872 case 0:
873 PRINTSCREEN(F("I V"));
874 NEWLINE();
875 PRINTSCREEN(F("P TEMP"));
876 break;
877 case 1:
878 PRINTSCREEN(F("C1 VDVCC"));
879 NEWLINE();
880 PRINTSCREEN(F("E1 TB1"));
881 break;
882 case 2:
883 PRINTSCREEN(F("C2 VDVCC"));
884 NEWLINE();
885 PRINTSCREEN(F("E2 TB2"));
886 break;
887 case 3:
888 PRINTSCREEN(F("IMIN IMAX"));
889 NEWLINE();
890 PRINTSCREEN(F("PMIN PMAX"));
891 break;
892 case 4:
893 PRINTSCREEN(F("VMIN VMAX"));
894 NEWLINE();
895 PRINTSCREEN(F("TMIN TMAX"));
896 break;
897 case 5:
898 PRINTSCREEN(F("TMIN TMAX"));
899 NEWLINE();
900 PRINTSCREEN(F("VDMIN VDMAX"));
901 break;
902 default:
903 PRINTSCREEN(F("CYCLE ALL"));
904 NEWLINE();
905 PRINTSCREEN(F("measurements"));
906 userGroup2Cycle = true;
907 break;
908 }
909 break;
910 case KEYPAD_UP:
911 case KEYPAD_DOWN:
912 if (previousKey == KEYPAD_DOWN)
913 {
914 if (userSelGroup1 == 0)
915 userSelGroup1 = USER_SEL_GRP1_COUNT - 1;
916 else
917 userSelGroup1--;
918 }
919 else if (previousKey == KEYPAD_UP)
920 {
921 if (userSelGroup1 == USER_SEL_GRP1_COUNT - 1)
922 userSelGroup1 = 0;
923 else
924 userSelGroup1++;
925 }
926 userGroupSelect = false;
927 userGroupCycleTimer = 0;
928 PRINTSCREEN(F("STATUS,ALERTS:"));
929 NEWLINE();
930 switch (userSelGroup1)
931 {
932 case 0:
933 PRINTSCREEN(F("STATUS"));
934 break;
935 case 1:
936 PRINTSCREEN(F("STATVT"));
937 break;
938 case 2:
939 PRINTSCREEN(F("STATIP"));
940 break;
941 case 3:
942 PRINTSCREEN(F("STATC"));
943 break;
944 case 4:
945 PRINTSCREEN(F("STATE"));
946 break;
947 case 5:
948 PRINTSCREEN(F("STATCEOF"));
949 break;
950 case 6:
951 PRINTSCREEN(F("STATTB"));
952 break;
953 case 7:
954 PRINTSCREEN(F("STATVDVCC"));
955 break;
956 default:
957 PRINTSCREEN(F("CYCLE ALL"));
958 userGroup1Cycle = true;
959 statusRegsRead = false; // this will make sure we read all STATUS regs once we enter the cycle the first time
960 userSelGroup1 = USER_SEL_GRP1_CYCLE_COUNT - 1; // this will make sure we start with STATUS
961 break;
962 }
963 break;
964 case KEYPAD_SELECT:
965 PRINTSCREEN(F("CLEAR"));
966 flagClear = true;
967 break;
968 }
969 previousKey = key;
970 return (key != KEYPAD_NONE);
971 }
972
973 /** \fn void processCommands()
974 \brief process commands received via serial interface. Those are the m,l commands and the basic DC590B commands
975 used for DC590B compatibility mode that allows the GUI to communicate with this sketch.
976 (basic set of DC590 commands to allow I2C communication to the LTC2947)
977 \param command the command to be decoded */
978 void processCommands(char command)
979 {
980 switch (command)
981 {
982 case 'm':
983 {
984 // show measurement menu
985 Serial.println();
986 Serial.print(F("0:"));
987 Serial.println(MEAS_LABEL00);
988 Serial.print(F(" "));
989 Serial.println(MEAS_LABEL01);
990 Serial.print(F("1:"));
991 Serial.println(MEAS_LABEL10);
992 Serial.print(F(" "));
993 Serial.println(MEAS_LABEL11);
994 Serial.print(F("2:"));
995 Serial.println(MEAS_LABEL20);
996 Serial.print(F(" "));
997 Serial.println(MEAS_LABEL21);
998 Serial.print(F("3:"));
999 Serial.println(MEAS_LABEL30);
1000 Serial.print(F(" "));
1001 Serial.println(MEAS_LABEL31);
1002 Serial.print(F("4:"));
1003 Serial.println(MEAS_LABEL40);
1004 Serial.print(F(" "));
1005 Serial.println(MEAS_LABEL41);
1006 Serial.print(F("5:"));
1007 Serial.println(MEAS_LABEL50);
1008 Serial.print(F(" "));
1009 Serial.println(MEAS_LABEL51);
1010 Serial.print(F("6:"));
1011 Serial.println(MEAS_LABEL60);
1012 Serial.print(F(" "));
1013 Serial.println(MEAS_LABEL61);
1014 Serial.println(F("enter 0-6, any other to cancel"));
1015 char sel = get_char() - 0x30;
1016 userGroupCycleTimer = 0;
1017 switch (sel)
1018 {
1019 case 0:
1020 case 1:
1021 case 2:
1022 case 3:
1023 case 4:
1024 case 5:
1025 lcd->EnableSerialOutput = true;
1026 userGroup1Cycle = false;
1027 userGroup2Cycle = false;
1028 userSelGroup2 = sel;
1029 userGroupSelect = true;
1030 break;
1031 case 6:
1032 lcd->EnableSerialOutput = true;
1033 userGroup1Cycle = false;
1034 userGroup2Cycle = true;
1035 userGroupSelect = true;
1036 break;
1037 default:
1038 lcd->EnableSerialOutput = false;
1039 Serial.println(F("canceled"));
1040 break;
1041 }
1042 }
1043 break;
1044 case 'l':
1045 {
1046 // show status / alerts menu
1047 Serial.println();
1048 Serial.println(F("0:STATUS"));
1049 Serial.println(F("1:STATVT"));
1050 Serial.println(F("2:STATIP"));
1051 Serial.println(F("3:STATC"));
1052 Serial.println(F("4:STATE"));
1053 Serial.println(F("5:STATCEOF"));
1054 Serial.println(F("6:STATTB"));
1055 Serial.println(F("7:STATVDVCC"));
1056 Serial.println(F("8:CYCLE ALL"));
1057 Serial.println(F("enter 0-8, any other to cancel"));
1058 char sel = get_char() - 0x30;
1059 userGroupCycleTimer = 0;
1060 switch (sel)
1061 {
1062 case 0:
1063 case 1:
1064 case 2:
1065 case 3:
1066 case 4:
1067 case 5:
1068 case 6:
1069 case 7:
1070 lcd->EnableSerialOutput = true;
1071 userGroup1Cycle = false;
1072 userGroup2Cycle = false;
1073 userSelGroup1 = sel;
1074 userGroupSelect = false;
1075 break;
1076 case 8:
1077 lcd->EnableSerialOutput = true;
1078 userGroup2Cycle = false;
1079 userGroupSelect = false;
1080 userGroup1Cycle = true;
1081 statusRegsRead = false; // this will make sure we read all STATUS regs once we enter the cycle the first time
1082 userSelGroup1 = USER_SEL_GRP1_CYCLE_COUNT - 1; // this will make sure we start with STATUS
1083 break;
1084 default:
1085 lcd->EnableSerialOutput = false;
1086 Serial.println(F("canceled"));
1087 break;
1088 }
1089 }
1090 break;
1091 }
1092 }
1093
1094
LTC2947_REG_STATTB
#define LTC2947_REG_STATTB
Definition: LTC2947.h:189
LTC2947_BM_TBCTL_PRE_0
#define LTC2947_BM_TBCTL_PRE_0
Definition: LTC2947.h:1245
SPLASH_SCREEN_DELAY
#define SPLASH_SCREEN_DELAY
Definition: DC2574A_KIT.ino:244
LTC2947_LSB_VMAX
#define LTC2947_LSB_VMAX
Definition: LTC2947.h:936
userGroupCycleTimer
static uint8_t userGroupCycleTimer
The user group cycle timer.
Definition: DC2574A_KIT.ino:295
statusRegs
byte statusRegs[8]
array to store all status / alert registers
Definition: DC2574A_KIT.ino:293
LTC2947_I2C_ADDR_LL
#define LTC2947_I2C_ADDR_LL
Definition: LTC2947.h:102
LTC2947_LSB_IMIN
#define LTC2947_LSB_IMIN
Definition: LTC2947.h:930
dc590Busy
boolean dc590Busy
DC590 busy check.
Definition: DC590_subset.ino:110
LTC2947_BM_STATC_C1L
#define LTC2947_BM_STATC_C1L
Definition: LTC2947.h:1094
LABEL_DELAY
#define LABEL_DELAY
Definition: DC2574A_KIT.ino:243
KEYPAD_SELECT
#define KEYPAD_SELECT
Definition: LCDKeypad.h:15
nextUpdateTime
unsigned long nextUpdateTime
The next update time.
Definition: DC2574A_KIT.ino:272
LTC2947_OFFS_TEMPMAX
#define LTC2947_OFFS_TEMPMAX
Definition: LTC2947.h:942
LTC2947_REG_STATE
#define LTC2947_REG_STATE
Definition: LTC2947.h:183
LTC2947_BM_STATUS_ADCERR
#define LTC2947_BM_STATUS_ADCERR
Definition: LTC2947.h:1062
NEWLINE
#define NEWLINE()
print newline
Definition: LCDKeypad.h:36
LTC2947_BM_STATTB_TB1TH
#define LTC2947_BM_STATTB_TB1TH
Definition: LTC2947.h:1122
LTC2947_PRE
#define LTC2947_PRE
Definition: LTC2947.h:900
LTC2947_BM_STATIP_PL
#define LTC2947_BM_STATIP_PL
Definition: LTC2947.h:1088
get_char
char get_char()
Gets the character.
Definition: DC590_subset.ino:191
LTC2947_BM_TBCTL_DIV_0
#define LTC2947_BM_TBCTL_DIV_0
Definition: LTC2947.h:1251
LTC2947_Read_I_P_V_TEMP_VCC
void LTC2947_Read_I_P_V_TEMP_VCC(float *I, float *P, float *V, float *TEMP, float *VCC)
Reads current (I), power (P), voltage (V), temperature (TEMP) and supply voltage (VCC) from the devic...
Definition: LTC2947.cpp:603
LTC2947_BM_STATC_C2L
#define LTC2947_BM_STATC_C2L
Definition: LTC2947.h:1098
userSelGroup2
static uint8_t userSelGroup2
User selection of the second group.
Definition: DC2574A_KIT.ino:285
LTC2947_BM_STATIP_IL
#define LTC2947_BM_STATIP_IL
Definition: LTC2947.h:1084
LTC2947_BM_STATTB_TB2TH
#define LTC2947_BM_STATTB_TB2TH
Definition: LTC2947.h:1124
LTC2947_RD_BYTES
static int8_t LTC2947_RD_BYTES(uint8_t REG_ADDR, uint8_t LENGTH, uint8_t *BYTES)
read multiple bytes via I2C/SPI
Definition: LTC2947.h:1588
LTC2947_InitSPI
void LTC2947_InitSPI()
Initializes the LTC2947 library for SPI mode operation.
Definition: LTC2947.cpp:91
MEAS_LABEL51
#define MEAS_LABEL51
Definition: DC2574A_KIT.ino:267
statusRegsRead
boolean statusRegsRead
flag is asserted once after all status registers were read.
Definition: DC2574A_KIT.ino:291
userInput
boolean userInput()
processes the user input from LCD keypad shield
Definition: DC2574A_KIT.ino:835
LTC2947_BM_STATVT_VH
#define LTC2947_BM_STATVT_VH
Definition: LTC2947.h:1068
LTC2947_REG_STATUS
#define LTC2947_REG_STATUS
Definition: LTC2947.h:171
LCDKeypad::button
int button()
Definition: LCDKeypad.cpp:92
setup
static void setup()
general initialization
Definition: DC2574A_KIT.ino:299
LTC2947_Read_C_E_TB
void LTC2947_Read_C_E_TB(boolean accuSet1, double *C, double *E, double *TB)
Reads charge (C), energy (E) and time (TB) from the device.
Definition: LTC2947.cpp:649
LTC2947_BM_STATVDVCC_VDVCCH
#define LTC2947_BM_STATVDVCC_VDVCCH
Definition: LTC2947.h:1132
LTC2947_BM_STATC_C2H
#define LTC2947_BM_STATC_C2H
Definition: LTC2947.h:1096
USER_SEL_GRP2_CYCLE_COUNT
#define USER_SEL_GRP2_CYCLE_COUNT
Menu Group 2 cycle count: RAW, ACCU1, ACCU2, Track1, Track2, Track3.
Definition: DC2574A_KIT.ino:252
MEAS_LABEL00
#define MEAS_LABEL00
Definition: DC2574A_KIT.ino:256
LTC2947_BM_STATC_C1H
#define LTC2947_BM_STATC_C1H
Definition: LTC2947.h:1092
LTC2947_BM_STATIP_IH
#define LTC2947_BM_STATIP_IH
Definition: LTC2947.h:1082
DC590_subset.ino
LTC2947_Read_Abs_C_E_TB
void LTC2947_Read_Abs_C_E_TB(boolean accuSet1, double *C, boolean *signC, double *E, boolean *signE, double *TB)
Reads charge (C), energy (E) and time (TB) from the device.
Definition: LTC2947.cpp:622
Linduino.h
Header File for Linduino Libraries and Demo Code.
DelayAndCheckSerialData
boolean DelayAndCheckSerialData(unsigned long ms)
Delay and check serial data.
Definition: DC590_subset.ino:212
BM2BITPOS
#define BM2BITPOS(bm)
Definition: LTC2947.h:93
KEYPAD_DOWN
#define KEYPAD_DOWN
Definition: LCDKeypad.h:13
LTC2947_BM_STATE_E2H
#define LTC2947_BM_STATE_E2H
Definition: LTC2947.h:1106
LTC2947_LSB_IMAX
#define LTC2947_LSB_IMAX
Definition: LTC2947.h:928
KEYPAD_LEFT
#define KEYPAD_LEFT
Definition: LCDKeypad.h:14
LTC2947_LSB_VDVCCMIN
#define LTC2947_LSB_VDVCCMIN
Definition: LTC2947.h:950
processCommands
static void processCommands(char command)
Definition: DC2574A_KIT.ino:978
LTC2947_LSB_FACTOR_MILLI_HOURS
#define LTC2947_LSB_FACTOR_MILLI_HOURS
Definition: LTC2947.h:113
spi_enable
void spi_enable(uint8_t spi_clock_divider)
Setup the processor for hardware SPI communication.
Definition: LT_SPI.cpp:160
LTC2947_BM_STATUS_TBERR
#define LTC2947_BM_STATUS_TBERR
Definition: LTC2947.h:1064
LTC2947_BM_STATVT_FANH
#define LTC2947_BM_STATVT_FANH
Definition: LTC2947.h:1076
LTC2947_BM_STATVT_TEMPH
#define LTC2947_BM_STATVT_TEMPH
Definition: LTC2947.h:1072
MEAS_LABEL61
#define MEAS_LABEL61
Definition: DC2574A_KIT.ino:269
LTC2947_SetPageSelect
void LTC2947_SetPageSelect(boolean page)
write LTC2947&#39;s page control register to selected one of two memory pages
Definition: LTC2947.cpp:598
LTC2947_BM_STATE_E1L
#define LTC2947_BM_STATE_E1L
Definition: LTC2947.h:1104
MEAS_LABEL60
#define MEAS_LABEL60
Definition: DC2574A_KIT.ino:268
LTC2947_BM_STATUS_UVLOA
#define LTC2947_BM_STATUS_UVLOA
Definition: LTC2947.h:1052
PRINTSCREEN
#define PRINTSCREEN(A)
print value / text
Definition: LCDKeypad.h:39
LTC2947_LSB_VMIN
#define LTC2947_LSB_VMIN
Definition: LTC2947.h:938
flagClear
boolean flagClear
flag to store actions from user input.
Definition: DC2574A_KIT.ino:279
LTC2947_VAL_IMAX
#define LTC2947_VAL_IMAX
Definition: LTC2947.h:762
LTC2947_REG_STATIP
#define LTC2947_REG_STATIP
Definition: LTC2947.h:177
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
LTC2947_VAL_VDVCC
#define LTC2947_VAL_VDVCC
Definition: LTC2947.h:804
loop
static void loop()
main loop
Definition: DC2574A_KIT.ino:790
DelayAndProcessInputs
static void DelayAndProcessInputs(unsigned long ms)
Delay and process input commands either from serial port or from keypad.
Definition: DC2574A_KIT.ino:799
userGroup1Cycle
boolean userGroup1Cycle
group 1 cycle enable
Definition: DC2574A_KIT.ino:283
USERGROUPCYCLETIMERRELOAD
#define USERGROUPCYCLETIMERRELOAD
defines how many cycles a single measurement group will be displayed on the LCD in case of "cycle all...
Definition: DC2574A_KIT.ino:254
LTC2947_LSB_PMIN
#define LTC2947_LSB_PMIN
Definition: LTC2947.h:934
LTC2947_BM_STATCEOF_E1OF
#define LTC2947_BM_STATCEOF_E1OF
Definition: LTC2947.h:1116
KEYPAD_UP
#define KEYPAD_UP
Definition: LCDKeypad.h:12
LTC2947_BM_STATUS_PORA
#define LTC2947_BM_STATUS_PORA
Definition: LTC2947.h:1054
update
static void update()
update LTC2947 measurement results
Definition: DC2574A_KIT.ino:345
LTC2947_BM_STATUS_UVLOD
#define LTC2947_BM_STATUS_UVLOD
Definition: LTC2947.h:1058
LTC2947_LSB_TEMPMAX
#define LTC2947_LSB_TEMPMAX
Definition: LTC2947.h:940
KEYPAD_RIGHT
#define KEYPAD_RIGHT
Definition: LCDKeypad.h:11
LTC2947_BM_STATTB_TB1OF
#define LTC2947_BM_STATTB_TB1OF
Definition: LTC2947.h:1126
MEAS_LABEL40
#define MEAS_LABEL40
Definition: DC2574A_KIT.ino:264
LTC2947_BM_STATUS_UPDATE
#define LTC2947_BM_STATUS_UPDATE
Definition: LTC2947.h:1060
MEAS_LABEL10
#define MEAS_LABEL10
Definition: DC2574A_KIT.ino:258
LTC2947_BM_STATCEOF_E2OF
#define LTC2947_BM_STATCEOF_E2OF
Definition: LTC2947.h:1118
LTC2947_BM_OPCTL_RST
#define LTC2947_BM_OPCTL_RST
Definition: LTC2947.h:1273
MEAS_LABEL31
#define MEAS_LABEL31
Definition: DC2574A_KIT.ino:263
LTC2947_2BytesToInt16
int16_t LTC2947_2BytesToInt16(byte *bytes)
converts an array of 2 bytes to 16-bit signed integer
Definition: LTC2947.cpp:301
CLEAR_SCREEN
#define CLEAR_SCREEN()
clear screen
Definition: LCDKeypad.h:30
LTC2947_REG_TBCTL
#define LTC2947_REG_TBCTL
Definition: LTC2947.h:240
MEAS_LABEL50
#define MEAS_LABEL50
Definition: DC2574A_KIT.ino:266
LTC2947_REG_STATVT
#define LTC2947_REG_STATVT
Definition: LTC2947.h:174
CheckSerialData
boolean CheckSerialData()
Determines if serial data is available and stores data in the queue.
Definition: DC590_subset.ino:200
LTC2947_BM_STATCEOF_C1OF
#define LTC2947_BM_STATCEOF_C1OF
Definition: LTC2947.h:1112
LTC2947_BM_OPCTL_CLR
#define LTC2947_BM_OPCTL_CLR
Definition: LTC2947.h:1266
bitMaskSetChk
#define bitMaskSetChk(value, bitMask)
Definition: LTC2947.h:75
lcd
LCDKeypad * lcd
pointer to the LCD keypad object
Definition: DC2574A_KIT.ino:275
userGroupSelect
boolean userGroupSelect
selected group 1: false, 2: true
Definition: DC2574A_KIT.ino:289
LTC2947_BM_STATE_E1H
#define LTC2947_BM_STATE_E1H
Definition: LTC2947.h:1102
LTC2947_InitI2C
void LTC2947_InitI2C(uint8_t slvAddr)
Initializes the LTC2947 library for I2C mode operation and configures the slave address see defines L...
Definition: LTC2947.cpp:85
LTC2947_VAL_TEMPMAX
#define LTC2947_VAL_TEMPMAX
Definition: LTC2947.h:780
userGroup2Cycle
boolean userGroup2Cycle
group 2 cycle enable
Definition: DC2574A_KIT.ino:287
LTC2947_OFFS_TEMPMIN
#define LTC2947_OFFS_TEMPMIN
Definition: LTC2947.h:946
MEAS_LABEL41
#define MEAS_LABEL41
Definition: DC2574A_KIT.ino:265
LCDKeypad::foundLCD
boolean foundLCD
Definition: LCDKeypad.h:62
LT_SPI.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
MEAS_LABEL30
#define MEAS_LABEL30
Definition: DC2574A_KIT.ino:262
LTC2947_BM_STATVT_VL
#define LTC2947_BM_STATVT_VL
Definition: LTC2947.h:1070
MEAS_LABEL21
#define MEAS_LABEL21
Definition: DC2574A_KIT.ino:261
LTC2947_LSB_VDVCC
#define LTC2947_LSB_VDVCC
Definition: LTC2947.h:962
tinyDC590B
boolean tinyDC590B(char command)
process commands received via serial interface.
Definition: DC590_subset.ino:255
LT_I2C.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
LTC2947_BM_STATCEOF_C2OF
#define LTC2947_BM_STATCEOF_C2OF
Definition: LTC2947.h:1114
LTC2947_BM_STATE_E2L
#define LTC2947_BM_STATE_E2L
Definition: LTC2947.h:1108
SCREENSETCURSOR
#define SCREENSETCURSOR(A, B)
move cursor
Definition: LCDKeypad.h:47
bitMaskClrChk
#define bitMaskClrChk(value, bitMask)
Definition: LTC2947.h:76
quikeval_SPI_connect
void quikeval_SPI_connect()
Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C...
Definition: LT_SPI.cpp:138
LCDKeypad::EnableSerialOutput
boolean EnableSerialOutput
Definition: LCDKeypad.h:63
LTC2947_REG_OPCTL
#define LTC2947_REG_OPCTL
Definition: LTC2947.h:243
LTC2947_VAL_VMAX
#define LTC2947_VAL_VMAX
Definition: LTC2947.h:774
LCDKeypad
Definition: LCDKeypad.h:51
LTC2947_REG_STATC
#define LTC2947_REG_STATC
Definition: LTC2947.h:180
LCDKeypad.h
LTC2947_REG_STATVDVCC
#define LTC2947_REG_STATVDVCC
Definition: LTC2947.h:192
USER_SEL_GRP2_COUNT
#define USER_SEL_GRP2_COUNT
Menu group 2 count: RAW, ACCU1, ACCU2, Track1, Track2, Track3, "Cycle meas.".
Definition: DC2574A_KIT.ino:250
LTC2947_LSB_TEMPMIN
#define LTC2947_LSB_TEMPMIN
Definition: LTC2947.h:944
LTC2947_BM_STATVT_TEMPL
#define LTC2947_BM_STATVT_TEMPL
Definition: LTC2947.h:1074
quikeval_I2C_init
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
LTC2947.h
LTC2947: LTC2947 a high-precision power and energy monitor with an internal sense resistor supporting...
E
const int16_t E
Definition: LTC2492_Thermocouple_Meter.ino:101
LTC2947_WR_BYTE
static int8_t LTC2947_WR_BYTE(uint8_t REG_ADDR, uint8_t VALUE)
write single byte via I2C
Definition: LTC2947.h:1626
LTC2947_BM_STATVDVCC_VDVCCL
#define LTC2947_BM_STATVDVCC_VDVCCL
Definition: LTC2947.h:1134
quikeval_I2C_connect
void quikeval_I2C_connect(void)
Switch MUX to connect I2C pins to QuikEval connector.
Definition: LT_I2C.cpp:401
MEAS_LABEL20
#define MEAS_LABEL20
Definition: DC2574A_KIT.ino:260
LTC2947_DIV
#define LTC2947_DIV
Definition: LTC2947.h:907
LTC2947_GetCurrentPageSelect
boolean LTC2947_GetCurrentPageSelect()
reads LTC2947&#39;s page control register to determine the currently selected memory page ...
Definition: LTC2947.cpp:591
LTC2947_REG_STATCEOF
#define LTC2947_REG_STATCEOF
Definition: LTC2947.h:186
LTC2947_BM_STATTB_TB2OF
#define LTC2947_BM_STATTB_TB2OF
Definition: LTC2947.h:1128
LTC2947_BM_OPCTL_CONT
#define LTC2947_BM_OPCTL_CONT
Definition: LTC2947.h:1271
LTC2947_BM_STATIP_PH
#define LTC2947_BM_STATIP_PH
Definition: LTC2947.h:1086
userSelGroup1
static uint8_t userSelGroup1
User selection of the first group.
Definition: DC2574A_KIT.ino:281
LTC2947_BM_STATVT_FANL
#define LTC2947_BM_STATVT_FANL
Definition: LTC2947.h:1078
LTC2947_BM_STATUS_UVLOSTBY
#define LTC2947_BM_STATUS_UVLOSTBY
Definition: LTC2947.h:1056
LTC2947_BytesToDouble
double LTC2947_BytesToDouble(uint8_t *bytes, uint8_t length, boolean sig, double lsb)
Converts a signed or unsigned value of arbitrary number of bytes to a floating point number...
Definition: LTC2947.cpp:121
USER_SEL_GRP1_CYCLE_COUNT
#define USER_SEL_GRP1_CYCLE_COUNT
Menu Group 1 cycle count: STATUS STATVT STATIP STATC STATE STATCEOF STATTB STATVDVCC.
Definition: DC2574A_KIT.ino:248
LCDKeypad::Disable4BitLCD
void Disable4BitLCD()
Definition: LCDKeypad.cpp:63
WRITE_DEGREE_C
#define WRITE_DEGREE_C()
Macros used to print simultaneously on LCD and serial port.
Definition: LCDKeypad.h:26
LCDKeypad::searchForLCD
void searchForLCD()
Definition: LCDKeypad.cpp:47
PRINTSCREEN2
#define PRINTSCREEN2(A, B)
print formatted value
Definition: LCDKeypad.h:43
LTC2947_LSB_VDVCCMAX
#define LTC2947_LSB_VDVCCMAX
Definition: LTC2947.h:948
SCREEN_UPDATE_TIME
#define SCREEN_UPDATE_TIME
Only one mode is possible at a time.
Definition: DC2574A_KIT.ino:242
KEYPAD_NONE
#define KEYPAD_NONE
Definition: LCDKeypad.h:10
LTC2947_RD_BYTE
static int8_t LTC2947_RD_BYTE(uint8_t REG_ADDR, uint8_t *RESULT)
read single byte via I2C/SPI
Definition: LTC2947.h:1614
USER_SEL_GRP1_COUNT
#define USER_SEL_GRP1_COUNT
Menu Group 1 count: STATUS STATVT STATIP STATC STATE STATCEOF STATTB STATVDVCC "CYCLE stats"...
Definition: DC2574A_KIT.ino:246
MEAS_LABEL11
#define MEAS_LABEL11
Definition: DC2574A_KIT.ino:259
previousKey
static int8_t previousKey
The previous key.
Definition: DC2574A_KIT.ino:277
MEAS_LABEL01
#define MEAS_LABEL01
Definition: DC2574A_KIT.ino:257
LTC2947_LSB_PMAX
#define LTC2947_LSB_PMAX
Definition: LTC2947.h:932