【问题标题】:How do i store data from HTTPREAD into a variable?如何将来自 HTTPREAD 的数据存储到变量中?
【发布时间】:2020-04-08 10:44:50
【问题描述】:

我需要一种将 HTTPREAD 数据存储到变量中的方法,因为我会将其值与另一个变量进行比较。有什么办法吗?

  {
  myGsm.print("AT+HTTPPARA=\"URL\",\"http://7ae0eae2.ngrok.io/get-ignition/ccb37bd2-a59e-4e56-a7e1-68fd0d7cf845"); // Send PARA command
  myGsm.print("\"\r\n"); 
  delay(1000);
  printSerialData();

  myGsm.println();
  myGsm.println("AT+HTTPACTION=0");//submit the GET request 
  delay(8000);//the delay is important if the return datas are very large, the time required longer.
  printSerialData();
  myGsm.println("AT+HTTPREAD=0,17");// read the data from the website you access
  delay(3000);
  printSerialData();
  delay(1000);
}

void printSerialData()
{
 while(myGsm.available()!=0)
 Serial.write(myGsm.read());
}

【问题讨论】:

  • AT+HTTPREAD=0,17 返回什么?
  • 您想将一些值存储到来自myGsm.read() 的变量中吗?

标签: http arduino iot gsm


【解决方案1】:

我假设Serial.write(myGsm.read())您要从中获取数据的位置。也就是说,你是通过串口接收数据,你想解析AT+HTTPREAD命令返回的数据。

由于您没有提供任何关于该命令在串行中返回的内容的任何线索,我将使用一个我知道输出的不同命令作为示例,如下所示:

TX=> AT+CCLK?
RX=> AT+CCLK?\n\r
     \t+CCLK: "2020/03/03, 22:00:14"\n\r

所以,你将从上面的AT+CCLK? 命令得到的字符串是这样的(为了理解,我分配了一个 char 指针):

char *answer = "AT+CCLK?\n\r\t+CCLK: "2020/03/03, 22:00:14"\n\r";

您需要解析答案(本例中为char *answer)以将“数字”转换为变量。

怎么做?

你需要走过那根绳子,移动到特定的地方。例如,为了能够将2020 转换为变量,您需要位于answer[19] 的位置,然后您可以使用strtoul() 转换为整数并将其存储到变量中.

uint32_t year = strtoul(&answer[19], NULL, 10);

那么,要得到月份,你需要多走一点才能到达字符串上月份的位置:

uint32_t month = strtoul(&answer[24], NULL, 10);

等等,但您使用的是 magic numbers,换句话说,数字 1924 是特定于这个字符串。

那么,如何让这个“走路”更聪明呢?

您可以将标记与strstr() 结合使用,以转到字符串中所需的特定点。在这种情况下,我们要将指针移动到第一个2,因此我们可以将该指针传递给strtoul(),以将其转换为整数。


#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

int main() {
    char *answer = "AT+CCLK?\n\r\t+CCLK: "2020/03/03, 22:00:14"\n\r";
    char *token = "CCLK: \"";
    char *ptr;
    uint32_t year;

    ptr = strstr(answer, token);

    if (ptr == NULL) {
        printf("Token not found\n");
        return -1;
    }

    year = strtoul(++ptr, NULL, 10);
    printf("Year = %d\n", year);

那么,为了让这段代码成为一个更通用的函数,这里是:

    bool parse_answer_to_uint32(char *buff, char *tokens[], uint32_t *val)
    {
        char *ptr;
        int i;

        if (val == NULL)
            return false;


        for (i = 0; buff != NULL && tokens[i] != NULL; i++) {
            ptr = strstr(buff, tokens[i]);
            if (ptr == NULL)
                return false;
            buff = (ptr + strlen(tokens[i]));
        }
        // Here, you reached the point you want, based on the tokens you seek
        if (buff == NULL)
            return false;

        *val = strtoul(buff, NULL, 10);
    }

所以,你可以像这样调用这个函数:

    char *tokens[] = { "CCLK: \"" };
    uint32_t year;

    if (parse_answer_to_uint32(myGsm.read().c_str(), tokens, &year) == false)
        return -1;
    printf("year is = %d\n", year);

printf 将根据上面的示例打印2020

这个函数非常灵活和通用。您所需要的只是传递不同的标记以到达字符串的不同点并达到您想要的值。

【讨论】:

  • 我一个都没听懂。
  • 我编辑了,请检查现在是否可以理解。如果不是,请更具体地说明您不明白的地方。
【解决方案2】:

将字符缓冲区、来自串行的 Concat 数据放入此缓冲区,并处理该缓冲区以进行比较。

【讨论】:

  • 我会使用strstr() 来查找特定令牌并在所需值之前达到您想要的点。
  • 能否请您更详细地解释一下或给我写一个示例代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 2017-06-27
  • 2011-10-26
  • 2018-04-15
  • 1970-01-01
相关资源
最近更新 更多