sim900d - arduino interfacing

hello there. newbie here. just need some help in interfacing sim900d gsm module to arduino.

i tried sending "AT" serially to the gsm module, then i tried to listen to whatever it will send back.

i should expect an "OK" repsonse from the module. but when i try to use gsmRxTx.read() then print it, i only get trash characters. (by the way i used NewSoftSerial in my program).

could anyone please help me? please. thanks in advance.

here's my code.

#include <stdio.h>
#include <NewSoftSerial.h>

#define powerOn 4

char filter[5];

NewSoftSerial gsmRxTx (2, 3);   //(rxpin, txpin)  declaration of new rx/tx pin

void setup(){
   Serial.begin(9600);
   gsmRxTx.begin(9600);
  
   digitalWrite(powerOn, HIGH);  //connect powerOn of gsm module to pin 4. this will open  gsm module 
   digitalWrite(powerOn, LOW);
   delay(5000);
   
   startUp();
}

void startUp(){
int i;

      gsmRxTx.print("AT\r\n");  //send AT serially, expect OK as gsm response
      delay(1000);
      if (gsmRxTx.available()){  //check if there's any available in serial port
      Serial.println("pass");
        for (i=0;i<5;i++){
          filter[i] = gsmRxTx.read();
          Serial.println(filter[i]);
        }
      }
}

void loop(){
  Serial.println("halo");
  delay(1000);
}
   digitalWrite(powerOn, HIGH);  //connect powerOn of gsm module to pin 4. this will open  gsm module 
   digitalWrite(powerOn, LOW);

NO experience with that module but these two lines made me think...

if HIGH is power on then LOW is power off ??? and a module switched off will not respond so much.

Do you have a link to the datasheet of the module?

NO experience with that module but these two lines made me think...

if HIGH is power on then LOW is power off ??? and a module switched off will not respond so much.

He's doing it this way because he's using (or at least should be using) a transistor to turn it on.

What you need to do is hold the power on pin low for at least one second before switching it back for the unit to power on.

digitalWrite(powerOn, HIGH);  //connect powerOn of gsm module to pin 4. this will open  gsm module 
delay(1100);
digitalWrite(powerOn, LOW);

i had modified my program. here it is..

#include <stdio.h>
#include <NewSoftSerial.h>

#define powerOn 4

enum gsmstate {
    gsmWaiting,
    gsmReceiving,
    gsmExecuting
};

enum gsmstate dvcState;
int i=0, j=0, msgread=0;
char temp, temp1[20], msgnum[3];

NewSoftSerial gsmRxTx (2, 3);   //(rxpin, txpin)  declaration of new rx/tx pin

void setup(){
   Serial.begin(9600);
   gsmRxTx.begin(9600);
  
   digitalWrite(powerOn, HIGH);  //connect powerOn of gsm module to pin 4. this will open gsm module 
   delay(1500);
   digitalWrite(powerOn, LOW);
   delay(15000);
   
   dvcState = gsmWaiting;
   
   startUp();
}

void chk_msg();
void msgopen();

void startUp(){

      gsmRxTx.print("AT\r\n");  //send AT serially, expect OK as gsm response
      delay(500);
      
      gsmRxTx.println("ATE0");
      delay(500);
      
      gsmRxTx.println("AT+CMGF=1");
      delay(500);
      
      gsmRxTx.println("AT+CNMI=2,1,0,0,0");
      delay(5000);
}

void loop(){
  if (msgread == 0)chk_msg();
  else msgopen();
  delay(50);
  
}

void chk_msg(){
char *s = NULL;

  switch(dvcState){
   case gsmWaiting:
     if (gsmRxTx.available()){ 
       if (gsmRxTx.read() == '+'){
         memset(temp1,0,sizeof(temp1));
         dvcState = gsmReceiving;
       }
     }
     break;
     
   case gsmReceiving:
     if (gsmRxTx.available())
       temp = gsmRxTx.read();
     if (temp != 13){
       temp1[i] = temp;
       temp1[i+1] = 0;
       i++;
     }
     else {
       dvcState = gsmExecuting;
       temp = 0;
       i = 0;
     }
     break;
     
   case gsmExecuting:
     Serial.println(temp1);
     //memset(msgnum,0,sizeof(msgnum));
     if (strncmp(temp1,"CMTI",4) == 0){
       s = strchr(temp1, ',');
       s++;
       while (*s != 0){
         msgnum[j] = *s;
         msgnum[j+1] = 0;
         j++;
         s++;
       }
       msgread = 1;
     }
     j = 0;
     s = NULL;
     dvcState = gsmWaiting;
     Serial.println("DUMAAN DITO.");
     break;
  }
}

void msgopen(){
char tempA=0, tempA1[100]="0";
int count=0, i=0;
  
  memset(tempA1,0,sizeof(tempA1));
  
  gsmRxTx.print("AT+CMGR=");
  gsmRxTx.println(msgnum);
  
  if (gsmRxTx.available()){
    tempA = gsmRxTx.read();
  }
  if (tempA == 13) count++;
  else if (count < 2){
      tempA1[i] = tempA;
      tempA1[i+1] = 0;
      i++;
    }
  gsmRxTx.flush();
  Serial.println(tempA1);
  
  dvcState = gsmWaiting;
  
  count=0;
  i=0;
  msgread=0;
}

flashed on the serial monitor:

CMTI: "SM",19
DUMAAN DITO.

CMGR: "REC UNREAD","+639054888383","","11(47/~5,1Q:20:26+32"
DUMAAN DITO.

as you will notice, there's trash message at the time stamp. also the real message (which should have been "TEST") was not read by the variable tempA1.

after the last line "DUMAAN DITO.", arduino cannot recognize the new incoming message.

what could be the problem with my code. can someone please help me. thanks

Quick look: you could put the hardware serial to 115200 to give the GPS serial more time to get data.

For receiving strings, you don't test the max size is reached;
temp1 = temp;

  • temp1[i+1] = 0;*
  • i++;*
    temp1[] has 20 positions... "11(47/~5,1Q:20:26+32" needs 21 = 20 char + \0 ...
    In startup you send a number of commands but you don't check what they return.
    I call this "good weather" programming and one thing is sure if it fails you don't know where ...
    Your statemachine has at least one bug:
    * *  case gsmReceiving:     if (gsmRxTx.available())    <<< if nothing is available       temp = gsmRxTx.read();    <<<< nothing is read     if (temp != 13){          <<<< but this is tested and       temp1[i] = temp;    <<<the prev value of temp is  added ?    causing repeating digits ....       temp1[i+1] = 0;    <<< to a string who's length is not checked....       i++;     }     else {       dvcState = gsmExecuting;        temp = 0;       i = 0;     }     break;* *
    Try to make a minimum sketch, I find it quite hard to follow your code..