PSoC4: GSM Modem

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
ShVy_264716
Level 4
Level 4
50 replies posted 25 replies posted 10 replies posted

Hi All !

   

I am quite near to complete the GSM Project. I am not getting desired results as of now. The project which I designed, sends message to Cellular Phone when a push button is pressed. It receives message from Celllular Phone also. It displays it on LCD. Currently I am facing a problem in which I am able to send the message as many times as I press the pushbutton, but not able to receive it and display it on LCD once I send a message priorly. Please find attached my project. I request all to contribute, so we can make a GSM Module for PSoC4.

   

 

   

Regards

   

Shaunak

0 Likes
17 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

There is one thing I would do differently: You reset the interrupt and then you remove the cause by reading off the character in your handler
 I would first remove the cause and then the symptom.(Rocky Hooror Picture Show Theorem)

   

 

   

Bob

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Well,not  just for the cosmetics: in the default branch of your switch(fsm) set the variable fsm to a legal value or you would loop forever.
A de-bouncing of your pushbutton would be a suggestion. You will always get more than one pulse within a few ms. Easiest is a delay (in main, not in the handler!!!).

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

You need to set the UART ISR to level triggered, from datasheet of

   

UART SCB -

   

 

   

0 Likes
lock attach
Attachments are accessible only for community members.
ShVy_264716
Level 4
Level 4
50 replies posted 25 replies posted 10 replies posted

Thank you for the suggestions. I just came to know that if the received data is greater than 4 bytes, an internal UART interrupt gets activated. In my project, when I receive the message on GSM Modem from a phone and read it using UART interrupt, the number of characters read are beyond the count 32, means it goes beyond 4 bytes. Perhaps that is why I am able to read the message on LCD only once even if I am clearing the UART Rx Buffer in the interrupt with the API UART_GSM_SpiUartClearRxBuffer();. After that I can see that the control of code goes in the UART interrupt, but it does not SET the read_message_status FLAG as the LCD does not show the message. Please find attached the project modified as per the suggestions of Bob and Dana (the solutions improved the code and I thank them for that).

   

 

   

Regards

   

Shaunak

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Its probably reading more chars because the buffer is not null terminated ? This

   

problem occurs when trying to print using a stirng API and the string is not NULL

   

terminated.

   

 

   

So whenever you clear/init the string buffer fill it with '\0' (NULL) chars, then as

   

you read from UART you will simply overwrite the NULLS and as long as you

   

do not read a total of chars > ( bufferlen - 1 ) it will always be a NULL terminated

   

string. Each time you use string and want to get ready for next string reload

   

the buffer with NULLS.

   

 

   

Regards, Dana.

0 Likes
lock attach
Attachments are accessible only for community members.
ShVy_264716
Level 4
Level 4
50 replies posted 25 replies posted 10 replies posted

@Dana: I tried with your suggestion of clearing the buffer array after reading it, but I am still getting the same output.

   

As per GSM message rule, every message that GSM module sends to UART, starts with <CR><LF> and ends with <CR><LF> where CR is "Carriage Return" and LF is "New Line Feed". So I have set code according to this standard in my UART Receiver ISR where I am extracting the message from the received data. I am programming the project with below mentioned steps:

   

1. Setting GSM Module in Text mode (SIM300sendcommand(CMGF1)).

   

2. Deleting the message at Slot number 1 of GSM (SIM300DeleteMsg()).

   

3. Clearing the receiver and transmitter buffers (UART_GSM_SpiUartClearRxBuffer(), UART_GSM_SpiUartClearTxBuffer())

   

4. If(pushbutton is pressed) -> Set the mobile number (SIM300sendcommand(CMGS1)) -> send the message   (SIM300sendcommand(MESSAGE1)).

   

5. If(message from phone is received on GSM Module) -> Send command from PSoC4 to GSM Module to read it (the message is stored on Slot 1) (SIM300ReadMsg()) -> Put the received message on LCD (DisplayOnLCD(1u, 0u, (char *)message)) -> Delete the message at slot 1 (SIM300DeleteMsg())

   

Currently I am facing a problem in which I have 2 things to get solved:

   

(A) If after power up, I press the pushbutton and send message from GSM Modem to phone, I get the message on phone. But after that if I send message from phone to GSM Modem, I am not able to read it on LCD despite getting the successful message delivery on phone as well as being able to see through LED blink that it has been received on UART. I can send message successfully from GSM Modem to phone as many times as I wish.

   

(B) If after power up, I send message from phone to GSM Modem, I am able to see it on LCD. I am also able to send the message from GSM Modem to phone through push button press afterwards. But here, I can not get the same message on GSM Modem through phone afterwards. The point is I am not able to get message on GSM Modem multiple times though I can send message successfully from GSM Modem to phone as many times as I wish.

   

 

   

Please find attached the above stated functioning fulfilling project.

   

 

   

Regards

   

Shaunak

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Hi Shaunak,

   

I think, best will be to do a hand-simulation of your rx-handler to see that it will not behave as you want.

   

Write down two or three messages with 0x0d and 0x0a in the corresponding positions and your (shortened) text in between. Write down the changed value of fsm and use it at the next cycle.

   

You cannot do that with breakpoints in debug mode, because the modem keeps on sending bytes while the PSoC is halted.

   

