EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Strange GSM modem behaviour

Started by Rav September 28, 2007
Hi,

I am using one Wavecom 2403A GSM modem interfaced to AVR AT90CAN128
microcontroller. Here, in the code i am sending AT command for sending
SMS to an arbitrary cellphone. I am using USART0 of the controller to
send the characters to my GSM modem. The AT command and the SMS text,
both are hardcoded into the source.
  After compiling and flashing my controller, i wait for sometime
staring at my cellphone but nothing comes. However, during the course
of debugging the code for which i am using JTAG, if i step through the
line in the while loops of functions cmdSendGSM() and SMS_SendGSM()
then after coming out of the SMS_SendGSM(), i am pleased to find that
SMS is received on my cellphone. The same doesn't work when i flash my
controller and Reset it. I have tried putting delays at various
position between successive sending of characters but it doesn't work.

The AT command reference manual says the format for the same is:

AT+CMGS="xxxxx"<CR>
Please call me soon.<CTRL+Z>

I have also tried putting a delay of 1-5 seconds in the beginning for
the GSM modem to setup, this didn't workout too :(
Any help is appreciated.

/**************************GSM.C*******************************/
//Code For USART and Wavecomm Modem Communication

#include <avr/io.h>
#include <avr/interrupt.h>
#include<inttypes.h>

#define F_CPU                           16000000L /* 16 MHz */
#define TIMER1_ PRESCALER   256

/*	Command buffer for storing the AT command for SMS send */
/*	AT+CMGS="9986366564" and 0x0D<CR>	*/
uint8_t USART_CMD_Buf[] =
{'A','T','+','C','M','G','S','=','"','9','8','8','6','6','7','2','8','8','3','"',
0x0D};

/*	SMS buffer for storing the text to be sent */
/*	"Hello" and 0x0D<CR>	*/
uint8_t USART_SMS_Buf[] = {'H','e','l','l','o',0x0D};

/* variables used inside the ISR's */
volatile uint8_t timer1Flag = 0;
volatile uint8_t u8genericUsartTxData = 0;

/* Interrupt Service Routine for Timer1 OutputComapreA */
ISR(TIMER1_COMPA_vect)
{
	timer1Flag = 1;
}

/* Interrupt Service Routine for USART0 data buffer empty */
ISR(USART0_UDRE_vect)
{
	UDR0 = 	u8genericUsartTxData;
	UCSR0B &= ~(1<<UDRIE0);
}

/* Function for generating delay of 'ms' milliseconds */
void timer1Dealy(uint8_t ms)
{
	uint16_t delay;

	delay = F_CPU/(TIMER1_PRESCALER*ms);

       /* Timer 1 Interrupt mask register */
	TIMSK1 |= (1<<OCIE1A);
	OCR1A = delay;
	sei();
	/* START Timer1 with Timer1 Clock prescaled to 256 */
	TCCR1B = 0x04;
	while(!timer1Flag); /* timer1Flag will be modified by ISR */
	TCCR1B = 0x00;      /* STOP the timer */
	timer1Flag = 0;     /* Reset timer1flag to 0 for next delay */
}

void USART0_Init()
{
  /* Set baud rate */
  UBRR0H = (unsigned char) (((F_CPU/(16L*BAUD))-1) >> 8);
  UBRR0L = (unsigned char) ((F_CPU/(16L*BAUD))-1);

  /* Set frame format: 8data, no parity & 1 stop bits */
  UCSR0C = (0<<UMSEL0) | (0<<UPM0) | (0<<USBS0) | (3<<UCSZ00);

  /* Enable transmitter and receiver */
  UCSR0B = (1<<TXEN0) | (1<<RXEN0) | (1<<UDRIE0); //Enable only the
receiver.
}


void cmdSendGSM()
{
	uint8_t u8temp = 0, tmpCount = 0;
	/* Gets the size of command buffer */
	u8temp = sizeof(USART_CMD_Buf);
	while(tmpCount < u8temp)
	{
		while(!(UCSR0A & (1<<UDRE0)));
		u8genericUsartTxData = USART_CMD_Buf[tmpCount];
		/* delay was used to insert a time gap between sending each
character to the GSM
                   modem */
		//timer1Dealy(100); /* 100 ms delay */
		UCSR0B |= (1<<UDRIE0);
		tmpCount++;
	}
}

