DIY Logging Volt/Ampmeter
display.c File Reference

Display updating functionality for high-precision logging voltage/current meter. More...

#include "display.h"
#include <stdint.h>
#include "ssd1306.h"
#include "conversion.h"
#include "util.h"
#include "rtc.h"

Go to the source code of this file.

Functions

void initDisplays (void)
 Function to initialize the OLED displays. More...
 
void updateLeftDisplay (void)
 Function to display updated info on the LEFT OLED screen. More...
 
void updateRightDisplay (void)
 Function to display updated info on the RIGHT OLED screen. More...
 
void finishDisplayUpdates (void)
 Function to finish the screen-updates. More...
 
void displaySaveIcon (void)
 Function to display the SAVE status icon on the RIGHT OLED screen. More...
 

Detailed Description

Display updating functionality for high-precision logging voltage/current meter.

Version
1.0
Author
Brecht Van Eeckhoudt

Versions

  • v1.0: Initial version.

Todo:
Future improvements:
  • Change left/right display selection logic so the two update methods can work independently and without finishDisplayUpdates.
  • Check/optimize flow in display updating logic.
  • Add page for setting min/max volt/amp (/watt/time?) values for relay opening functionality.
  • Add status message display functionality on left display/save icon location, stops running & gets removed by any (?) key-press.

License

Copyright (C) 2021 - Brecht Van Eeckhoudt

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

A copy of the GNU General Public License can be found in the LICENSE file along with this source code.

Definition in file display.c.

Function Documentation

◆ displaySaveIcon()

void displaySaveIcon ( void  )

Function to display the SAVE status icon on the RIGHT OLED screen.

Definition at line 558 of file display.c.

559 {
560  /* Select RIGHT display */
562 
563  ssd1306_SetCursor(80, 0);
565 
566  /* Make sure other display logic replaces the icon again */
567  settings.newMode = 1;
568 
569  /* Write changes to RIGHT display */
571 }

◆ finishDisplayUpdates()

void finishDisplayUpdates ( void  )

Function to finish the screen-updates.

This function partially handles the selected-screen line logic.

Definition at line 548 of file display.c.

549 {
551 }

◆ initDisplays()

void initDisplays ( void  )

Function to initialize the OLED displays.

Definition at line 71 of file display.c.

72 {
73  /* Initialize LEFT display */
75  ssd1306_Init();
76  ssd1306_SetContrast(0xFF); /* 90 about equals 255/0xFF of RIGHT display... */
78 
79  /* Initialize RIGHT display */
81  ssd1306_Init();
82  ssd1306_SetContrast(0xFF);
84 }

◆ updateLeftDisplay()

void updateLeftDisplay ( void  )

Function to display updated info on the LEFT OLED screen.

Only updated and visible items on the OLED screens get redrawn.

Definition at line 94 of file display.c.

95 {
96  /* Variable for selective screen updating logic */
97  uint8_t needsUpdate = 0;
98 
99  /* Select LEFT display */
101 
102 
103  /* Update POWER value if necessary */
104  if (cData.newPow)
105  {
106  ssd1306_SetCursor(2, 0);
111 
112  cData.newPow = 0;
113 
114  needsUpdate = 1;
115  }
116 
117  if (settings.leftPage == 0)
118  {
119  /* Update MAX VOLT value if necessary */
120  if (cData.newMaxVolt)
121  {
122  /* Erase previous pixels above smaller text */
123  ssd1306_SetCursor(2, 26);
125 
126  /* Draw new text */
127  ssd1306_SetCursor(2, 32);
129  ssd1306_SetCursor(37, 26);
134 
135  cData.newMaxVolt = 0;
136 
137  needsUpdate = 1;
138  }
139 
140  /* Update MIN VOLT value if necessary */
141  if (cData.newMinVolt)
142  {
143  /* Erase previous pixels above smaller text */
144  ssd1306_SetCursor(2, 44);
146 
147  /* Draw new text */
148  ssd1306_SetCursor(2, 52);
150  ssd1306_SetCursor(37, 44);
155 
156  cData.newMinVolt = 0;
157 
158  needsUpdate = 1;
159  }
160  }
161  else if (settings.leftPage == 1)
162  {
163  /* Update MAX CURR value if necessary */
164  if (cData.newMaxCurr)
165  {
166  /* Erase previous pixels above smaller text */
167  ssd1306_SetCursor(2, 26);
169 
170  /* Draw new text */
171  ssd1306_SetCursor(2, 32);
173  ssd1306_SetCursor(37, 26);
178 
179  cData.newMaxCurr = 0;
180 
181  needsUpdate = 1;
182  }
183 
184  /* Update MIN CURR value if necessary */
185  if (cData.newMinCurr)
186  {
187  /* Erase previous pixels above smaller text */
188  ssd1306_SetCursor(2, 44);
190 
191  /* Draw new text */
192  ssd1306_SetCursor(2, 52);
194  ssd1306_SetCursor(37, 44);
199 
200  cData.newMinCurr = 0;
201 
202  needsUpdate = 1;
203  }
204  }
205  else if (settings.leftPage == 2)
206  {
207  /* Update Ah value if necessary */
208  if (cData.newAh)
209  {
210  ssd1306_SetCursor(2, 26);
215  ssd1306_SetCursor(104, 26);
217 
218  cData.newAh = 0;
219 
220  needsUpdate = 1;
221  }
222 
223  /* Update Wh value if necessary */
224  if (cData.newWh)
225  {
226  ssd1306_SetCursor(2, 44);
231  ssd1306_SetCursor(104, 44);
233 
234  cData.newWh = 0;
235 
236  needsUpdate = 1;
237  }
238  }
239 
240 
241  /* Update display selection lines if necessary */
243  {
244  /* Draw display selection-lines */
245  ssd1306_Line(2, 63, 129, 63, White);
246  ssd1306_Line(129, 53, 129, 63, White);
247 
248  needsUpdate = 1;
249  }
250  else if ((settings.selectedDisplay == 1) && settings.newSelDisplay)
251  {
252  /* Remove display selection-lines */
253  ssd1306_Line(2, 63, 129, 63, Black);
254  ssd1306_Line(129, 53, 129, 63, Black);
255 
256  needsUpdate = 1;
257  }
258 
259 
260  /* Write changes to LEFT display if necessary */
261  if (needsUpdate)
262  {
263 // SEGGER_RTT_printf(0, "Left");
265  }
266 }

