

## 発生している問題・エラーメッセージ

SpresenseのWi-Fi化を試みています。  
SpresenseにSPRESENSE用Wi-Fi add-onボードを取り付けて、値をスプレッドシートに送信したいのですが、HTTP/1.1 400
Bad Requestとなり、送れません。

ESPの場合、WiFiClientSecure.hが使えるので、データ送信できたのですが、SpresenseではWiFiClientSecure.hやESP8266WiFi.hが使えません。  
リクエストの仕方が間違っているのでしょうか。

SpresenseとWi-Fi add-onボードを使って、スプレッドシートに値を送信する方法を教えていただけませんでしょうか。

よろしくお願いいたします。  
長文で申し訳ございません。（プログラムの#defineの#が消えてしまい、文字サイズが大きく表示されてしまいました。）

SPRESENSE用Wi-Fi add-onボード：<https://www.switch-science.com/catalog/4042/>

## ソースコード

[code]

    // サンプルプログラム：SPRESENSE_ESP8266.inoを改良
    // https://github.com/tomorrow56/SPRESENSE_ESP8266
    // This is a super simple demo program for ESP8266's that can be used by SPRESENSE
    // Serial2 @ 115200 baud.
    
    #define SSID "ポケットWi-FiのSSID"      //your wifi ssid here
    #define PASS "パスワード"   //your wifi key here
    
    /* サンプルプログラムのコードをコメント化 */
    //  wifitest.adafruit.com/testwifi/index.html
    //#define HOST "wifitest.adafruit.com"
    //#define WEBPAGE "/testwifi/index.html"
    //#define PORT  "80"
    
    /* スプレッドシートにアクセスするために書き換え */
    #define HOST "script.google.com"
    char* WEBPAGE;
    #define PORT  "80"
    
    const char* ssGasID = "スプレッドシートのGasID";
    
    
    /* スプレッドシートに書き込む値 */
    float val1 = 0, val2 = 0, val3 = 0, val4 = 0, val5 = 0, val6 = 0, val7 = 0, val8 = 0, val9 = 0, val10 = 0;
    
    /* サンプルプログラムそのまま */
    #define LED_PIN LED0
    
    #define REPLYBUFFSIZ 0xFFFF
    char replybuffer[REPLYBUFFSIZ];
    uint8_t getReply(char *send, uint16_t timeout = 500, boolean echo = true);
    uint8_t espreadline(uint16_t timeout = 500, boolean multiline = false);
    boolean sendCheckReply(char *send, char *reply, uint16_t timeout = 500);
    
    enum {WIFI_ERROR_NONE = 0, WIFI_ERROR_AT, WIFI_ERROR_RST, WIFI_ERROR_SSIDPWD, WIFI_ERROR_SERVER, WIFI_ERROR_UNKNOWN};
    
    void setup()
    {
      pinMode(LED_PIN, OUTPUT);
    
      //blink LED0 to indicate power up
      for (int i = 0; i < 3; i++)
      {
        digitalWrite(LED_PIN, HIGH);
        delay(50);
        digitalWrite(LED_PIN, LOW);
        delay(100);
      }
    
      // Serial debug console
      Serial.begin(115200);
    
      //Open software serial for chatting to ESP
      Serial2.begin(115200);
    
      Serial.println(F("SPRESENSE ESP8266 Demo"));
    
      //connect to the wifi
      /* Wi-Fi接続 */
      byte err = setupWiFi();
    
      if (err) {
        // error, print error code
        Serial.print("setup error:");  Serial.println((int)err);
        debugLoop();
      }
    
      // success, print IP
      getIP();
    
      //set TCP server timeout
      //sendCheckReply("AT+CIPSTO=0", "OK");
    }
    
    
    boolean ESP_GETpage(char *host, uint16_t port, char *page) {
      String cmd = "AT+CIPSTART=\"TCP\",\"";
      cmd += host;
      cmd += "\",";
      cmd += port;
      cmd.toCharArray(replybuffer, REPLYBUFFSIZ);
    
      getReply(replybuffer);
    
      if (strcmp(replybuffer, "OK") != 0) {
        while (true) {
          espreadline(500);  // this is the 'echo' from the data
          Serial.print("<--- "); Serial.println(replybuffer);
          if (strstr(replybuffer, "OK"))
            break;
        }
      }
    
      delay(500);
    
      String request = "GET ";
      request += page;
      request += " HTTP/1.1\r\nHost: ";
      request += host;
      request += "\r\n\r\n";
    
      cmd = "AT+CIPSEND=";
      cmd += request.length();
      cmd.toCharArray(replybuffer, REPLYBUFFSIZ);
      sendCheckReply(replybuffer, ">");
    
      Serial.println("");
      Serial.print("Sending: "); Serial.println(request.length());
      Serial.println(F("*********SENDING*********"));
      Serial.print(request);
      Serial.println(F("*************************"));
      Serial.println("");
    
      request.toCharArray(replybuffer, REPLYBUFFSIZ);
    
      Serial2.println(request);
    
      while (true) {
        espreadline(3000);  // this is the 'echo' from the data
        Serial.print(">"); Serial.println(replybuffer); // probably the 'busy s...'
    
        // LOOK AT ALL THESE POSSIBLE ARBITRARY RESPONSES!!!
        if (strstr(replybuffer, "wrong syntax"))
          continue;
        else if (strstr(replybuffer, "ERROR"))
          continue;
        else if (strstr(replybuffer, "busy s..."))
          continue;
        else if (strstr(replybuffer, "OK"))
          break;
        //    else break;
      }
    
      //  if (! strstr(replybuffer, "SEND OK") ) return false;
    
      if (! strstr(replybuffer, "OK") ) return false;
    
      espreadline(50);
      Serial.print("3>"); Serial.println(replybuffer);
      if (char *s = strstr(replybuffer, "+IPD,")) {
        uint16_t len = atoi(s + 5);
        Serial.print(len); Serial.println(" bytes total");
      }
    
      unsigned long i = 0;
      while (1) {
        char c;
        if (Serial2.available()) {
          c = Serial2.read(); //UDR0 = c;
          //      Serial.write(c);
          replybuffer[i] = c;
          i++;
          delay(1);
          if (!Serial2.available()) {
            return true;
          }
        }
      }
      //while (1) {
      //  if (esp.available()) UDR0 = esp.read();
      //}
    }
    
    
    void loop()
    {
      /* 送信データを集めてURLを作成 */
      String url_write = "https://script.google.com/macros/s/";
      url_write += ssGasID;
    
      url_write += "/exec?";
      url_write += "1_cell=";
      url_write += String(val1);
      url_write += "&2_cell=";
      url_write += String(val2);
      url_write += "&3_cell=";
      url_write += String(val3);
      url_write += "&4_cell=";
      url_write += String(val4);
      url_write += "&5_cell=";
      url_write += String(val5);
      url_write += "&6_cell=";
      url_write += String(val6);
      url_write += "&7_cell=";
      url_write += String(val7);
      url_write += "&8_cell=";
      url_write += String(val8);
      url_write += "&9_cell=";
      url_write += String(val9);
      url_write += "&10_cell=";
      url_write += String(val10);
    
      Serial.print("SS書き込みURL："); Serial.println(url_write);
    
      WEBPAGE = url_write.c_str();
    
      Serial.print("WEBPAGE："); Serial.println(WEBPAGE);
    
    
      ESP_GETpage(HOST, 80, WEBPAGE);
    
      delay(100);
    
      Serial.println("");
      Serial.println(F("**********REPLY***********"));
      Serial.println(replybuffer);
      Serial.println(F("**************************"));
      Serial.println("");
    
      sendCheckReply("AT+CIPCLOSE", "OK");
      while (true) {
        espreadline(3000);  // this is the 'echo' from the data
        Serial.print(">"); Serial.println(replybuffer); // probably the 'busy s...'
    
        if (strstr(replybuffer, "busy s..."))
          continue;
        else break;
      }
    
      debugLoop();
    
      delay(1000);
    
      while (1);
    
    }
    
    
    boolean getVersion() {
    
      // Get version?
      getReply("AT+GMR", 100, true);
      while (true) {
        espreadline(50);  // this is the 'echo' from the data
        Serial.print("<--- "); Serial.println(replybuffer);
        if (strstr(replybuffer, "OK"))
          break;
      }
      return true;
    }
    
    
    /* ESP8266のリセット */
    boolean espReset() {
      Serial.println ("espReset");
    
      getReply("AT+RST", 1000, true);
      if (! strstr(replybuffer, "OK")) return false;
      delay(500);
    
      // turn off echo
      getReply("ATE0", 250, true);
    
      return true;
    }
    
    
    boolean ESPconnectAP(char *s, char *p) {
    
      getReply("AT+CWMODE=1", 500, true);
      if (! (strstr(replybuffer, "OK") || strstr(replybuffer, "no change")) )
        return false;
    
      String connectStr = "AT+CWJAP=\"";
      connectStr += SSID;
      connectStr += "\",\"";
      connectStr += PASS;
      connectStr += "\"";
      connectStr.toCharArray(replybuffer, REPLYBUFFSIZ);
      getReply(replybuffer, 200, true);
    
      while (true) {
        espreadline(200);  // this is the 'echo' from the data
        if ((String)replybuffer == "") {
          Serial.print(".");
        } else {
          Serial.println("");
          Serial.print("<--- "); Serial.println(replybuffer);
        }
        if (strstr(replybuffer, "OK"))
          break;
      }
    
      return true;
    }
    
    
    byte setupWiFi() {
    
      // reset WiFi module
      Serial.println(F("Soft resetting..."));
      if (!espReset())
        return WIFI_ERROR_RST;
    
      delay(500);
    
      Serial.println(F("Checking for ESP AT response"));
      if (!sendCheckReply("AT", "OK"))
        return WIFI_ERROR_AT;
    
      getVersion();
    
      Serial.print(F("Connecting to ")); Serial.println(SSID);
      if (!ESPconnectAP(SSID, PASS))
        return WIFI_ERROR_SSIDPWD;
    
      Serial.println(F("Single Client Mode"));
    
      if (!sendCheckReply("AT+CIPMUX=0", "OK"))
        return WIFI_ERROR_SERVER;
    
      return WIFI_ERROR_NONE;
    }
    
    
    boolean getIP() {
    
      getReply("AT+CIFSR", 100, true);
      while (true) {
        espreadline(50);  // this is the 'echo' from the data
        Serial.print("<--- "); Serial.println(replybuffer);
        if (strstr(replybuffer, "OK"))
          break;
      }
    
      delay(100);
    
      return true;
    }
    
    
    /************************/
    uint8_t espreadline(uint16_t timeout, boolean multiline) {
    
      uint16_t replyidx = 0;
    
      while (timeout--) {
        if (replyidx > REPLYBUFFSIZ - 1) break;
    
        while (Serial2.available()) {
          char c =  Serial2.read();
          if (c == '\r') continue;
          if (c == 0xA) {
            if (replyidx == 0)   // the first 0x0A is ignored
              continue;
    
            if (!multiline) {
              timeout = 0;         // the second 0x0A is the end of the line
              break;
            }
          }
          replybuffer[replyidx] = c;
          // Serial.print(c, HEX); Serial.print("#"); Serial.println(c);
          replyidx++;
        }
    
        if (timeout == 0) break;
        delay(1);
      }
      replybuffer[replyidx] = 0;  // null term
      return replyidx;
    }
    
    
    uint8_t getReply(char *send, uint16_t timeout, boolean echo) { 
    
      // flush input
      while (Serial2.available()) {
        Serial2.read();
        delay(1);
      }
    
      if (echo) {
        Serial.print("---> "); Serial.println(send);
      }
      Serial2.println(send);
    
      // eat first reply sentence (echo)
      uint8_t readlen = espreadline(timeout);
    
      //Serial.print("echo? "); Serial.print(readlen); Serial.print(" vs "); Serial.println(strlen(send));
    
      if (strncmp(send, replybuffer, readlen) == 0) {
        // its an echo, read another line!
        readlen = espreadline();
      }
    
      if (echo) {
        Serial.print ("<--- "); Serial.println(replybuffer);
      }
      return readlen;
    }
    
    
    boolean sendCheckReply(char *send, char *reply, uint16_t timeout) {
    
      getReply(send, timeout, true);
    
      /*
        for (uint8_t i=0; i<strlen(replybuffer); i++) {
         Serial.print(replybuffer[i], HEX); Serial.print(" ");
        }
        Serial.println();
        for (uint8_t i=0; i<strlen(reply); i++) {
         Serial.print(reply[i], HEX); Serial.print(" ");
        }
        Serial.println();
      */
      return (strcmp(replybuffer, reply) == 0);
    }
    
    
    void debugLoop() {
      Serial.println("========================");
      //serial loop mode for diag
      while (1) {
        if (Serial.available()) {
          Serial2.write(Serial.read());
          //      delay(1);
        }
        if (Serial2.available()) {
          Serial.write(Serial2.read());
          //      delay(1);
        }
      }
    }
    
