2013-12-24 50 views
2

我正在研究一個小型的Arduino項目,當一個新的追隨者獲得時,它將使LED燈閃爍。顯然,我在這方面受到了部分Twitter規則的限制(來自服務器的請求數量等),但我找到了一種可能使其工作的方法。新推特追隨者閃爍LED

我有一個PHP腳本,用於檢查我擁有的關注者數量。腳本第一次運行時,如果沒有文件存在,它將創建一個文本文件,其中追隨者的數量是該文件的唯一內容。如果我有42個追隨者,那麼這個文件將包含42而沒有別的。在後續運行中,該腳本檢查文件的內容是否與新的跟隨者計數匹配。如果是這樣,它不會對文件執行任何操作並輸出n。如果數字不匹配(意味着我獲得了新的追隨者),那麼我更新文本文件並輸出y

在Arduino方面,我只是檢查腳本頁面的輸出是否包含yn,意圖是前者導致我的LED閃爍。

兩個問題我運行到:

通常,當我從腳本文件本身,在n一個響應的情況下閱讀,我越來越喜歡輸出:

1 
n 
0 

這很奇怪,1和0從哪裏來?它們在頁面輸出本身中不可見。我已經儘可能將編碼類型設置爲plain/text。當我從普通的文本文件中讀取時,我只能得到文件的內容(在這種情況下,它將是n)。

我面對的另一個問題是,有時,而不是獲得上述輸出,我得到整個HTTP響應。那就是:

HTTP/1.1 200 OK 
Date: Tue, 24 Dec 2013 04:03:32 GMT 
Server: Apache 
X-Powered-By 

你要知道,它停在那裏我的輸出,因爲我有y代碼檢查。這顯然是有缺陷的,但我希望能儘快解決第一個問題。這就是說,爲什麼它有時會給我這樣的整個HTTP響應?

所以問題是:我的代碼有什麼問題導致了這個?如果是這樣,我如何修改它以更好地讀取我喜歡的HTTP響應?

這將是沒有代碼一個無用的問題,所以這裏是(當然沒有互聯網登錄信息...我也掛在這裏 - CODE):

#include <SPI.h> 
#include <WiFi.h> 
#include <Twitter.h> 

int led = 13; 

char ssid[] = ""; // your network SSID (name) 
char pass[] = ""; // your network password (use for WPA, or use as key for WEP) 

int keyIndex = 0;   // your network key Index number (needed only for WEP) 

int status = WL_IDLE_STATUS; // status of the wifi connection 

// initialize the library instance: 
WiFiClient client; 

const unsigned long requestInterval = 30*1000; // delay between requests; 30 seconds 

// if you don't want to use DNS (and reduce your sketch size) 
// use the numeric IP instead of the name for the server: 
//IPAddress server(199,59,149,200); // numeric IP for api.twitter.com 
char server[] = "raw-d.com";  // name address for twitter API 

boolean requested;      // whether you've made a request since connecting 
unsigned long lastAttemptTime = 0;  // last time you connected to the server, in milliseconds 

String currentLine = "";    // string to hold the text from server 
String tweet = "";      // string to hold the tweet 
boolean readingTweet = false;   // if you're currently reading the tweet 

String lastCount = ""; //last number counted 

int numberOfBytes=0; 

char* textFound; 


void setup() 
{ 
    // reserve space for the strings: 
    currentLine.reserve(256); 
    tweet.reserve(150); 
    //Initialize serial and wait for port to open: 
    Serial.begin(9600); 
    while (!Serial) { 
    ; // wait for serial port to connect. Needed for Leonardo only 
    } 

    // check for the presence of the shield: 
    if (WiFi.status() == WL_NO_SHIELD) { 
    Serial.println("WiFi shield not present"); 
    // don't continue: 
    while(true); 
    } 

    // attempt to connect to Wifi network: 
    while (status != WL_CONNECTED) { 
    Serial.print("Attempting to connect to SSID: "); 
    Serial.println(ssid); 
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:  
    status = WiFi.begin(ssid, pass); 

    // wait 10 seconds for connection: 
    delay(10000); 
    } 
    // you're connected now, so print out the status: (or not) 
    //printWifiStatus(); 
// connectToServer(); 
} 

