(SOLVED) Sim800L- POST HTTP with AT Commands

Hi All

Hope you are doing well

I am trying to send DHT22 data via Sim800L to ThingSpeak.

This is my code;

#include <SoftwareSerial.h>
#include <dht.h>
dht DHT;
SoftwareSerial gsm(3, 2); // RX, TX
#define DHT22_PIN 8
int chk;
int humi = 0;
int temp = 0;
void setup()
{
  Serial.begin(9600);
  gsm.begin(9600);
  modem_init();
  data_init();
  internet_init();
}
void loop()
{
  chk = DHT.read22(DHT22_PIN);
  switch (chk)
  {
    case DHTLIB_OK:
      Serial.print("OK,\t");
      break;
    case DHTLIB_ERROR_CHECKSUM:
      Serial.print("Checksum error,\t");
      break;
    case DHTLIB_ERROR_TIMEOUT:
      Serial.print("Time out error,\t");
      break;
    case DHTLIB_ERROR_CONNECT:
      Serial.print("Connect error,\t");
      break;
    case DHTLIB_ERROR_ACK_L:
      Serial.print("Ack Low error,\t");
      break;
    case DHTLIB_ERROR_ACK_H:
      Serial.print("Ack High error,\t");
      break;
      default:
      Serial.print("Unknown error,\t");
      break;
  }
  Serial.print("Humidity: ");
  Serial.print(DHT.humidity, 1);
  Serial.print("%");
  Serial.print(",\t");
  Serial.print("Temperature: ");
  Serial.print(DHT.temperature, 1);
  Serial.println("*C");
  temp = DHT.temperature;
  humi = DHT.humidity;
  delay(5000);
  Send_data();
}
void modem_init()
{
  Serial.println("Please wait.....");
  gsm.println("AT");
  delay(1000);
  gsm.println("AT+CMGF=1");
  delay(1000);
  gsm.println("AT+CNMI=2,2,0,0,0");
  delay(1000);
}
void data_init()
{
  Serial.println("Please wait.....");
  gsm.println("AT");
  delay(1000); delay(1000);
  gsm.println("AT+CPIN?");
  delay(1000); delay(1000);
  gsm.print("AT+SAPBR=3,1");
  gsm.write(',');
  gsm.write('"');
  gsm.print("contype");
  gsm.write('"');
  gsm.write(',');
  gsm.write('"');
  gsm.print("GPRS");
  gsm.write('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000); ;
  gsm.print("AT+SAPBR=3,1");
  gsm.write(',');
  gsm.write('"');
  gsm.print("APN");
  gsm.write('"');
  gsm.write(',');
  gsm.write('"');
 
  
 
  gsm.print("internet"); //APN Here
  
  
 
  gsm.write('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);
  gsm.print("AT+SAPBR=3,1");
  gsm.write(',');
  gsm.write('"');
  gsm.print("USER");
  gsm.write('"');
  gsm.write(',');
  gsm.write('"');
  gsm.print("vodafone");
  gsm.write('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);
  gsm.print("AT+SAPBR=3,1");
  gsm.write(',');
  gsm.write('"');
  gsm.print("PWD");
  gsm.write('"');
  gsm.write(',');
  gsm.write('"');
  gsm.print("vodafone");
  gsm.write('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(2000);
  gsm.print("AT+SAPBR=1,1");
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(3000);
}
void internet_init()
{
  Serial.println("Please wait.....");
  delay(1000);
  gsm.println("AT+HTTPINIT");
  delay(1000); delay(1000);
  gsm.print("AT+HTTPPARA=");
  gsm.print('"');
  gsm.print("CID");
  gsm.print('"');
  gsm.print(',');
  gsm.println('1');
  delay(1000);
}
void Send_data()
{
  gsm.print("AT+HTTPPARA=");
  gsm.print('"');
  gsm.print("URL");
  gsm.print('"');
  gsm.print(',');
  gsm.print('"');
  gsm.print("https:");
  gsm.print('/');
  gsm.print('/');


  
  gsm.print("api.thingspeak.com/update?api_key=xxxxxxxxxxxxxxxxx&field1="); 
///xxx is the api key
 
  gsm.print(temp); //>>>>>>  variable 1 (temperature)
  gsm.print("&field2=");
  gsm.print(humi); //>>>>>> variable 2 (Humidity)
  gsm.print('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);
  gsm.println("AT+HTTPACTION=0");
  delay(1000);
}

When I type the url to my browser, it updates the ThingSpeak so it's working well. But I am having trouble to do that with this code. And I am powering up the Sim800L from 5v pin of Arduino Uno, maybe this is the issue, I don't know.

Can you see my mistake? Please help asap if you can.

And also I am using the forum for the first time. If I've done any mistake, I apologize from you all.

King Regards to All Community.

Congratulations using code tags on your first post.

And I am powering up the Sim800L from 5v pin of Arduino Uno, maybe this is the issue, I don't know.

This would be a very good place to start. Google "SIM800L power requirements"

You should use a regulated power supply of at least 2A, and use a large capacitor across the output as well.

cattledog:
Congratulations using code tags on your first post.

This would be a very good place to start. Google "SIM800L power requirements"

You should use a regulated power supply of at least 2A, and use a large capacitor across the output as well.

Thank you for your attention. I've checked the power requirements. I've bought 1200mAh, 3.7V Li po battery. But nothing has changed. I've added "ShowSerialData();" function. When I look at the serial monitor, I get this output;

Please wait.....
Please wait.....
Please wait.....
OK, Humidity: 76.6%, Temperature: 26.9*C
�AT

OK
AT+CMGF=1

OK
AT+CNMI=2,2,0,0,0

OK
AT

OK
AT+COK, Humidity: 76.4%, Temperature: 26.9*C
AT+HTTPACTION=0

ERROR
AT+HTTPPARA="URL","https://api.thingspOK, Humidity: 76.5%, Temperature: 27.0*C
AT+HTTPACTION=0

ERROR
AT+HTTPPARA="URL","https://api.thingspOK, Humidity: 76.5%, Temperature: 27.0*C
AT+HTTPACTION=0

ERROR
AT+HTTPPARA="URL","https://api.thingspOK, Humidity: 76.7%, Temperature: 26.9*C
AT+HTTPACTION=0

ERROR
AT+HTTPPARA="URL","https://api.thingspOK, Humidity: 76.8%, Temperature: 26.9*C
AT+HTTPACTION=0

ERROR
AT+HTTPPARA="URL","https://api.thingspOK, Humidity: 76.8%, Temperature: 27.0*C
AT+HTTPACTION=0

ERROR
AT+HTTPPARA="URL","https://api.thingspOK, Humidity: 76.5%, Temperature: 26.9*C
AT+HTTPACTION=0

ERROR
AT+HTTPPARA="URL","https://api.thingspOK, Humidity: 76.6%, Temperature: 27.0*C
AT+HTTPACTION=0

ERROR

It's look like my serial buffer's size is not enough (btw I am not sure). So I have checked how I can expand the size. I saw some examples to expand it from Program Files by creating copy of the board in the "boards" file. I am using mac so, there is no such a file. Are there any way to do it so? Or I am not right about buffer size? I am leaving the updated code here;

#include <Sim800L.h>
#include <dht.h>
dht DHT;

SoftwareSerial gsm(11,10); // RX, TX
#define BUFFER_RESERVE_MEMORY  2048
#define DHT22_PIN 8
int chk;
int humi = 0;
int temp = 0;


void ShowSerialData()
{
 while(gsm.available()!=0)
   Serial.write(gsm.read());
}
void setup()
{
  Serial.begin(9600);
  gsm.begin(9600);
  modem_init();
  data_init();
  internet_init();
}
void loop()
{
  chk = DHT.read22(DHT22_PIN);
  switch (chk)
  {
    case DHTLIB_OK:
      Serial.print("OK,\t");
      break;
    case DHTLIB_ERROR_CHECKSUM:
      Serial.print("Checksum error,\t");
      break;
    case DHTLIB_ERROR_TIMEOUT:
      Serial.print("Time out error,\t");
      break;
    case DHTLIB_ERROR_CONNECT:
      Serial.print("Connect error,\t");
      break;
    case DHTLIB_ERROR_ACK_L:
      Serial.print("Ack Low error,\t");
      break;
    case DHTLIB_ERROR_ACK_H:
      Serial.print("Ack High error,\t");
      break;
      default:
      Serial.print("Unknown error,\t");
      break;
  }
  Serial.print("Humidity: ");
  Serial.print(DHT.humidity, 1);
  Serial.print("%");
  Serial.print(",\t");
  Serial.print("Temperature: ");
  Serial.print(DHT.temperature, 1);
  Serial.println("*C");
  temp = DHT.temperature;
  humi = DHT.humidity;
  delay(1000);
  Send_data();
}
void modem_init()
{
  Serial.println("Please wait.....");
  gsm.println("AT");
  delay(1000);
  gsm.println("AT+CMGF=1");
  delay(1000);
  gsm.println("AT+CNMI=2,2,0,0,0");
  delay(1000);
}
void data_init()
{
  Serial.println("Please wait.....");
  gsm.println("AT");
  delay(1000); 
  delay(1000);
  gsm.println("AT+CPIN?");
  delay(1000); 
  delay(1000);
  gsm.print("AT+SAPBR=3,1");
  gsm.write(',');
  gsm.write('"');
  gsm.print("contype");
  gsm.write('"');
  gsm.write(',');
  gsm.write('"');
  gsm.print("GPRS");
  gsm.write('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000); ;
  gsm.print("AT+SAPBR=3,1");
  gsm.write(',');
  gsm.write('"');
  gsm.print("APN");
  gsm.write('"');
  gsm.write(',');
  gsm.write('"');
 
  
 
  gsm.print("internet"); //APN Here
  
  
 
  gsm.write('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);
  gsm.print("AT+SAPBR=3,1");
  gsm.write(',');
  gsm.write('"');
  gsm.print("USER");
  gsm.write('"');
  gsm.write(',');
  gsm.write('"');
  gsm.print("vodafone");
  gsm.write('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);
  gsm.print("AT+SAPBR=3,1");
  gsm.write(',');
  gsm.write('"');
  gsm.print("PWD");
  gsm.write('"');
  gsm.write(',');
  gsm.write('"');
  gsm.print("vodafone");
  gsm.write('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);
  gsm.print("AT+SAPBR=1,1");
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);
}
void internet_init()
{
  Serial.println("Please wait.....");
  delay(1000);
  gsm.println("AT+HTTPINIT");
  delay(1000); delay(1000);
  gsm.print("AT+HTTPPARA=");
  gsm.print('"');
  gsm.print("CID");
  gsm.print('"');
  gsm.print(',');
  gsm.println('1');
  delay(1000);
}
void Send_data()
{
  gsm.print("AT+HTTPPARA=");
  gsm.print('"');
  gsm.print("URL");
  gsm.print('"');
  gsm.print(',');
  gsm.print('"');
  gsm.print("https:");
  gsm.print('/');
  gsm.print('/');


  
  gsm.print("api.thingspeak.com/update?api_key=xxxxxxxxxxx&field1=");
// xxxx part is my api key
 
  gsm.print(temp); //>>>>>>  variable 1 (temperature)
  gsm.print("&field2=");
  gsm.println(humi); //>>>>>> variable 2 (Humidity)
  
  
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);
  ShowSerialData();
  gsm.println("AT+HTTPACTION=0");
  delay(1000);
}

As you can see I've added something like; to expand the buffer size. I found it in Sim800L library.

#define BUFFER_RESERVE_MEMORY  2048

This is what I ve done. But problem remains. If you have any idea?

Thank you!

As you can see I've added something like; to expand the buffer size. I found it in Sim800L library.

I would not mess with the buffer size. It's not clear to me if this #define is doing what you think.

Instead call your ShowSerialData() way more frequently and not just in sendData(). Ideally, you want to see the response to every AT command.

If you use the sim800l library you were investigating instead of the direct AT command set, does the module work as expected?

cattledog:
I would not mess with the buffer size. It's not clear to me if this #define is doing what you think.

Instead call your ShowSerialData() way more frequently and not just in sendData(). Ideally, you want to see the response to every AT command.

If you use the sim800l library you were investigating instead of the direct AT command set, does the module work as expected?

Module works as expected but when I am sending the to serial port, it cuts the url. I put ShowSerialData() more frequently. Now this is my output;

Please wait.....
AT

OK

SMS Ready
AT+CMGF=1

OK
AT+CNMI=2,2,0,0,0

OK
Please wait.....
AT

OK
AT+CPIN?

+CPIN: READY

OK
AT+SAPBR=3,1,"contype","GPRS"

OK
AT+SAPBR=3,1,"APN","internet"

OK
AT+SAPBR=3,1,"USER","vodafone"

OK
AT+SAPBR=3,1,"PWD","vodafone"

OK
AT+SAPBR=1,1

OK
Please wait.....
AT+HTTPINIT

OK
AT+HTTPPARA="CID",1

OK
AT+HTTPPARA=
"URL","https://api.thingspeak.com/update?api_key=WAT+HTTPACTION=0

ERROR
OK,	Humidity: 58.3%,	Temperature: 29.1*C
AT+HTTPPARA=
"URL","https://api.thingspeak.com/update?api_key=WAT+HTTPACTION=0

ERROR
OK,	Humidity: 57.5%,	Temperature: 29.1*C
AT+HTTPPARA=
"URL","https://api.thingspeak.com/update?api_key=WAT+HTTPACTION=0

ERROR
OK,	Humidity: 57.4%,	Temperature: 29.0*C

it cuts the url

I really do not understand why this truncation is happening. You certainly have isolated the issue.

AT+HTTPPARA=
"URL","https://api.thingspeak.com/update?api_key=WAT+HTTPACTION=0
ERROR

A Google search for "sim800l connect to thingspeak" led me to this tutorial which you appear to be following Send Data to Thingspeak Using GSM – DIY Electronics Projects
There are several other interesting references returned by the search.

Are you certain that you have the correct APN for the sim card you are using?

This thread is at a point where I can not really help you any more. Perhaps someone else with more direct experience with Thingspeak and the sim800l will jump in.

EDIT: I do see one error in your transmission, but it is after the line with the problem and I don't know if it an issue. You are repeating the line endings.

gsm.print("&field2=");
  //gsm.println(humi); //>>>>>> variable 2 (Humidity)
  gsm.print(humi);
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);[\code]

now I am trying a different code with a different module named GPRS A6. But problem same again.
https://forum.arduino.cc/index.php?topic=625571.0

I would add some lines to your code to see if you are getting assigned an IP address.

I see this test in this tutorial https://www.raviyp.com/embedded/194-sim900-gprs-http-at-commands

After the series of AT +SAPBR commands which set up the GPRS connection in data_init() try adding the following after the AT+SAPBR=1,1. Check if the connection is setup properly. You should get back an IP address. Use your serial print echo commands.

gsm.print("AT+SAPBR=1,1");
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);
  gsm.print("AT+SAPBR=2,1");
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);

I changed http connection to tcp connection. The new code is here;

#include <SoftwareSerial.h>
#include <dht.h>
dht DHT;
SoftwareSerial gsm(11,10); //RX, TX


#define DHT22_PIN 8
int chk;
int humi= 0;
int temp= 0;
void ShowSerialData()
{
 while(gsm.available()!=0)
   Serial.write(gsm.read());
}

void setup() {
  Serial.begin(9600);
  gsm.begin(9600);
  falan();
  singlecon();
}

void loop() {
  chk = DHT.read22(DHT22_PIN);
  switch (chk)
  {
    case DHTLIB_OK:
      Serial.print("OK,\t");
      break;
    case DHTLIB_ERROR_CHECKSUM:
      Serial.print("Checksum error,\t");
      break;
    case DHTLIB_ERROR_TIMEOUT:
      Serial.print("Time out error,\t");
      break;
    case DHTLIB_ERROR_CONNECT:
      Serial.print("Connect error,\t");
      break;
    case DHTLIB_ERROR_ACK_L:
      Serial.print("Ack Low error,\t");
      break;
    case DHTLIB_ERROR_ACK_H:
      Serial.print("Ack High error,\t");
      break;
      default:
      Serial.print("Unknown error,\t");
      break;
  }
  Serial.print("Humidity: ");
  Serial.print(DHT.humidity, 1);
  Serial.print("%");
  Serial.print(",\t");
  Serial.print("Temperature: ");
  Serial.print(DHT.temperature, 1);
  Serial.println("*C");
  temp = DHT.temperature;
  humi = DHT.humidity;
  delay(2000);
  ShowSerialData();
  falan();
  singlecon();
  ShowSerialData();
}
void falan()
{
  Serial.println("Bekle...");
  gsm.println("AT");
  delay(2000);
  ShowSerialData();
  gsm.println("AT+CPIN?");
  delay(2000);
  ShowSerialData();
  gsm.println("AT+CREG?");
  delay(2000);
  ShowSerialData();
  gsm.println("AT+CIPSHUT");
  delay(3000);
  ShowSerialData();
  gsm.println("AT+CIPSTATUS");
  
  delay(2000);
  ShowSerialData();
}
void singlecon()
{
  Serial.println("Bekle2...");
  gsm.println("AT+CIPMUX=0");
  delay(2000);
  ShowSerialData();
  gsm.print("AT+CSTT=");
  gsm.print('"');
  gsm.print("internet");
  gsm.println('"');
  
  delay(2000);
  ShowSerialData();
  gsm.println("AT+CIICR");
  delay(2000);
  
  ShowSerialData();
  gsm.println("AT+CIFSR");
  delay(2000);
  
  ShowSerialData();
  gsm.print("AT+CIPSTART=");
  gsm.print('"');
  gsm.print("TCP");
  gsm.print('"');
  gsm.print(',');
  gsm.print('"');
  gsm.print("api.thingspeak.com");
  gsm.print('"');
  gsm.print(',');
  gsm.print("80");
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(2000);
  ShowSerialData();
  gsm.println("AT+CIPSEND");
  delay(5000);
  ShowSerialData();
  gsm.print("GET");
  gsm.print(' ');
  //gsm.print("http:");
  //gsm.print('/');
  //gsm.print('/');
  //gsm.print("api.thingspeak.com");
  gsm.print('/');
  gsm.print("update?api_key=");
  gsm.print("xxxxxxxxx");//my API Key
  gsm.print("&field1=");
  gsm.print(temp);
  gsm.print("&field2=");
  gsm.print(humi);
  
  gsm.write(0x0d);
  gsm.write(0x0a);
  
  gsm.write(0x1a); // the trick is here to send the request. Its Ctrl+Z to start send process.
  delay(15000);
  
  ShowSerialData();
  
  //gsm.println("AT+CIPSHUT");
  gsm.println("AT+CIPCLOSE");
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(30000);
  ShowSerialData(); 
}

Thank you for your help. The problem solved !

1 Like

I changed http connection to tcp connection.

Why do you think the http application-layer protocol that runs over tcp did not work correctly?

The Sim800l appears to support it, and tutorials indicate others have used it successfully.

Is it a Thingspeak issue, a Sim800l issue, or do you think the code was in error?

Problem was based on the code, I think. I cannot address if there is an issue with sim800L because I broke the module and I ve ran my code with GPRS A6 which does not support HTTP. So I've tried with TCP. I was having errors after CIPSEND so I've noticed that after the GET request, I should not put the IP (api.thingspeak.com) and start with "/update?api_key......" The other problem, with CIPSEND command, I am requesting to initiate the send mode and not commanding to finalize the mode after my URL. I've learnt to finalize the send mode with "Ctrl+Z(0xa1)". And I was able to send the data.