Anfänger bracht hilfe um Daten von einer anderen Api auszulesen

Liebes Forum,

ich bräuchte Hilfe bei einen Arduino Sketch.
Ich habe folgenden Sketch erfolgreich installiert.

Jetzt möchte ich aber nicht den Bitcoin Preis auslesen sondern den von Crypto.com
Ich habe mir eine Api ausgesucht und den Sketch versucht anzupassen. Leider ohne Erfolg.
kann mir bitte jemand Helfen?

Neue Api:
https://api.kucoin.com/api/v1/market/orderbook/level1?symbol=CRO-USDT
"price" möchte ich gerne auslesen und auf dem Max7219 darstellen

Danke


#include <Arduino.h>

#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

const uint16_t WAIT_TIME = 1000;

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 5
#define CLK_PIN   D5
#define DATA_PIN  D7
#define CS_PIN    D2
#define BRIGHTNESS 1

// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary output pins
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
const char* ssid = "Philipp";
const char* password = "0123456789";
const char* host = "api.coindesk.com";

float previousValue = 0.00;
float threshold = 0.05;



void setup() {
  pinMode(D3, OUTPUT); //Price down
  pinMode(D4, OUTPUT); //Price up
  
  
  Serial.begin(9600);               
  delay(10);

  WiFi.begin(ssid, password);

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

}



void loop() {

  // Connect to API
  Serial.print("connecting to ");
  Serial.println(host);
  
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
  
  // We now create a URI for the request
  String url = "/v1/bpi/currentprice.json";
  
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
  delay(500); //geändert von 100
  
  // Read all the lines of the reply from server and print them to Serial
  String answer;
  while(client.available()){
    String line = client.readStringUntil('\r');
    answer += line;
  }

  client.stop();
  Serial.println();
  Serial.println("closing connection");

  // Process answer
  Serial.println();
  Serial.println("Answer: ");
  Serial.println(answer);

  // Convert to JSON
  String jsonAnswer;
  int jsonIndex;

  for (int i = 0; i < answer.length(); i++) {
    if (answer[i] == '{') {
      jsonIndex = i;
      break;
    }
  }

  // Get JSON data
  jsonAnswer = answer.substring(jsonIndex);
  Serial.println();
  Serial.println("JSON answer: ");
  Serial.println(jsonAnswer);
  jsonAnswer.trim();

  // Get rate as float
  int rateIndex = jsonAnswer.indexOf("rate_float");
  String priceString = jsonAnswer.substring(rateIndex + 12, rateIndex + 18);
  priceString.trim();
  float price = priceString.toFloat();
    
  // Print price
  Serial.println();
 
   Serial.println("Bitcoin price: "
);

Serial.println(price,0);

P.setIntensity(0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         );
P.setTextAlignment(PA_CENTER);

    P.print(String(price,0)+"$");
    
  
 
  
 


  // Init previous value 
  if (previousValue == 0.00) {
    previousValue = price;
  }

  // Alert down ?
  if (price < (previousValue - threshold)) {

    // Flash LED
    digitalWrite(D3, LOW);
    digitalWrite(D4, HIGH);
  }

  // Alert up ?
 if (price > (previousValue + threshold)) {

    // Flash LED
    digitalWrite(D4, LOW);
    digitalWrite(D3, HIGH);
  }
 
  // Store value
  previousValue = price;

  // Wait 1 minute
  delay(60000);


  }

  

Dort ist zu lesen:

Das bedeutet, das System will mit Dir per HTTPS und nicht mit HTTP kommkunizieren. Das ist Port 443 und Du brauchst einen Secure Client.
Ich habe dazu mal ein Tutorial erstellt, evtl. hilft es Dir weiter.

Gruß Tommy

1 Like

Basierend auf dem Link von Thommy habe ich für meinen ESP32 (ESP8266 habe ich nicht) ein Programm für Deine Preisabfrage geschrieben:

