0

So lately I've been messing around with the idea of making my own cellphone nothing spectacular, just a basic one with touchscreen and basic functions call message calendar contacts list and the ability to connect to the internet and provide weather information via an api call.. The module Im using for gsm and GPRS communications is the popular sim900 module. I can communicate I can make calls I can do everything. But in stuck on a maybe (if not impossible to overcome) difficult roadblock.. You see sim900 module when receives a call transmits through the serial port the "RING" command followed by the "+CLIP.... (caller Id stuff)". OK I'm receiving that and I am breaking it down and accepting the command and all fine it works. But here comes the situation.. I want to read the battery capacity that is left (AT+CBC) and the gsm signal strength (AT+CSQ) all fine I'm sending those 2 commands at a fixed interval of like 3 seconds for the signal 10 for the battery. But now when a call comes it might overlap with the incoming response from trying to read the battery.. Let's say that I asked the module what is the battery level. Then the module will respond by sending "+CBC: (and battery level)" then let's say at the same exact time I receive a call.. Then all the data on the serial port just gets messed up and nothing is working.. My code is pretty rough and definitely the parsing section is awful but I'm more concerned that the parsing is not the problem. And the problem is the conflicting incoming data.. Is there any way of solving this problem? Or any other advice of where to look and how to approach the problem? Every command from the gsm is delimited by the 0D0A sequence (CRLF)

Bellow is an example code from what i am doing

//for parsing
String incomStr;
String FirstStr;
String SecondStr;
String ThirdStr;
String FourthStr;
String FifthStr;
String SixthStr;
int strcount;
char incomChar;
boolean flagz = false;


//parsing
void getIncomingCommand() {
  if (Gsm.available()) {
    incomChar = Gsm.read();
    //check to see if 0D0A if yes split the string 
    if ((incomChar == 0x0D) | flagz) {
      flagz = true;
      if (incomChar == 0x0A) {
        switch (strcount) {
          case 0:
            FirstStr = incomStr;
            incomStr = "";
            strcount++;
            flagz = false;
            break;
          case 1:
            SecondStr = incomStr;
            incomStr = "";
            strcount++;
            flagz = false;
            break;
          case 2:
            ThirdStr = incomStr;
            incomStr = "";
            strcount++;
            flagz = false;
            break;
          case 3:
            FourthStr = incomStr;
            incomStr = "";
            strcount++;
            flagz = false;
            break;
          case 4:
            FifthStr = incomStr;
            incomStr = "";
            strcount++;
            flagz = false;
            break;
          case 5:
            SixthStr = incomStr;
            incomStr = "";
            strcount++;
            flagz = false;
            break;
          default:
            strcount++;
            flagz = false;
            incomStr = "";
        }
      }
    } else {
      incomStr += incomChar;
    }
  }
}


void clearIncomingCommand() {
  FirstStr = "";
  SecondStr = "";
  ThirdStr = "";
  FourthStr = "";
  FifthStr = "";
  SixthStr = "";
  strcount = 0;
}


int getSignalLvl() {
  char tempchar;
  String tempstr;
  Gsm.print("AT+CSQ");
  Gsm.write(0x0D);
  Gsm.write(0x0A);
  delay(180);
  while (Gsm.available()) {
    tempchar = Gsm.read();
    tempstr += tempchar;
  }
  return tempstr.substring(16, tempstr.indexOf(",")).toInt();
}

String getTime() {
  char tempchar;
  String tempstr;
  Gsm.print("AT+CCLK?");
  Gsm.write(0x0D);
  Gsm.write(0x0A);
  delay(180);
  while (Gsm.available()) {
    tempchar = Gsm.read();
    tempstr += tempchar;
  }
  return tempstr.substring(tempstr.indexOf(",") + 1, tempstr.lastIndexOf(":"));
}

void setup() {
  //start serial port
  Serial.begin(115200);
  //start the gsm port
  Gsm.begin(9600, SERIAL_8N1, 32, 33);
  strcount = 0;
  updateTime(getTime());
  delay(200);
  updateSignal(getSignalLvl());
}

