如何使用 SIM900A 和 Arduino 从 Thingspeak 服务器控制 LED?

How to control an led from Thingspeak server using SIM900A and Arduino?

我正在尝试使用 GSM 模块从 Thingspeak 服务器控制 LED。 接收到的数据已成功打印在串行监视器上(上次更新时为“1”)但是当我试图将该数据分配给变量以控制 Arduino 的内置 LED 时,没有任何反应。

#include <SoftwareSerial.h>
SoftwareSerial SIM900A(10, 11);
void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  SIM900A.begin(9600);
  Serial.begin(9600);
  while (!Serial)
    ;
  Serial.println("Arduino is ready");
  SIM900A.begin(9600);
  Serial.println("SIM900A started at 9600");
  delay(1000);
  Serial.println("Setup Complete");
}

void loop()
{
  SIM900A.println("AT");
  delay(1000);
  ShowSerialData();

  SIM900A.println("AT+CIPSHUT");
  delay(2000);
  ShowSerialData();

  SIM900A.println("AT+CIPMUX=0");
  delay(2000);
  ShowSerialData();

  SIM900A.println("AT+CGATT=1");
  delay(5000);

  SIM900A.println("AT+CSTT=\"INTERNET\",\"\",\"\"");
  delay(4000);

  SIM900A.println("AT+CIICR");
  delay(3000);
  ShowSerialData();

  SIM900A.println("AT+CIFSR");
  delay(5000);
  ShowSerialData();

  SIM900A.println("AT+CIPSTART=\"TCP\",\"184.106.153.149\",\"80\"");
  delay(4000);
  ShowSerialData();

  SIM900A.println("AT+CIPSEND");
  delay(4000);

  SIM900A.print("GET /channels/798173/fields/1/last");
  SIM900A.print("\r\n\x1A");
  ShowSerialData();

  char led = SIM900A.read();
  Serial.print(led);

  if (led == '1')
  {
    digitalWrite(LED_BUILTIN, HIGH);
  }

  else if (led == '0')
  {
    digitalWrite(LED_BUILTIN, LOW);
  }

  delay(8000);
}

void ShowSerialData()
{
  while (SIM900A.available() != 0)
    Serial.print(char(SIM900A.read()));
}

串行监视器输出的最后一部分:

CONNECT OK
AT+CIPSEND

> ⸮GET /channels/798173/fields/1/last

SEND OK
1

根据我目前的理解,在这个片段中

SIM900A.print("GET /channels/798173/fields/1/last");  
SIM900A.print("\r\n\x1A");
ShowSerialData(); 

ShowSerialData() 正在打印输出“1”。然后您立即将数据读入变量 led。因为,接收到的实际数据已经从 ShowSerialData() 打印出来,下次您调用 SIM900A.read() 时,您的模块将 return 不发送任何数据或下一组数据。

正如@Saurabh P Bhandari 所指出的,您不能从串行中读取相同的数据两次,因此如果您希望使用它,您需要首先读取变量中的数据。

String getSerialData(){
      String buffer="";
      while (SIM900A.available() ){
        char c = SIM900A.read();
        buffer+=c;    
      }
      return buffer;
     }

然后您可以使用 String led = getSerialData() 将缓冲区填充到 led
在这里,您需要注意函数 getSerialData 会 return 缓冲区中存在的任何内容,并且看起来像:

GET /channels/798173/fields/1/last
SEND

HTTP RESPONSE

您似乎只对 HTTP RESPONSE 感兴趣,因此您可以将条件更新为

if(led.endsWith("1"))
...
else if(led.endsWith("0"))

您访问 ThingSpeak 服务器的频率可能会受到限制。您只能使用免费帐户每 15 秒更新一次频道。显然,要求一个值的更新速度快于更新速度是没有意义的,即每 15 秒一次免费帐户。

考虑在您的代码中加入一些必要的延迟,以确保您的设备不会因滥用条款而被列入黑名单。