// ESP32
#define LED_BUILTIN 13
#include "zugangsdaten.h"
#include <Arduino_JSON.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>

WiFiClientSecure client;  // Use WiFiClientSecure class to create TLS connection

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  delay(500);
  Serial.println("\nStart ...");

  const char *ssid = STA_SSID;
  const char *pass = STA_PASSWORD;

  const char *host = "api.kucoin.com";
  String url = "/api/v1/market/orderbook/level1?symbol=CRO-USDT";
  const uint16_t port = 443;

  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_BUILTIN, 1);
    delay(250);
    digitalWrite(LED_BUILTIN, 0);
    delay(250);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  Serial.print("Connecting to ");
  Serial.println(host);

  Serial.println("Mit setInsecure()");
  client.setInsecure();                       // <--------------------------

  if (!client.connect(host, port)) {
    Serial.println("Connection failed");
    return;
  }

  HTTPClient http;

  //String answer = "{\"code\":\"200000\",\"data\":{\"time\":1664101750686,\"sequence\":\"2780341\",\"price\":\"0.1166\",\"size\":\"2.4467\",\"bestBid\":\"0.1165\",\"bestBidSize\":\"14250.7193\",\"bestAsk\":\"0.1166\",\"bestAskSize\":\"9223.9829\"}}";
  String answer;

  Serial.print("[HTTPS] begin...\n");
  if (http.begin(client, "https://api.kucoin.com/api/v1/market/orderbook/level1?symbol=CRO-USDT")) {

    Serial.print("[HTTPS] GET...\n");
    // start connection and send HTTP header
    int httpCode = http.GET();
    // httpCode will be negative on error
    if (httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      Serial.printf("[HTTPS] GET... code: %d\n", httpCode);

      // file found at server
      if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
        answer = http.getString();
        Serial.println(answer);
      }
    } else {
      Serial.printf("[HTTPS] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    }

    http.end();
  } else {
    Serial.printf("[HTTPS Unable to connect\n");
  }

  // Convert to JSON
  JSONVar myObject = JSON.parse(answer);
  // JSON.typeof(jsonVar) can be used to get the type of the var
  if (JSON.typeof(myObject) == "undefined") {
    Serial.println("Parsing input failed!");
  } else {
    Serial.print("myObject[\"price\"] = ");
    Serial.println((const char*) myObject["data"]["price"]);
    String tmp = (const char*) myObject["data"]["price"];
    tmp.replace("\"", "");
    float price = tmp.toFloat();

    Serial.println();
    Serial.print("price: ");
    Serial.println(price, 4);
  }
}

void loop() {}

Deine Vorlage fand ich nicht so toll, daher bin ich auf die Bibliothek Arduino_JSON (leider BETA) umgestiegen, geht aber sicherlich auch besser als in der Vorlage mit der anderen.

1 Like

Mit 2 anderen Libbezeichnungen dürfte es auch auf dem ESP8266 funktionieren.

#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#elif defined(ESP32)
#include <WiFi.h>
#include <HTTPClient.h>
#else
#error "Only ESP8266 or ESP32"
#endif

Gruß Tommy

Vielen Dank für eure schnelle Hilfe!
Ich habe jetzt den Sketch soweit fertig. Der aktuelle Preis wird angezeigt.
Leider aktualisiert er sich nicht.
Was muss ich machen das der Preis alle 5 Minuten aktualisiert wird?

grüße Philipp

#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#elif defined(ESP32)
#include <WiFi.h>
#include <HTTPClient.h>
#else
#error "Only ESP8266 or ESP32"
#endif
#define LED_BUILTIN 13
#include <Arduino_JSON.h>
#include <WiFiClientSecure.h>
#include <MD_Parola.h>
#include <MD_MAX72xx.h>

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 5
#define CLK_PIN   D5
#define DATA_PIN  D7
#define CS_PIN    D2
#define BRIGHTNESS 1

// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary output pins
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

