Introduction: REAL TIME BITCOIN-TICKER (POV)

About: Lets make world a better place :)

Crypto Currencies have grabbed huge attention in the past year due to their rapidly increasing price. And many people has invested in these crypto currencies. Therefore an idea came to my mind to make a real time btc-ticker which will update the user with the price every next minute. This will make the trading more efficient.

As POV displays are attractive and can be placed anywhere on the office table or as a showpiece on the showcase. Therefore I decided to make a btc-ticker using NodeMcu and POV display

Its very Easy and Quick to make. Lets learn HOW?

Step 1: Parts, Supplies and Tools

Hardware Required

  • General Purpose Board
  • Ice-Cream sticks ( 3 nos.)
  • DC-Motor Assembly
  • LEDS-5mm (5 nos,)
  • Connecting Wires
  • Node MCU 1.0
  • Li-Po Battery
  • Solder Iron
  • Wire Cutter
  • Solder Wire
  • Glue Gun
  • Epoxy Glue
  • Wooden sheets
  • Nails
  • Aluminum Foil
  • Measuring tape

  • Bugstrips

Software Required

  • Coindesk API
  • Arduino IDE

Arduino Libraries

  • ESP8266WiFi
  • ArduinoJson

Step 2: How Does It Work?

What is POV(Persistence of Vision)?

It can be defined in simple words. When a person sees an object, its image remains in the retina of the eye for a time interval of 1/16th of a second. This phenomenon is known as persistence of vision.

This phenomenon is used in the POV Display to form images. We turn the LEDs on and off in such a way that the different images overlap each other forming letters. For example:

Arduino POV display Formation of letter “E” with 5 LEDs

1 2 3 <– Time

1 1 1 <– Bulb 1

1 0 0 <– Bulb 2

1 1 1 <– Bulb 3

1 0 0 <– Bulb 4

1 1 1 <– Bulb 5

Each row represents the 5 LEDs we use to make the Arduino POV display and each column is a time interval. Each element in the row represents the state of the LED at that given time.

At t = 1 Bulbs 1,2,3,4,5 are ON

At t = 2 Bulbs 1,3,5 are ON

This way we can visually see the letter E formed by the LEDs but the time interval would be very small in milliseconds. Due to the short time intervals and the ability of the LEDs to turn ON and OFF very quickly we can see the letter E as all the 3 images merge. As the motor is spinning and time passes, each LED moves from one position to the next, so all these images merge together.

Step 3: Getting Started With NodeMCU

Firstly open the Arduino IDE

Go to files and click on the preference in the Arduino IDE

copy the below code in the Additional boards Manager

http://arduino.esp8266.com/stable/package_esp8266com_index.json

click OK to close the preference Tab.

After completing the above steps , go to Tools and board, and then select board Manager

Navigate to esp8266 by esp8266 community and install the software for Arduino.Once all the above process been completed we are read to program our esp8266 with Arduino IDE.For this example I have used NodeMCU esp8266 and if you are using any other vendor wifi chips or generic wifi module please check with the esp8266 Pin mapping which is very essential to make things works.The reason why I used D7 pin for this example is , I uploaded the basic blink program that comes with the examples program in the arduino IDE which is connected with 13 pin of arduino. The 13th pin is mapped into D7 pin of NodeMCU.go to board and select the type of esp8266 you are using. and select the correct COM port to run the program on your esp8266 device.

Step 4: Making the Circuit for the Portable NodeMCU POV Display

  • Choose the ice cream sticks as per the length you want. Stick them together as shown in the pictures using hot glue or epoxy glue. Now cut a small square from GPB and make a hole in the middle of it. Be careful while making the hole or else it will become loose enough to get fit with the motor assembly.
  • Now Stick this GPB exactly at the center of the Ice Cream Sticks formation as shown in pictures. Now make 5 pair of small holes for the LEDs. You can make these holes using a needle or any sharp object available. Just make sure that the holes made are at equal distance for proper vision. On the other side of Sticks formation Stick Node MCU and Battery with Hot Glue as shown in pictures

Soldering Part : First of all connect all the Grounds (the small pin) of all LEDs with each other and Solder a Black Wire with it for Common Ground to Node MCU. Now Solder Each LED using connecting Wire with Pins Shown Below.

Connections (You can modify it by changing the necessary Code) :

LED 1 > Digital Pin 1 (05)

LED 2 > Digital Pin 0 (16)

LED 3 > Digital Pin 3 (00)

LED 4 > Digital Pin 2 (04)

LED 5 > Digital Pin 4 (02)

Step 5: Getting the Wooden Stand Ready

To Provide the POV Setup a certain height we have to make a wooden stand. It also provides stability to rotary part.