A way out could be

   

Not using the interrupt, increasing the rx-buffer of the component to two times the message length.

   

Poll in main() the Rx_BufferSize() which will not return the buffer's size but the number of characters in the buffer. When there is a complete message in the buffer start to read off the characters using ch = (uint8)(UART_GSM_GetByte() & 0x00ff) and handle that as you did in your interrupt handler before.

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

This is just a minor observation, this code line (30) is doubly terminated -

   

 

   

volatile char message[512];;
 

   

should be -

   

 

   

volatile char message[512];

   

 

   

Also noticed on system tab of .cydwr file your heap size is 128 bytes, you might want

   

to increase that.

   

 

   

Regards, Dana.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Here you do not terminate these with NULL, so when you use strglen() to

   

determine length of message to send you will get indeterminate results.

   

You will have to increase array sizes by +1 to accomidate the NULL character.

   

 

   

www.gnu.org/software/libc/manual/html_node/String-Length.html

   

 

   

char CMGF1[10] = {'A','T','+','C','M','G','F','=','1',0x0D}; /*  Command: AT+CMGF=1 'Carriage Return'  */
char CMGS1[21] = {'A','T','+','C','M','G','S','=','"','0','0','0','0','0','0','0','0','0','0','"',0x0D}; /*  Command: AT+CMGS="0000000000" 'Carriage Return'. Here 0000000000 refers to the 10-digit phone number  */
char MESSAGE1[25] = {'B','I','G',' ','H','E','L','L','O',' ','F','R','O','M',' ','P','S','o','C',' ','4',' ','!','!',0x1A};  /*  "MESSAGE SENT FROM MODEM" '^Z'. This is the message sent  */
char CMGD1[10] = {'A','T','+','C','M','G','D','=','1',0x0D};/* Delete Message at Slot 1 of GSM Modem*/
char CMGR1[10] = {'A','T','+','C','M','G','R','=','1',0x0D};/* Read Message at Slot 1 of GSM Modem*/

   

 

   

Regards, Dana.
 

0 Likes
EvPa_264126
Level 7
Level 7
500 replies posted 250 replies posted 100 likes received

I think it's more convenient: (0x0d = \015 oct       or  \x0d     in hex)

   

char AT1[3] = "AT\015 ;

   

char CMGF1[10] = "AT+KMGF=1\x0d";

   

char CMGS1[21] = "AT+KMGS=0000000000\015";

   

char MESSAGE1[25] = "BIG HELLO FROM PSoC 4!!\032";

   

char CMGD1[10] = "AT+KMGD=1\015";

   

char CMGR1[10] = "AT+KMGR=1\015";

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

@Pav, I did not realize you could use the backslash in a string

   

like that. I kept looking at his strings thinking the same, way too

   

much typing.

   

 

   

Thanks for the post.

   

 

   

Regards, Dana.

0 Likes
lock attach
Attachments are accessible only for community members.
EvPa_264126
Level 7
Level 7
500 replies posted 250 replies posted 100 likes received

I needed to connect the battery to the contact VBTA.
Otherwise - after the first activation of the transmitter modem stops responding.

0 Likes
rola_264706
Level 8
Level 8
50 likes received 25 likes received 10 likes received

Your module says that it is a SIM900 but your code states that it is a SIM300 in the top part of the main.c but later it has code for a SIM900.  Are the commands the same between them? Also where did you get the module?  I would like to check out the program and see how it works.

0 Likes
lock attach
Attachments are accessible only for community members.
rola_264706
Level 8
Level 8
50 likes received 25 likes received 10 likes received

Here is a data sheet for the SIM900.

0 Likes
ShVy_264716
Level 4
Level 4
50 replies posted 25 replies posted 10 replies posted

@Bob: I will try your suggested method of not using interrupt asap and let you know the results.

   

@Dana: I removed the doubly termination, but the result is same. I even increased the heap size, not getting the desired result yet. As far as terminating the strings with NULL, I do not think that is the reason for failure, as these all are "AT" commands of GSM SIM900 and they work quite good as of now also.

   

@pavloven: I tried with your method to declared the character strings in " ", but it did not work for GSM SIM900 and SIM300. That is why I adopted the current method.

   

@bobgoar: I have tested this code on both SIM300 and SIM900. The commands are same for both. You have seen SIM300 in comments because I tested with SIM300 previously. I am sorry for not replacing it with SIM900 in comments which confused you guys a bit. I purchased this module online from India.

   

 

   

Regards

   

Shaunak

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Shaunak,

   

there is a common way to interpret the input-stream that consists of different "words" usually ás part of a compiler:

   

The stream is broken up into "Tokens" that are delimited by "Delimiters" as ";",",","." etc.

   

The "Tokens" are checked for beeing a "Symbol" which are known  words or numbers or whatever you define to be a symbol.

   

You can find a lot of information, have a look at (google for) unix-programs "lex" and "yacc", the latter is able to write the program for you ;-))

   

 

   

Bob

0 Likes
EvPa_264126
Level 7
Level 7
500 replies posted 250 replies posted 100 likes received

   

I also made a small alarm device project with SIM900 and PSoC4

   

   

Maybe you will be interested

   


SIM900_PSoC 4_Alarm.zip
 

   

   

0 Likes