使用Arduino和GSM shield以及Parse REST API将数据上传到Parse.com

时间:2013-06-29 01:35:23

标签: api arduino parse-platform gprs

我正在尝试使用带有GSM屏蔽的Arduino,使用他们的REST API通过GPRS将传感器数据发布到www.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();
}

我需要能够使用App ID和API密钥等将“Level”和“Temp”数据发布到Parse.com,如上面的API示例所示。关于如何在草图中执行此操作的任何想法?

提前致谢!!

3 个答案:

答案 0 :(得分:2)

我对此进行了一些额外的研究,似乎Arduino无法通过安全(https)连接连接到Web服务器。要做到这一点,我需要选择不同的硬件。

我在上面尝试了zmo的答案,它返回0,因为Arduino无法建立连接。目前使用Arduino的唯一方法是将传感器数据发布到运行脚本的中间服务器,然后将数据发布到Parse。

答案 1 :(得分: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")以获得胜利!

答案 2 :(得分:0)

现在有http://www.temboo.com的可能性。试一试,在这里我解释了它是如何工作的: https://stackoverflow.com/a/24213165/1862909

但我认为它仅适用于wifi屏蔽和以太网屏蔽。也许你可以向temboo的那些人提出要求吗?