WiFiClientSecure client;  // Use WiFiClientSecure class to create TLS connection

void setup() {

  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  delay(500);
  Serial.println("\nStart ...");

  const char* ssid = "Philipp";
const char* pass = "0123456789";
  const char *host = "api.kucoin.com";
  String url = "/api/v1/market/orderbook/level1?symbol=CRO-USDT";
  const uint16_t port = 443;

  P.begin();
    WiFi.persistent(false);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_BUILTIN, 1);
    delay(250);
    digitalWrite(LED_BUILTIN, 0);
    delay(250);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  
  Serial.print("Connecting to ");
  Serial.println(host);

  Serial.println("Mit setInsecure()");
  client.setInsecure();                       // <--------------------------

  if (!client.connect(host, port)) {
    Serial.println("Connection failed");
    return;
  }

  HTTPClient http;

  //String answer = "{\"code\":\"200000\",\"data\":{\"time\":1664101750686,\"sequence\":\"2780341\",\"price\":\"0.1166\",\"size\":\"2.4467\",\"bestBid\":\"0.1165\",\"bestBidSize\":\"14250.7193\",\"bestAsk\":\"0.1166\",\"bestAskSize\":\"9223.9829\"}}";
  String answer;

  Serial.print("[HTTPS] begin...\n");
  if (http.begin(client, "https://api.kucoin.com/api/v1/market/orderbook/level1?symbol=CRO-USDT")) {

    Serial.print("[HTTPS] GET...\n");
    // start connection and send HTTP header
    int httpCode = http.GET();
    // httpCode will be negative on error
    if (httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      Serial.printf("[HTTPS] GET... code: %d\n", httpCode);

      // file found at server
      if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
        answer = http.getString();
        Serial.println(answer);
      }
    } else {
      Serial.printf("[HTTPS] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    }

    http.end();
  } else {
    Serial.printf("[HTTPS Unable to connect\n");
  }

  // Convert to JSON
  JSONVar myObject = JSON.parse(answer);
  // JSON.typeof(jsonVar) can be used to get the type of the var
  if (JSON.typeof(myObject) == "undefined") {
    Serial.println("Parsing input failed!");
  } else {
    Serial.print("myObject[\"price\"] = ");
    Serial.println((const char*) myObject["data"]["price"]);
    String tmp = (const char*) myObject["data"]["price"];
    tmp.replace("\"", "");
    float price = tmp.toFloat();

    Serial.println();
    Serial.print("price: ");
    Serial.println(price, 3);

    P.setIntensity(0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         );
P.setTextAlignment(PA_CENTER);

    P.print(String(price,4)+"$");
      }
        // Wait 1 minute
  delay(60000);
      }

setup wird nur einmal durchlaufen.

Wo hast Du loop versteckt, da gehört ein Teil des Programms rein.

und was muss ich machen damit er das setup alle 5 Minuten wiederholt?

sorry das is so dumm Frage. Ich mache so etwas zum ersten mal.
Das Matrix Display zeigt immer den selben Preis an.

Alles was wiederholt ausgeführt werden soll, gehört in die Funktion loop.
Auch dein

damit es sich nicht dauernd, sondern nur einmal pro Minute, wiederholt.

Die Bibliothek ArduinoJson bietet die Möglichkeit, direkt mittels deserializeJson(doc, client); auf client zuzugreifen, also ohne Umweg über einen Text. Als Vorlage dient das Beispiel JsonHttpClient.ino der Bibliothek.

// nur mit ESP32 getestet
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#elif defined(ESP32)
#include <WiFi.h>
#include <HTTPClient.h>
#else
#error "Only ESP8266 or ESP32"
#endif

#include <WiFiClientSecure.h>
WiFiClientSecure client;  // Use WiFiClientSecure class to create TLS connection

const char *host = "api.kucoin.com";
const char *url = "/api/v1/market/orderbook/level1?symbol=CRO-USDT";
const uint16_t port = 443;

