I am trying to post GPS data to firebase using the Arduino Uno R3, SIM800L and NEO6M via GPRS. I have managed to connect to the APN, but I can't get the "http_client.connect()" to work. It keeps giving the same error.
Code
#define TINY_GSM_MODEM_SIM800
#define TINY_GSM_RX_BUFFER 256
#include <TinyGsmClient.h>
#include <ArduinoHttpClient.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#define SerialMonitor Serial
#define ARDUINO_GPS_RX 3
#define ARDUINO_GPS_TX 2
TinyGPSPlus tinyGPS;
SoftwareSerial ss(ARDUINO_GPS_TX , ARDUINO_GPS_RX);
#define gpsPort ss
#define rxPin 9
#define txPin 8
SoftwareSerial sim800(txPin,rxPin);
const char FIREBASE_HOST[] = "realtimedatabase.firebaseio.com";
const String FIREBASE_AUTH = "";
const String FIREBASE_PATH = "/gps-data/coordinate/employee_03";
const int SSL_PORT = 443;
char apn[] = "";
char user[] = "";
char pass[] = "";
TinyGsm modem(sim800);
TinyGsmClientSecure gsm_client_secure_modem(modem,0);
HttpClient http_client = HttpClient(gsm_client_secure_modem, FIREBASE_HOST, SSL_PORT);
unsigned long previousMillis = 0;
void setup()
{
Serial.begin(9600);
gpsPort.begin(9600);
Serial.println(F("gps serial initialize"));
sim800.begin(9600);
Serial.println(F("SIM800A serial initialize"));
Serial.println(F("Initializing modem..."));
modem.init();
String modemInfo = modem.getModemInfo();
Serial.print(F("Modem: "));
Serial.println(modemInfo);
http_client.setHttpResponseTimeout(10 * 1000);
}
void loop()
{
Serial.print(F("Connecting to "));
Serial.print(apn);
if (!modem.gprsConnect(apn, user, pass))
{
Serial.println(F(" fail"));
//delay(1000);
return;
}
Serial.println(F(" OK"));
if (modem.isGprsConnected()) { Serial.println("GPRS connected"); }
http_client.connect(FIREBASE_HOST, SSL_PORT);
while (true) {
if (!http_client.connected())
{
Serial.println();
http_client.stop();// Shutdown
Serial.println(F("HTTP not connected"));
break;
}
else
{
//ss.listen();
gps_loop();
}
}
}
void PostToFirebase(const char* method, const String & path , const String & data, HttpClient* http)
{
String response;
int statusCode = 0;
http->connectionKeepAlive();
String url;
if (path[0] != '/')
{
url = "/";
}
url += path + ".json";
url += "?auth=" + FIREBASE_AUTH;
Serial.print("POST:");
Serial.println(url);
Serial.print("Data:");
Serial.println(data);
String contentType = "application/json";
http->put(url, contentType, data);
statusCode = http->responseStatusCode();
Serial.print(F("Status code: "));
Serial.println(statusCode);
response = http->responseBody();
Serial.print(F("Response: "));
Serial.println(response);
if (!http->connected())
{
Serial.println();
http->stop();// Shutdown
Serial.println(F("HTTP POST disconnected"));
}
}
void gps_loop()
{
// ss.listen();
boolean newData = false;
for (unsigned long start = millis(); millis() - start < 2000;){
//ss.listen();
while (ss.available()){
if (tinyGPS.encode(ss.read())){
newData = true;
break;
}
}
}
if(true){
newData = false;
String latitude, longitude;
latitude = String(tinyGPS.location.lat(), 6);
longitude = String(tinyGPS.location.lng(), 6);
Serial.print("Latitude= ");
Serial.print(latitude);
Serial.print(" Longitude= ");
Serial.println(longitude);
String gpsData = "{";
gpsData += "\"lat\":" + latitude + ",";
gpsData += "\"lng\":" + longitude + "";
gpsData += "}";
PostToFirebase("PATCH", FIREBASE_PATH, gpsData, &http_client);
}
}
Error
gps serial initialize
SIM800A serial initialize
Initializing modem...
Modem: SIM800 R14.18
Connecting to apn OK
GPRS connected
HTTP not connected
Connecting to apn OK
GPRS connected
I have tried using ESP8266 (Wemos D1 R1) to save my GPS data to the database via WiFi, and that worked. Now, the problem is I can't connect to the firebase database using my Arduino and SIM800L. What should I do?
Related
I am using ESP32 integrated Sim7600CE module to transfer data to Firebase Realtime database using http and got 400 Bad Request, please help me to solve this.
13:36:48.693 -> Status code: 400
13:36:48.833 -> Response: <html>
13:36:48.833 -> <head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
13:36:48.833 -> <body>
13:36:48.833 -> <center><h1>400 Bad Request</h1></center>
#define TINY_GSM_MODEM_SIM7600
#define TINY_GSM_RX_BUFFER 650
#include <ArduinoJson.h>
#include <TinyGsmClient.h>
#include <ArduinoHttpClient.h> //https://github.com/arduino-libraries/ArduinoHttpClient
#include "TinyGsmClient.h"
#define SIM_RESET_PIN 15
#define SIM_AT_BAUDRATE 115200
#define GSM_PIN ""
#define SIM_TX 17
#define SIM_RX 16
const char FIREBASE_HOST[] = "smartgrid1-930b0-default-rtdb.firebaseio.com";
const String FIREBASE_AUTH = "zezoyo69fX9eqPDpjaom6CJAyXhnW081GlJ4ah5c";
const String FIREBASE_PATH = "/";
const int SSL_PORT = 443;
char APN[] = "v-internet"; //
char USER[] = "";
char PASS[] = "";
TinyGsm modem(Serial2);
TinyGsmClient gsm_client_secure_modem(modem);
HttpClient http_client = HttpClient(gsm_client_secure_modem, FIREBASE_HOST, SSL_PORT);
unsigned long previousMillis = 0;
// Hàm dùng để thiết lập modem SIM tạo kết nối GPRS
bool connectToGPRS() {
// Unlock SIM (nếu có)
if (GSM_PIN && modem.getSimStatus() != 3)
modem.simUnlock(GSM_PIN);
Serial.println("Ket noi toi nha mang...");
while (!modem.waitForNetwork(60000L)) {
Serial.println("._.");
delay(5000);
}
// Nếu không thấy sóng từ nhà mạng thì thoát hàm
if (!modem.isNetworkConnected())
return false;
Serial.println("Ket noi GPRS");
if (!modem.gprsConnect(APN)) {// Hàm kết nối tới gprs trả về true/false cho biết có kết nối được hay chưa
Serial.print("Khong the ket noi GPRS - ");
Serial.println(APN);
return false;
}
// Kiểm tra lại lần nữa để chắc cú
if (modem.isGprsConnected()){
Serial.println("Da ket noi duoc GPRS!");
return true;
}
return false;
}
// Hàm khởi động module SIM
bool initModemSIM() {
Serial.println("Bat dau khoi dong module SIM");
// Đặt chân reset của module xuống LOW để chạy
pinMode(SIM_RESET_PIN, OUTPUT);
digitalWrite(SIM_RESET_PIN, LOW);
delay(5000);
Serial2.begin(SIM_AT_BAUDRATE);// Module SIM giao tiếp với ESP qua cổng Serial2 bằng AT cmds
if (!modem.restart()) {
Serial.println("Khong the khoi dong lai module SIM => Co loi");
return false;
}
return true;
}
void setup() {
Serial.begin(115200);
if (initModemSIM()){
while(!connectToGPRS()) delay(100);
}
if (modem.isGprsConnected()) {
Serial.print(F("Connecting to "));
Serial.println(APN);
if (!modem.gprsConnect(APN, USER, PASS))
{
Serial.println(" fail");
delay(1000);
return;
}
}
if (initModemSIM()){
while(!connectToGPRS()) delay(100);
}
modem.restart();
String modemInfo = modem.getModemInfo();
Serial.print("Modem: ");
Serial.println(modemInfo);
http_client.setHttpResponseTimeout(10 * 1000); //^0 secs timeout
}
void loop() {
Serial.print(F("Connecting to "));
Serial.println(APN);
if (!modem.gprsConnect(APN, USER, PASS))
{
Serial.println(" fail");
delay(1000);
return;
}
Serial.println(" OK");
http_client.connect(FIREBASE_HOST, SSL_PORT);
while (true) {
if (!http_client.connected())
{
Serial.println();
http_client.stop();// Shutdown
Serial.println("HTTP not connect");
break;
}
else
{
dht_loop();
}
}
}
void PostToFirebase(const char* method, const String & path , const String & data, HttpClient* http)
{
String response;
int statusCode = 0;
http->connectionKeepAlive(); // Currently, this is needed for HTTPS
String url;
if (path[0] != '/')
{
url = "/";
}
url += path + ".json";
url += "?auth=" + FIREBASE_AUTH;
Serial.print("POST:");
Serial.println(url);
Serial.print("Data:");
Serial.println(data);
String contentType = "application/json";
http->put(url, contentType, data);
statusCode = http->responseStatusCode();
Serial.print("Status code: ");
Serial.println(statusCode);
response = http->responseBody();
Serial.print("Response: ");
Serial.println(response);
// if (!http->connected())
// {
// Serial.println();
// http->stop();// Shutdown
// Serial.println("HTTP POST disconnected");
// }
}
void dht_loop()
{
String h = String(random(1,100));
delay(100);
Serial.print("h = ");
Serial.println(h);
String Data = "{";
Data += "\"Sim\":" + h + "";
Data += "}";
PostToFirebase("PATCH", FIREBASE_PATH, Data, &http_client);
}
This is the problem continue from my previous question. After I added for listen() in loop function, the data can be read from the GPS and shown in Serial Monitor, but the http connection for now is failed, and it shows the status -2, anyone knows this status error? Is it I need to add other function as well?
#define TINY_GSM_MODEM_SIM800
#define TINY_GSM_RX_BUFFER 256
#include <TinyGsmClient.h>
#include <ArduinoHttpClient.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#define SerialMonitor Serial
#define ARDUINO_GPS_RX 10
#define ARDUINO_GPS_TX 11
TinyGPSPlus tinyGPS;
SoftwareSerial ss(ARDUINO_GPS_TX , ARDUINO_GPS_RX);
#define gpsPort ss
#define rxPin 8
#define txPin 9
SoftwareSerial sim800(txPin,rxPin);
const char FIREBASE_HOST[] = "my-firebase-host";
const String FIREBASE_AUTH = "my-firebase-auth";
const String FIREBASE_PATH = "/";
const int SSL_PORT = 443;
char apn[] = "internet";
char user[] = "";
char pass[] = "";
TinyGsm modem(sim800);
TinyGsmClientSecure gsm_client_secure_modem(modem, 0);
HttpClient http_client = HttpClient(gsm_client_secure_modem, FIREBASE_HOST, SSL_PORT);
unsigned long previousMillis = 0;
void setup()
{
Serial.begin(9600);
gpsPort.begin(9600);
Serial.println(F("gps serial initialize"));
sim800.begin(9600);
Serial.println(F("SIM800A serial initialize"));
Serial.println(F("Initializing modem..."));
modem.init();
String modemInfo = modem.getModemInfo();
Serial.print(F("Modem: "));
Serial.println(modemInfo);
http_client.setHttpResponseTimeout(10 * 1000);
}
void loop()
{
Serial.print(F("Connecting to "));
Serial.print(apn);
if (!modem.gprsConnect(apn, user, pass))
{
Serial.println(F(" fail"));
//delay(1000);
return;
}
Serial.println(F(" OK"));
http_client.connect(FIREBASE_HOST, SSL_PORT);
while (true) {
if (!http_client.connected())
{
Serial.println();
http_client.stop();// Shutdown
Serial.println(F("HTTP not connected"));
break;
}
else
{
//ss.listen();
gps_loop();
}
}
}
void PostToFirebase(const char* method, const String & path , const String & data, HttpClient* http)
{
String response;
int statusCode = 0;
http->connectionKeepAlive();
String url;
if (path[0] != '/')
{
url = "/";
}
url += path + ".json";
url += "?auth=" + FIREBASE_AUTH;
Serial.print("POST:");
Serial.println(url);
Serial.print("Data:");
Serial.println(data);
String contentType = "application/json";
http->put(url, contentType, data);
statusCode = http->responseStatusCode();
Serial.print(F("Status code: "));
Serial.println(statusCode);
response = http->responseBody();
Serial.print(F("Response: "));
Serial.println(response);
if (!http->connected())
{
Serial.println();
http->stop();// Shutdown
Serial.println(F("HTTP POST disconnected"));
}
}
void gps_loop()
{
ss.listen();
boolean newData = false;
for (unsigned long start = millis(); millis() - start < 2000;){
//ss.listen();
while (ss.available()){
if (tinyGPS.encode(ss.read())){
newData = true;
break;
}
}
}
if(true){
newData = false;
String latitude, longitude;
latitude = String(tinyGPS.location.lat(), 6);
longitude = String(tinyGPS.location.lng(), 6);
Serial.print("Latitude= ");
Serial.print(latitude);
Serial.print(" Longitude= ");
Serial.println(longitude);
String gpsData = "{";
gpsData += "\"lat\":" + latitude + ",";
gpsData += "\"lng\":" + longitude + "";
gpsData += "}";
PostToFirebase("PATCH", FIREBASE_PATH, gpsData, &http_client);
}
}
I am using Arduino Uno R3, GSM SIM 800 and GPS to get the latitude and longitude and send to the Firebase cloud, but end up I only can get 0.0000 for the location, was trying for TinyGPS++ code before and the GPS is working. Can someone helps me to see where is the error, I really tried for many solutions but still can't work
*** solved for the above problems
But now comes with the problem is about the http connect with the firebase. The status showing -2 for the http connection problem.
#define TINY_GSM_MODEM_SIM800
#define TINY_GSM_RX_BUFFER 256
#include <TinyGsmClient.h>
#include <ArduinoHttpClient.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#define SerialMonitor Serial
#define ARDUINO_GPS_RX 11
#define ARDUINO_GPS_TX 10
TinyGPSPlus tinyGPS;
SoftwareSerial ss(ARDUINO_GPS_TX , ARDUINO_GPS_RX);
#define gpsPort ss
#define rxPin 3
#define txPin 2
SoftwareSerial sim800(txPin,rxPin);
const char FIREBASE_HOST[] = "my_firebase_host";
const String FIREBASE_AUTH = "my_firebase_auth";
const String FIREBASE_PATH = "/";
const int SSL_PORT = 443;
char apn[] = "internet";
char user[] = "";
char pass[] = "";
TinyGsm modem(sim800);
TinyGsmClientSecure gsm_client_secure_modem(modem, 0);
HttpClient http_client = HttpClient(gsm_client_secure_modem, FIREBASE_HOST, SSL_PORT);
unsigned long previousMillis = 0;
void setup()
{
Serial.begin(9600);
gpsPort.begin(9600);
Serial.println(F("gps serial initialize"));
sim800.begin(9600);
Serial.println(F("SIM800A serial initialize"));
Serial.println(F("Initializing modem..."));
modem.init();
String modemInfo = modem.getModemInfo();
Serial.print(F("Modem: "));
Serial.println(modemInfo);
http_client.setHttpResponseTimeout(10 * 1000);
}
void loop()
{
Serial.print(F("Connecting to "));
Serial.print(apn);
if (!modem.gprsConnect(apn, user, pass))
{
Serial.println(F(" fail"));
//delay(1000);
return;
}
Serial.println(F(" OK"));
http_client.connect(FIREBASE_HOST, SSL_PORT);
while (true) {
if (!http_client.connected())
{
Serial.println();
http_client.stop();// Shutdown
Serial.println(F("HTTP not connected"));
break;
}
else
{
gps_loop();
}
}
}
void PostToFirebase(const char* method, const String & path , const String & data, HttpClient* http)
{
String response;
int statusCode = 0;
http->connectionKeepAlive();
String url;
if (path[0] != '/')
{
url = "/";
}
url += path + ".json";
url += "?auth=" + FIREBASE_AUTH;
Serial.print("POST:");
Serial.println(url);
Serial.print("Data:");
Serial.println(data);
String contentType = "application/json";
http->put(url, contentType, data);
statusCode = http->responseStatusCode();
Serial.print(F("Status code: "));
Serial.println(statusCode);
response = http->responseBody();
Serial.print(F("Response: "));
Serial.println(response);
if (!http->connected())
{
Serial.println();
http->stop();// Shutdown
Serial.println(F("HTTP POST disconnected"));
}
}
void gps_loop()
{
boolean newData = false;
for (unsigned long start = millis(); millis() - start < 2000;){
while (ss.available()){
if (tinyGPS.encode(ss.read())){
newData = true;
break;
}
}
}
if(true){
newData = false;
String latitude, longitude;
latitude = String(tinyGPS.location.lat(), 6);
longitude = String(tinyGPS.location.lng(), 6);
Serial.print("Latitude= ");
Serial.print(latitude);
Serial.print(" Longitude= ");
Serial.println(longitude);
String gpsData = "{";
gpsData += "\"lat\":" + latitude + ",";
gpsData += "\"lng\":" + longitude + "";
gpsData += "}";
PostToFirebase("PATCH", FIREBASE_PATH, gpsData, &http_client);
}
}
The error I'm facing is about using talkback function of thingspeak to control my Arduino LED. it cannot execute the talkback command to off the led. The error is in my void get talkback. Please help me
#include "ThingSpeak.h"
#include <Ethernet.h>
#define redLED 8
byte mac[] = {0x90, 0xA2, 0xDA, 0x10, 0x40, 0x4F};
const String channelsAPIKey = "";
const String talkBackAPIKey = "";
const String talkBackID = "";
const String talkCommandID = "";
const unsigned int getTalkBackInterval = 10 * 1000;
const unsigned int updateChannelsInterval = 15 * 1000;
String talkBackCommand;
long lastConnectionTimeChannels = 0;
boolean lastConnectedChannels = false;
int failedCounterChannels = 0;
long lastConnectionTimeTalkBack = 0;
boolean lastConnectedTalkBack = false;
int failedCounterTalkBack = 0;
char charIn;
// Arduino Ethernet Client is initialized
EthernetClient client;
void setup()
{
Ethernet.init(10); // Most Arduino Ethernet hardware
Serial.begin(9600); //Initialize serial
// start the Ethernet connection:
pinMode(redLED, OUTPUT);
digitalWrite(redLED, HIGH);
}
void loop()
{
getTalkBack();
}
void getTalkBack()
{
String tsData;
tsData = talkBackID + "/commands/execute?api_key=" + talkBackAPIKey;
if ((!client.connected() && (millis() - lastConnectionTimeTalkBack > getTalkBackInterval)))
{
if (client.connect("api.thingspeak.com", 80))
{
client.println("GET /talkbacks/" + tsData + " HTTP/1.0");
client.println();
lastConnectionTimeTalkBack = millis();
if (client.connected())
{
Serial.println("---------------------------------------");
Serial.println("GET TalkBack command");
Serial.println();
Serial.println("Connecting to ThingSpeak");
Serial.println();
Serial.println();
Serial.println("Server response");
Serial.println();
failedCounterTalkBack = 0;
while (client.connected() && !client.available()) delay(2000); //waits for data
while (client.connected() || client.available())
{
charIn = client.read();
talkBackCommand += charIn;
Serial.print(charIn);
if (talkBackCommand == "LED_ON")
{
digitalWrite(redLED, HIGH);
}
if (talkBackCommand == "LED_OFF")
{
digitalWrite(redLED, LOW);
}
}
if (talkBackCommand = talkBackCommand.substring(talkBackCommand.indexOf("_CMD_") + 5));
{
Serial.println();
Serial.println();
Serial.println("Disconnected");
Serial.println();
Serial.println("--------");
Serial.println();
Serial.println("talkback command was");
Serial.println();
Serial.println("--------");
Serial.println();
Serial.println(talkBackCommand);
Serial.println("--------");
Serial.println();
}
}
else
{
failedCounterTalkBack++;
Serial.println("Connection to ThingSpeak failed (" + String(failedCounterTalkBack, DEC) + ")");
Serial.println();
lastConnectionTimeChannels = millis();
}
}
}
if (failedCounterTalkBack > 3 )
{
startEthernet();
}
client.stop();
Serial.flush();
}
The below is a image from my serial monitor. It shows that I can capture the command but couldn't execute it.
Looks like you are reading and appending all the received bytes to talkBackCommand. So, talkBackCommand is "HTTP/1.1 200 OK Date...." and if (talkBackCommand == "LED_ON") would never be true.
I think you wanted to see if the received data contain your commands LED_ON or LED_OFF. You can do something like this:
if (talkBackCommand.indexOf("LED_ON") != -1)
indexOf() locates a String in a String and returns index or -1 if not found.
See more info about indexOf() here: https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/indexof/
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
byte mac[] = { 0xde, 0xed, 0xba, 0xfe, 0xfe, 0xed};
String macstr="deedbafefeed";
byte ip[] = {192,168,1,1 };
char servername[]="quickstart.messaging.internetofthings.ibmcloud.com";
String clientName = String("d:quickstart:iotsample-arduino:")+macstr;
String topicName = String("iot-2/evt/ledstat/fmt/json");
float tempF = 0.0;
float tempC = 0.0;
float humidity = 0.0;
EthernetClient ethClient;
PubSubClient client(servername, 1883,0,ethClient);
void setup()
{
Ethernet.begin(mac,ip);
Serial.begin(9600);
}
void loop()
{
char clientStr[324];
clientName.toCharArray(clientStr,324);
char topicStr[26];
topicName.toCharArray(topicStr,26);
getData();
if (!client.connected()) {
Serial.println(client.connected());
Serial.print("Trying to connect to: ");
Serial.println(clientStr);
client.connect(clientStr);
Serial.println(client.connected());
Serial.print("attempt to send ");
Serial.println(buildJson());
delay(20000);
}
if (client.connected() ) {
String json = buildJson();
char jsonStr[200];
json.toCharArray(jsonStr,200);
boolean pubresult = client.publish(topicStr,jsonStr);
Serial.print("attempt to send ");
Serial.println(jsonStr);
Serial.print("to ");
Serial.println(topicStr);
if (pubresult)
Serial.println("successfully sent");
else
Serial.println("unsuccessfully sent");
}
delay(5000);
}
String buildJson() {
String data = "\n{";
data+="\n";
data+= "\"d\": {";
data+="\n";
data+="\"myName\": \"Arduino DHT11\",";
data+="\n";
data+="\"temperature (F)\": ";
data+=(int)tempF;
data+= ",";
data+="\n";
data+="\"temperature (C)\": ";
data+=(int)tempC;
data+= ",";
data+="\n";
data+="\"humidity\": ";
data+=(int)humidity;
data+="\n";
data+="}";
data+="\n";
data+="}";
return data;
}
void getData() {
int chk=0;
switch (chk)
{
case 0:
Serial.println("Read OK");
humidity = 90;
tempF = 12;
tempC = 56;
break;
case -1:
Serial.println("Checksum error");
break;
case -2:
Serial.println("Time out error");
break;
default:
Serial.println("Unknown error");
break;
}
}
the mac address when given in upper case also gives the same result. Trying any other mac address doesn't show any thing connected on the quickstart website.
The output of serial monitor and what is shown on the quickstart website is shown below
enter image description here
Have you tried recipe on Connecting Arduino Uno to IBM Watson IoT Platform? Where did you get this code from? Looks like the code that you are using is not same as the one given with the recipe. Here is the link to the recipe - https://developer.ibm.com/recipes/tutorials/connect-an-arduino-uno-device-to-the-ibm-internet-of-things-foundation/