I cannot make a get request using ESP32 connected SIM800L

179 views Asked by At

I have a API key in openweathermap and I use it to get temperature data of cities. I tested that api on python however I want to make something fancy with esp32 however I couldnt make it and I got 603 http error code. here is my code :

#include <Arduino.h>
#include <SoftwareSerial.h>
#define SIM800L_IP5306_VERSION_20200811
#include "utilities.h"
#include <ArduinoJson.h>
// Define the software serial pins for communication with SIM800L
SoftwareSerial sim800lSerial(26, 27);  // RX, TX

// Replace with your OpenWeatherMap API key
const char* apiKey = "bbb1506b80137280e7cbdc2c3c72e628";
const char* city = "adana"; // Replace with the city you want to query


void setupModem()
{
#ifdef MODEM_RST
    // Keep reset high
    pinMode(MODEM_RST, OUTPUT);
    digitalWrite(MODEM_RST, HIGH);
#endif

    pinMode(MODEM_PWRKEY, OUTPUT);
    pinMode(MODEM_POWER_ON, OUTPUT);

    // Turn on the Modem power first
    digitalWrite(MODEM_POWER_ON, HIGH);

    // Pull down PWRKEY for more than 1 second according to manual requirements
    digitalWrite(MODEM_PWRKEY, HIGH);
    delay(100);
    digitalWrite(MODEM_PWRKEY, LOW);
    delay(1000);
    digitalWrite(MODEM_PWRKEY, HIGH);

    // Initialize the indicator as an output
    pinMode(LED_GPIO, OUTPUT);
    digitalWrite(LED_GPIO, LED_OFF);
}


void setup() {
  Serial.begin(115200);
  sim800lSerial.begin(115200);
  setupModem();
  delay(10000);
  // Initialize SIM800L
  sendATCommand("AT");
  sendATCommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"");
  sendATCommand("AT+SAPBR=3,1,\"APN\",\"internet\"");
  sendATCommand("AT+SAPBR=1,1");
  delay(1000); // Wait for the GPRS connection to establish
}

void loop() {
  // Query temperature
  float temperature = getTemperature(city);

  if (temperature != -999) {
    Serial.print("Temperature in ");
    Serial.print(city);
    Serial.print(": ");
    Serial.println(temperature);
  } else {
    Serial.println("Failed to fetch temperature.");
  }

  // Delay before making another request
  delay(20000); // 10 minutes
}

float getTemperature(const char* city) {
  // Create a HTTP client object
  sendATCommand("AT+HTTPINIT");
  sendATCommand("AT+HTTPPARA=\"CID\",1");
  
  // Replace with the URL for the OpenWeatherMap API
  String url = "http://api.openweathermap.org/data/2.5/weather?q=";
  url += city;
  url += "&appid=";
  url += apiKey;

  // Make a GET request
  sendATCommand("AT+HTTPPARA=\"URL\",\"" + url + "\"");

  // Send the API key as USERDATA
  String apiKeyString = String(apiKey);

  // Send the API key as USERDATA
  sendATCommand("AT+HTTPPARA=\"USERDATA\",\"Authorization: Bearer " + apiKeyString + "\"");
  
  // Make the GET request
  sendATCommand("AT+HTTPACTION=0");

  // Wait for the HTTP request to complete
  delay(15000); // Adjust the delay as needed

  // Read and parse the HTTP response
  sendATCommand("AT+HTTPREAD");
  String response = readResponse();

  if (response != "") {
    // Parse the JSON response
    DynamicJsonDocument doc(1024); // Adjust the size as needed
    DeserializationError error = deserializeJson(doc, response);

    if (!error) {
      float temperature = doc["main"]["temp"];
      // Convert from Kelvin to Celsius
      temperature -= 273.15;
      return temperature;
    } else {
      Serial.println("Failed to parse JSON");
      return -999;
    }
  } else {
    Serial.println("Failed to read HTTP response");
    return -999;
  }

  // Close the HTTP connection
  sendATCommand("AT+HTTPTERM");
}

void sendATCommand(String command) {
  sim800lSerial.println(command);
  delay(1000);
  while (sim800lSerial.available()) {
    Serial.write(sim800lSerial.read());
  }
}

String readResponse() {
  String response = "";
  while (sim800lSerial.available()) {
    char c = sim800lSerial.read();
    response += c;
  }
  return response;
}
void printSerialData()
{
 while(sim800lSerial.available()!=0)
 Serial.write(sim800lSerial.read());
}

My main goal is to get 200 http code and I will convert that temperature data

2

There are 2 answers

0
ashraf minhaj On

HTTP response code 603 is an error and it means 'Access Denied' - Authentication is successful but user doesn't have sufficient permission to call this API or at least get that data - Reference.

Try fetching simple things, and see if it works. My guess is you are trying to access something you don't have permission to.

You said you also have used python, try implementing this code using Python and see if it works.

If it still works with Python but does not with your sim card, try using different sim card.

0
enis On

