Project Help Multiple things at the same time Arduino

can someone can help me Identify the problem of the code that I posted? its just I cant seem to make it work. the code is the combination of two codes the GPS code and the TIMER code. The code will work if
the timer code is commented which is the proc_TIMER and proc_SIM808 in the void loop. (before combining I tested the Timer part of the code and it is working).

This is what I wanna do:

I am trying to make a project that via txt the LCD will start a timer. While the timer is running , the GSM can send coordinates to the phone when texted via phone without the timer being interrupted and stop. But all the things that I did seems to not work. The things that I managed to succeed in making is:

GPS when texted it can send coordinates to phone. And also the other one is

when texted the LCD start the timer (for example start2, means 2 minutes.)

my goal is to combine the two of them in one whole code and that’s where I keep failing.
I hope someone can guide me and can help me make progress. Thank you very much!
MATERIALS:
Arduino UNO
LCD 16x2
Sim808

#include<LiquidCrystal.h>
#include <SoftwareSerial.h>
#include <Wire.h>

SoftwareSerial gps (10, 11); // rx-tx , tx-rx
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

//Loop Declarations
unsigned long previousMillis;
uint8_t fixCount = 0;

//LCD Variables
int runtime;
int countminutes;
int countseconds = 0;
bool overdue = false;
bool runme = false;
String sim808data;

//GPS VAR
int Contrast = 50;
char str[70];
String gpsString = "";
char *test = "$GPGGA";
String latitude = "No Range      ";
String longitude = "No Range     ";
int temp = 0, i;
int timetemp = 0;
boolean gps_status = 0;

void setup()
{
  analogWrite(9, Contrast);
  lcd.begin(16, 2);
  Serial.begin(9600);
  gps.begin(9600);
  lcd.print("Vehicle Tracking");
  lcd.setCursor(0, 1);
  lcd.print("    System      ");
  delay(2000);
  gsm_init();
  lcd.clear();
  Serial.println("AT+CSCS=\"GSM\"");
  Serial.println("AT+CMGF=1");
  Serial.println("AT+CNMI=2,2,0,0,0");
  lcd.print("GPS Initializing");
  lcd.setCursor(0, 1);
  lcd.print("  No GPS Range  ");
  get_gps();
  delay(2000);
  lcd.clear();
  lcd.print("GPS Range Found");
  lcd.setCursor(0, 1);
  lcd.print("GPS is Ready");
  delay(2000);
  lcd.clear();
  lcd.print("System Ready");
  temp = 0;
  timetemp = 0;
}

void loop() {
  proc_SIM808();
  proc_TIMER();
  serialEvent();
  
  if (temp)
  {
    get_gps();
    tracking();
  }
}

void serialEvent()
{
  while (Serial.available())
  {
    if (Serial.find("Track"))
    {
      temp = 1;
      break;
    }
    else
    {
      temp = 0;
    }
  }
}

void gsm_init()
{
  lcd.clear();
  lcd.print("Finding Module..");
  boolean at_flag = 1;
  while (at_flag)
  {
    Serial.println("AT");
    while (Serial.available() > 0)
    {
      if (Serial.find("OK"))
        at_flag = 0;
    }

    delay(1000);
  }
  lcd.clear();
  lcd.print("Module Connected..");
  delay(1000);
  lcd.clear();
  lcd.print("Disabling ECHO");
  boolean echo_flag = 1;
  while (echo_flag)
  {
    Serial.println("ATE0");
    while (Serial.available() > 0)
    {
      if (Serial.find("OK"))
        echo_flag = 0;
    }
    delay(1000);
  }
  lcd.clear();
  lcd.print("Echo OFF");
  delay(1000);
  lcd.clear();
  lcd.print("Finding Network..");
  boolean net_flag = 1;
  while (net_flag)
  {
    Serial.println("AT+CPIN?");
    while (Serial.available() > 0)
    {
      if (Serial.find("+CPIN: READY"))
        net_flag = 0;
    }
    delay(1000);
  }
  lcd.clear();
  lcd.print("Network Found..");
  delay(1000);
  lcd.clear();
}
//GPS CODE - - - - - - - - - - - -- - - - - - - - - - - - - -
void gpsEvent()
{
  gpsString = "";
  while (1)
  {
    while (gps.available() > 0)          //checking serial data from GPS
    {
      char inChar = (char)gps.read();
      gpsString += inChar;                   //store data from GPS into gpsString
      i++;
      if (i < 7)
      {
        if (gpsString[i - 1] != test[i - 1])    //checking for $GPGGA sentence
        {
          i = 0;
          gpsString = "";
        }
      }
      if (inChar == '\r')
      {
        if (i > 65)
        {
          gps_status = 1;
          break;
        }
        else
        {
          i = 0;
        }
      }
    }
    if (gps_status)
      break;
  }
}


void get_gps()
{
  gps_status = 0;
  int x = 0;
  while (gps_status == 0)
  {
    gpsEvent();
    int str_lenth = i;
    latitude = "";
    longitude = "";
    int comma = 0;
    while (x < str_lenth)
    {
      if (gpsString[x] == ',')
        comma++;
      if (comma == 2)     //extract latitude from string
        latitude += gpsString[x + 1];
      else if (comma == 4)     //extract longitude from string
        longitude += gpsString[x + 1];
      x++;
    }
    int l1 = latitude.length();
    latitude[l1 - 1] = ' ';
    l1 = longitude.length();
    longitude[l1 - 1] = ' ';
    Serial.println("Debugging: GPS Area");
    Serial.println(latitude);
    Serial.println(longitude);
    /*
      // Debugging Purposes
      lcd.clear();
      lcd.print("Lat:");
      lcd.print(latitude);
      lcd.setCursor(0, 1);
      lcd.print("Long:");
      lcd.print(longitude);
    */
    i = 0; x = 0;
    str_lenth = 0;
    delay(2000);
  }
}


//SMS CODE - - - - - - - - - - - - - - - - - - - - - - - - - -
void init_sms()
{
  Serial.println("AT+CMGS=\"+639058072930\"");   // use your 10 digit cell no. here
  delay(400);
}

void send_data(String message)
{
  Serial.println(message);
  delay(200);
}

void send_sms()
{
  Serial.write(26);
}

/*
  // Debugging Purposes
  void lcd_status()
  {
  lcd.clear();
  lcd.print("Message Sent");
  delay(2000);
  lcd.clear();
  lcd.print("System Ready");
  return;
  }
*/

void tracking()
{
  init_sms();
  send_data(longitude);
  send_data(latitude);
  send_sms();
  delay(500);
  //lcd_status();
}

//TIMER LCD CODE - - - - - - - - - - - -- - - - - - - - - - - - - -
void proc_SIM808() {
  if (Serial.available()) {
    sim808data = Serial.readString();

    if (sim808data.indexOf("start") > 0) {
      int value = sim808data.indexOf("start");
      runtime = sim808data.substring(value + 5).toInt();
      countseconds = 0;
      runme = true;
    }

    if (sim808data.indexOf("stop") > 0) {
      if (overdue)
      {
        lcd.setCursor(0, 1);
        lcd.print(F("--DEVICE STOP!--"));
      } else {
        lcd.setCursor(0, 1);
        lcd.print(F("--DEVICE STOP!--"));
      }
      runme = false;
      overdue = false;
    }
    Serial.println(sim808data);
  }
}

void proc_TIMER() {
  if (runme == true) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= 1000 ) {
      lcd.clear();
      if (runtime <= 0 && overdue) {
        if (countseconds == 59)
        {
          runtime--;
          countseconds = 0;
        }
        lcd.setCursor(0, 1);
        lcd.print(F("Cost:"));
        lcd.print((runtime * -1));
        countseconds++;
      } else if (runtime >= 0) {
        if (countseconds == 0) {
          runtime--;
          countseconds = 59;
          if (runtime == -1) {
            overdue = true;
            runtime = 0;
            countseconds = 1;
          }
        }
        countseconds--;
      }
      lcd.setCursor(5, 0);
      if (runtime == 0 && overdue) {
        lcd.print("-" + runtime);
      }
      lcd.print(runtime);
      lcd.print(F(":"));
      lcd.print(countseconds);
      previousMillis = currentMillis;
    }
  }
}