#define LED_BUILTIN 13
#include "zugangsdaten.h"
#include <ArduinoJson.h>

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  delay(500);
  // Serial.setDebugOutput(true);
  Serial.println("\nStart ...");

  const char *ssid = STA_SSID;
  const char *pass = STA_PASSWORD;

  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_BUILTIN, 1);
    delay(250);
    digitalWrite(LED_BUILTIN, 0);
    delay(250);
    Serial.print(".");
  }
  Serial.println("\nWiFi connected\nIP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  client.setInsecure();
  if (!client.connect(host, port)) {
    Serial.println(F("Connection failed"));
    return;
  }
  Serial.println(F("Connected!"));

  // Send HTTP request
  client.print(F("GET "));
  client.print(url);
  client.println(F(" HTTP/1.0"));
  client.print(F("Host: "));
  client.println(host);
  client.println(F("Connection: close"));
  if (client.println() == 0) {
    Serial.println(F("Failed to send request"));
    client.stop();
    return;
  }

  // Check HTTP status
  char status[32] = {0};
  client.readBytesUntil('\r', status, sizeof(status));
  // It should be "HTTP/1.0 200 OK" or "HTTP/1.1 200 OK"
  if (strcmp(status + 9, "200 OK") != 0) {
    Serial.print(F("Unexpected response: "));
    Serial.println(status);
    client.stop();
    return;
  }

  // Skip HTTP headers
  char endOfHeaders[] = "\r\n\r\n";
  if (!client.find(endOfHeaders)) {
    Serial.println(F("Invalid response"));
    client.stop();
    return;
  }

  DynamicJsonDocument doc(400);  // Allocate the JSON document. Use https://arduinojson.org/v6/assistant to compute the capacity.
  DeserializationError error = deserializeJson(doc, client);  // Parse JSON object
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  } else {
    Serial.println(doc["data"]["price"].as<const char*>());
    const char* sensor = doc["data"]["price"];
    float price = 0.0;
    sscanf(sensor, "%f", &price);
    // Print price
    Serial.print("price: ");
    Serial.println( price, 4 );
    Serial.println();
  }

  // Disconnect
  client.stop();
  delay(360000UL);
}

Ausgabe:

11:35:31.954 -> 
11:35:31.954 -> Start ...
11:35:32.592 -> .
11:35:32.592 -> WiFi connected
11:35:32.592 -> IP address: 
11:35:32.592 -> 192.168.178.22
11:35:33.642 -> Connected!
11:35:33.943 -> 0.1136
11:35:33.943 -> price: 0.1136
11:35:33.943 -> 
11:41:37.241 -> Connected!
11:41:37.542 -> 0.1132
11:41:37.542 -> price: 0.1132
11:41:37.542 -> 
11:47:38.622 -> Connected!
11:47:39.024 -> 0.1131
11:47:39.024 -> price: 0.1131
11:47:39.024 -> 
11:53:40.095 -> Connected!
11:53:40.496 -> 0.1129
11:53:40.496 -> price: 0.1129
11:53:40.496 -> 
1 Like

Vielen Dank für eure tolle Hilfe. Mein Projekt ist dank euch fertig geworden.

schöne Grüße
Philipp

1 Like

Vergebe ein paar Herzchen für die Helfer. Die haben sich echt ins Zeug gelegt.
Und dann markier den, der Dich zur Lösung geführt hat als Lösung. Hat die Nachwelt auch noch was von und wird in der Suchfunktion mitverwendet...

Glückwunsch und Danke fürs zeigen des fertigen Produkts.

Dank der Hilfe von @agmue konnten einige Beispiele meines Tutorials HTTPS mit ESP8266 auch für ESP32 getestet werden und können damit genutzt werden.
Leider können (bisher) nicht alle Varianten auch mit ESP32 genutzt werden, da ESPRESSIF beim ESP32 teilweise andere Wege geht.

Gruß Tommy

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.