Skip to content

Instantly share code, notes, and snippets.

@dmiddlecamp
Created July 21, 2014 19:35
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save dmiddlecamp/3affed45070bcefbfafd to your computer and use it in GitHub Desktop.
/*
* 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