void loop() 
{ 
    //connectToServer(); 
    //delay(10000); 
    if (client.connected()) 
    { 
    Serial.println("Connected. Checking for availabiilty of client..."); 
    if (client.available()) 
    { 
     Serial.println("Client is available! Trying to read from client..."); 
     // read incoming bytes: 

     if(client.find("\r\n\r\n")) 
     { 
     char inChar; 

     while(inChar=client.read()) 
     { 
     if(inChar==-1) break; 
     currentLine+=inChar; //read in all characters of count 
     Serial.print("\n\nCurrent follower count: " + currentLine + "\n\n"); 
     if(inChar=='y' || inChar == 'n') break; 
     } 
     if(inChar=='y') 
     { 
     //lastCount=currentLine; 
     Serial.println("BLINKING LED"); 
     blink(); //blink LED 
     } 
     else 
     { 
     Serial.println("NOT BLINKING."); 
     } 
     currentLine=""; //clear 
     delay(5000); //delay 5 seconds (don't kill server) 
    } 
    else 
    { 
     Serial.println("newlines not found - error with request"); 
    } 
    } 
    } 
    else if (millis() - lastAttemptTime > requestInterval) 
    { 
    // if you're not connected, and two minutes have passed since 
    // your last connection, then attempt to connect again: 
    connectToServer(); 
    } 
} 

void blink() 
{ 
    digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) 
    delay(3000);    // wait for a second 
    digitalWrite(led, LOW); // turn the LED off by making the voltage LOW 
    //delay(1000);    // wait for a second 
} 

void connectToServer() 
{ 
    // attempt to connect, and wait a millisecond: 
    Serial.println("connecting to server..."); 
    if (client.connect(server, 80)) 
    { 
    Serial.println("making HTTP request..."); 
    // make HTTP GET request to twitter: 
    client.println("GET /private/followers.php HTTP/1.1"); 
    client.println("Host:raw-d.com"); 
    client.println("Connection:close"); 
    client.println(); 


    } 
    else 
    { 
    Serial.println("Failure to connect."); 
    } 
    // note the time of this connect attempt: 
    lastAttemptTime = millis(); 
} 

void runPhpScript() 
{ 
    // attempt to connect, and wait a millisecond: 
    Serial.println("connecting to server..."); 
    if (client.connect(server, 80)) 
    { 
    Serial.println("making HTTP request..."); 
    client.println("GET /private/followers.php HTTP/1.1"); 
    client.println("Host:raw-d.com"); 
    client.println("Connection:close"); 
    client.println(); 
    } 
    else 
    { 
    Serial.println("Failure to run script."); 
    } 
    // note the time of this connect attempt: 
    lastAttemptTime = millis(); 
} 


void printWifiStatus() { 
    // print the SSID of the network you're attached to: 
    Serial.print("SSID: "); 
    Serial.println(WiFi.SSID()); 

    // print your WiFi shield's IP address: 
    IPAddress ip = WiFi.localIP(); 
    Serial.print("IP Address: "); 
    Serial.println(ip); 

    // print the received signal strength: 
    long rssi = WiFi.RSSI(); 
    Serial.print("signal strength (RSSI):"); 
    Serial.print(rssi); 
    Serial.println(" dBm"); 
} 

回答

0

對於第一你的問題的一部分,額外的1和0,看起來可能是HTTP分塊編碼,其中服務器以長度爲前綴的塊發送響應。如果是這種情況,那麼在響應中將會有一個如Transfer-Encoding: chunked的頭部,這表示客戶端必須對分塊編碼進行解碼才能獲得原始有效載荷。你可以在你的PHP腳本中明確設置Content-Length頭可能防止服務器採用分塊編碼:

header('Content-Length: 1'); 

隨着信息提供它不是100%清楚爲什麼你會間歇性地看到HTTP標頭出現有效載荷,但通常HTTP有一堆可能在這裏玩的功能。既然你控制了這個服務器,並且它與你的Arduino項目緊密結合,那麼一個快速而又髒亂的解決方案就是將你的信號字節改成你知道不會出現在HTTP標題中的值,比如一些字節值大於127。完全處理Arduino方面的分塊編碼和其他HTTP特性是可能的,但對於這個應用來說可能是不值得的,因爲你已經將服務器定製爲Arduino草圖。