簡體   English   中英

Arduino-獲取響應並解析json數組的正確方法

[英]Arduino - Proper way to get response and parse a json array

這是我想做的事情 :我有一個帶有REST API的django應用程序。 其中一台路由器返回的json數組如下所示: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0] 1、0、0、0、0、0、0、0、0、0、0、0、3、0、0、1、1、0 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]並且大小始終相同,並且包含整數。

現在,我有一個Arduino Uno,上面有Adafruit cc3000 wifi屏蔽。 我設法連接到wifi,執行請求並打印結果,甚至將其保存為char *。

我的第一個問題是:

我很確定我沒有以正確的方式構造char數組(至少,這不是正確的方式,我沒有太多的C,C ++等經驗),如果這是一個借口)。 而且我認為這阻止了我解析json數組。

#include <ArduinoJson.h>
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include <Adafruit_NeoPixel.h>

int PIN = 6;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
StaticJsonBuffer<600> jsonBuffer;

#define ADAFRUIT_CC3000_IRQ   3  
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10

Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIVIDER);
#define WLAN_SSID       "mywifi"
#define WLAN_PASS       "mypwd"
#define WLAN_SECURITY   WLAN_SEC_WPA2
uint32_t ip = cc3000.IP2U32(00,00,00,00);


void setup(void)
{
  Serial.begin(9600);
  if (!cc3000.begin())
  {
    while(1);
  }
  strip.begin();
  strip.show();
  char *ssid = WLAN_SSID;
  Serial.print(F("\nAttempting to connect to "));
  Serial.println(ssid);
  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
  Serial.println("Connected to WiFi network!");

  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(3000);
  }
}


void loop(void){
  int lap = 0;
  if(!cc3000.checkConnected()){
    while(1){
    }
  }
  char *result;
  result  = send_request();
  result[71] = ']';
  JsonArray& root = jsonBuffer.parseArray(result);
  if (!root.success())
  {
    Serial.println("parseObject() failed");
  }
  while(lap<61){
    for (int i=0; i<24; i++){
      long is_free = root[i];
      if (is_free == 0){
        strip.setPixelColor(i, 255, 0, 0);
      }
      if(is_free == 1){
        strip.setPixelColor(i, 0, 255, 0);
      }
      if(lap % 2 ==0){
        if(is_free == 2){
          strip.setPixelColor(i, 0, 255, 0);
        }
        if(is_free == 3){
          strip.setPixelColor(i, 0, 255, 0);
        }
      }
      else{
        if(is_free == 2){
          strip.setPixelColor(i, 0, 0, 0);
        }
        if(is_free == 3){
          strip.setPixelColor(i, 0, 0, 0);
        }
      }
    }
    strip.setBrightness(15);
    strip.show();
    lap += 1;
    delay(1000);
  }  
}


char* send_request (void)
{
  char result[100];
  Serial.print(F("Initializing SendGET request\n"));
  Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 8000);

  if (client.connected()) {
    //starts client connection, checks for connection
    Serial.println(F("Adding state to DB\n"));
    client.println("GET /myurl/?format=json"); //download text
    client.println(F("Host: xx.xx.xx.xx"));
    client.println("Connection: close");  //close 1.1 persistent connection  
    client.println(); //end of get request
    Serial.println(F("Ending connection to DB\n"));
  } 
  else {
    Serial.println("Connection to server failed"); //error message if no client connect
    Serial.println();
  }
  int i = 0;
  while (client.connected()){
    while (client.available()) {
      if (i<71){
        //Read answer
        char c = client.read();
        result[i] = c ;
        i++;
      }
      else{
        client.close();
        return result;
      }
    }
  }
}

對我來說, send_request()確實很臟,因為我決定i必須小於71,因為我要打印的結果看起來像我想要的。 但是我認為數組的大小是錯誤的,這就是為什么我不能在loop()函數中解析它的原因。

請問這樣做的好,好,清晰,精確的方法是什么? 我已經嘗試了很多錯誤的想法,但我的想法已經耗盡。

第二個問題是:

如果我更換

char *result;
result[71] = ']';

通過result = "[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]"; 然后打印is_free ,我得到像這樣的隨機值:

91
49
44
32
48
44
32
48
44
32
48
44
32
48

等等

所以我的猜測是我只是沒有正確使用ArduinoJson,或者是我沒有在正確的位置查看其值。 我正在尋找有關的見解

感謝您的閱讀和將來的幫助!

您的代碼有多個問題,但是主要的問題是send_request函數返回一個指向局部變量的指針。 可變的result位於一個堆棧框架中,該堆棧框架可能會被接下來出現的任何堆棧框架覆蓋(我猜是函數loop ); 因此你看到的垃圾。

一種快速而骯臟的解決方案是更換:

char result[100];

通過:

static char result[100];

這會將result移到專用內存中,直到程序完成后才將其回收。

解析可能會失敗,因為您永遠不會終止字符串。 但是,在上述修復之后(靜態變量以null初始化)后,這可能不再是問題。 但是請確保在調用parseArray之前添加以下命令:

result[72] = '\0';

其他事宜:

  • 您的部分代碼丟失; 調用 setupsend_requestloop的主要功能在哪里? 感謝您的解釋。
  • while(1); 是一個無限循環,只會將您的Arduino變成烤面包機,什么也不會做; 那是故意的嗎?
  • long is_free = result[i]; 應該很 long is_free = root[i]; 感謝您相應地更改代碼; 我很確定這可以解決問題2。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM