Arduino Nano + GPS + GPRS + LoRa + WebSocket + PHP + MySQL

Question for Arduino Forum

Hello I'm working on a project in which I need to remotely control, Radio Communication Towers Autonomous Safety Lights.

At the top of the tower there's the Master light ,that sends data via GPRS to a central server, for example, the GPS location, battery status, charge status ,condition ON/OFF, blinks per second and a few things more.

On the lower levels, the other lights ( you can have more than 1 light on each floor, more specifically, one in each corner, or at least 2 lights, on opposite sides ), report their status to the master/

The idea is to interconnect for examples 2 towers to get redundancy, in case the cellular network goes down, and use LoRa to send messages between towers (10 miles maximum ).

I’ve been testing alone each of the modules that I have, and they seem to work fine, but I’m having a bit of trouble to get all the system working together.

Actually I can read the NMEA sentences from the GPS, and I can contact servers using my modem.

But after watching the server with MySQL database, there's no trace of the data being sent.

Maybe the PHP script is wrong, but really it looks so simple that I doubt that's the problem. I believe that the delays I wrote after each of the AT commands ,are giving me some trouble. But I don’t have any previous experience with this kind of stuff.

My Arduino has plenty of space left and is working fine.

The idea is to send the GPS data to the MySQL server with the SIM800L, establish a WebSocket to interact between the Arduino and the server, and the WebPage and the server, so I can control for example the switching of the lights, the brightness and also show the location in google maps of the light (I’m planning on using GeoFencing to detect movement of the lights, besides having a shock sensor ).

If there's some kind of alarm it will send an email to a list of recipients.

I need to protect the access to the web page with a simple user/password, and if its possible...log time and date of each user that logs in.

I know I’ve wrote a lot and that can be a little bit intimidating but ……

If someone is willing to help me I can post the code and start to troubleshoot it.

Thank you in advance.

My hardware specs are:

Modem SIM800L

GPS UBLOX 7

Arduino Nano

LoRa DRF1278DM

Software specs:

Arduino IDE

PHP Servers Programming

HTML Client

Database MySQL

Google Maps API

how do you want to connect this modules to Nano? has Nano enough pins?

Sure, I'm currently using the Software Serial library so I can connect multiple devices.
That part is working fine.

show schematic

For example using pins 8,9 and 10,11 for the GPS and SIM800L ,TX and RX.

Although you say that your sketch works, but you don't get data in the DB so it actually does not work. Two or more SoftwareSerial instances are very tricky. Only one can listen at a time. I think it will help others to help you if you post you sketch.

For debugging you need the standard serial port but once it really works I would move one of the SoftwareSerial instances to the HardwareSerial. Or opt for another board with more hardware serial ports; Mega is the obvious choice (3 extra hardware serial ports), Micro and Leonardo have a hardware serial port that is independent of the communication with the PC and the Nanoa Every can be configured for multiple serial ports (not sure of the exact details).

I don't know enough about your devices to be of further help.

Then use an Arduino that is capable of providing adequate and reliable hardware connections.

I would suggest that under no circumstances should you consider using an Arduino that forces you to use software serial interfaces for the GPS, SIM800L and LoRa device.

Not only is the hardware selected likely to be inadequate, the Nano has very limited memory and you seem to want to run a heap of applications.

Here is the part that involves GPS and GPRS . Do you think a ESP32 could be a good choice ?


#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <AltSoftSerial.h>

#define rxPin 8
#define txPin 9
SoftwareSerial sim800L(rxPin,txPin); 

//GPS Module RX pin to Arduino 9
//GPS Module TX pin to Arduino 8
AltSoftSerial neogps(10,11);

TinyGPSPlus gps;

unsigned long previousMillis = 0;
long interval = 60000;


void setup()
{
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(9600);
  
  //Begin serial communication with Arduino and SIM800L
  sim800L.begin(9600);

  //Begin serial communication with Arduino and SIM800L
  neogps.begin(9600);

  Serial.println("Initializing...");
  //delay(10000);

  //Once the handshake test is successful, it will back to OK
  sendATcommand("AT", "OK", 2000);
  sendATcommand("AT+CMGF=1", "OK", 2000);
  //sim800L.print("AT+CMGR=40\r");
  
}

void loop()
{
  while(sim800L.available()){
    Serial.println(sim800L.readString());
  }
  while(Serial.available())  {
    sim800L.println(Serial.readString());
  }

    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis > interval) {
       previousMillis = currentMillis;
       sendGpsToServer();
    }
}

