如何使用 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 秒一次免费帐户。
考虑在您的代码中加入一些必要的延迟,以确保您的设备不会因滥用条款而被列入黑名单。
我正在尝试使用 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 秒一次免费帐户。
考虑在您的代码中加入一些必要的延迟,以确保您的设备不会因滥用条款而被列入黑名单。