This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Bitcoin Price Index JSON Parsing TCP Client Example | |
* BDub @ Technobly.com 6/27/2014 | |
* LICENSE: MIT (C) 2014 BDub | |
* | |
*/ | |
#pragma SPARK_NO_PREPROCESSOR | |
#include "application.h" | |
#include "rest_client.h" | |
#include "jsmnSpark.h" | |
#define TOKEN_STRING(js, t, s) \ | |
(strncmp(js+(t).start, s, (t).end - (t).start) == 0 \ | |
&& strlen(s) == (t).end - (t).start) | |
#define TOKEN_PRINT(t) \ | |
Serial.print(", type: "); Serial.print((t).type); Serial.print(" size: "); Serial.print((t).size); \ | |
Serial.print(" start: "); Serial.print((t).start); Serial.print(" end: "); Serial.println((t).end) | |
/* IMPORTANT TO CHANGE THE NUMBER OF TOKENS TO MATCH YOUR DATA CLOSELY */ | |
#define NUM_TOKENS 23 | |
#define MAX_OBJ_SIZE 50 | |
#define HOSTNAME "api.coindesk.com" | |
int LED = D7; | |
RestClient client = RestClient(HOSTNAME); | |
String response; | |
uint8_t fwver[2]; | |
void setup() { | |
Serial.begin(9600); // Make sure serial terminal is closed before powering up Core | |
delay(2000); | |
Serial.flush(); | |
Serial.println(Network.SSID()); | |
Serial.println(Network.gatewayIP()); | |
Serial.println(Network.subnetMask()); | |
Serial.println(Network.localIP()); | |
Serial.println(Network.RSSI()); | |
nvmem_read_sp_version(fwver); | |
Serial.print("CC3000 Ver: "); | |
Serial.print(fwver[0]); | |
Serial.println(fwver[1]); | |
pinMode(LED, OUTPUT); | |
while(!Serial.available()) SPARK_WLAN_Loop(); // Open serial terminal now, and press ENTER | |
} | |
int i, r; | |
jsmn_parser p; | |
jsmntok_t tok[NUM_TOKENS]; | |
char obj[MAX_OBJ_SIZE]; | |
void loop() { | |
/* | |
// Press ENTER in your serial terminal to continue... | |
if (!Serial.available()) | |
return; | |
obj[0] = Serial.read(); // Flush the serial buffer to pause next time through | |
digitalWrite(LED, HIGH); | |
delay(1000); | |
*/ | |
response = ""; // Clear the response String | |
Serial.println("Try 6"); | |
// GET request | |
int statusCode = client.get("/v1/bpi/currentprice/USD.json", &response); | |
// Uncomment following line to force a test response, real response will not have all of these escaped characters | |
//response = "{\"time\":{\"updated\":\"Jun 27, 2014 04:17:00 UTC\",\"updatedISO\":\"2014-06-27T04:17:00+00:00\",\"updateduk\":\"Jun 27, 2014 at 05:17 BST\"},\"disclaimer\":\"This data was produced from the CoinDesk Bitcoin Price Index (USD). Non-USD currency data converted using hourly conversion rate from openexchangerates.org\",\"bpi\":{\"USD\":{\"code\":\"USD\",\"rate\":\"577.6150\",\"description\":\"United States Dollar\",\"rate_float\":577.615}}}"; | |
if(statusCode != 200) { | |
Serial.print("Error code from server: "); | |
Serial.println(statusCode); | |
return; | |
} | |
Serial.print("Response body from server: "); | |
Serial.println(response); | |
Serial.println(" "); | |
// Parse response from server | |
jsmn_init(&p); | |
r = jsmn_parse(&p, response.c_str(), tok, NUM_TOKENS); | |
// Determine status code | |
if (r == JSMN_SUCCESS) { | |
Serial.println("Parsed successfully."); | |
} | |
else if(r == JSMN_ERROR_INVAL) { | |
Serial.println("Bad token, JSON string is corrupted!"); | |
return; | |
} | |
else if(r == JSMN_ERROR_NOMEM) { | |
Serial.println("Not enough tokens, JSON string is too large! Increase NUM_TOKENS."); | |
return; | |
} | |
else if(r == JSMN_ERROR_PART) { | |
Serial.println("JSON string is too short, expecting more JSON data!"); | |
return; | |
} | |
else { | |
Serial.println("Parse failed! Unknown Error."); | |
return; | |
} | |
digitalWrite(LED, LOW); | |
delay(1000); | |
// Print out a list of Tokens | |
for (i = 0; i < NUM_TOKENS; i++) { | |
Serial.print("Token "); | |
Serial.print(i); | |
TOKEN_PRINT(tok[i]); | |
delay(10); | |
} | |
// Convert 17th token to string | |
i = 17; | |
strlcpy(obj, &response.c_str()[tok[i].start], (tok[i].end - tok[i].start + 1)); | |
Serial.print("\nToken["); Serial.print(i); Serial.print("]: "); | |
Serial.println(obj); // Print it out now just in case it's not the right one, | |
// we'll get and idea of where we are in the object | |
// Does this token == "rate" ? | |
if ( TOKEN_STRING(response.c_str(), tok[i], "rate") ) | |
{ | |
// Convert next token to string | |
i++; | |
strlcpy(obj, &response.c_str()[tok[i].start], (tok[i].end - tok[i].start + 1)); | |
// Convert string to double, contains numerical value of Bitcoin Price Index | |
double bpi = strtod(obj, NULL); | |
// Print double out to 4 decimal places | |
Serial.print("Token["); Serial.print(i); Serial.print("]: "); | |
Serial.println(bpi, 4); | |
// Take control of the RGB LED | |
RGB.control(true); | |
// Change the RGB's color to GREEN | |
RGB.color(0, 255, 0); | |
// Delay for one second | |
delay(1000); | |
// Release control of the RGB LED | |
RGB.control(false); | |
} | |
else { | |
Serial.println("'rate' token not found"); | |
} | |
delay(5000); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment