-
Notifications
You must be signed in to change notification settings - Fork 8
/
util.cpp
125 lines (110 loc) · 2.92 KB
/
util.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <Arduino.h>
#include "util.h";
unsigned int calculateChecksum(char* input){
unsigned int result = 0;
for(int i=0;i<strlen(input);++i){
result^=input[i];
}
return result;
}
void blink(int times){
for(int i=0;i<times+1;i++){
digitalWrite(D4, LOW);
delay(70);
digitalWrite(D4, HIGH);
delay(70);
}
}
//
// Produce a formatted string in a buffer corresponding to the value provided.
// If the 'width' parameter is non-zero, the value will be padded with leading
// zeroes to achieve the specified width. The number of characters added to
// the buffer (not including the null termination) is returned.
//
unsigned
fmtUnsigned(unsigned long val, char *buf, unsigned bufLen, byte width)
{
if (!buf || !bufLen)
return(0);
// produce the digit string (backwards in the digit buffer)
char dbuf[10];
unsigned idx = 0;
while (idx < sizeof(dbuf))
{
dbuf[idx++] = (val % 10) + '0';
if ((val /= 10) == 0)
break;
}
// copy the optional leading zeroes and digits to the target buffer
unsigned len = 0;
byte padding = (width > idx) ? width - idx : 0;
char c = '0';
while ((--bufLen > 0) && (idx || padding))
{
if (padding)
padding--;
else
c = dbuf[--idx];
*buf++ = c;
len++;
}
// add the null termination
*buf = '\0';
return(len);
}
//
// Format a floating point value with number of decimal places.
// The 'precision' parameter is a number from 0 to 6 indicating the desired decimal places.
// The 'buf' parameter points to a buffer to receive the formatted string. This must be
// sufficiently large to contain the resulting string. The buffer's length may be
// optionally specified. If it is given, the maximum length of the generated string
// will be one less than the specified value.
//
// example: fmtDouble(3.1415, 2, buf); // produces 3.14 (two decimal places)
//
void
fmtDouble(double val, byte precision, char *buf, unsigned bufLen)
{
if (!buf || !bufLen)
return;
// limit the precision to the maximum allowed value
const byte maxPrecision = 6;
if (precision > maxPrecision)
precision = maxPrecision;
if (--bufLen > 0)
{
// check for a negative value
if (val < 0.0)
{
val = -val;
*buf = '-';
bufLen--;
}
// compute the rounding factor and fractional multiplier
double roundingFactor = 0.5;
unsigned long mult = 1;
for (byte i = 0; i < precision; i++)
{
roundingFactor /= 10.0;
mult *= 10;
}
if (bufLen > 0)
{
// apply the rounding factor
val += roundingFactor;
// add the integral portion to the buffer
unsigned len = fmtUnsigned((unsigned long)val, buf, bufLen);
buf += len;
bufLen -= len;
}
// handle the fractional portion
if ((precision > 0) && (bufLen > 0))
{
*buf++ = '.';
if (--bufLen > 0)
buf += fmtUnsigned((unsigned long)((val - (unsigned long)val) * mult), buf, bufLen, precision);
}
}
// null-terminate the string
*buf = '\0';
}