And i also made another code for the gps if you guys want to see

#include <AltSoftSerial.h>
#include <Wire.h>
#include <NMEAGPS.h>

AltSoftSerial port (8, 9); // rx-tx , tx-rx

//GPS Variables
static NMEAGPS  gps;
static gps_fix  fix;
char message[30] = {0};
char floatlat[10];
char floatlon[11];
float dlat, dlon;
String sim808data;

//Loop Declarations
unsigned long previousMillis;
uint8_t fixCount = 0;


void setup()
{
  Serial.begin(9600);
  port.begin(4800);
  delay(300);
  clear_Sim();
  gps_Start();
  port.println("AT+CSCS=\"GSM\"");
  port.println("AT+CMGF=1");
  port.println("AT+CNMI=1,2,0,0,0");
  delay(5000);
  Serial.println(F("DEVICE READY"));
}


void loop() {
  locData();
}

//SMS CODE - - - - - - - - - - - - - - - - - - - - - - - - - -
void clear_Sim() {
  port.print("AT+CMGD=4\n");
  delay(300);
  while (port.available())
    Serial.write(port.read());
}

void send_SMS(char* data) {
  port.print("AT+CMGS=\"+639058072930\"\n");
  delay(100);
  port.println(data);
  delay(100);
  port.println((char)26);
  delay(100);
  port.println();
  delay(500);
}

//GPS CODE - - - - - - - - - - - -- - - - - - - - - - - - - -
void gps_Start() {
  Serial.println(F("GPS STARTING."));
  bool startup = false;
  port.print("AT+CGNSPWR=1\r\n");
  delay(500);
  port.print("AT+CGNSTST=1\r\n");
  delay(500);
  port.println(F("GPS READY"));
  while (!startup) {
    if (port.available()) {
      sim808data = port.readString();
      Serial.println(sim808data);
      startup = true;
    }
  }
}

void locData() {
  if (gps.available(port)) {
    fix = gps.read();
    fixCount++;

    if (fixCount >= 10) {
      fixCount = 0;
      Serial.println("\nNumber of satellies: ");
      if (fix.valid.satellites) {
        Serial.println(fix.satellites);
      }

      if (fix.valid.location) {
        dlat = fix.latitude();
        dlon = fix.longitude();
      }

      dtostrf(dlat,  9, 6, floatlat);
      dtostrf(dlon, 10, 6, floatlon);
      Serial.println(floatlat);
      Serial.println(floatlon);

      //SEND TO SMS
      strncat(message, floatlat, 30);
      strncat(message, ";", 30);
      strncat(message, floatlon, 30);
      //send_SMS(message);
    }
  }
}

This is the Timer Code

#include <AltSoftSerial.h>
#include <LiquidCrystal.h>
#include <Wire.h>

AltSoftSerial port (8, 9); // rx-tx , tx-rx
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//LCD Variables
int runtime;
int countminutes;
int countseconds = 0;
bool overdue = false;
bool runme = false;
int Contrast = 75;

//Loop Declarations
unsigned long previousMillis;
uint8_t fixCount = 0;
String sim808data;

void setup()
{
  Serial.begin(9600);
  port.begin(4800);
  delay(300);
  analogWrite(6, Contrast);
  lcd.begin(16, 2);
 //port.println("AT+CSCS=\"GSM\"");
 //port.println("AT+CMGF=1");
  port.println("AT+CNMI=1,2,0,0,0");
  delay(5000);
  lcd.setCursor(0, 0);
  lcd.print(F("DEVICE READY!"));
}

void loop()
{
  proc_SIM808();
  proc_TIMER();
}

void proc_SIM808() {
  if (port.available()) {
    sim808data = port.readString();

    if (sim808data.indexOf("start") > 0) {
      int value = sim808data.indexOf("start");
      runtime = sim808data.substring(value + 5).toInt();
      countseconds = 0;
      runme = true;
    }

    if (sim808data.indexOf("stop") > 0) {
      if (overdue)
      {
        lcd.setCursor(0, 1);
        lcd.print(F("--DEVICE STOP!--"));
      } else {
        lcd.setCursor(0, 1);
        lcd.print(F("--DEVICE STOP!--"));
      }
      runme = false;
      overdue = false;
    }
    Serial.println(sim808data);
  }
}

void proc_TIMER() {
  if (runme) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= 1000 ) {
      lcd.clear();
      if (runtime <= 0 && overdue) {
        if (countseconds == 59)
        {
          runtime--;
          countseconds = 0;
        }
        lcd.setCursor(0, 1);
        lcd.print(F("Cost:"));
        lcd.print((runtime * -1));
        countseconds++;
      } else if (runtime >= 0) {
        if (countseconds == 0) {
          runtime--;
          countseconds = 59;
          if (runtime == -1) {
            overdue = true;
            runtime = 0;
            countseconds = 1;
          }
        }
        countseconds--;
      }
      lcd.setCursor(5, 0);
      if (runtime == 0 && overdue) {
        lcd.print("-" + runtime);
      }
      lcd.print(runtime);
      lcd.print(F(":"));
      lcd.print(countseconds);
      previousMillis = currentMillis;
    }
  }
}

as you noticed the gps code is not the same as the 1st code that i posted its because the gps on the 1st code i based it on the vehicle tracking code that i saw on google and tried if the timer will work if i combined it on the code.

What do you mean by "texted"?

You should learn a couple of things:

  • avoid delay()
  • avoid String
  • use state machines
  • use char arrays to buffer input
  • process input only when a complete line or record has been received
  • understand other people's code before using it
    ...

See BlinkWithoutDelay in the IDE examples, "...several things at a time" on top of this forum.

I'd choose a simpler project for starting.

Thank you for the reply sir!

What I mean texted sir is for example when I text "start1" to the GSM the LCD starts counting down from 1 min then when it reaches 0 it becomes counting up but with "-" then when texted stop it will stop sir this is the timer code sir and its working sir when its separated from GPS code sir.

And its a also part of my thesis project sir :frowning: its the reason why i cant move on on my project.
and i think i already tried searching them on google sir the ones that you mentioned sir but i still ended up with those codes sir.

You seem to mean "send" characters or commands. The description of your project still is confusing. Try harder to describe what exactly you want to do, then it becomes much easier to write the according code. Have you ever tried to describe your project to your wife or mother, or somebody else with no special knowledge about controllers and processes?

Are you trying to make a tracker?
text to it "start" sets timer, gathers gps data transmits its position through a text when timer ends it sleeps then waits for text to restart timer

oh sorry sir my explanation is bad. uhm il try to do it again sir its like this sir .

TIMER CODE EXPLANATION:

PHONE ---> Sends "start3" (3 means the start of the countdown) --> when gsm receives start3 it will get the 3 and starts the countdown on the LCD.

WITH GPS:

OPTION1:
What I wana do is while 3 mins is running on the LCD. Whenever the GSM receives another text "getgps" the gsm will send coordinates to the phone.

or

OPTION2:
while 3 mins is running on the LCD. the GSM continuously sends coordinates to the Phone.

what i really wana do sir is the option 2. but if i cant make it possible to work then i will try the option1 sir. i hope you guys can understand my explanation better sir.

Much clearer now :slight_smile:

You can use a buffer (array of char) to receive messages (SMS?) from the phone. Once a message has arrived, compare it to "start3", start the countdown.

During countdown send regularly the coordinates.

See BlinkWithoutDelay for both countdown and sending messages, e.g. do it every 10 seconds.

The demo Several Things at a Time illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

Also have a look at have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