◆ updateRightDisplay()

void updateRightDisplay ( void  )

Function to display updated info on the RIGHT OLED screen.

Only updated and visible items on the OLED screens get redrawn.

Definition at line 276 of file display.c.

277 {
278  /* Variable for selective screen updating logic */
279  uint8_t needsUpdate = 0;
280 
281  /* Select RIGHT display */
283 
284 
285  /* Update internal battery voltage value if necessary */
286  if (settings.newCharVbat)
287  {
288  ssd1306_SetCursor(2, 4);
293 
294  settings.newCharVbat = 0;
295 
296  needsUpdate = 1;
297  }
298 
299 
300  /* Update mode indication field if necessary */
301  if (settings.newMode)
302  {
303  if (settings.mode == 0)
304  {
305  ssd1306_SetCursor(80, 0);
307  }
308  else if (settings.mode == 1)
309  {
310  ssd1306_SetCursor(80, 0);
312  }
313 
314  settings.newMode = 0;
315 
316  needsUpdate = 1;
317  }
318 
319 
320  /* Enter logic if we're on the correct page and a second has passed or the time was manually changed */
322  {
323  /* Update day if necessary */
325  {
326  ssd1306_SetCursor(2, 26);
328  rtc.newCharDay = 0;
330  }
331 
332  /* Update month if necessary */
334  {
335  ssd1306_SetCursor(35, 26);
337  rtc.newCharMonth = 0;
339  }
340 
341  /* Update year if necessary */
343  {
344  ssd1306_SetCursor(68, 26);
346  rtc.newCharYear = 0;
347  }
348 
349  /* Update hour if necessary */
351  {
352  ssd1306_SetCursor(2, 44);
355  rtc.newCharHour = 0;
357  }
358 
359  /* Update minutes if necessary */
361  {
362  ssd1306_SetCursor(46, 44);
364  rtc.newCharMin = 0;
366  }
367 
368  /* Update seconds if necessary */
370  {
371  ssd1306_SetCursor(79, 44);
373  rtc.newCharSec = 0;
375  }
376 
377  /* Draw editing-line under day-field if necessary */
379  {
380  ssd1306_Line(2, 42, 22, 42, White);
381  ssd1306_Line(2, 43, 22, 43, White);
382  }
383 
384  /* Draw editing-line under month-field if necessary */
386  {
387  ssd1306_Line(35, 42, 55, 42, White);
388  ssd1306_Line(35, 43, 55, 43, White);
389  }
390 
391  /* Draw editing-line under year-field if necessary */
393  {
394  ssd1306_Line(68, 42, 110, 42, White);
395  ssd1306_Line(68, 43, 110, 43, White);
396  }
397 
398  /* Draw editing-line under hour-field if necessary */
400  {
401  ssd1306_Line(13, 60, 35, 60, White);
402  ssd1306_Line(13, 61, 35, 61, White);
403  }
404 
405  /* Draw editing-line under minutes-field if necessary */
407  {
408  ssd1306_Line(46, 60, 68, 60, White);
409  ssd1306_Line(46, 61, 68, 61, White);
410  }
411 
412  /* Draw editing-line under seconds-field if necessary */
414  {
415  ssd1306_Line(79, 60, 101, 60, White);
416  ssd1306_Line(79, 61, 101, 61, White);
417  }
418 
419  /* Reset date/time updating logic if time was manually changed */
421 
422  needsUpdate = 1;
423  }
424  /* Update measurement-period if necessary */
425  else if ((settings.rightPage == 1) && settings.periodChanged)
426  {
427  ssd1306_SetCursor(2, 26);
428  ssd1306_WriteString(" Period ", Font_11x18, White);
429 
430  ssd1306_SetCursor(2, 44);
432 
433  /* Calculate hours-mins-secs from selected period value */
434  uint16_t secs = settings.measPeriodS;
435  uint16_t mins = secs / 60;
436  secs = secs - (60 * mins);
437  uint8_t hours = mins / 60;
438  mins = mins - (60 * hours);
439 
440  /* Write hours to screen if necessary */
441  if (hours > 0)
442  {
443  char charHours[3]; /* Value won't exceed 99 (2 chars + NULL termination = 3) */
444  uint32_to_charDec(charHours, hours, 2);
445  ssd1306_WriteString(charHours, Font_11x18, White);
447  }
448 
449  /* Write minutes to screen if necessary */
450  if (mins > 0)
451  {
452  char charMins[3]; /* Value won't exceed 59 (2 chars + NULL termination = 3) */
453  uint32_to_charDec(charMins, mins, 2);
456  }
457 
458  /* Write seconds to screen if necessary */
459  if (secs > 0)
460  {
461  char charSecs[3]; /* Value won't exceed 59 (2 chars + NULL termination = 3) */
462  uint32_to_charDec(charSecs, secs, 2);
465  }
466 
468 
469 
470  /* Draw editing-line under period field if necessary */
471  if (settings.changePeriod == 1)
472  {
473  ssd1306_Line(35, 60, 68, 60, White);
474  ssd1306_Line(35, 61, 68, 61, White);
475  }
476 
478 
479  needsUpdate = 1;
480  }
481  /* Update runtime hour/minute values if necessary */
482  else if ((settings.rightPage == 2) && (cData.newRunHours || cData.newRunMins))
483  {
484  ssd1306_SetCursor(2, 26);
485  ssd1306_WriteString(" Runtime ", Font_11x18, White);
486  ssd1306_SetCursor(2, 44);
487 
493 
494  cData.newRunHours = 0;
495  cData.newRunMins = 0;
496 
497  needsUpdate = 1;
498  }
499 
500  /* Update runtime second value if necessary */
501  if ((settings.rightPage == 2) && cData.newRunSecs)
502  {
503  ssd1306_SetCursor(77, 44);
506 
507  cData.newRunSecs = 0;
508 
509  needsUpdate = 1;
510  }
511 
512 
513  /* Update display selection lines if necessary */
515  {
516  /* Draw display selection-lines */
517  ssd1306_Line(2, 63, 129, 63, White);
518  ssd1306_Line(129, 53, 129, 63, White);
519 
520  needsUpdate = 1;
521  }
522  else if ((settings.selectedDisplay == 0) && settings.newSelDisplay)
523  {
524  /* Remove display selection-lines */
525  ssd1306_Line(2, 63, 129, 63, Black);
526  ssd1306_Line(129, 53, 129, 63, Black);
527 
528  needsUpdate = 1;
529  }
530 
531 
532  /* Write changes to RIGHT display if necessary */
533  if (needsUpdate)
534  {
535 // SEGGER_RTT_printf(0, "Right");
537  }
538 }
Settings_t::rightPage
uint8_t rightPage
Definition: conversion.h:151
Settings_t::selectedDisplay
uint8_t selectedDisplay
Definition: conversion.h:148
settings
struct Settings_t settings
cData_t::aMaxLeft
char aMaxLeft[2]
Definition: conversion.h:109
cData_t::aMaxRight
char aMaxRight[5]
Definition: conversion.h:110
cData_t::newMaxCurr
uint8_t newMaxCurr
Definition: conversion.h:111
ssd1306_SetCursor
void ssd1306_SetCursor(uint8_t x, uint8_t y)
Definition: ssd1306.c:344
cData_t::newRunHours
uint8_t newRunHours
Definition: conversion.h:128
cData_t::ahLeft
char ahLeft[5]
Definition: conversion.h:120
Settings_t::leftPage
uint8_t leftPage
Definition: conversion.h:150
Black
@ Black
Definition: ssd1306.h:106
cData_t::newPow
uint8_t newPow
Definition: conversion.h:118
rtc
struct RTC_dateTime_t rtc
ssd1306_WriteString
char ssd1306_WriteString(char *str, FontDef Font, SSD1306_COLOR color)
Definition: ssd1306.c:327
cData_t::charRunHours
char charRunHours[3]
Definition: conversion.h:127
cData
struct cData_t cData
ssd1306_UpdateScreen
void ssd1306_UpdateScreen(void)
Definition: ssd1306.c:220
ssd1306_SelectDisplay
void ssd1306_SelectDisplay(uint8_t display)
Definition: ssd1306.c:19
RTC_dateTime_t::newCharMonth
uint8_t newCharMonth
Definition: rtc.h:80
RTC_dateTime_t::charMonth
char charMonth[3]
Definition: rtc.h:79
Font_11x18
FontDef Font_11x18
Definition: ssd1306_fonts.c:409
RTC_dateTime_t::charHour
char charHour[3]
Definition: rtc.h:57
Settings_t::changePeriod
uint8_t changePeriod
Definition: conversion.h:156
Settings_t::newMode
uint8_t newMode
Definition: conversion.h:147
cData_t::whLeft
char whLeft[5]
Definition: conversion.h:123
RTC_dateTime_t::newCharMin
uint8_t newCharMin
Definition: rtc.h:63
cData_t::whRight
char whRight[4]
Definition: conversion.h:124
Font_16x26
FontDef Font_16x26
Definition: ssd1306_fonts.c:412
RTC_dateTime_t::charSec
char charSec[3]
Definition: rtc.h:67
RTC_dateTime_t::charDay
char charDay[3]
Definition: rtc.h:72
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
RTC_dateTime_t::newCharDay
uint8_t newCharDay
Definition: rtc.h:73
cData_t::newMaxVolt
uint8_t newMaxVolt
Definition: conversion.h:101
RTC_dateTime_t::newCharYear
uint8_t newCharYear
Definition: rtc.h:85
Settings_t::vbatRight
char vbatRight[3]
Definition: conversion.h:142
cData_t::newAh
uint8_t newAh
Definition: conversion.h:122
RTC_dateTime_t::newCharHour
uint8_t newCharHour
Definition: rtc.h:58
Settings_t::periodChanged
uint8_t periodChanged
Definition: conversion.h:157
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
Settings_t::measPeriodS
uint16_t measPeriodS
Definition: conversion.h:155
cData_t::charRunSecs
char charRunSecs[3]
Definition: conversion.h:131
cData_t::newMinCurr
uint8_t newMinCurr
Definition: conversion.h:114
RTC_dateTime_t::charYear
char charYear[5]
Definition: rtc.h:84
cData_t::ahRight
char ahRight[4]
Definition: conversion.h:121
Settings_t::newCharVbat
uint8_t newCharVbat
Definition: conversion.h:143
ssd1306_SetContrast
void ssd1306_SetContrast(const uint8_t value)
Sets the contrast of the display.
Definition: ssd1306.c:522
ssd1306_WriteChar
char ssd1306_WriteChar(char ch, FontDef Font, SSD1306_COLOR color)
Definition: ssd1306.c:274
Settings_t::newSelDisplay
uint8_t newSelDisplay
Definition: conversion.h:149
Font_7x10
FontDef Font_7x10
Definition: ssd1306_fonts.c:406
RTC_dateTime_t::newCharSec
uint8_t newCharSec
Definition: rtc.h:68
cData_t::newMinVolt
uint8_t newMinVolt
Definition: conversion.h:104
Settings_t::changeDateTime
uint8_t changeDateTime
Definition: conversion.h:158
cData_t::vMaxRight
char vMaxRight[4]
Definition: conversion.h:100
ssd1306_Init
void ssd1306_Init(void)
Definition: ssd1306.c:94
cData_t::aMinLeft
char aMinLeft[2]
Definition: conversion.h:112
cData_t::vMaxLeft
char vMaxLeft[3]
Definition: conversion.h:99
cData_t::vMinRight
char vMinRight[4]
Definition: conversion.h:103
cData_t::newRunMins
uint8_t newRunMins
Definition: conversion.h:130
cData_t::newRunSecs
uint8_t newRunSecs
Definition: conversion.h:132
Settings_t::vbatLeft
char vbatLeft[2]
Definition: conversion.h:141
cData_t::newWh
uint8_t newWh
Definition: conversion.h:125
ssd1306_Line
void ssd1306_Line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color)
Definition: ssd1306.c:358
White
@ White
Definition: ssd1306.h:107
cData_t::vMinLeft
char vMinLeft[3]
Definition: conversion.h:102
Settings_t::mode
uint8_t mode
Definition: conversion.h:146
uint32_to_charDec
void uint32_to_charDec(char *buf, uint32_t value, uint8_t totalChars)
Convert a uint32_t value to a decimal char array (string).
Definition: util.c:149