First Cut out four equal Rectangular Parts of a desired length. For the base cut out a Big Square of around 40*40 cm. Also cut a small piece to cover the top of the wooden stand. Now to create wooden stand joint all four Rectangular Parts as shown in pictures.

Now Place it exactly at the center of the Square Piece. And also cover the top with small one.

Step 6: Placing the Rotary Assembly on the Wooden Stand

  • First Connect the GPB and Ice Scream Stick assembly on the Shaft of the Motor Assembly.
  • Now Place this whole assembly on the Wooden Stand using Hot Glue.
  • Solder 2 wires with the motor to provide it power. Now Connect this motor wires with the power adapter and switch.
  • Use this switch to turn on and off the rotation of motors.

Step 7: CODEEEE

Here the coding part begins..!!

Fetching the API :

  • Here we have used Coindesk API to Fetch the current Value of the bitcoin. You also have to copy SSH fingerprint for HTTPS Connection to coindesk server.
  • By Understanding the Concept of POV , we had written the code.

Changes in Code :

  • To use this code you have to just change the delay in the displayString() Function.
  • To change the width of the letters printed change the value of delayTime in code.
  • To change the Space between letters change the value of charBreak in code.
  • And to change the Currency Mode Just replace it with your currency instead of USD.

For Example : For USD : String bitcoin = root["bpi"]["USD"]["rate_float"];

For EUR: String bitcoin = root["bpi"]["EUR"]["rate_float"];

Code :

<p>/****************************<br>Name:         Kathan Patel,Karanveer,Avan Chaudhari
Date:         1/15/2018
Description:  This program uses the ESP2866 and Custom POV Device to display current Bitcoin
              prices every 10 minutes.
License:      MIT License
******************************/

#include  <ESP8266WiFi.h> 
#include  <WiFiClientSecure.h>
#include  <ArduinoJson.h>
#include  <string.h>

// API of Coin Desk website to fetch Price JSON
#define COIN_DESK "api.coindesk.com"

// Wifi Login in
const char* ssid     = "Your SSID";
const char* password = "Your Password";

// Times for delay
const unsigned long SECOND = 1000;
const unsigned long HOUR = 3600*SECOND;
int delayTime = 1.2;
int charBreak = 1.2;

//LED Pins Define
int LED1 =05;                           //LED1 Pin On Node MCU
int LED2 =16;                           //LED2 Pin On Node MCU
int LED3 =00;                           //LED3 Pin On Node MCU
int LED4 =04;                           //LED4 Pin On Node MCU
int LED5 =02;                           //LED5 Pin ON Node MCU

void setup(){
// Outputs serial to 115200 for debugging
Serial.begin(115200);

// Connects to wifi
WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
      }

Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());

//Set all LED Pins as Output  
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
}

// Used to store the JSON file from Coin Base
static char jsonBuf[4096];

char bitcoinfetched[50];    

// showBusTimes function
bool showBitcoinPrice(char *json);

int a1[] = {1, 17, 31, 1, 1};
int a2[] = {23, 21, 21, 21, 29};
int a3[] = {17, 21, 21, 21, 31};
int a4[] = {0, 28, 4, 31, 0};
int a5[] = {23, 21, 21, 21, 23};
int a6[] = {31, 21, 21, 21, 23};
int a7[] = {16, 24, 24, 31, 0};
int a8[] = {31, 21, 21, 21, 31};
int a9[] = {25, 21, 21, 21, 31};
int a0[] = {14, 17, 17, 14, 0};
int a[] = {1, 6, 26, 6, 1};
int b[] = {31, 21, 21, 10, 0};
int c2[] = {14, 17, 17, 10, 0};
int d[] = {31, 17, 17, 14, 0};
int e[] = {31, 21, 21, 17, 0};
int f[] = {31, 20, 20, 16, 0};
int g[] = {14, 17, 19, 10, 0};
int h[] = {31, 4, 4, 4, 31};
int i[] = {0, 17, 31, 17, 0};
int j[] = {0, 17, 30, 16, 0};
int k[] = {31, 4, 10, 17, 0};
int l[] = {31, 1, 1, 1, 0};
int m[] = {31, 12, 3, 12, 31};
int n[] = {31, 12, 3, 31, 0};
int o[] = {14, 17, 17, 14, 0};
int p[] = {31, 20, 20, 8, 0};
int q[] = {14, 17, 19, 14, 2};
int r[] = {31, 20, 22, 9, 0};
int s[] = {8, 21, 21, 2, 0};
int t[] = {16, 16, 31, 16, 16};
int u[] = {30, 1, 1, 30, 0};
int v[] = {24, 6, 1, 6, 24};
int w[] = {28, 3, 12, 3, 28};
int x[] = {17, 10, 4, 10, 17};
int y[] = {17, 10, 4, 8, 16};
int z[] = {19, 21, 21, 25, 0};

