Ankit Sharma
Ankit Sharma

Reputation: 13

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

I am trying to control a LED from Thingspeak server by using the GSM module. The data received is successfully being printed on serial monitor(which is '1' as last updated) but when I am trying to assign that data to a variable so as to control the inbuilt LED of Arduino, nothing happens.

#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()));
}

Last portion of the output from the serial monitor:

CONNECT OK
AT+CIPSEND

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

SEND OK
1

Upvotes: 1

Views: 877

Answers (3)

user11638063
user11638063

Reputation:

You are likely getting rate limited because you are hitting ThingSpeak servers too frequently. You can only update a channel once every 15s with a free account. Obviously, it makes no sense to ask for a value faster than it can be updated, i.e., once every 15s with a free account.

Consider putting some required delays in your code to ensure your device is not blacklisted for abuse of terms.

Upvotes: 1

Hritik
Hritik

Reputation: 722

As pointed out by @Saurabh P Bhandari, you cannot read the same data from the serial twice, thus you'd need to read the data in a variable in the first place if you wish to use it.

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

Then you can use String led = getSerialData() to populate led with the buffer.
Here, you need to beware that the function getSerialData would return anything present on the buffer and would look something like:

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

HTTP RESPONSE

It appears that you're only interested in HTTP RESPONSE, thus you can update your conditionals to be

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

Upvotes: 1

Saurabh P Bhandari
Saurabh P Bhandari

Reputation: 6742

From what I have understood so far, in this snippet

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

ShowSerialData() is printing the output which is '1'. Then immediately your are reading data into the variable led. Since, the actual data received is being printed already from ShowSerialData(), the next time you call SIM900A.read() will return either nothing or next set of data being sent by your module.

Upvotes: 1

Related Questions