1
- // Sample Arduino Json Web Client
2
- // Downloads and parse http://jsonplaceholder.typicode.com/users/1
3
- //
4
1
// ArduinoJson - arduinojson.org
5
2
// Copyright Benoit Blanchon 2014-2017
6
3
// MIT License
4
+ //
5
+ // Example of an HTTP client parsing a JSON response.
6
+ //
7
+ // This program perform an HTTP GET of arduinojson.org/example.json
8
+ // Here is the expected response:
9
+ // {
10
+ // "sensor": "gps",
11
+ // "time": 1351824120,
12
+ // "data": [
13
+ // 48.756080,
14
+ // 2.302038
15
+ // ]
16
+ // }
17
+ // See http://arduinojson.org/assistant/ to compute the size of the buffer.
18
+ //
19
+ // Disclaimer: the code emphasize the communication between client and server,
20
+ // it doesn't claim to be a reference of good coding practices.
7
21
8
22
#include < ArduinoJson.h>
9
23
#include < Ethernet.h>
10
24
#include < SPI.h>
11
25
12
- EthernetClient client;
13
-
14
- const char * server = " jsonplaceholder.typicode.com" ; // server's address
15
- const char * resource = " /users/1" ; // http resource
16
- const unsigned long BAUD_RATE = 9600 ; // serial connection speed
17
- const unsigned long HTTP_TIMEOUT = 10000 ; // max respone time from server
18
- const size_t MAX_CONTENT_SIZE = 512 ; // max size of the HTTP response
19
-
20
- // The type of data that we want to extract from the page
21
- struct UserData {
22
- char name[32 ];
23
- char company[32 ];
24
- };
25
-
26
- // ARDUINO entry point #1: runs once when you press reset or power the board
27
26
void setup () {
28
- initSerial ();
29
- initEthernet ();
30
- }
27
+ Serial.begin (9600 );
28
+ while (!Serial);
31
29
32
- // ARDUINO entry point #2: runs over and over again forever
33
- void loop () {
34
- if (connect (server)) {
35
- if (sendRequest (server, resource) && skipResponseHeaders ()) {
36
- UserData userData;
37
- if (readReponseContent (&userData)) {
38
- printUserData (&userData);
39
- }
40
- }
41
- }
42
- disconnect ();
43
- wait ();
44
- }
45
-
46
- // Initialize Serial port
47
- void initSerial () {
48
- Serial.begin (BAUD_RATE);
49
- while (!Serial) {
50
- ; // wait for serial port to initialize
51
- }
52
- Serial.println (" Serial ready" );
53
- }
54
-
55
- // Initialize Ethernet library
56
- void initEthernet () {
30
+ echo (" Initialize Ethernet library" );
57
31
byte mac[] = {0xDE , 0xAD , 0xBE , 0xEF , 0xFE , 0xED };
58
- if (!Ethernet.begin (mac)) {
59
- Serial.println (" Failed to configure Ethernet" );
60
- return ;
61
- }
62
- Serial.println (" Ethernet ready" );
32
+ Ethernet.begin (mac) || die (" Failed to configure Ethernet" );
63
33
delay (1000 );
64
- }
65
34
66
- // Open connection to the HTTP server
67
- bool connect ( const char * hostName) {
68
- Serial. print ( " Connect to " );
69
- Serial. println (hostName );
35
+ echo ( " Connect to HTTP server" );
36
+ EthernetClient client;
37
+ client. setTimeout ( 10000 );
38
+ client. connect ( " arduinojson.org " , 80 ) || die ( " Connection failed " );
70
39
71
- bool ok = client.connect (hostName, 80 );
72
-
73
- Serial.println (ok ? " Connected" : " Connection Failed!" );
74
- return ok;
75
- }
76
-
77
- // Send the HTTP GET request to the server
78
- bool sendRequest (const char * host, const char * resource) {
79
- Serial.print (" GET " );
80
- Serial.println (resource);
81
-
82
- client.print (" GET " );
83
- client.print (resource);
84
- client.println (" HTTP/1.0" );
85
- client.print (" Host: " );
86
- client.println (host);
40
+ echo (" Send HTTP request" );
41
+ client.println (" GET /example.json HTTP/1.0" );
42
+ client.println (" Host: arduinojson.org" );
87
43
client.println (" Connection: close" );
88
- client.println ();
89
-
90
- return true ;
91
- }
92
-
93
- // Skip HTTP headers so that we are at the beginning of the response's body
94
- bool skipResponseHeaders () {
95
- // HTTP headers end with an empty line
96
- char endOfHeaders[] = " \r\n\r\n " ;
97
-
98
- client.setTimeout (HTTP_TIMEOUT);
99
- bool ok = client.find (endOfHeaders);
100
-
101
- if (!ok) {
102
- Serial.println (" No response or invalid response!" );
44
+ client.println () || die (" Failed to send request" );
45
+
46
+ echo (" Check HTTP status" );
47
+ char status[32 ] = {0 };
48
+ client.readBytesUntil (' \r ' , status, sizeof (status));
49
+ if (strcmp (status, " HTTP/1.1 200 OK" ) != 0 ) {
50
+ echo (status);
51
+ die (" Unexpected HTTP response" );
103
52
}
104
53
105
- return ok;
106
- }
107
-
108
- // Parse the JSON from the input string and extract the interesting values
109
- // Here is the JSON we need to parse
110
- // {
111
- // "id": 1,
112
- // "name": "Leanne Graham",
113
- // "username": "Bret",
114
- // "email": "Sincere@april.biz",
115
- // "address": {
116
- // "street": "Kulas Light",
117
- // "suite": "Apt. 556",
118
- // "city": "Gwenborough",
119
- // "zipcode": "92998-3874",
120
- // "geo": {
121
- // "lat": "-37.3159",
122
- // "lng": "81.1496"
123
- // }
124
- // },
125
- // "phone": "1-770-736-8031 x56442",
126
- // "website": "hildegard.org",
127
- // "company": {
128
- // "name": "Romaguera-Crona",
129
- // "catchPhrase": "Multi-layered client-server neural-net",
130
- // "bs": "harness real-time e-markets"
131
- // }
132
- // }
133
- bool readReponseContent (struct UserData * userData) {
134
- // Compute optimal size of the JSON buffer according to what we need to parse.
135
- // See http://arduinojson.org/assistant/
136
- const size_t BUFFER_SIZE =
137
- JSON_OBJECT_SIZE (8 ) // the root object has 8 elements
138
- + JSON_OBJECT_SIZE (5 ) // the "address" object has 5 elements
139
- + JSON_OBJECT_SIZE (2 ) // the "geo" object has 2 elements
140
- + JSON_OBJECT_SIZE (3 ) // the "company" object has 3 elements
141
- + MAX_CONTENT_SIZE; // additional space for strings
54
+ echo (" Skip HTTP headers" );
55
+ char endOfHeaders[] = " \r\n\r\n " ;
56
+ client.find (endOfHeaders) || die (" Invalid response" );
142
57
143
- // Allocate a temporary memory pool
58
+ echo (" Allocate JsonBuffer" );
59
+ const size_t BUFFER_SIZE = JSON_OBJECT_SIZE (3 ) + JSON_ARRAY_SIZE (2 ) + 60 ;
144
60
DynamicJsonBuffer jsonBuffer (BUFFER_SIZE);
145
61
62
+ echo (" Parse JSON object" );
146
63
JsonObject& root = jsonBuffer.parseObject (client);
64
+ if (!root.success ()) die (" Parsing failed!" );
147
65
148
- if (!root.success ()) {
149
- Serial.println (" JSON parsing failed!" );
150
- return false ;
151
- }
152
-
153
- // Here were copy the strings we're interested in
154
- strcpy (userData->name , root[" name" ]);
155
- strcpy (userData->company , root[" company" ][" name" ]);
156
- // It's not mandatory to make a copy, you could just use the pointers
157
- // Since, they are pointing inside the "content" buffer, so you need to make
158
- // sure it's still in memory when you read the string
66
+ echo (" Extract values" );
67
+ echo (root[" sensor" ].as <char *>());
68
+ echo (root[" time" ].as <char *>());
69
+ echo (root[" data" ][0 ].as <char *>());
70
+ echo (root[" data" ][1 ].as <char *>());
159
71
160
- return true ;
72
+ echo (" Disconnect" );
73
+ client.stop ();
161
74
}
162
75
163
- // Print the data extracted from the JSON
164
- void printUserData (const struct UserData * userData) {
165
- Serial.print (" Name = " );
166
- Serial.println (userData->name );
167
- Serial.print (" Company = " );
168
- Serial.println (userData->company );
169
- }
76
+ void loop () {}
170
77
171
- // Close the connection with the HTTP server
172
- void disconnect () {
173
- Serial.println (" Disconnect" );
174
- client.stop ();
78
+ void echo (const char * message) {
79
+ Serial.println (message);
175
80
}
176
81
177
- // Pause for a 1 minute
178
- void wait () {
179
- Serial. println ( " Wait 60 seconds " );
180
- delay ( 60000 ) ;
181
- }
82
+ bool die ( const char * message) {
83
+ Serial. println (message);
84
+ while ( true ); // loop forever
85
+ return false ;
86
+ }
0 commit comments