-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprintfToSerial.h
More file actions
133 lines (114 loc) · 4.77 KB
/
printfToSerial.h
File metadata and controls
133 lines (114 loc) · 4.77 KB
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
125
126
127
128
129
130
131
132
/*
Library to make printf available in Arduino.
*/
#include <stdio.h> // for printf
#include <stdint.h> // for uint64_t
#include <stdarg.h> // for printf
///
/// @brief The ulltoa function converts an uint64_t to a string. Will always write a '\0'-terminated string
/// in buffer. Will write "too big" (eventually truncated) in buffer if buffer is to small to hold the
/// representation of ll.
/// @param ll the uint64_t to convert
/// @param buffer a char array where the string will be written
/// @param bufsize size of buffer
/// @param radix to use for the string representation
/// @return pointer to first char of buffer
///
char * ulltoa(uint64_t ll, char *buffer, const size_t bufsize, const unsigned int radix=10);
template <unsigned int BUF_SIZE>
class CircularBuffer {
public :
/// @brief To be called very frequently. Will write one char to Serial if there are data in the buffer.
void engine(int numToSend=1){
numToSend = numToSend < charactersToSend() ? numToSend : charactersToSend();
while (numToSend--) {
Serial.print(buffer[oldestI]);
if (buffer[oldestI] == '\n') {
Serial.flush();
}
oldestI = (oldestI + 1)%BUF_SIZE ;
}
}
/// @brief Removes chars from circular buffer, and puts them into *to
/// @param to : destination where to put the taken chars
/// @param maxSize : maximum number of chars to take
/// @return actual number of chars taken
int take(char* to, int maxSize){
int count = 0;
while (oldestI != nextI && count < maxSize ) {
to[count] = buffer[oldestI];
oldestI = (oldestI + 1)%BUF_SIZE ;
count++;
}
return count;
}
/// @brief Adds a string to the circular buffer, to be printed to the serial port. Will truncate the string if there is not enough space left in the buffer
/// @param str address of a null-terminated string.
int enqueueString(const char *str){
int queued = 0;
while (str[queued] != '\0' && nextI != ( (oldestI + BUF_SIZE - 1) % BUF_SIZE) ){
buffer[nextI] = str[queued];
queued++;
nextI = (nextI + 1) % BUF_SIZE;
}
return queued;
}
/// @brief Prints a formatted string into the buffer.
int printf(const char *format, ...){
va_list vargs;
va_start(vargs, format);
int ret = this->vprintf(format, vargs);
va_end(vargs);
return ret;
}
/// @brief Prints a formatted string into the buffer.
int vprintf(const char *format, va_list ap){
int maxSize = availableSize();
char buffer2[maxSize];
vsnprintf(buffer2, maxSize, format, ap);
return enqueueString(buffer2);
}
/// @brief Prints a formatted string into the buffer, pre-pended with an integer (example : timestamp). Pre-pending can be disabled by enableTSPrint(bool)
int printf(uint32_t ts, const char *format, ...){
int ret = 0;
if ( TSPrintEnabled ) printf("%" PRIu32 " ", ts);
va_list vargs;
va_start(vargs, format);
ret += this->vprintf(format, vargs);
va_end(vargs);
return ret;
}
/// @brief Returns the available size in the circular bufffer.
int availableSize(){
return BUF_SIZE - ((nextI + BUF_SIZE - oldestI) % BUF_SIZE);
}
/// @brief Returns the number of characters to send
int charactersToSend(){
return (nextI + BUF_SIZE - oldestI) % BUF_SIZE;
}
/// @brief discards everything in the circular buffer
void clear(){
oldestI = 0;
nextI = 0;
buffer[0] = '\0';
}
/// @brief Returns the available size in the circular bufffer.
int availableChars(){
return ((nextI + BUF_SIZE - oldestI) % BUF_SIZE);
}
/// @brief Returns the available size in the circular bufffer.
void enableTSPrint(bool enable) {
TSPrintEnabled = enable;
}
void flushToSerial(){
while (charactersToSend()){
engine(64); // 64, because it is the default output buffer size on arduino
}
Serial.flush();
}
private :
int oldestI = 0; // oldest index (next to be written on the serial port)
int nextI = 0; // next position to write to.
char buffer[BUF_SIZE]; // the buffer.
bool TSPrintEnabled = false; // disables timestamp printing in "int printf(uint32_t, const char *, ...)"
};