Robofun 機器人論壇

標題: 想請問Arduino內的範例SimpleWebServerWiFi 的問題 [打印本頁]

作者: powq9764    時間: 2017-11-20 13:41
標題: 想請問Arduino內的範例SimpleWebServerWiFi 的問題
  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("Click <a href=\"/H\">here</a> turn the LED on pin 9 on<br>");
            client.print("Click <a href=\"/L\">here</a> turn the LED on pin 9 off<br>");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {    // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(9, HIGH);               // GET /H turns the LED on
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(9, LOW);                // GET /L turns the LED off
        }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }




想請問 c在這幾行程式中 扮演的是甚麼角色

以及  if (c == '\n')  else if (c != '\r')     currentLine += c;  

這些的用意是甚麼 光看後面的註解還是不太了解  

小弟新手 請求幫忙
作者: 超新手    時間: 2017-11-20 13:52
http 的命令都是以 "\r\n" 做結束
所以除了收到 '\r', 都必須把收到的字元依序存起來
currentLine += c;

而收到 '\n', 就表示已經收到一個完整的命令
就可以開始根據該命令, 去做應該做的事情


作者: powq9764    時間: 2017-11-20 14:05
超新手 發表於 2017-11-20 13:52
http 的命令都是以 "\r\n" 做結束
所以除了收到 '\r', 都必須把收到的字元依序存起來
currentLine += c;

原來如此

那如果我不想要Web功能了

是否就不需要  if (c == '\n')


還有 char c = client.read() 這個讀到的值 是什麼的值呢

目前使用MIT App Inventor

我把程式改成
if(client){
    Serial.println("new client");
    String currentLine = "";
    while (client.connected()){
      if (client.available()){
        char c = client.read();
        Serial.write(c);
        if (c == '\n'){
          if (currentLine.length() == 0){
            break;
          } else{
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
        if (currentLine.startsWith("GET /ON")){
          digitalWrite(11, HIGH);
        }
        if (currentLine.startsWith("GET /OFF")){
          digitalWrite(11, LOW);
        }
      }
    }
    client.stop();
    Serial.println("client disconnected");
  }

這樣做的話 能夠正常使用我想要的功能

但是貌似有很多多餘的 只是不太了解currentLine 這邊的意思

不太知道要從哪邊刪除下手

可以的話能稍微舉個範例嗎

像是c 收到 甚麼字元  跟 currentLine 的用處嗎
作者: 超新手    時間: 2017-11-20 14:31
本帖最後由 超新手 於 2017-11-20 16:15 編輯

>>那如果我不想要Web功能了
>>是否就不需要  if (c == '\n')
如果你是跑 HTTP 的話
還是需要 '\r\n'
否則你怎麼知道命令什麼時候結束?
>>還有 char c = client.read() 這個讀到的值 是什麼的值呢
這個值就是當你在瀏灠器的網址列輸入網址後, 按下 ENTER
瀏灠器就會送一堆資料過來, 例如
GET /index.html HTTP/1.1


而你所用的這個例子
就是(.....表示一堆資料)
............GET /H

............GET /L
每讀一個字元client.read(), 就會依收到
......'G', 'E', 'T', ' ', '/', 'H', '\r', '\n'
所以每收到一個字元
就用
currentLine += c;   
去一個字一個字結合起來
最後會得到
currentLine = "..........GET /H";   


因為網頁長這個樣子
Click <a href=\"/H\">here</a> turn the LED on pin 9 on<br>
Click <a href=\"/L\">here</a> turn the LED on pin 9 off<br>
所以當你按下了網頁的H 的 here  (或 L 的 here )
瀏灠器就需要去取得H這個網頁(或 L)


除非你不走 HTTP, 改用 TCP/IP
那就可以把 '\n' 一堆東西拿掉


作者: powq9764    時間: 2017-11-20 15:00
超新手 發表於 2017-11-20 14:31
>>那如果我不想要Web功能了
>>是否就不需要  if (c == '\n')
如果你是跑 HTTP 的話

原來如此  我大概了解了  我來改寫試試看

謝謝你的幫忙




歡迎光臨 Robofun 機器人論壇 (https://robofun.net/forum/) Powered by Discuz! X3.2