2013-06-29 37 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

相关问题