DIY Logging Volt/Ampmeter
util.c File Reference

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

#include "util.h"
#include <stdint.h>

Go to the source code of this file.

Macros

#define TO_DEC(i)   (i <= 9 ? '0' + i : '?') /* return "?" if out of range */
 

Functions

float bytes_to_float (uint8_t byte0, uint8_t byte1, uint8_t byte2, uint8_t byte3)
 Convert four bytes into a float. More...
 
void splitFloat (float fValue, uint16_t *beforeComma, uint16_t *afterComma, uint8_t decimalPlaces)
 Split a float value in two uint values (before and after the comma). More...
 
void uint32_to_charDec (char *buf, uint32_t value, uint8_t totalChars)
 Convert a uint32_t value to a decimal char array (string). More...
 

Detailed Description

Utility functionality for high-precision logging voltage/current meter.

Version
1.0
Author
Brecht Van Eeckhoudt

Versions

  • v1.0: Initial version.

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 util.c.

Macro Definition Documentation

◆ TO_DEC

#define TO_DEC (   i)    (i <= 9 ? '0' + i : '?') /* return "?" if out of range */

Definition at line 42 of file util.c.

Function Documentation

◆ bytes_to_float()

float bytes_to_float ( uint8_t  byte0,
uint8_t  byte1,
uint8_t  byte2,
uint8_t  byte3 
)

Convert four bytes into a float.

Parameters
[in]byte0First byte.
[in]byte1Second byte.
[in]byte2Third byte.
[in]byte3Fourth byte.
Returns
The converted float-value.

Definition at line 72 of file util.c.

73 {
74  /* Define union */
75  union
76  {
77  float fValue;
78  uint8_t byte[4];
79  } data;
80 
81  /* Assign the four bytes to the union array */
82  data.byte[0]=byte0;
83  data.byte[1]=byte1;
84  data.byte[2]=byte2;
85  data.byte[3]=byte3;
86 
87  return (data.fValue);
88 }

◆ splitFloat()

void splitFloat ( float  fValue,
uint16_t *  beforeComma,
uint16_t *  afterComma,
uint8_t  decimalPlaces 
)

Split a float value in two uint values (before and after the comma).

Parameters
[in]fValueThe float value to convert.
[in,out]beforeCommaPointer to the uint16_t value before the comma.
[in,out]afterCommaPointer to the uint16_t value after the comma.
[in]decimalPlacesAmount of decimal places to use after the comma.

Definition at line 107 of file util.c.

108 {
109  /* Separate value before comma */
110  *beforeComma = (uint16_t)fValue;
111 
112  /* Separate value after comma according to given argument */
113  float multiplicationFactor = 1.0;
114  for (uint8_t counter = 0; counter < decimalPlaces; counter++) multiplicationFactor *= 10.0;
115  *afterComma = (uint16_t)((float)(fValue-(*beforeComma))*multiplicationFactor);
116 
117  /* Round up if necessary */
118  uint8_t roundingNumber = (uint8_t)(((float)(fValue-(*beforeComma))*(multiplicationFactor*10.0))-(*afterComma)*10);
119  if (roundingNumber > 4)
120  {
121  (*afterComma)++;
122  if ((decimalPlaces == 1) && (*afterComma) == 10)
123  {
124  (*beforeComma)++;
125  (*afterComma) = 0;
126  }
127  }
128 }

◆ 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).

This method can also add a specific amount of leading zero's if necessary.

Parameters
[out]bufThe buffer to put the resulting string in.
This needs to have a length of 10: char buf[10];!
[in]valueThe uint32_t value to convert to a string.
[in]totalCharsTotal amount of characters, to be filled with leading zero's if necessary.
If a value <= 1 is given, no zero's will be added

Definition at line 149 of file util.c.

150 {
151  if (value == 0)
152  {
153  uint8_t counter;
154  for (counter = 0; counter < totalChars; counter++)
155  {
156  buf[counter] = '0';
157  }
158 
159  buf[counter++] = '\0'; /* NULL termination character */
160  }
161  else
162  {
163  /* MAX uint32_t value = FFFFFFFFh = 4294967295d (10 decimal chars) */
164  char backwardsBuf[10];
165 
166  uint32_t calcval = value;
167  uint8_t length = 0;
168  uint8_t lengthCounter = 0;
169 
170 
171  /* Loop until the value is zero (separate characters 0-9) and calculate length */
172  while (calcval)
173  {
174  uint32_t rem = calcval % 10;
175  backwardsBuf[length] = TO_DEC(rem); /* Convert to ASCII character */
176  length++;
177 
178  calcval = calcval - rem;
179  calcval = calcval / 10;
180  }
181 
182  uint8_t index = 0;
183  uint8_t addedZeros = 0;
184 
185  /* Add leading zero's if necessary */
186  if (totalChars > 1)
187  {
188  /* Calculate power */
189  uint16_t power = 1;
190  while (totalChars != 1) {
191  power *= 10;
192  totalChars--;
193  }
194 
195  /* Print leading zero's if necessary */
196  if (value < power)
197  {
198  /* Add the correct amount of zero's */
199  uint16_t checkValue = value;
200  while (checkValue < power)
201  {
202  buf[index] = '0';
203  addedZeros++;
204  checkValue *= 10;
205  index++;
206  }
207  }
208  }
209 
210  /* Backwards counter */
211  lengthCounter = length;
212 
213  /* Reverse the characters in the buffer for the final string */
214  while (index < (length + addedZeros))
215  {
216  buf[index] = backwardsBuf[lengthCounter-1];
217  lengthCounter--;
218  index++;
219  }
220 
221  /* Add NULL termination character */
222  buf[(length + addedZeros)] = '\0';
223  }
224 }
data
struct Data_t data
TO_DEC
#define TO_DEC(i)
Definition: util.c:42