Inspired by a similar weekend project, I decided to try to test my programming chops to build a simple/quick & dirty/fast & furious project that uses the ESP8266 ESPresso Lite V2 board to grab external JSON API (in this case I turn to Fixer.io) for a currency exchange website and display it on the OLED screen. In view that I tend to spent some time travelling to US, Malaysia, Indonesia and Thailand, it will be good to use these currencies as comparison against the SGD.
1. Hardware setup.As shown, the hardware setup is fairly easy: just plug the OLED display directly on top the built-in header on the ESPresso Lite V2 board.
#include <ESPert.h>
ESPert espert;
const char *host = "api.fixer.io";
const char *ssid = "xxxx"; //change to your own SSID
const char *password = "xxxx"; //change to your own password
const int httpPort = 80;
const char *path = "/latest?base=SGD"; //check out fixer.io for different JSON API
const int sleepTimeS = 43200; //wakes up every 12 hours
In this example, the real magic is in the codes. To make it easier for me to test the Arduino sketch, I included my Wi-Fi login credentials (SSID and password) directly so that it will be connected automatically instead of having to configure the Wi-Fi connection each time I upload the sketch to the board. And since the exchange rate does not fluctuate much throughout the day, I decided to make the device sleep most of the time and only wakes up to report the exchange rate at 12-hour intervals.
String exchange = espert.wifi.getHTTP(host, path); //get exchange rates from api.fixer.io
if (espert.json.init(exchange)) {
if (espert.json.containsKey("base")) {
espert.oled.clear();
espert.oled.println("CURRENCY EXCHANGE");
espert.oled.print("Base currency:");
espert.oled.println(espert.json.get("base"));
espert.oled.print("Date:");
espert.oled.println(espert.json.get("date"));
}
}
Using some useful functions espert.wifi.getHTTP(host,path)
, espert.json.init(<string>)
and espert.json.containsKey(<keyword>)
already built-in the ESPert library, I can grab and parse the JSON data directly. However it get tricky when dealing with nested array of data like below.
{"base":"SGD","date":"2016-07-29","rates":{"AUD":0.98448,"BGN":1.3026,"BRL":2.4294,"CAD":0.97522,"CHF":0.72081,"CNY":4.9223,"CZK":18.003,"DKK":4.9533,"GBP":0.5621,"HKD":5.7416,"HRK":4.9867,"HUF":207.92,"IDR":9696.8,"ILS":2.8301,"INR":49.555,"JPY":76.477,"KRW":830.39,"MXN":14.005,"MYR":3.0103,"NOK":6.3331,"NZD":1.04,"PHP":34.919,"PLN":2.9058,"RON":2.974,"RUB":49.609,"SEK":6.3718,"THB":25.782,"TRY":2.2326,"USD":0.74013,"ZAR":10.476,"EUR":0.666}}
Using an example borrowed from marcoschwartz, I managed to solve the problem by breaking down the JSON data into individual substrings can count their relative positions to the currency keyword to obtain the exchange rates.
String jsonExchange;
int jsonIndex;
for (int i = 0; i < exchange.length(); i++) {
if (exchange[i] == '{') {
jsonIndex = i;
break;
}
}
jsonExchange = exchange.substring(jsonIndex);
jsonExchange.trim();
int rateIndexUS = jsonExchange.indexOf("USD");
int rateIndexINR = jsonExchange.indexOf("INR");
int rateIndexMYR = jsonExchange.indexOf("MYR");
int rateIndexTHB = jsonExchange.indexOf("THB");
String priceStringUS = jsonExchange.substring(rateIndexUS + 5, rateIndexUS +11);
String priceStringMYR = jsonExchange.substring(rateIndexMYR + 5, rateIndexMYR +10);
String priceStringINR = jsonExchange.substring(rateIndexINR + 5, rateIndexINR +10);
String priceStringTHB= jsonExchange.substring(rateIndexTHB + 5, rateIndexTHB +10);
priceStringUS.trim();
priceStringMYR.trim();
priceStringINR.trim();
priceStringTHB.trim();
float priceUS = priceStringUS.toFloat();
float priceINR = priceStringINR.toFloat();
float priceMYR = priceStringMYR.toFloat();
float priceTHB = priceStringTHB.toFloat();
espert.oled.print("USD:");
espert.oled.println(priceUS);
espert.oled.print("INR:");
espert.oled.println(priceINR);
espert.oled.print("MYR:");
espert.oled.println(priceMYR);
espert.oled.print("THB:");
espert.oled.println(priceTHB);
Another feature which can easily added is the smartphone notification. As the OLED display the rates, it will also send a similar message to your smartphone, as shown below.
You can added the following code that will trigger the string of message to be pushed to your smartphone.
String message = "Currency Exchange Rate: SGD/USD: " + (String)(priceUS) + " "+ "SGD/INR: " + (String)(priceINR) + " " + "SGD/MYR: " + (String)(priceMYR) + " " +"SGD/THB:" + (String)(priceTHB);
message.replace(String(" "), String("%20"));
String path = "/MySmartphone/send?key=" + smartphone_key + "&message=" + message;
espert.println(">>" + espert.wifi.getHTTP(mqhost, path.c_str()) + "<<");
delay(30000);
espert.oled.clear();
You will need to also declare the following variable earlier in the sketch:
String smartphone_key = "xxxxxx"; //change to your own smartphone key. Check out www.espert.io
You can refer to this link for more information regarding creation of the cloud account and obtaining the smartphone key.
Of course if you have a much better and efficient way to reduce repetitive lines of codes, do let me know. Thank you and have a good weekend.
Comments