int eos[] = {0, 1, 0, 0, 0};
int excl[] = {0, 29, 0, 0, 0};
int ques[] = {8, 19, 20, 8, 0};

void displayLine(int line){
int myline;
myline = line;
if (myline>=16) {digitalWrite(LED1, HIGH); myline-=16;} else {digitalWrite(LED1, LOW);}
if (myline>=8)  {digitalWrite(LED2, HIGH); myline-=8;}  else {digitalWrite(LED2, LOW);}
if (myline>=4)  {digitalWrite(LED3, HIGH); myline-=4;}  else {digitalWrite(LED3, LOW);}
if (myline>=2)  {digitalWrite(LED4, HIGH); myline-=2;}  else {digitalWrite(LED4, LOW);}
if (myline>=1)  {digitalWrite(LED5, HIGH); myline-=1;}  else {digitalWrite(LED5, LOW);}
}

void displayChar(char c){
if (c == '1'){for (int i = 0; i <5; i++){displayLine(a1[i]);delay(delayTime);}displayLine(0);}
if (c == '2'){for (int i = 0; i <5; i++){displayLine(a2[i]);delay(delayTime);}displayLine(0);}
if (c == '3'){for (int i = 0; i <5; i++){displayLine(a3[i]);delay(delayTime);}displayLine(0);}
if (c == '4'){for (int i = 0; i <5; i++){displayLine(a4[i]);delay(delayTime);}displayLine(0);}
if (c == '5'){for (int i = 0; i <5; i++){displayLine(a5[i]);delay(delayTime);}displayLine(0);}
if (c == '6'){for (int i = 0; i <5; i++){displayLine(a6[i]);delay(delayTime);}displayLine(0);}
if (c == '7'){for (int i = 0; i <5; i++){displayLine(a7[i]);delay(delayTime);}displayLine(0);}
if (c == '8'){for (int i = 0; i <5; i++){displayLine(a8[i]);delay(delayTime);}displayLine(0);}
if (c == '9'){for (int i = 0; i <5; i++){displayLine(a9[i]);delay(delayTime);}displayLine(0);}
if (c == '0'){for (int i = 0; i <5; i++){displayLine(a0[i]);delay(delayTime);}displayLine(0);}
if (c == 'a'){for (int i = 0; i <5; i++){displayLine(a[i]);delay(delayTime);}displayLine(0);}
if (c == 'b'){for (int i = 0; i <5; i++){displayLine(b[i]);delay(delayTime);}displayLine(0);}
if (c == 'c2'){for (int i = 0; i <5; i++){displayLine(c2[i]);delay(delayTime);}displayLine(0);}
if (c == 'd'){for (int i = 0; i <5; i++){displayLine(d[i]);delay(delayTime);}displayLine(0);}
if (c == 'e'){for (int i = 0; i <5; i++){displayLine(e[i]);delay(delayTime);}displayLine(0);}
if (c == 'f'){for (int i = 0; i <5; i++){displayLine(f[i]);delay(delayTime);}displayLine(0);}
if (c == 'g'){for (int i = 0; i <5; i++){displayLine(g[i]);delay(delayTime);}displayLine(0);}
if (c == 'h'){for (int i = 0; i <5; i++){displayLine(h[i]);delay(delayTime);}displayLine(0);}
if (c == 'i'){for (int it = 0; it <5; it++){displayLine(i[it]);delay(delayTime);}displayLine(0);}
if (c == 'j'){for (int i = 0; i <5; i++){displayLine(j[i]);delay(delayTime);}displayLine(0);}
if (c == 'k'){for (int i = 0; i <5; i++){displayLine(k[i]);delay(delayTime);}displayLine(0);}
if (c == 'l'){for (int i = 0; i <5; i++){displayLine(l[i]);delay(delayTime);}displayLine(0);}
if (c == 'm'){for (int i = 0; i <5; i++){displayLine(m[i]);delay(delayTime);}displayLine(0);}
if (c == 'n'){for (int i = 0; i <5; i++){displayLine(n[i]);delay(delayTime);}displayLine(0);}
if (c == 'o'){for (int i = 0; i <5; i++){displayLine(o[i]);delay(delayTime);}displayLine(0);}
if (c == 'p'){for (int i = 0; i <5; i++){displayLine(p[i]);delay(delayTime);}displayLine(0);}
if (c == 'q'){for (int i = 0; i <5; i++){displayLine(q[i]);delay(delayTime);}displayLine(0);}
if (c == 'r'){for (int i = 0; i <5; i++){displayLine(r[i]);delay(delayTime);}displayLine(0);}
if (c == 's'){for (int i = 0; i <5; i++){displayLine(s[i]);delay(delayTime);}displayLine(0);}
if (c == 't'){for (int i = 0; i <5; i++){displayLine(t[i]);delay(delayTime);}displayLine(0);}
if (c == 'u'){for (int i = 0; i <5; i++){displayLine(u[i]);delay(delayTime);}displayLine(0);}
if (c == 'v'){for (int i = 0; i <5; i++){displayLine(v[i]);delay(delayTime);}displayLine(0);}
if (c == 'w'){for (int i = 0; i <5; i++){displayLine(w[i]);delay(delayTime);}displayLine(0);}
if (c == 'x'){for (int i = 0; i <5; i++){displayLine(x[i]);delay(delayTime);}displayLine(0);}
if (c == 'y'){for (int i = 0; i <5; i++){displayLine(y[i]);delay(delayTime);}displayLine(0);}
if (c == 'z'){for (int i = 0; i <5; i++){displayLine(z[i]);delay(delayTime);}displayLine(0);}
if (c == '!'){for (int i = 0; i <5; i++){displayLine(excl[i]);delay(delayTime);}displayLine(0);}
if (c == '?'){for (int i = 0; i <5; i++){displayLine(ques[i]);delay(delayTime);}displayLine(0);}
if (c == '.'){for (int i = 0; i <5; i++){displayLine(eos[i]);delay(delayTime);}displayLine(0);}
delay(charBreak);
}