[/code]

## 実行結果

[code]

    SPRESENSE ESP8266 Demo
    setupWiFi
    Soft resetting...
    espReset
    getReply
    ---> AT+RST
    espreadline
    espreadline
    <--- OK
    getReply
    ---> ATE0
    espreadline
    espreadline
    <--- OK
    Checking for ESP AT response
    sendCheckReply
    getReply
    ---> AT
    espreadline
    <--- OK
    getVersion
    getReply
    ---> AT+GMR
    espreadline
    <--- AT version:1.6.2.0(Apr 13 2018 11:10:59)
    espreadline
    <--- SDK version:2.2.1(6ab97e9)
    espreadline
    <--- compile time:Jun  7 2018 19:34:26
    espreadline
    <--- Bin version(Wroom 02):1.6.2
    espreadline
    <--- OK
    Connecting to ポケットWi-FiのSSID
    ESPconnectAP
    getReply
    ---> AT+CWMODE=1
    espreadline
    <--- OK
    getReply
    ---> AT+CWJAP="ポケットWi-FiのSSID","パスワード"
    espreadline
    espreadline
    <--- 
    espreadline
    .espreadline
    .espreadline
    .espreadline
    .espreadline
    .espreadline
    .espreadline
    .espreadline
    .espreadline
    .espreadline
    .espreadline
    .espreadline
    
    <--- WIFI CONNECTED
    espreadline
    .espreadline
    .espreadline
    .espreadline
    .espreadline
    
    <--- WIFI GOT IP
    espreadline
    .espreadline
    .espreadline
    .espreadline
    .espreadline
    .espreadline
    
    <--- OK
    Single Client Mode
    sendCheckReply
    getReply
    ---> AT+CIPMUX=0
    espreadline
    <--- OK
    getIP
    getReply
    ---> AT+CIFSR
    espreadline
    <--- +CIFSR:STAIP,"192.168.128.105"
    espreadline
    <--- +CIFSR:STAMAC,"b4:e6:2d:63:30:0c"
    espreadline
    <--- OK
    SS書き込みURL：https://script.google.com/macros/s/スプレッドシートのGasID/exec?1_cell=0.00&2_cell=0.00&3_cell=0.00&4_cell=0.00&5_cell=0.00&6_cell=0.00&7_cell=0.00&8_cell=0.00&9_cell=0.00&10_cell=0.00
    WEBPAGE：https://script.google.com/macros/s/スプレッドシートのGasID/exec?1_cell=0.00&2_cell=0.00&3_cell=0.00&4_cell=0.00&5_cell=0.00&6_cell=0.00&7_cell=0.00&8_cell=0.00&9_cell=0.00&10_cell=0.00
    getReply
    ---> AT+CIPSTART="TCP","script.google.com",80
    espreadline
    espreadline
    <--- OK
    sendCheckReply
    getReply
    ---> AT+CIPSEND=259
    espreadline
    espreadline
    <--- > 
    
    Sending: 259
    *********SENDING*********
    GET https://script.google.com/macros/s/スプレッドシートのGasID/exec?1_cell=0.00&2_cell=0.00&3_cell=0.00&4_cell=0.00&5_cell=0.00&6_cell=0.00&7_cell=0.00&8_cell=0.00&9_cell=0.00&10_cell=0.00 HTTP/1.1
    Host: script.google.com
    
    *************************
    
    espreadline
    >busy s...
    espreadline
    >Recv 259 bytes
    espreadline
    >SEND OK
    espreadline
    3>+IPD,1382:HTTP/1.1 400 Bad Request
    1382 bytes total
    
    **********REPLY***********
    Content-Type: text/html; charset=UTF-8
    Referrer-Policy: no-referrer
    Content-Length: 1555
    Date: Thu, 26 Mar 2020 07:20:26 GMT
    
    <!DOCTYPE html>
    <html lang=en>
      <meta charset=utf-8>
      <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
      <title>Error 400 (Bad Request)!!1</ti
    **************************
    
    sendCheckReply
    getReply
    ---> AT+CIPCLOSE
    espreadline
    <--- CLOSED
    espreadline
    >OK
    debugLoop ========================
    
[/code]


CC BY-SA 4.0
2020-03-27T02:22:45.513
64144
2020-03-29T16:38:33.050
2020-03-27T03:39:23.143
32986
35680
question
spresense google-spreadsheet
SPRESENSE Wi-Fi Add-onボードでスプレッドシートにデータを送信する方法


質問にURLが示されている"SPRESENSE用Wi-Fi add-onボード"のページには、『ESP-
WROOM-02（技適取得済）を搭載』と書かれていますので、WiFi add-onボードを使う場合はESPの場合と考えて良いのでは？

[SPRESENSE の Wi-Fi アドオンボードを動かしてみた！](https://makers-with-myson.blog.ss-
blog.jp/2019-03-17) のページを見ると、割と簡単に使えるように思えます。


CC BY-SA 4.0
2020-03-28T04:52:04.503
64175
2020-03-28T04:52:04.503
217
64144
answer


SPRESENSE の ESP-WROOM-02 向けのライブラリを次の github で公開していますので、もしよかったら使ってみてください。

<https://github.com/YoshinoTaro/ESP8266ATLib-for-Spresense>


CC BY-SA 4.0
2020-03-29T16:38:33.050
65208
2020-03-29T16:38:33.050
27334
64144
answer