-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJsonSerialStream.h
More file actions
125 lines (106 loc) · 3.54 KB
/
JsonSerialStream.h
File metadata and controls
125 lines (106 loc) · 3.54 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
// Format to JSON as data is printed to Serial
// This class was written to transfer information off the Arduino using the
// JavaScript Object Notation (JSON) standard. This causes us to send
// extra characters, take the time to format the data, and this class
// takes executable space, but this standardization will improve usability
// on reciever's side as many libraries exist for many langauges to
// "rehydrate" JSON strings into variables again.
// This class makes extensive use of template functions. These are
// functions in which a datatype is variable. This class makes use of this
// in order to make functions independent of input type, essentially
// acting as an overload for any datatype, and instead the work of sending
// the data by Serial is put upon .print() and not me.
// Please note:
// - template functions are required to be implemented at declaration
// - the use of F() is a macro to save RAM
// - the use of & is Pass by Reference, saves RAM and time by giving the
// actual String rather than a copy of the String
// - this class does not have proper format error checking
// Prevents this file from being loaded multiple times
#pragma once
#include <Arduino.h>
#include <HardwareSerial.h>
class JsonSerialStream
{
private:
bool empty;
HardwareSerial& serialStream;
// Most common process, add name to property or nested object
template <class S>
void addName(S name)
{
// Prevent comma for first element
if (empty)
{
serialStream.print(F("\""));
empty = false;
}
else
serialStream.print(F(",\""));
serialStream.print(name);
serialStream.print(F("\":"));
}
// Handle types that are JavaScript strings: ex. String, char[], char
template <class S>
void addStringValue(S value)
{
// Add quotes for string
serialStream.print(F("\""));
serialStream.print(value);
serialStream.print(F("\""));
}
public:
// Attach JsonSerialStream to a HardwareSerial line
JsonSerialStream(HardwareSerial& serial);
// Open JSON String
void openMessage();
// Close JSON String
void closeMessage();
// Overload to handle String values
template <class S>
void addProperty(S name, String &value)
{
addName(name);
addStringValue(value);
}
// Overload to handle string literals (const char*) values
template <class S>
void addProperty(S name, const char value[])
{
addName(name);
addStringValue(value);
}
// Overload to convert Bool values to true/false instead of 1/0
template <class S>
void addProperty(S name, bool value)
{
addName(name);
// Ternary operator to simplify process
serialStream.print( (value) ? F("true") : F("false") );
}
// General property
template <class S, class T>
void addProperty(S name, T value)
{
addName(name);
serialStream.print(value);
}
// Let user force data to be sent as string data
template <class S, class T>
void addPropertyAsString(S name, T value)
{
addName(name);
addStringValue(value);
}
// Open nested object, behaves like a new JSON message
template <class S>
void addNestedObject(S objectName)
{
addName(objectName);
serialStream.print(F("{"));
// Behave as if empty for interior properties
empty = true;
}
// Close nested object, but not end of message
void closeNestedObject();
};