int sendGpsToServer()
{
    //Can take up to 60 seconds
    boolean newData = false;
    for (unsigned long start = millis(); millis() - start < 2000;){
      while (neogps.available()){
        if (gps.encode(neogps.read())){
          newData = true;
          break;
        }
      }
    }
  
    //If newData is true
    if(true){
      newData = false;
      
      String latitude, longitude;
      float altitude;
      unsigned long date, time, speed, satellites;
  
      latitude = String(gps.location.lat(), 6); // Latitude in degrees (double)
      longitude = String(gps.location.lng(), 6); // Longitude in degrees (double)
      altitude = gps.altitude.meters(); // Altitude in meters (double)
      date = gps.date.value(); // Raw date in DDMMYY format (u32)
      time = gps.time.value(); // Raw time in HHMMSSCC format (u32)
      speed = gps.speed.kmph();
      
      Serial.print("Latitude= "); 
      Serial.print(latitude);
      Serial.print(" Longitude= "); 
      Serial.println(longitude);
  
      //if (latitude == 0) {return 0;}
      
      String url, temp;
      url = "http://https://balizas2.000webhostapp.com/gpsdata.php?lat=";
      url += latitude;
      url += "&lng=";
      url += longitude;

      

      Serial.println(url);    
      delay(3000);
          
   sim800L.println("AT+CIPSTATUS");//Consultar el estado actual de la conexión
delay(2000);
sim800L.println("AT+CIPMUX=0");//comando configura el dispositivo para una conexión IP única o múltiple (0=única).
delay(3000);
mostrarDatosSeriales();
sim800L.println("AT+CSTT=\"antel.lte\",\"Vera 1\",\"\"");//comando configura el APN, nombre de usuario y contraseña."gprs.movistar.com.ar","wap","wap"->Movistar Arg.
delay(1000);
mostrarDatosSeriales();
sim800L.println("AT+CIICR");//REALIZAR UNA CONEXIÓN INALÁMBRICA CON GPRS O CSD
delay(3000);
mostrarDatosSeriales();
sim800L.println("AT+CIFSR");// Obtenemos nuestra IP local
delay(2000);
mostrarDatosSeriales();
    //Init HTTP service
    sendATcommand("AT+HTTPINIT", "OK", 2000); 
    sendATcommand("AT+HTTPPARA"="CID","1", "OK", 1000); //repasar este parametro
    sim800L.print("AT+HTTPPARA=\"URL\",\"");
    sim800L.print(url);
    sendATcommand("\"", "OK", 1000);
    //Set up the HTTP action
    sendATcommand("AT+HTTPACTION=0", "0,200", 1000);
    //Terminate the HTTP service
    sendATcommand("AT+HTTPTERM", "OK", 1000);
    //shuts down the GPRS connection. This returns "SHUT OK".
    sendATcommand("AT+CIPSHUT", "SHUT OK", 1000);

  }
  return 1;    
}

int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout){

    uint8_t x=0,  answer=0;
    char response[100];
    unsigned long previous;

    //Initialice the string
    memset(response, '\0', 100);
    delay(100);
    
    //Clean the input buffer
    while( sim800L.available() > 0) sim800L.read();
    
    if (ATcommand[0] != '\0'){
      //Send the AT command 
      sim800L.println(ATcommand);
    }

    x = 0;
    previous = millis();

    //this loop waits for the answer with time out
    do{
        //if there are data in the UART input buffer, reads it and checks for the asnwer
        if(sim800L.available() != 0){
            response[x] = sim800L.read();
            //Serial.print(response[x]);
            x++;
            // check if the desired answer (OK) is in the response of the module
            if(strstr(response, expected_answer) != NULL){
                answer = 1;
            }
        }
    }while((answer == 0) && ((millis() - previous) < timeout));

  Serial.println(response);
  return answer;
}
void mostrarDatosSeriales()//Muestra los datos que va entregando el sim800
{
while(sim800L.available()!=0) //Mientras existan datos desde el SIM800...
Serial.write(sim800L.read()); //Escribirlos en el puerto TX serial de Arduino 
}

I see, I thought that as I was sending a few bytes, the multitasking of the virtual serial ports was enough. But I understand that's not the case.

By applications you mean for example opening the web sockets, to make a bidirectional communication?

Please post your code as described in How to get the best out of this forum.

Edit your post #8, select all code and click the <CODE> button. Next save your post.

Better as it will maintain syntax highlighting

  1. Edit your post
  2. Place ```cpp (that is, three backticks plus the 'word' cpp) on a line before it.
  3. Place ``` (three backticks) on a new line after the code.
  4. Save your post.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.