void SMS_SendGSM()
{
	uint8_t u8tempCount = 0;

	while(u8tempCount < 8)
	{
		while(!(UCSR0A & (1<<UDRE0)));
		u8genericUsartTxData = USART_SMS_Buf[u8tempCount];
		u8tempCount++;
		/* delay was used to insert a time gap between sending each
character to the GSM
                   modem */
		//timer1Dealy(100); /* 100 ms delay */
		UCSR0B |= (1<<UDRIE0);
	}

	/* delay was used to insert a time gap between sending each character
to the GSM
           modem */
	//timer1Dealy(100); /* 100 ms delay */
        /* Sending ASCII equivalent of ctrl+Z */
	u8genericUsartTxData = 0x1A;
	UCSR0B |= (1<<UDRIE0);
}

void main()
{
    USART0_Init();
    timer1Dealy(250);
    timer1Dealy(250);
    sei() /* Enable Global Interrupts */
    cmdSendGSM();
    SMS_SendGSM();

    while(1)
	asm volatile("nop"::);

}

In comp.arch.embedded,
Rav <rav.tech.cs@gmail.com> wrote:
> Hi, > > I am using one Wavecom 2403A GSM modem interfaced to AVR AT90CAN128 > microcontroller. Here, in the code i am sending AT command for sending > SMS to an arbitrary cellphone. I am using USART0 of the controller to > send the characters to my GSM modem. The AT command and the SMS text, > both are hardcoded into the source. > After compiling and flashing my controller, i wait for sometime > staring at my cellphone but nothing comes. However, during the course > of debugging the code for which i am using JTAG, if i step through the > line in the while loops of functions cmdSendGSM() and SMS_SendGSM() > then after coming out of the SMS_SendGSM(), i am pleased to find that > SMS is received on my cellphone. The same doesn't work when i flash my > controller and Reset it. I have tried putting delays at various > position between successive sending of characters but it doesn't work. >
Have you made sure all your hardware handshake lines (RT, CTS, etc.) are at the apropriate levels? -- Stef (remove caps, dashes and .invalid from e-mail address to reply by mail)
On Sep 28, 2:47 pm, Rav <rav.tech...@gmail.com> wrote:
> Hi, > > I am using one Wavecom 2403A GSM modem interfaced to AVR AT90CAN128 > microcontroller. Here, in the code i am sending AT command for sending > SMS to an arbitrary cellphone. I am using USART0 of the controller to > send the characters to my GSM modem. The AT command and the SMS text, > both are hardcoded into the source. > After compiling and flashing my controller, i wait for sometime > staring at my cellphone but nothing comes. However, during the course > of debugging the code for which i am using JTAG, if i step through the > line in the while loops of functions cmdSendGSM() and SMS_SendGSM() > then after coming out of the SMS_SendGSM(), i am pleased to find that > SMS is received on my cellphone. The same doesn't work when i flash my > controller and Reset it. I have tried putting delays at various > position between successive sending of characters but it doesn't work. > > The AT command reference manual says the format for the same is: > > AT+CMGS=3D"xxxxx"<CR> > Please call me soon.<CTRL+Z> > > I have also tried putting a delay of 1-5 seconds in the beginning for > the GSM modem to setup, this didn't workout too :( > Any help is appreciated. > > /**************************GSM.C*******************************/ > //Code For USART and Wavecomm Modem Communication > > #include <avr/io.h> > #include <avr/interrupt.h> > #include<inttypes.h> > > #define F_CPU 16000000L /* 16 MHz */ > #define TIMER1_ PRESCALER 256 > > /* Command buffer for storing the AT command for SMS send */ > /* AT+CMGS=3D"9986366564" and 0x0D<CR> */ > uint8_t USART_CMD_Buf[] =3D > {'A','T','+','C','M','G','S','=3D','"','9','8','8','6','6','7','2','8','8=
','3=AD','"',
> 0x0D}; > > /* SMS buffer for storing the text to be sent */ > /* "Hello" and 0x0D<CR> */ > uint8_t USART_SMS_Buf[] =3D {'H','e','l','l','o',0x0D}; > > /* variables used inside the ISR's */ > volatile uint8_t timer1Flag =3D 0; > volatile uint8_t u8genericUsartTxData =3D 0; > > /* Interrupt Service Routine for Timer1 OutputComapreA */ > ISR(TIMER1_COMPA_vect) > { > timer1Flag =3D 1; > > } > > /* Interrupt Service Routine for USART0 data buffer empty */ > ISR(USART0_UDRE_vect) > { > UDR0 =3D u8genericUsartTxData; > UCSR0B &=3D ~(1<<UDRIE0); > > } > > /* Function for generating delay of 'ms' milliseconds */ > void timer1Dealy(uint8_t ms) > { > uint16_t delay; > > delay =3D F_CPU/(TIMER1_PRESCALER*ms); > > /* Timer 1 Interrupt mask register */ > TIMSK1 |=3D (1<<OCIE1A); > OCR1A =3D delay; > sei(); > /* START Timer1 with Timer1 Clock prescaled to 256 */ > TCCR1B =3D 0x04; > while(!timer1Flag); /* timer1Flag will be modified by ISR */ > TCCR1B =3D 0x00; /* STOP the timer */ > timer1Flag =3D 0; /* Reset timer1flag to 0 for next delay */ > > } > > void USART0_Init() > { > /* Set baud rate */ > UBRR0H =3D (unsigned char) (((F_CPU/(16L*BAUD))-1) >> 8); > UBRR0L =3D (unsigned char) ((F_CPU/(16L*BAUD))-1); > > /* Set frame format: 8data, no parity & 1 stop bits */ > UCSR0C =3D (0<<UMSEL0) | (0<<UPM0) | (0<<USBS0) | (3<<UCSZ00); > > /* Enable transmitter and receiver */ > UCSR0B =3D (1<<TXEN0) | (1<<RXEN0) | (1<<UDRIE0); //Enable only the > receiver. > > } > > void cmdSendGSM() > { > uint8_t u8temp =3D 0, tmpCount =3D 0; > /* Gets the size of command buffer */ > u8temp =3D sizeof(USART_CMD_Buf); > while(tmpCount < u8temp) > { > while(!(UCSR0A & (1<<UDRE0))); > u8genericUsartTxData =3D USART_CMD_Buf[tmpCount]; > /* delay was used to insert a time gap between sending ea=
ch
> character to the GSM > modem */ > //timer1Dealy(100); /* 100 ms delay */ > UCSR0B |=3D (1<<UDRIE0); > tmpCount++; > } > > } > > void SMS_SendGSM() > { > uint8_t u8tempCount =3D 0; > > while(u8tempCount < 8) > { > while(!(UCSR0A & (1<<UDRE0))); > u8genericUsartTxData =3D USART_SMS_Buf[u8tempCount]; > u8tempCount++; > /* delay was used to insert a time gap between sending ea=
ch
> character to the GSM > modem */ > //timer1Dealy(100); /* 100 ms delay */ > UCSR0B |=3D (1<<UDRIE0); > } > > /* delay was used to insert a time gap between sending each chara=
cter
> to the GSM > modem */ > //timer1Dealy(100); /* 100 ms delay */ > /* Sending ASCII equivalent of ctrl+Z */ > u8genericUsartTxData =3D 0x1A; > UCSR0B |=3D (1<<UDRIE0); > > } > > void main() > { > USART0_Init(); > timer1Dealy(250); > timer1Dealy(250); > sei() /* Enable Global Interrupts */ > cmdSendGSM(); > SMS_SendGSM(); > > while(1) > asm volatile("nop"::); > > > > }- Hide quoted text - > > - Show quoted text -
Some times modem takes too long time to get initilize, mine was taking around 15 seconds to get connected with network so increase the delay and wait for little long.
Hi Rav,

Modems are a bitch to work with, generally.

First, you should make sure that your micro is actually sending the
correct thing.  Hook it to a PC and look at its output.  Use a hex
terminal (eg "Sickterm", an old DOS program) to make sure there's no
excessive 0x00 byte at the end etc (wouldn't show up in Hyperterm).

Second, some modems won't see the AT when it's not preceeded by a CR.

Third, you should wait for "modem ready" by sending AT and CR in a
loop (with 1-2 sec pause) until the modem answers OK CRLF.

Fourth, you seem to rely on factory defaults from the modem manual.
But your modem may have a different configuration, until you force it
to load those factory defaults (typically with AT&F).

Regards,
Marc


The 2024 Embedded Online Conference