void loop() {
  //stuff inside here will only be called / run only every X amount of time
  // X = SECONDS/1000;
  if ((millis() - lastupdate) >= 60000) {
    updateTime(getTime());
    lastupdate = millis();
  }



  getIncomingCommand();
  if (SecondStr == "RING" & FourthStr.substring(0, 5) == "+CLIP") {
    Serial.print("SomeOne is calling!! Number: ");
    Serial.println(FourthStr.substring(8, 21));
      Serial.println(phoneNums[i]);
      Serial.println(FourthStr.substring(8, 21));
      callerPhone = FourthStr.substring(8, 21);
      clearIncomingCommand();
    //important change state only once!
    if (!change_state) {
      came_from = state ;
      change_state = 1;
    }
    Serial.print("coming from: ");
    Serial.println(came_from);
    state = 4;
    flag = 0;
  }
  else if (SecondStr == "NO CARRIER") {
    Serial.println("CALL ENDED");
    clearIncomingCommand();
    if (state == 3) {
      state = 5;
      flag = 0;
    } else if (state == 4) {
      state = came_from;
      flag = 0;
    }
    change_state = 0;
  }
  else if (SecondStr == "MO RING") {
    Serial.println("CALLING...");
    clearIncomingCommand();

  }
  else if (SecondStr == "MO CONNECTED") {
    Serial.println("CALL CONNECTED");
    clearIncomingCommand();
    if (state == 2) {
      state = 3;
      flag = 0;
    }
  } else if (FourthStr == "OK" | ThirdStr == "OK") {
    Serial.println("Recieved ok clearing buffers");
    clearIncomingCommand();

  }


}

  • Nice project! The roadblock can surely be overcome -- every cellphone around is able to do it ;-). I suppose that a response from the battery has a certain format that can be used to distinguish it from caller ID etc. You simply must be prepared to potentially receive battery stuff even when you read call info, and vice versa, and handle it accordingly. – Peter - Reinstate Monica Apr 04 '22 at 22:41
  • By the way, `case 4: FifthStr = incomStr; incomStr = ""; strcount++; flagz = false; break;` etc. calls for an array of arrays. – Peter - Reinstate Monica Apr 04 '22 at 22:42
  • I'm now rethinking it and it just now blinked to me. Every response ends with an 0x0D,0x0A OK 0x0D,0X0A sequence so I'm now thinking in the methods to get battery and the signal to replace the while gsm available with a while!= to that sequence. Thus the reading from the serial port will be running until the OK response.. Hm I may try it again tomorrow. Also yes array of arrays will be the way also strings are so messy. Just cobbled together some lines for a proof of concept. Thanks for the reply – Hardwarenerd Apr 04 '22 at 22:49
  • Yeah the data doesn't overlap. I mean the response from the battery will be completed the OK will be received and then the ring will come. The problem I think has to be with the while loop. Because while reading the battery response a ring may come thus filling more the serial buffer and finally giving more time to the while to run. Yeah makes senses ill try to implement a do while it will be far better I think... Generally I took it as a challenge. Moreover the actual code is like 1,5k lines.. A huge state machine inside the loop function.. I'll figure it out – Hardwarenerd Apr 04 '22 at 23:04
  • Yes !! so it seems that by reading and testing for the "OK" and then reading 2 more times from the serial buffer (thus clearing it ) it works flawlessly while (Gsm.available()) { tempchar = Gsm.read(); if(tempchar == 'O' | flagz){ flagz = true; if(tempchar == 'K') { Gsm.read(); Gsm.read(); Serial.println(Gsm.available()); flagz = false; break; } } tempstr += tempchar; } return tempstr.substring(16, tempstr.indexOf(",")).toInt(); } for sure it needs clean up but it works all the times ! – Hardwarenerd Apr 05 '22 at 05:35
  • Just make sure to be prepared for all possible sequences. – Peter - Reinstate Monica Apr 05 '22 at 09:33
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Apr 05 '22 at 21:06

0 Answers0