UPDATE: I added some functions to handle messy responses (like AT+HTTPREAD and AT+HTTPACTION). Good thing is you can store http response to a variable using my code above. here :

#include <Arduino.h>
#define SIM800L_IP5306_VERSION_20200811
#include "utilities.h"
#include <ArduinoJson.h>


#define SerialMon Serial
// Set serial for AT commands (to the module)
#define SerialAT  Serial1

void setupModem()
{
#ifdef MODEM_RST
    // Keep reset high
    pinMode(MODEM_RST, OUTPUT);
    digitalWrite(MODEM_RST, HIGH);
#endif

    pinMode(MODEM_PWRKEY, OUTPUT);
    pinMode(MODEM_POWER_ON, OUTPUT);

    // Turn on the Modem power first
    digitalWrite(MODEM_POWER_ON, HIGH);

    // Pull down PWRKEY for more than 1 second according to manual requirements
    digitalWrite(MODEM_PWRKEY, HIGH);
    delay(100);
    digitalWrite(MODEM_PWRKEY, LOW);
    delay(1000);
    digitalWrite(MODEM_PWRKEY, HIGH);

    // Initialize the indicator as an output
    pinMode(LED_GPIO, OUTPUT);
    digitalWrite(LED_GPIO, LED_OFF);
}


void setup() {
    // Start serial communication
    SerialMon.begin(9600);
    setupModem();
    delay(15000);
    
    SerialAT.begin(9600, SERIAL_8N1, MODEM_RX, MODEM_TX); 
    
    SerialAT.println("AT");
    printSerialData();
    delay(2000);
    SerialAT.println("AT+CSQ");
    printSerialData();
    delay(2000);
    SerialAT.println("AT+CGATT?");
    printSerialData();
    delay(2000);
    SerialAT.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
    printSerialData();
    delay(2000);
    SerialAT.println("AT+SAPBR=3,1,\"APN\",\"internet\"");
    printSerialData();
    delay(2000);
    SerialAT.println("AT+SAPBR=1,1");
    printSerialData();
    delay(2000);
    
}

void loop() {
  
    SerialAT.println("AT+HTTPINIT");
    printSerialData();
    delay(1000);
    
    String url = "your URL";
    SerialAT.println("AT+HTTPPARA=\"URL\",\"" + url + "\"");
    delay(1000);
    printSerialData();
    
    // Start the HTTP GET request
    SerialAT.println("AT+HTTPACTION=0\r\n");
    getResponse_action("AT+HTTPACTION=0\r\n",10000);
    
    // Read the HTTP response
    SerialAT.println("AT+HTTPREAD\r\n");
    String response = getResponse("AT+HTTPREAD\r\n",10000);
     
  
    
    // Parse the JSON response
    StaticJsonDocument<1024> doc;
    DeserializationError error = deserializeJson(doc, response);

    JsonObject main = doc["main"];
    float temperature = doc["main"]["temp"];
    SerialMon.print("main object : ");
    SerialMon.println(temperature);
    delay(1000);
    
    
    if (!error) {
        // Check if the JSON structure is correct and extract data
        if (doc.containsKey("main") && doc["main"].containsKey("temp")) {
            float temperature = doc["main"]["temp"];
            // Convert from Kelvin to Celsius
            temperature -= 273.15;
            SerialMon.print("Temperature at somewhere : ");
            SerialMon.println(temperature);
        } else {
            SerialMon.println("JSON structure is missing temperature data");
        }
    } else {
        SerialMon.println("Failed to parse JSON");
        SerialMon.println(error.c_str()); // Print the parsing error for debugging
    }


    
    // Close the HTTP connection
    SerialAT.print("AT+HTTPTERM\r\n");
    printSerialData();


    // Wait for some time before the next request
    delay(20000);
 }


void printSerialData()
{
 while(SerialAT.available()!=0)
 SerialMon.write(SerialAT.read());
}

String getResponse(String command, unsigned long timeoutMillis) {
  unsigned long startTime = millis();
  String response = "";

  if (command.startsWith("AT+HTTPREAD")) {
    while (millis() - startTime < timeoutMillis) {
      if (SerialAT.available()) {
        String c = SerialAT.readStringUntil('\n');

        if (c.startsWith("{")) {
          SerialMon.print("Received JSON response : ");
          SerialMon.println(c);
          response = c;
          break; // Exit the loop when a JSON response is received
        }
      }
    }
  }

  return response; // Return the response (empty string if no JSON response)
}


String getResponse_action(String command, unsigned long timeoutMillis) {
  unsigned long startTime = millis();
  String response = "";

  if (command.startsWith("AT+HTTPACTION")) {
    while (millis() - startTime < timeoutMillis) {
      if (SerialAT.available()) {
        String c = SerialAT.readStringUntil('\n');

        if (c.startsWith("+HTTPACTION")) {
          SerialMon.print("Action Response : ");
          SerialMon.println(c);
          response = c;
          break; // Exit the loop when a JSON response is received
        }
      }
    }
  }

  return response; // Return the response (empty string if no JSON response)
}