2013-06-29 38 views
2

我正嘗試使用具有GSM屏蔽的Arduino通過GPRS使用REST API將傳感器數據發佈到www.parse.com。這是他們的文檔如何顯示它需要完成的:使用Arduino和GSM屏蔽和Parse REST API將數據上傳到Parse.com

curl -X POST \ 
    -H "X-Parse-Application-Id: gmOpYot0OhWGnkMojjZv9KYUHMySCSeTGyyplArZ" \ 
    -H "X-Parse-REST-API-Key: XQMA4Wd3SQdOsxudtKz5OdbPaVN3YE9aOKx0VSh2" \ 
    -H "Content-Type: application/json" \ 
    -d '{"Level":90, "Temp":25}' \ 
    https://api.parse.com/1/classes/PercentFull 

我需要在Arduino草圖中實現它。這是我的出發點,因爲它包含了我的盾牌所使用的庫。此示例草圖連接到Google並顯示結果。我測試過它,它工作。

#include "SIM900.h" 
#include <SoftwareSerial.h> 
#include "inetGSM.h" 
//#include "sms.h" 
//#include "call.h" 

//To change pins for Software Serial, use the two lines in GSM.cpp. 

//GSM Shield for Arduino 
//www.open-electronics.org 
//this code is based on the example of Arduino Labs. 

//Simple sketch to start a connection as client. 

InetGSM inet; 
//CallGSM call; 
//SMSGSM sms; 

char msg[50]; 
int numdata; 
char inSerial[50]; 
int i=0; 
boolean started=false; 

void setup() 
{ 
    //Serial connection. 
    Serial.begin(9600); 
    Serial.println("GSM Shield testing."); 
    //Start configuration of shield with baudrate. 
    //For http uses is raccomanded to use 4800 or slower. 
    if (gsm.begin(2400)){ 
    Serial.println("\nstatus=READY"); 
    started=true; 
    } 
    else Serial.println("\nstatus=IDLE"); 

    if(started){ 
    //GPRS attach, put in order APN, username and password. 
    //If no needed auth let them blank. 
    if (inet.attachGPRS("internet.wind", "", "")) 
     Serial.println("status=ATTACHED"); 
    else Serial.println("status=ERROR"); 
    delay(1000); 

    //Read IP address. 
    gsm.SimpleWriteln("AT+CIFSR"); 
    delay(5000); 
    //Read until serial buffer is empty. 
    gsm.WhileSimpleRead(); 


    // Change this bit!! 

    //TCP Client GET, send a GET request to the server and 
    //save the reply. 
    numdata=inet.httpGET("www.google.co.nz", 80, "/", msg, 50); 
    //Print the results. 
    Serial.println("\nNumber of data received:"); 
    Serial.println(numdata); 
    Serial.println("\nData received:"); 
    Serial.println(msg); 
    } 
}; 

void loop() 
{ 
    //Read for new byte on serial hardware, 
    //and write them on NewSoftSerial. 
    serialhwread(); 
    //Read for new byte on NewSoftSerial. 
    serialswread(); 
}; 

void serialhwread(){ 
    i=0; 
    if (Serial.available() > 0){    
    while (Serial.available() > 0) { 
     inSerial[i]=(Serial.read()); 
     delay(10); 
     i++;  
    } 

    inSerial[i]='\0'; 
    if(!strcmp(inSerial,"/END")){ 
     Serial.println("_"); 
     inSerial[0]=0x1a; 
     inSerial[1]='\0'; 
     gsm.SimpleWriteln(inSerial); 
    } 
    //Send a saved AT command using serial port. 
    if(!strcmp(inSerial,"TEST")){ 
     Serial.println("SIGNAL QUALITY"); 
     gsm.SimpleWriteln("AT+CSQ"); 
    } 
    //Read last message saved. 
    if(!strcmp(inSerial,"MSG")){ 
     Serial.println(msg); 
    } 
    else{ 
     Serial.println(inSerial); 
     gsm.SimpleWriteln(inSerial); 
    }  
    inSerial[0]='\0'; 
    } 
} 

void serialswread(){ 
    gsm.SimpleRead(); 
} 

我需要能夠使用的應用程序ID和API密鑰等,在上述API示例所示張貼「等級」和「溫度」的數據到Parse.com。關於如何在草圖中做到這一點的任何想法?

在此先感謝!

回答

2

我已經做了一些額外的研究,似乎Arduino無法通過安全(https)連接連接到網絡服務器。要做到這一點,我需要選擇不同的硬件。

我試過zmo的回答,它返回0,因爲Arduino無法建立連接。目前使用Arduino的唯一方法是將傳感器數據發佈到運行腳本的中間服務器,然後將數據發佈到Parse。

+0

你有這樣的腳本的例子嗎?也許運行與瓶和python甚至在節點? – otmezger

1

你需要用叉子叉庫和重寫httpPost()函數中添加你需要的標題元素:

#define REST_APP_ID "gmOpYot0OhWGnkMojjZv9KYUHMySCSeTGyyplArZ" 
#defnie REST_API_KEY "XQMA4Wd3SQdOsxudtKz5OdbPaVN3YE9aOKx0VSh2" 

int InetGSM::parsePOST(const char* path, const char* parameters, char* result, int resultlength) 
{ 
    const char* server = "https://api.parse.com"; 
    int port = 443; 

    char itoaBuffer[8]; 
    int num_char; 

    if (!gsm.connectTCP(server, port)){ 
     return 0; 
    } 

    strcpy(_buffer,"POST "); 
    strcat(_buffer,path); 
    strcat(_buffer," HTTP/1.0\nHost: "); 
    strcat(_buffer,); 
    strcat(_buffer,"\nX-Parse-Application-Id: "); 
    strcat(_buffer,REST_APP_ID); 
    strcat(_buffer,"\nX-Parse-REST-API-Key: "); 
    strcat(_buffer,REST_API_KEY); 
    strcat(_buffer,"\nContent-Type: application/json"); 
    strcat(_buffer,"\nContent-Length: "); 
    itoa(strlen(parameters),itoaBuffer,10); 
    strcat(_buffer,itoaBuffer); 
    strcat(_buffer,"\n\n"); 
    strcat(_buffer,parameters); 
    strcat(_buffer,"\n\n"); 

    gsm.SimpleWrite(_buffer); 

    gsm.disconnectTCP(); 
    return 1; 
} 

你可能想通過REST_APP_IDREST_API_KEY作爲參數也是如此。並且不要忘記在header中添加 函數的原型。爲了然後用你的功能,您可以按以下稱之爲:

inet.parsePOST("/1/classes/PercentFull", "{\"Level\":90, \"Temp\":25}", msg, 50); 

要小心,每默認_buffer大小隻有50字符。你可能想要增加它的大小。你可能想要 把所有的字符串放在閃存中,以節省一些珍貴的內存F("my string")爲勝利!

+0

有趣!感謝您的回覆。我沒有考慮過這種方式。我不得不改變它來編譯。該行現在是:'numdata = inet.parsePOST(「/ 1/classes/PercentFull」,「{\」Level \「:90,\」Temp \「:25}」,msg,50);'。我也必須評論'strcat(_buffer,);'在inetGSMParse.cpp中。出於某種原因,resquest不會返回數據,甚至不會返回錯誤消息,因此很難調試!從這裏前進的任何想法? –

+0

有趣的是,在答案後超過2年沒有解釋-1的情況下:-) – zmo

相關問題