I have had a quick look at your proc_TIMER() function and I can't figure out what it is supposed to do. Can you describe it please?It seems very complicated. I imagine you could achieve what you want just using millis(). For example save the value of millis() when the start message arrives and set a variable (let's call it GpsMayReply) to true. When the time is up set the variable back to false. Elsewhere in your program your code can check that variable to see if it should respond to requests for data.

...R

ERROR when compiling...
OP.c: line 07 - wanna is not a recognised command.
^

Thank you for the tips sir! I will look into the links that you’ve given and starts doing the codes again from scratch!

uhm the proc_Timer sir is like this sir

The LCD displays two things : The Timer and the Cost when Overdue is true. (lets assume I sent start2 on the gsm (This is the proc_SIM808 code))

NORMAL DISPLAY

The lcd will just countdown for 2 mins.

Timer : 2 min (This one doing a countdown)

OVERDUE DISPLAY

when the timer reaches 0 it will countup but it wil be negative for exmaple 0, -1 -2 and so on, every time a negative minute was done the Cost: will increment by 1 Peso (ph money)

it looks like this

Timer: -2:30 (imagine this going up 31 32 and so on)

Cost: 2 ( 2 pesos because its been 2 mins)

nao201431688:
uhm the proc_Timer sir is like this sir

That's not what I wanted you to describe. I would like you to describe how the internals of the function proc_TIMER() are intended to work.

...R

oh sorry for the very late reply sir! sorry I don’t also quite understand my timer code as well all I know is that it does that kind of function, its one of my friend’s friend who made that code haha so whenever I make a new code that’s the one I always use for the timer part. But I’m planning on making also a new one sir based on links that you’ve given me :D. The reason for the late reply sir is that iv been trying to follow the links,

iv been trying to put the input on char array buffer and also been trying to not use Strings and also tried to do some tests if the input from text that i sent to the gsm is really there! and it seems that it wont work. Can you guys tell me what i am doing wrong here? i based this on serial input basic link

#include <AltSoftSerial.h>

AltSoftSerial port(8, 9);

boolean newData = false;
const unsigned int MAX_INPUT = 50;
static char smsBuff[MAX_INPUT];
static byte ndx = 0;
char rc;


void setup() {
  port.begin(9600);
  Serial.begin(9600);
  port.println("AT");
  delay(1000);
  port.println("AT+CSCS=\"GSM\"");
  delay(100);
  port.println("AT+CNMI=2,2,0,0,0");
  delay(100);
  port.println("AT+CMGF=1");
  delay(100);

}

void loop() {
  show_Data();
  rc_Process();
}

void rc_Process() {
  while (port.available() > 0 && newData == false) {
    rc = port.read();

    if (rc != '\n') {
      smsBuff[ndx] = rc;
      ndx++;
      if (ndx >= MAX_INPUT) {
        ndx = MAX_INPUT - 1;
      }
    } else {
      smsBuff[ndx] = '\0';
      ndx = 0;
      newData = true;
    }
  }
}

void show_Data() {
  if (newData == true) {
    Serial.println(smsBuff);

    if (strcmp(smsBuff, "start") == 0) {
      Serial.println("Found!");
    }
    newData = false;
  }
}

why is it that "Serial.println(“Found”) wont appear on Serial monitor? even though I can see in the serial monitor that the text “start” is received.

Any help is very much appreciated!

Keep in mind the strcmp() is case sensitive, and compares the whole string buffer.
You may want to verify the line-end characters or try strstr() which looks for the occurrence of a substring.

nao201431688:
ts one of my friend's friend who made that code

Perhaps you can ask him (or her) for an explanation. I suspect it is unnecessarily complicated.

Also, when you don't understand how a piece of code works you cannot know its limitations.

...R

@OP, your ‘continuous’ Option 2 is not much different to Option 1, but how are you sending the GPS coordinates back to the phone...
SMS will chew up your cell plan with continuous text messages - speed limited by the cell’s ability to take them - about 1/second.
The only really practical way to ‘stream’ data continuously from a mobile is using 3G/4G data.
If you go with data, it changes the whole complexion of the goal, and adds a lot of potential features.

Higher Power consumption may be an issue with Option 2