void displayString(char* s){
for (int i = 0; i<=strlen(s); i++){
displayChar(s[i]);
}
delay(186.9);
}

bool showBitcoinPrice(char *json)
{
StaticJsonBuffer<3*1024> jsonBuffer;

// Skip characters until first '{' found
char *jsonStart = strchr(json, '{');

// Checks to see if jsonStart is empty
if (jsonStart == NULL) {
  Serial.println(F("JSON data missing"));
  return false;
 }

json = jsonStart;

// Parse json file
JsonObject& root = jsonBuffer.parseObject(json);

// Throws an error if json is not properly parsed
if (!root.success()) {
  Serial.println(F("jsonBuffer.parseObject() failed"));
  return false;
   }

// Extracts the data in USD
String bitcoin = root["bpi"]["USD"]["rate_float"];
Serial.println(bitcoin);

// Prints to screen
for(int i = 0;i < bitcoin.length(); i++) {

// Breaks if we reach a decimal point (bit lazy)
if(bitcoin[i]=='.'){break;}

    }
bitcoin.toCharArray(bitcoinfetched, 50);     
return true;
}

void loop(){

// Connect through port 443
const int httpsPort = 443;
const char* fingerprint = "CF 05 98 89 CA FF 8E D8 5E 5C E0 C2 E4 F7 E6 C3 C7 50 DD 5C";

// Use WiFiClientSecure class to create TLS connection
WiFiClientSecure httpclient;
Serial.print("connecting to ");
Serial.println(COIN_DESK);
if (!httpclient.connect(COIN_DESK, httpsPort)) {
    Serial.println("connection failed");
    return;
   }
displayString(bitcoinfetched);

// Requests URL data
httpclient.print(String("GET ") + "/v1/bpi/currentprice.json" + " HTTP/1.1\r\n" +
               "Host: " + COIN_DESK + "\r\n" +
               "User-Agent: BuildFailureDetectorESP8266\r\n" +
               "Connection: close\r\n\r\n");

Serial.println("request sent");
// Collect http response headers and content from Coin Base
// HTTP headers are discarded.
// The content is formatted in JSON and is left in jsonBuf.
int jsonLen = 0;
bool skip_headers = true;
while (httpclient.connected() || httpclient.available()) {
    if (skip_headers) {
      String aLine = httpclient.readStringUntil('\n');
      //Serial.println(aLine);
      // Blank line denotes end of headers
      if (aLine.length() <= 1) {
        skip_headers = false;
     }
  }
   else {
      int bytesIn;
      bytesIn = httpclient.read((uint8_t *)&jsonBuf[jsonLen], sizeof(jsonBuf) - jsonLen);
      Serial.print(F("bytesIn ")); Serial.println(bytesIn);
      if (bytesIn > 0) {
        jsonLen += bytesIn;
        if (jsonLen > sizeof(jsonBuf)) jsonLen = sizeof(jsonBuf);
      }
      else if (bytesIn < 0) {
        Serial.print(F("read error "));
        Serial.println(bytesIn);
      }
    }
    delay(1);
  }
displayString(bitcoinfetched);

httpclient.stop();
showBitcoinPrice(jsonBuf);

// Starts the showBitcoinPrice function
for(int wait = 0; wait < 120; wait++)
  {

   displayString(bitcoinfetched);
    delay(10);
  }

}

Step 8: FINISHED PRODUCT

This now can be placed anywhere where you can constantly have the constant vision.

examples :

  • On the office table.
  • In the living room etc,
Arduino Contest 2017

Participated in the
Arduino Contest 2017

LED Contest 2017

Participated in the
LED Contest 2017