DIY Logging Volt/Ampmeter
main.c
Go to the documentation of this file.
1 /* USER CODE BEGIN Header */
2 
3 /***************************************************************************//**
4  * @file main.c
5  * @brief Main source-file for the high-precision logging voltage/current meter project.
6  * @details
7  * The code in this project asks two BY56W volt/current meters for measurements,
8  * calculates a few additional values (min/max/power/Ah/Wh) with these, prints
9  * them to displays and sends them (with time/date values) to a UART port so
10  * a Sparkfun OpenLog can log these measurements to a `.TXT` file, which can
11  * eventually be renamed to a `.CSV` so the measurements can be easily plotted.
12  * @version 1.2
13  * @author Brecht Van Eeckhoudt
14  *
15  * ******************************************************************************
16  *
17  * @section Versions
18  *
19  * @li v1.0: Initial version.
20  * @li v1.1: Started printing date before time for each measurement-line, removed day-writing in footer.
21  * @li v1.2: Compared power floats more reliably.
22  *
23  * ******************************************************************************
24  *
25  * @todo
26  * **Things to do in the near future:**@n
27  * - Check Ah/Wh calculations.
28  * - Check if the power/Ah/Wh calculations are done using wrong/old measurements.
29  * - Handle uint32_t wraparound for time between calculations measurements and waiting time.
30  * - Don't send/do certain functions if one of the meters is powered down.
31  *
32  * @todo
33  * **Long-term future improvements:**@n
34  * - Add function to stop measurements when the voltage/current is (above/) below a certain value.
35  * - Add external temperature reading functionality.
36  * - Add internal temperature reading functionality (`MX_ADC1_Init();`).
37  * - Add interrupt-logging functionality.
38  * - Add relay-opening functionality.
39  * - Add "manual measurement-mode" to log on up-button press.
40  * - Add "performance-mode" with no display refreshes.
41  * - (sub-page on right display, start/stop with up, beeps for confirmation)
42  * - Add low-battery beeping.
43  * - Add buzzer functionality using TIM2 (`MX_TIM2_Init();`).
44  * - (short beep button-press, longer when measurement taken, add ON/OFF settings page)
45  * - Optimize encoder logic so there is less copy-pasting.
46  * - Add debounce logic to `getSW0();`, `getSW1();` and `getENCkey();`.
47  * - Use `LL_GetTick();` instead of `HAL_GetTick();`?
48  * - Add circular pages for setting day/month/hour/minute/second (`changeDateTime`).
49  * - Add day-checking in function of the month?
50  * - Use defines for circular pages?
51  * - Start using `aBY56W_ContinuousRead`? Send on every meter power-up?
52  * - Only one while-loop (`USART_HandleContinuousReception`) when one meter is
53  * connected, way more if both are? Optimize this?
54  * - Add overflow catch if data.voltage/current are negative values?
55  * - `data.power > 999.999`, `data.ah > 9999.999`, `data.wh > 9999.999`
56  * - Remove all Segger-RTT functionality?
57  * - Store settings in power-down-safe memory.
58  *
59  * ******************************************************************************
60  *
61  * @section License
62  *
63  * **Copyright (C) 2021 - Brecht Van Eeckhoudt**
64  *
65  * This program is free software: you can redistribute it and/or modify
66  * it under the terms of the **GNU General Public License** as published by
67  * the Free Software Foundation, either **version 3** of the License, or
68  * (at your option) any later version.
69  *
70  * This program is distributed in the hope that it will be useful,
71  * but WITHOUT ANY WARRANTY; without even the implied warranty of
72  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
73  * GNU General Public License for more details.
74  *
75  * *A copy of the GNU General Public License can be found in the `LICENSE`
76  * file along with this source code.*
77  *
78  * @n
79  *
80  * Some methods also use code obtained from examples from STMicroelectronics.
81  *
82  * **Copyright (c) 2020 STMicroelectronics. All rights reserved.**
83  *
84  * These sections are licensed by ST under BSD 3-Clause license, the "License";
85  * One may not use these example files except in compliance with the License.
86  * One may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause
87  *
88  ******************************************************************************/
89 
90 /* USER CODE END Header */
91 /* Includes ------------------------------------------------------------------*/
92 #include "main.h"
93 #include "adc.h"
94 #include "i2c.h"
95 #include "tim.h"
96 #include "gpio.h"
97 
98 /* Private includes ----------------------------------------------------------*/
99 /* USER CODE BEGIN Includes */
100 
101 #include "usart.h" /* UART communication functionality */
102 #include "SEGGER_RTT.h" /* Segger RTT debugging functionality */
103 #include "util.h" /* Utility functionality */
104 #include "conversion.h" /* Conversion and settings */
105 #include "display.h" /* Display functionality */
106 #include "rtc.h" /* Real Time Clock and Calendar functionality */
107 
108 /* USER CODE END Includes */
109 
110 /* Private typedef -----------------------------------------------------------*/
111 /* USER CODE BEGIN PTD */
112 
113 /* USER CODE END PTD */
114 
115 /* Private define ------------------------------------------------------------*/
116 /* USER CODE BEGIN PD */
117 
118 /** Max amount of while loop passes before exiting the while loop early (~meter unresponsive) */
119 #define MAX_WHILELOOPS_METER_RESPONSE 9000
120 
121 /** Waiting time before shutting down the external UART logger after writing the footer */
122 #define SHUTDOWN_DELAY_UART_MODULE_MS 500
123 
124 /** Waiting time for an external UART power-up message before writing the header */
125 #define STARTUP_DELAY_UART_MODULE_MS 2000
126 
127 /** Time between battery voltage measurements */
128 #define VBAT_MEASUREMENT_PERIOD_S 10
129 
130 /* USER CODE END PD */
131 
132 /* Private macro -------------------------------------------------------------*/
133 /* USER CODE BEGIN PM */
134 
135 /* USER CODE END PM */
136 
137 /* Private variables ---------------------------------------------------------*/
138 
139 /* USER CODE BEGIN PV */
140 
141 /* BY56W meter commands */
142 static const uint8_t aBY56W_SingleRead[4] = {0x88, 0xAE, 0x00, 0x11}; /* 0x00 = Device address */
143 //static const uint8_t aBY56W_ContinuousRead[4] = {0x88, 0xAE, 0x00, 0x21}; /* 0x00 = Device address */
144 //static const uint8_t aBY56W_StopRead[4] = {0x88, 0xAE, 0x00, 0x01}; /* 0x00 = Any byte */
145 
146 /* Data in structs */
147 struct Data_t data; /* Measurement data (changes a lot) */
148 struct cData_t cData; /* Measuremtn data converted to char-arrays */
149 struct Settings_t settings; /* General data/settings (changes less frequently */
150 struct RTC_dateTime_t rtc; /* Date and time */
151 
152 /** LUT for period selection [s] (0 = as fast as possible) */
153 static const uint16_t LUT_period_s[16] = {0, 1, 2, 5, 10, 15, 30, 60, 120, 300, 600, 900, 1800, 3600, 7200, 18000};
154 
155 /** Length of LUT */
156 static const uint8_t LUT_period_s_length = 16;
157 
158 /* USER CODE END PV */
159 
160 /* Private function prototypes -----------------------------------------------*/
161 void SystemClock_Config(void);
162 /* USER CODE BEGIN PFP */
163 
164 void writeHeader(void);
165 void writeFooter(void);
166 void writeMeasurements(void);
167 void checkEncoder(void);
168 void checkSwitches(void);
169 
170 /* USER CODE END PFP */
171 
172 /* Private user code ---------------------------------------------------------*/
173 /* USER CODE BEGIN 0 */
174 
175 /* USER CODE END 0 */
176 
177 /**
178  * @brief The application entry point.
179  * @retval int
180  */
181 int main(void)
182 {
183  /* USER CODE BEGIN 1 */
184 
185  /* USER CODE END 1 */
186 
187  /* MCU Configuration--------------------------------------------------------*/
188 
189  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
190  HAL_Init();
191 
192  /* USER CODE BEGIN Init */
193 
194  /* USER CODE END Init */
195 
196  /* Configure the system clock */
198 
199  /* USER CODE BEGIN SysInit */
200 
201  /* USER CODE END SysInit */
202 
203  /* Initialize all configured peripherals */
204  MX_GPIO_Init();
205 // MX_ADC1_Init();
206  MX_I2C1_Init();
207  MX_ADC2_Init();
208  MX_TIM3_Init();
209 // MX_TIM2_Init();
210  /* USER CODE BEGIN 2 */
211 
212  /* Power down UART voltage output */
213  LL_GPIO_SetOutputPin(UART1_3V3out_GPIO_Port, UART1_3V3out_Pin); /* P-MOS so inverted logic! */
214 
215  /* Power up UART DTR (~reset)-pin so we're not resetting the module */
216  LL_GPIO_SetOutputPin(UART1_DTRout_GPIO_Port, UART1_DTRout_Pin);
217 
218 
219  /* Enable output channel 1 (rotary encoder) */
220  LL_TIM_CC_EnableChannel(TIM3, LL_TIM_CHANNEL_CH1 | LL_TIM_CHANNEL_CH2);
221 
222  /* Enable counter */
223  LL_TIM_EnableCounter(TIM3);
224 
225  /* Force update generation */
226  LL_TIM_GenerateEvent_UPDATE(TIM3);
227 
228 
229  /* Initialize date/time functionality */
230  RTC_Init();
231 
232 
233  /* Enable the update interrupt (logging-timing) */
234 // LL_TIM_EnableIT_UPDATE(TIM2); // TODO change to buzzer timing
235 
236  /* Enable counter */
237 // LL_TIM_EnableCounter(TIM2); // TODO change to buzzer timing
238 
239  /* Force update generation */
240 // LL_TIM_GenerateEvent_UPDATE(TIM2); // TODO change to buzzer timing
241 
242 
243  /* Initialize UART functionality */
244  USART1_INIT();
245  USART2_INIT();
246  USART3_INIT();
247 
248  /* Initialize structs */
249  initDataStruct();
251 
252  /* Activate ADC for battery voltage measurements */
253  Activate_ADC();
254 
255  /* Clear Terminal for Segger RTT functionality */
256  SEGGER_RTT_WriteString(0, RTT_CTRL_CLEAR"START\r\n");
257 
258  /* Initialize displays */
259  initDisplays();
260 
261  /* Disable buzzer */
262 // LL_GPIO_ResetOutputPin(Buzzer_GPIO_Port, Buzzer_Pin);
263 
264 // LL_GPIO_TogglePin(Relay_GPIO_Port, Relay_Pin);
265 // LL_GPIO_TogglePin(Buzzer_GPIO_Port, Buzzer_Pin);
266 
267 
268 // SEGGER_RTT_printf(0, "%sTime:%s%s %.7d\n\r",
269 // RTT_CTRL_RESET,
270 // RTT_CTRL_BG_BRIGHT_RED,
271 // RTT_CTRL_TEXT_BRIGHT_WHITE,
272 // 1111111
273 // );
274 // SEGGER_RTT_WriteString(0, RTT_CTRL_RESET"Red: "RTT_CTRL_TEXT_BRIGHT_RED"This text is red."RTT_CTRL_TEXT_BLACK""RTT_CTRL_BG_BRIGHT_RED"This background is red. "RTT_CTRL_RESET"Normal text again.\n\r");
275 // SEGGER_RTT_printf(0, "Value = %x\r\n", value);
276 // SEGGER_RTT_printf(0, RTT_CTRL_RESET"%-.3d ", value);
277 // SEGGER_RTT_printf(0, RTT_CTRL_TEXT_BRIGHT_RED"0x%.2x ", value);
278 
279 
280  /* USER CODE END 2 */
281 
282  /* Infinite loop */
283  /* USER CODE BEGIN WHILE */
284  while (1)
285  {
286  /* USER CODE END WHILE */
287 
288  /* USER CODE BEGIN 3 */
289 
290  checkEncoder();
291  checkSwitches();
292 
293  USART2_SendCommand(aBY56W_SingleRead, 4); /* Voltage */
294  USART3_SendCommand(aBY56W_SingleRead, 4); /* Current */
295 
296  uint16_t whileLoops = 0;
297 
298  while (!(data.voltReceived) && !(data.currReceived) && (whileLoops < MAX_WHILELOOPS_METER_RESPONSE))
299  {
301  whileLoops++;
302  }
303 
304 // SEGGER_RTT_printf(0, "%d ", whileLoops);
305 
306  if (whileLoops < MAX_WHILELOOPS_METER_RESPONSE)
307  {
308  /* Store tick-value of latest measurements */
309  if (data.latestMScounter == 0)
310  {
312  data.latestMScounter = 1;
313  }
314  else if (data.latestMScounter == 1)
315  {
317  data.latestMScounter = 0;
318  }
319  }
320 
321  /* Calculate power, Ah and Wh */
323  {
325  if (data.power > 999.999) data.power = 999.999;
326 
327  /* Convert floats to uint32_t (power has 3 decimal places: *1000) */
328  uint32_t oldPower = FLOAT_TO_INT(data.oldPower*1000);
329  uint32_t power = FLOAT_TO_INT(data.power*1000);
330 
331  if (oldPower != power)
332  {
334  data.newPow = 1;
335  }
336 
337  /* Calculate time between measurements */
338  uint32_t msTime = 0;
339  if (data.latestMScounter == 0) msTime = data.msCounter0 - data.msCounter1;
340  else if (data.latestMScounter == 1) msTime = data.msCounter1 - data.msCounter0;
341 
342 // SEGGER_RTT_printf(0, "%dms ", msTime);
343 
344  data.ah += data.current * ((float)msTime / 3600000.0);
345  if (data.ah > 9999.999) data.ah = 9999.999;
346 
347  data.newAh = 1;
348 
349  data.wh += data.power * ((float)msTime / 3600000.0);
350  if (data.wh > 9999.999) data.wh = 9999.999;
351 
352  data.newWh = 1;
353  }
354 
355  data.voltReceived = 0;
356  data.currReceived = 0;
357 
358  /* Change variables if one second is elapsed */
359  if (decSecondPassed())
360  {
361  /* Signal (second) conversion logic */
362  settings.newSec = 1;
363 
364  /* Get new RTC values if not changing the date/time manually */
365  if ((settings.changeDateTime == 0) && (settings.secPassed == 0)) readFromRTC();
366 
367  /* Update runtime if running */
368  if ((settings.mode == 1) && settings.loggerReady)
369  {
371 
372  /* Re-calculate runtime */
373  if (data.runSecs < 59) data.runSecs++;
374  else if (data.runSecs == 59)
375  {
376  if (data.runMins < 59) data.runMins++;
377  else if (data.runMins == 59)
378  {
379  if (data.runHours < 99) data.runHours++;
380 
381  data.newRunHours = 1; /* Display needs updating */
382  data.runMins = 0;
383  }
384  data.newRunMins = 1; /* Display needs updating */
385  data.runSecs = 0;
386  }
387  data.newRunSecs = 1; /* Display needs updating */
388  }
389 
391  else if (settings.vbatCounter == 0)
392  {
395  }
396  }
397 
398  convertValues();
399 
400  /* Stopped, Logger needs to be disabled */
401  if ((settings.mode == 0) && settings.headerSaved)
402  {
403  if (settings.msWaiting == 0)
404  {
405  /* Make sure all values are converted to chars */
406  forceConversion();
407 
408  displaySaveIcon();
409  writeFooter();
410 
411  /* Set waiting time */
414  }
416  {
417  /* Disable power to logger */
418  LL_GPIO_SetOutputPin(UART1_3V3out_GPIO_Port, UART1_3V3out_Pin); /* P-MOS so inverted logic! */
419 
420  /* Reset waiting functionality */
421  settings.msWaiting = 0;
423 
424  settings.loggerReady = 0;
425  settings.headerSaved = 0;
426  }
427  }
428 
429  /* Just started, header not yet saved */
430  if ((settings.mode == 1) && !(settings.headerSaved))
431  {
432  if (settings.msWaiting == 0)
433  {
434  settings.remMeasPeriodS = 0; /* Force immediate measurement */
435  settings.rightPage = 2; /* Go to runtime sub-page */
436 
437  /* Enable power to logger */
438  LL_GPIO_ResetOutputPin(UART1_3V3out_GPIO_Port, UART1_3V3out_Pin); /* P-MOS so inverted logic! */
439 
440  /* Set waiting-time */
443  }
445  {
446  /* Reset values */
447  initDataStruct();
448  convertValues();
449 
450  displaySaveIcon();
451  writeHeader();
452 
453  /* Reset waiting functionality */
454  settings.msWaiting = 0;
456 
457  settings.loggerReady = 1; /* If we got here by timeout make sure the runtime logic will still work */
458  settings.headerSaved = 1;
459  }
460  }
461  /* Running, header already saved, amount of seconds necessary reached */
462  else if ((settings.mode == 1) && settings.headerSaved && (settings.remMeasPeriodS == 0))
463  {
465 
466  displaySaveIcon();
468 
469  }
470 
474 
475  /* Insert millisecond delay */
476 // SEGGER_RTT_printf(0, "Loop ");
477 // LL_mDelay(250);
478 
479  }
480  /* USER CODE END 3 */
481 }
482 
483 /**
484  * @brief System Clock Configuration
485  * @retval None
486  */
488 {
489  LL_FLASH_SetLatency(LL_FLASH_LATENCY_0);
490  while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_0)
491  {
492  }
493  LL_RCC_HSI_SetCalibTrimming(16);
494  LL_RCC_HSI_Enable();
495 
496  /* Wait till HSI is ready */
497  while(LL_RCC_HSI_IsReady() != 1)
498  {
499 
500  }
501  LL_PWR_EnableBkUpAccess();
502  LL_RCC_LSE_Enable();
503 
504  /* Wait till LSE is ready */
505  while(LL_RCC_LSE_IsReady() != 1)
506  {
507 
508  }
509  if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE)
510  {
511  LL_RCC_ForceBackupDomainReset();
512  LL_RCC_ReleaseBackupDomainReset();
513  LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
514  }
515  LL_RCC_EnableRTC();
516  LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
517  LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
518  LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
519  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
520 
521  /* Wait till System clock is ready */
522  while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
523  {
524 
525  }
526  LL_SetSystemCoreClock(8000000);
527 
528  /* Update the time base */
530  {
531  Error_Handler();
532  }
533  LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSRC_PCLK2_DIV_2);
534 }
535 
536 /* USER CODE BEGIN 4 */
537 
538 
539 /**************************************************************************//**
540  * @brief
541  * Function to handle switch presses.
542  *****************************************************************************/
543 void checkSwitches(void)
544 {
545  /* UP */
546  if (getSW0())
547  {
548  if ((settings.mode == 0) && !(settings.headerSaved) && (settings.changeDateTime == 0))
549  {
550  settings.mode = 1;
551  settings.newMode = 1; /* Display needs updating */
552  }
553  else if (settings.mode == 1)
554  {
555  settings.mode = 0;
556  settings.newMode = 1; /* Display needs updating */
557  }
558 
559  setSW0(0); /* Interrupt handled */
560  }
561 
562  /* DOWN */
563  if (getSW1())
564  {
567 
568  settings.newSelDisplay = 1; /* Display needs updating */
569 
570  setSW1(0); /* Interrupt handled */
571  }
572 
573  /* Encoder press */
574  if (getENCkey())
575  {
576  /* Only change when not running */
577  if (settings.mode == 0)
578  {
579  /* Reset value on selected LEFT page */
580  if ((settings.selectedDisplay == 0) && (settings.leftPage == 0))
581  {
582  data.firstVolt = 1;
583  data.minVoltage = 0.0;
584  data.newMinVolt = 1;
585  data.maxVoltage = 0.0;
586  data.newMaxVolt = 1;
587  }
588  else if ((settings.selectedDisplay == 0) && (settings.leftPage == 1))
589  {
590  data.firstCurr = 1;
591  data.minCurrent = 0.0;
592  data.newMinCurr = 1;
593  data.maxCurrent = 0.0;
594  data.newMaxCurr = 1;
595  }
596  else if ((settings.selectedDisplay == 0) && (settings.leftPage == 2))
597  {
598  data.ah = 0.0;
599  data.newAh = 1;
600  data.wh = 0.0;
601  data.newWh = 1;
602  }
603 
604  /* Set values on selected RIGHT page */
605  if ((settings.selectedDisplay == 1) && (settings.rightPage == 0))
606  {
607  if (settings.changeDateTime == 0)
608  {
609  settings.changeDateTime = 1; /* Start by changing day */
610  settings.dateTimeChanged = 1; /* Force display update (a.o. underline) */
611  }
612  else if (settings.changeDateTime == 6) /* End by changing seconds */
613  {
615  settings.dateTimeChanged = 1; /* Force display update (a.o. underline) */
616  writeToRTC();
617  }
618  else if (settings.changeDateTime > 0)
619  {
622  }
623  }
624  else if ((settings.selectedDisplay == 1) && (settings.rightPage == 1))
625  {
626  /* Enable/disable period change on encoder turn */
627  if (settings.changePeriod == 0)
628  {
631  }
632  else if (settings.changePeriod == 1)
633  {
636  }
637  }
638  /* Directly change period on encoder press on runtime page */
639  else if ((settings.selectedDisplay == 1) && (settings.rightPage == 2))
640  {
641  settings.rightPage = 1;
644  }
645  }
646 
647  setENCkey(0); /* Interrupt handled */
648  }
649 }
650 
651 
652 /**************************************************************************//**
653  * @brief
654  * Function to handle encoder rotation logic.
655  *****************************************************************************/
656 void checkEncoder(void)
657 {
658  int16_t steps = 0;
659  uint16_t encValue = LL_TIM_GetCounter(TIM3);
660 
661  if (encValue != settings.oldTIM3)
662  {
663  /* Make sure we get a stable value */
664  while ((encValue % 4) > 0) encValue++;
665 
666  /* Calculate steps */
667  steps = encValue - settings.oldTIM3;
668  steps /= 4;
669 
670  /* Logic for circular pages */
671  if (steps > 0)
672  {
673  for (uint8_t counter = 0; counter < steps; counter++)
674  {
675  /* Rotate LEFT display pages (if selected) */
676  if (settings.selectedDisplay == 0)
677  {
678  if (settings.leftPage < 2) settings.leftPage++;
679  else settings.leftPage = 0;
680 
681  /* Indicate that a certain page needs to be updated */
682  if (settings.leftPage == 0)
683  {
684  cData.newPow = 1;
685  cData.newMaxVolt = 1;
686  cData.newMinVolt = 1;
687  }
688  else if (settings.leftPage == 1)
689  {
690  cData.newPow = 1;
691  cData.newMaxCurr = 1;
692  cData.newMinCurr = 1;
693  }
694  else if (settings.leftPage == 2)
695  {
696  cData.newPow = 1;
697  cData.newAh = 1;
698  cData.newWh = 1;
699  }
700  }
701 
702  /* Rotate RIGHT display pages (if selected) */
703  if (settings.selectedDisplay == 1)
704  {
705  /* Change period (if selected) */
706  if (settings.changePeriod == 1)
707  {
709  {
714  }
715  }
716  /* Change day (if selected) */
717  else if (settings.changeDateTime == 1)
718  {
719  if ((rtc.latest == 0) && (rtc.day0 < 31)) rtc.day0++;
720  else if ((rtc.latest == 1) && (rtc.day1 < 31)) rtc.day1++;
721 
723  }
724  /* Change month (if selected) */
725  else if (settings.changeDateTime == 2)
726  {
727  if ((rtc.latest == 0) && (rtc.month0 < 12)) rtc.month0++;
728  else if ((rtc.latest == 1) && (rtc.month1 < 12)) rtc.month1++;
729 
731  }
732  /* Change year (if selected) */
733  else if (settings.changeDateTime == 3)
734  {
735  if (rtc.latest == 0) rtc.year0++;
736  else if (rtc.latest == 1) rtc.year1++;
737 
739  }
740  /* Change hour (if selected) */
741  else if (settings.changeDateTime == 4)
742  {
743  if ((rtc.latest == 0) && (rtc.hour0 < 23)) rtc.hour0++;
744  else if ((rtc.latest == 1) && (rtc.hour1 < 23)) rtc.hour1++;
745 
747  }
748  /* Change minutes (if selected) */
749  else if (settings.changeDateTime == 5)
750  {
751  if ((rtc.latest == 0) && (rtc.min0 < 59)) rtc.min0++;
752  else if ((rtc.latest == 1) && (rtc.min1 < 59)) rtc.min1++;
753 
755  }
756  /* Change seconds (if selected) */
757  else if (settings.changeDateTime == 6)
758  {
759  if ((rtc.latest == 0) && (rtc.sec0 < 59)) rtc.sec0++;
760  else if ((rtc.latest == 1) && (rtc.sec1 < 59)) rtc.sec1++;
761 
763  }
764  else
765  {
766  /* Rotate right display pages (if selected) */
768  else settings.rightPage = 0;
769 
770  /* Indicate that a certain page needs to be updated after switching between them */
771  if (settings.rightPage == 0)
772  {
774  }
775  else if (settings.rightPage == 1)
776  {
778  }
779  else if (settings.rightPage == 2)
780  {
781  cData.newRunHours = 1;
782  cData.newRunMins = 1;
783  cData.newRunSecs = 1;
784  }
785  }
786  }
787  }
788  }
789  else if (steps < 0)
790  {
791  for (int8_t counter = 0; counter > steps; counter--)
792  {
793  /* Rotate LEFT display pages (if selected) */
794  if (settings.selectedDisplay == 0)
795  {
796  if (settings.leftPage > 0) settings.leftPage--;
797  else settings.leftPage = 2;
798 
799  /* Indicate that a certain page needs to be updated */
800  if (settings.leftPage == 0)
801  {
802  cData.newPow = 1;
803  cData.newMaxVolt = 1;
804  cData.newMinVolt = 1;
805  }
806  else if (settings.leftPage == 1)
807  {
808  cData.newPow = 1;
809  cData.newMaxCurr = 1;
810  cData.newMinCurr = 1;
811  }
812  else if (settings.leftPage == 2)
813  {
814  cData.newPow = 1;
815  cData.newAh = 1;
816  cData.newWh = 1;
817  }
818  }
819 
820  /* Rotate RIGHT display pages (if selected) */
821  if (settings.selectedDisplay == 1)
822  {
823  /* Change period (if selected) */
824  if (settings.changePeriod == 1)
825  {
826  if (settings.measPeriodIndex > 0)
827  {
832  }
833  }
834  /* Change day (if selected) */
835  else if (settings.changeDateTime == 1)
836  {
837  if ((rtc.latest == 0) && (rtc.day0 > 1)) rtc.day0--;
838  else if ((rtc.latest == 1) && (rtc.day1 > 1)) rtc.day1--;
839 
841  }
842  /* Change month (if selected) */
843  else if (settings.changeDateTime == 2)
844  {
845  if ((rtc.latest == 0) && (rtc.month0 > 1)) rtc.month0--;
846  else if ((rtc.latest == 1) && (rtc.month1 > 1)) rtc.month1--;
847 
849  }
850  /* Change year (if selected) */
851  else if (settings.changeDateTime == 3)
852  {
853  if (rtc.latest == 0) rtc.year0--;
854  else if (rtc.latest == 1) rtc.year1--;
855 
857  }
858  /* Change hour (if selected) */
859  else if (settings.changeDateTime == 4)
860  {
861  if ((rtc.latest == 0) && (rtc.hour0 > 0)) rtc.hour0--;
862  else if ((rtc.latest == 1) && (rtc.hour1 > 0)) rtc.hour1--;
863 
865  }
866  /* Change minutes (if selected) */
867  else if (settings.changeDateTime == 5)
868  {
869  if ((rtc.latest == 0) && (rtc.min0 > 0)) rtc.min0--;
870  else if ((rtc.latest == 1) && (rtc.min1 > 0)) rtc.min1--;
871 
873  }
874  /* Change seconds (if selected) */
875  else if (settings.changeDateTime == 6)
876  {
877  if ((rtc.latest == 0) && (rtc.sec0 > 0)) rtc.sec0--;
878  else if ((rtc.latest == 1) && (rtc.sec1 > 0)) rtc.sec1--;
879 
881  }
882  else
883  {
884  /* Rotate right display pages (if selected) */
886  else settings.rightPage = 2;
887 
888  /* Indicate that a certain page needs to be updated */
889  if (settings.rightPage == 0)
890  {
892  }
893  else if (settings.rightPage == 1)
894  {
896  }
897  else if (settings.rightPage == 2)
898  {
899  cData.newRunHours = 1;
900  cData.newRunMins = 1;
901  cData.newRunSecs = 1;
902  }
903  }
904  }
905  }
906  }
907 
908  /* Update field with new value */
909  settings.oldTIM3 = encValue;
910  }
911 }
912 
913 
914 /**************************************************************************//**
915  * @brief
916  * Function to print the header of the logfile to indicate the columns.
917  *
918  * @details
919  * This function also prints debugging information using Segger RTT.
920  *****************************************************************************/
921 void writeHeader(void)
922 {
923  USART1_print("Date and Time [day/month/year hour:min:sec],Runtime [hour:min:sec],Voltage [V],Current [A],Power [W]\r\n");
924  SEGGER_RTT_printf(0, "Date and Time [day/month/year hour:min:sec], Runtime [hour:min:sec], Voltage [V], Current [A], Power [W]\r\n");
925 }
926 
927 
928 /**************************************************************************//**
929  * @brief
930  * Function to print the footer of the logfile (two lines).
931  *
932  * @details
933  * This function prints data which doesn't change every measurement. @n
934  * This function also prints debugging information using Segger RTT.
935  *****************************************************************************/
936 void writeFooter(void)
937 {
938  /* Print footer-header */
939  USART1_print("Total runtime [hour:min:sec],Capacity [Ah],Capacity [Wh],Max Volt [V],Min Volt [V],Max Curr [A],Min Curr [A]\r\n");
940  SEGGER_RTT_printf(0, "Total runtime [hour:min:sec], Capacity [Ah], Capacity [Wh], Max Volt [V], Min Volt [V], Max Curr [A], Min Curr [A]\r\n");
941 
942  /* Print RUNTIME */
944  USART1_print(":");
946  USART1_print(":");
949 
950  /* Print spacing */
951  USART1_print(",");
952  SEGGER_RTT_printf(0, " ");
953 
954 
955  /* Print CAPACITY Ah */
957  USART1_print(".");
959  SEGGER_RTT_printf(0, "%s.%s Ah", cData.ahLeft, cData.ahRight);
960 
961  /* Print spacing */
962  USART1_print(",");
963  SEGGER_RTT_printf(0, " ");
964 
965 
966  /* Print CAPACITY Wh */
968  USART1_print(".");
970  SEGGER_RTT_printf(0, "%s.%s Wh", cData.whLeft, cData.whRight);
971 
972  /* Print spacing */
973  USART1_print(",");
974  SEGGER_RTT_printf(0, " ");
975 
976 
977  /* Print MAX VOLTAGE */
979  USART1_print(".");
982 
983  /* Print spacing */
984  USART1_print(",");
985  SEGGER_RTT_printf(0, " ");
986 
987 
988  /* Print MIN VOLTAGE */
990  USART1_print(".");
993 
994  /* Print spacing */
995  USART1_print(",");
996  SEGGER_RTT_printf(0, " ");
997 
998 
999  /* Print MAX CURRENT */
1001  USART1_print(".");
1004 
1005  /* Print spacing */
1006  USART1_print(",");
1007  SEGGER_RTT_printf(0, " ");
1008 
1009 
1010  /* Print MIN CURRENT */
1012  USART1_print(".");
1015 
1016  /* Print spacing */
1017  USART1_print("\r\n");
1018  SEGGER_RTT_printf(0, "\r\n");
1019 }
1020 
1021 
1022 /**************************************************************************//**
1023  * @brief
1024  * Function to print measurement data.
1025  *
1026  * @details
1027  * This function also prints debugging information using Segger RTT.
1028  *****************************************************************************/
1030 {
1031  /* Print DATE and TIME */
1033  USART1_print("/");
1035  USART1_print("/");
1037  USART1_print(" ");
1039  USART1_print(":");
1041  USART1_print(":");
1044 
1045  /* Print spacing */
1046  USART1_print(",");
1047  SEGGER_RTT_printf(0, " ");
1048 
1049 
1050  /* Print RUNTIME */
1052  USART1_print(":");
1054  USART1_print(":");
1057 
1058  /* Print spacing */
1059  USART1_print(",");
1060  SEGGER_RTT_printf(0, " ");
1061 
1062 
1063  /* Print VOLTAGE */
1065  USART1_print(".");
1067  SEGGER_RTT_printf(0, "%s.%s V", cData.vLeft, cData.vRight);
1068 
1069  /* Print spacing */
1070  USART1_print(",");
1071  SEGGER_RTT_printf(0, " ");
1072 
1073 
1074  /* Print CURRENT */
1076  USART1_print(".");
1078  SEGGER_RTT_printf(0, "%s.%s A", cData.aLeft, cData.aRight);
1079 
1080  /* Print spacing */
1081  USART1_print(",");
1082  SEGGER_RTT_printf(0, " ");
1083 
1084 
1085  /* Print POWER */
1087  USART1_print(".");
1089  SEGGER_RTT_printf(0, "%s.%s W", cData.pLeft, cData.pRight);
1090 
1091  /* Print spacing */
1092  USART1_print("\r\n");
1093  SEGGER_RTT_printf(0, "\r\n");
1094 }
1095 
1096 /* USER CODE END 4 */
1097 
1098 /**
1099  * @brief This function is executed in case of error occurrence.
1100  * @retval None
1101  */
1102 void Error_Handler(void)
1103 {
1104  /* USER CODE BEGIN Error_Handler_Debug */
1105  /* User can add his own implementation to report the HAL error return state */
1106  __disable_irq();
1107  while (1)
1108  {
1109  }
1110  /* USER CODE END Error_Handler_Debug */
1111 }
1112 
1113 #ifdef USE_FULL_ASSERT
1114 /**
1115  * @brief Reports the name of the source file and the source line number
1116  * where the assert_param error has occurred.
1117  * @param file: pointer to the source file name
1118  * @param line: assert_param error line source number
1119  * @retval None
1120  */
1121 void assert_failed(uint8_t *file, uint32_t line)
1122 {
1123  /* USER CODE BEGIN 6 */
1124  /* User can add his own implementation to report the file name and line number,
1125  ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
1126  /* USER CODE END 6 */
1127 }
1128 #endif /* USE_FULL_ASSERT */
1129 
1130 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Settings_t::headerSaved
uint8_t headerSaved
Definition: conversion.h:161
Data_t::runSecs
uint8_t runSecs
Definition: conversion.h:85
RTC_dateTime_t::hour0
uint8_t hour0
Definition: rtc.h:55
Settings_t::rightPage
uint8_t rightPage
Definition: conversion.h:151
Settings_t::selectedDisplay
uint8_t selectedDisplay
Definition: conversion.h:148
displaySaveIcon
void displaySaveIcon(void)
Function to display the SAVE status icon on the RIGHT OLED screen.
Definition: display.c:558
checkSwitches
void checkSwitches(void)
Function to handle switch presses.
Definition: main.c:543
startBattVoltMeasurement
void startBattVoltMeasurement(void)
Definition: adc.c:264
Data_t::current
float current
Definition: conversion.h:64
checkEncoder
void checkEncoder(void)
Function to handle encoder rotation logic.
Definition: main.c:656
data
struct Data_t data
Definition: main.c:147
USART1_INIT
void USART1_INIT(void)
USART1 Initialization Function.
Definition: usart.c:365
cData_t::aMaxLeft
char aMaxLeft[2]
Definition: conversion.h:109
cData_t
Definition: conversion.h:94
HAL_InitTick
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
cData_t::aMaxRight
char aMaxRight[5]
Definition: conversion.h:110
__disable_irq
#define __disable_irq
Definition: cmsis_iccarm.h:545
RTC_dateTime_t::min1
uint8_t min1
Definition: rtc.h:61
LL_SetSystemCoreClock
void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
This function sets directly SystemCoreClock CMSIS variable.
Definition: stm32f1xx_ll_utils.c:240
cData_t::newMaxCurr
uint8_t newMaxCurr
Definition: conversion.h:111
cData_t::newRunHours
uint8_t newRunHours
Definition: conversion.h:128
Settings_t::msWaiting
uint16_t msWaiting
Definition: conversion.h:168
Data_t::newRunHours
uint8_t newRunHours
Definition: conversion.h:82
cData_t::ahLeft
char ahLeft[5]
Definition: conversion.h:120
Settings_t::leftPage
uint8_t leftPage
Definition: conversion.h:150
Data_t::newMaxVolt
uint8_t newMaxVolt
Definition: conversion.h:61
RTT_CTRL_CLEAR
#define RTT_CTRL_CLEAR
Definition: SEGGER_RTT.h:373
cData_t::newPow
uint8_t newPow
Definition: conversion.h:118
SHUTDOWN_DELAY_UART_MODULE_MS
#define SHUTDOWN_DELAY_UART_MODULE_MS
Definition: main.c:122
getSW1
uint8_t getSW1(void)
Definition: gpio.c:51
Data_t::maxCurrent
float maxCurrent
Definition: conversion.h:70
Data_t::maxVoltage
float maxVoltage
Definition: conversion.h:60
Data_t::newAh
uint8_t newAh
Definition: conversion.h:77
tim.h
This file contains all the function prototypes for the tim.c file.
USART2_SendCommand
void USART2_SendCommand(uint8_t *command, uint8_t bytes)
Send a byte (uint8_t) command to USART2.
Definition: usart.c:299
cData_t::charRunHours
char charRunHours[3]
Definition: conversion.h:127
Data_t::runHours
uint8_t runHours
Definition: conversion.h:81
cData_t::aRight
char aRight[5]
Definition: conversion.h:107
USART3_SendCommand
void USART3_SendCommand(uint8_t *command, uint8_t bytes)
Send a byte (uint8_t) command to USART3.
Definition: usart.c:334
RTC_dateTime_t
Definition: rtc.h:50
UART1_DTRout_GPIO_Port
#define UART1_DTRout_GPIO_Port
Definition: main.h:134
Data_t::newRunSecs
uint8_t newRunSecs
Definition: conversion.h:86
adc.h
This file contains all the function prototypes for the adc.c file.
RTC_dateTime_t::charMonth
char charMonth[3]
Definition: rtc.h:79
RTC_dateTime_t::charHour
char charHour[3]
Definition: rtc.h:57
Settings_t::loggerReady
volatile uint8_t loggerReady
Definition: conversion.h:167
settings
struct Settings_t settings
Definition: main.c:149
RTC_dateTime_t::year0
uint16_t year0
Definition: rtc.h:82
Data_t::wh
float wh
Definition: conversion.h:78
Settings_t::changePeriod
uint8_t changePeriod
Definition: conversion.h:156
Data_t::newMinVolt
uint8_t newMinVolt
Definition: conversion.h:59
getSW0
uint8_t getSW0(void)
Definition: gpio.c:41
Data_t::currReceived
uint8_t currReceived
Definition: conversion.h:63
cData_t::vLeft
char vLeft[3]
Definition: conversion.h:96
Data_t::msCounter0
uint32_t msCounter0
Definition: conversion.h:88
aBY56W_SingleRead
static const uint8_t aBY56W_SingleRead[4]
Definition: main.c:142
Settings_t::newMode
uint8_t newMode
Definition: conversion.h:147
cData_t::whLeft
char whLeft[5]
Definition: conversion.h:123
cData
struct cData_t cData
Definition: main.c:148
cData_t::whRight
char whRight[4]
Definition: conversion.h:124
UART1_DTRout_Pin
#define UART1_DTRout_Pin
Definition: main.h:133
RTC_dateTime_t::charSec
char charSec[3]
Definition: rtc.h:67
RTC_dateTime_t::charDay
char charDay[3]
Definition: rtc.h:72
writeMeasurements
void writeMeasurements(void)
Function to print measurement data.
Definition: main.c:1029
cData_t::pLeft
char pLeft[4]
Definition: conversion.h:116
cData_t::charRunMins
char charRunMins[3]
Definition: conversion.h:129
cData_t::pRight
char pRight[4]
Definition: conversion.h:117
cData_t::newMaxVolt
uint8_t newMaxVolt
Definition: conversion.h:101
setSW1
void setSW1(uint8_t value)
Definition: gpio.c:56
setSW0
void setSW0(uint8_t value)
Definition: gpio.c:46
MX_ADC2_Init
void MX_ADC2_Init(void)
Definition: adc.c:140
Settings_t::measPeriodIndex
uint8_t measPeriodIndex
Definition: conversion.h:153
TIM3
#define TIM3
Definition: stm32f103xb.h:649
cData_t::newAh
uint8_t newAh
Definition: conversion.h:122
RTC_dateTime_t::min0
uint8_t min0
Definition: rtc.h:60
STARTUP_DELAY_UART_MODULE_MS
#define STARTUP_DELAY_UART_MODULE_MS
Definition: main.c:125
USART_HandleContinuousReception
void USART_HandleContinuousReception(void)
This function monitors USART1/2/3 buffer filling indication and moves data around accordingly.
Definition: usart.c:114
RTC_dateTime_t::month0
uint8_t month0
Definition: rtc.h:77
cData_t::aLeft
char aLeft[2]
Definition: conversion.h:106
Data_t::voltage
float voltage
Definition: conversion.h:54
convertValues
void convertValues(void)
Function to convert the measurements to char-arrays.
Definition: conversion.c:172
Data_t::oldPower
float oldPower
Definition: conversion.h:74
RTC_dateTime_t::year1
uint16_t year1
Definition: rtc.h:83
Settings_t::periodChanged
uint8_t periodChanged
Definition: conversion.h:157
cData_t::vRight
char vRight[4]
Definition: conversion.h:97
LUT_period_s_length
static const uint8_t LUT_period_s_length
Definition: main.c:156
TICK_INT_PRIORITY
#define TICK_INT_PRIORITY
Definition: stm32f1xx_hal_conf.h:131
Data_t::power
float power
Definition: conversion.h:73
cData_t::aMinRight
char aMinRight[5]
Definition: conversion.h:113
Settings_t::dateTimeChanged
uint8_t dateTimeChanged
Definition: conversion.h:159
RTC_dateTime_t::charMin
char charMin[3]
Definition: rtc.h:62
Data_t::newMinCurr
uint8_t newMinCurr
Definition: conversion.h:69
Settings_t::measPeriodS
uint16_t measPeriodS
Definition: conversion.h:155
Data_t
Definition: conversion.h:51
UART1_3V3out_GPIO_Port
#define UART1_3V3out_GPIO_Port
Definition: main.h:125
usart.h
U(S)ART functionality for high-precision logging voltage/current meter.
cData_t::charRunSecs
char charRunSecs[3]
Definition: conversion.h:131
Settings_t::vbatCounter
uint8_t vbatCounter
Definition: conversion.h:144
writeHeader
void writeHeader(void)
Function to print the header of the logfile to indicate the columns.
Definition: main.c:921
initDataStruct
void initDataStruct(void)
Function to initialize/reset the values in the data-struct.
Definition: conversion.c:69
cData_t::newMinCurr
uint8_t newMinCurr
Definition: conversion.h:114
RTC_dateTime_t::charYear
char charYear[5]
Definition: rtc.h:84
Settings_t
Definition: conversion.h:136
RTC_dateTime_t::sec1
uint8_t sec1
Definition: rtc.h:66
writeToRTC
void writeToRTC(void)
Function to update the RTC values according to the data in the struct.
Definition: rtc.c:319
updateRightDisplay
void updateRightDisplay(void)
Function to display updated info on the RIGHT OLED screen.
Definition: display.c:276
cData_t::ahRight
char ahRight[4]
Definition: conversion.h:121
Data_t::msCounter1
uint32_t msCounter1
Definition: conversion.h:89
initDisplays
void initDisplays(void)
Function to initialize the OLED displays.
Definition: display.c:71
forceConversion
void forceConversion(void)
Function to force a conversion of all values not (yet) displayed on the OLED screens.
Definition: conversion.c:155
Data_t::firstVolt
uint8_t firstVolt
Definition: conversion.h:56
Settings_t::newSelDisplay
uint8_t newSelDisplay
Definition: conversion.h:149
VBAT_MEASUREMENT_PERIOD_S
#define VBAT_MEASUREMENT_PERIOD_S
Definition: main.c:128
SEGGER_RTT_WriteString
unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char *s)
Definition: SEGGER_RTT.c:1215
LUT_period_s
static const uint16_t LUT_period_s[16]
Definition: main.c:153
HAL_OK
@ HAL_OK
Definition: stm32f1xx_hal_def.h:41
cData_t::newMinVolt
uint8_t newMinVolt
Definition: conversion.h:104
RTC_dateTime_t::day0
uint8_t day0
Definition: rtc.h:70
Settings_t::changeDateTime
uint8_t changeDateTime
Definition: conversion.h:158
Data_t::minVoltage
float minVoltage
Definition: conversion.h:58
conversion.h
Conversion and settings-related methods and structs for high-precision logging voltage/current meter.
Data_t::newMaxCurr
uint8_t newMaxCurr
Definition: conversion.h:71
cData_t::vMaxRight
char vMaxRight[4]
Definition: conversion.h:100
getENCkey
uint8_t getENCkey(void)
Definition: gpio.c:61
SystemClock_Config
void SystemClock_Config(void)
System Clock Configuration.
Definition: main.c:487
Data_t::ah
float ah
Definition: conversion.h:76
HAL_Init
HAL_StatusTypeDef HAL_Init(void)
cData_t::aMinLeft
char aMinLeft[2]
Definition: conversion.h:112
Settings_t::msWaitingStart
uint32_t msWaitingStart
Definition: conversion.h:169
RTC_dateTime_t::sec0
uint8_t sec0
Definition: rtc.h:65
main
int main(void)
The application entry point.
Definition: main.c:181
Data_t::voltReceived
uint8_t voltReceived
Definition: conversion.h:53
Data_t::newWh
uint8_t newWh
Definition: conversion.h:79
RTC_dateTime_t::latest
uint8_t latest
Definition: rtc.h:53
display.h
Display updating functionality for high-precision logging voltage/current meter.
cData_t::vMaxLeft
char vMaxLeft[3]
Definition: conversion.h:99
Data_t::firstCurr
uint8_t firstCurr
Definition: conversion.h:66
rtc
struct RTC_dateTime_t rtc
Definition: main.c:150
UART1_3V3out_Pin
#define UART1_3V3out_Pin
Definition: main.h:124
decSecondPassed
uint8_t decSecondPassed(void)
Function to decrease the value of secondPassed.
Definition: conversion.c:447
Data_t::minCurrent
float minCurrent
Definition: conversion.h:68
main.h
Main header-file for the high-precision logging voltage/current meter project.
gpio.h
This file contains all the function prototypes for the gpio.c file.
cData_t::vMinRight
char vMinRight[4]
Definition: conversion.h:103
Settings_t::remMeasPeriodS
uint16_t remMeasPeriodS
Definition: conversion.h:154
Settings_t::oldTIM3
uint16_t oldTIM3
Definition: conversion.h:163
MX_TIM3_Init
void MX_TIM3_Init(void)
Definition: tim.c:51
cData_t::newRunMins
uint8_t newRunMins
Definition: conversion.h:130
RTC_dateTime_t::day1
uint8_t day1
Definition: rtc.h:71
cData_t::newRunSecs
uint8_t newRunSecs
Definition: conversion.h:132
readFromRTC
void readFromRTC(void)
Function to update the RTC data in the struct.
Definition: rtc.c:309
cData_t::newWh
uint8_t newWh
Definition: conversion.h:125
initSettingsStruct
void initSettingsStruct(void)
Function to initialize/reset the values in the settings-struct.
Definition: conversion.c:119
Settings_t::secPassed
volatile uint8_t secPassed
Definition: conversion.h:164
SEGGER_RTT_printf
int SEGGER_RTT_printf(unsigned BufferIndex, const char *sFormat,...)
Definition: SEGGER_RTT_printf.c:491
FLOAT_TO_INT
#define FLOAT_TO_INT(x)
Definition: conversion.h:48
HAL_GetTick
uint32_t HAL_GetTick(void)
rtc.h
RTC functionality for high-precision logging voltage/current meter.
MAX_WHILELOOPS_METER_RESPONSE
#define MAX_WHILELOOPS_METER_RESPONSE
Definition: main.c:119
USART3_INIT
void USART3_INIT(void)
USART3 Initialization Function.
Definition: usart.c:491
Data_t::runMins
uint8_t runMins
Definition: conversion.h:83
Settings_t::newSec
uint8_t newSec
Definition: conversion.h:165
USART1_print
void USART1_print(char *message)
Print a string (char array) to USARTx.
Definition: usart.c:556
USART2_INIT
void USART2_INIT(void)
USART2 Initialization Function.
Definition: usart.c:428
SEGGER_RTT.h
setENCkey
void setENCkey(uint8_t value)
Definition: gpio.c:66
Activate_ADC
void Activate_ADC(void)
Perform ADC activation procedure to make it ready to convert (ADC instance: ADC2).
Definition: adc.c:197
MX_I2C1_Init
void MX_I2C1_Init(void)
Definition: i2c.c:30
Data_t::latestMScounter
uint8_t latestMScounter
Definition: conversion.h:90
cData_t::vMinLeft
char vMinLeft[3]
Definition: conversion.h:102
Settings_t::mode
uint8_t mode
Definition: conversion.h:146
Data_t::newPow
uint8_t newPow
Definition: conversion.h:75
RTC_dateTime_t::hour1
uint8_t hour1
Definition: rtc.h:56
i2c.h
This file contains all the function prototypes for the i2c.c file.
util.h
Utility functionality for high-precision logging voltage/current meter.
RTC_dateTime_t::month1
uint8_t month1
Definition: rtc.h:78
finishDisplayUpdates
void finishDisplayUpdates(void)
Function to finish the screen-updates.
Definition: display.c:548
Error_Handler
void Error_Handler(void)
This function is executed in case of error occurrence.
Definition: main.c:1102
updateLeftDisplay
void updateLeftDisplay(void)
Function to display updated info on the LEFT OLED screen.
Definition: display.c:94
MX_GPIO_Init
void MX_GPIO_Init(void)
Definition: gpio.c:81
Data_t::newRunMins
uint8_t newRunMins
Definition: conversion.h:84
writeFooter
void writeFooter(void)
Function to print the footer of the logfile (two lines).
Definition: main.c:936
RTC_Init
void RTC_Init(void)
Function to initialize the Real Time Clock.
Definition: rtc.c:97