CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Please help! Modem <-> RS232 <-> 18F452
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
qleyo



Joined: 23 Aug 2005
Posts: 22

View user's profile Send private message

Please help! Modem <-> RS232 <-> 18F452
PostPosted: Tue Mar 21, 2006 11:30 am     Reply with quote

I've been trying to avoid opening a new topic, but have searched this forum high and low to no avail.

I am using a PIC millenium dev board, a pic18F452(with 4mhz crystal) and a round solutions GSM-GPRS modem. First things first, I have buzzed all rs232 cables to check cross over or not. And they aren't i.e. non cross over.

When I connect my modem to a PC using hyperterminal (setup is - baud: 9600, data bits: 8, parity: None, Stop bits: 1, Flow control: none), my AT commands work fine. I have used a port sniffer to get the exact hex values going out.

I then connected my PIC to the PC and got all my AT commands, once again with the port sniffer to get hex values. On comparison, the hex values were exactly the same. So I know I'm sending valid data.

I have grounded RTS, and sent an AT&K0 to disable hardware handshaking. My program is below. The GPRS modem does not respond. I included a function that waits for a khbit() rather than using delays, but RX is inactive High, so my function does not work well. I can't think of anything else, I've checked logics, voltages everything I can think of. And i'm running out of time :'(



Code:
#include <18F452.h>
#include <string.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232 (BAUD=9600,parity=N,XMIT=PIN_C6,RCV=PIN_C7,ERRORS,bits=8)

#define CR 0x0D
#define LF 10

void gprs_error()
{
   char msg[20];
   char response_ok[25];
   char response_connect[25];
   strcpy(response_ok,"OK");
   strcpy(response_connect,"CONNECT");

      //check if command returned an error
      //program will not continue until gprs returns a string
      gets(msg);

      //check if error returned
      delay_ms(100);

      if (stricmp(msg, response_ok))
         printf("\r\nok\r\n");
      else if (stricmp(msg, response_connect))
         printf("\r\nconnect\r\n");
}

void delay_sec (void)
{
      delay_ms(200);
      delay_ms(200);
      delay_ms(200);
      delay_ms(200);
      delay_ms(200);
}

void flash()
{
   delay_sec();
   output_low(PIN_B2);
   delay_sec();
   output_high(PIN_B2);
}

void flash3()
{
   delay_sec();
   output_high(PIN_B3);
   delay_sec();
   output_low(PIN_B3);
}

//PROGRAM WILL HALT UNTIL RESPONSE FROM GPRS ON RX IS RECEIVED
void wait_for_response ()
{
   while(!kbhit())
      flash();
     
   flash3();
}

void main()
{

setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);

   /***start test sequence***/

   while(TRUE)
   {
      delay_sec();
     
      printf("AT&K0%c",CR); //turn off handshaking

      flash();

      printf("ATE1%c",CR); //enable echo
     
      wait_for_response();
     
      printf("ATD 07745691189;%c",CR); //make a phone call

      wait_for_response();

      flash();

   }

}

newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Tue Mar 21, 2006 11:40 am     Reply with quote

Note: open invitation for someone to correct me follows. Very Happy

Your PIC development board and the modem are both (???) DTE's (???) or is it DCE's (???).

I can't remember the proper terminology at the moment. Basically the PC is wired to be "boss". The PIC development board and the modem are wired to be "slaves".

To get one slave to speak to the other (PIC board --> modem) you'll need a null modem serial cable. A null modem cable is not a straight pass-through. Among other things, the most important switch is pin 2 -> pin 3 and pin 3 -> pin 2. This allows one slave's TX to be routed to the other's RX and vice-versa.

Hope this helps.
rberek



Joined: 10 Jan 2005
Posts: 207
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Tue Mar 21, 2006 11:55 am     Reply with quote

The board and modem are both DCE's. The PC is the DTE. And you are correct!
qleyo



Joined: 23 Aug 2005
Posts: 22

View user's profile Send private message

PostPosted: Tue Mar 21, 2006 11:59 am     Reply with quote

newguy wrote:

Your PIC development board and the modem are both (???) DTE's (???) or is it DCE's (???).


Nope controlling device is DTE so here PIC is DTE so is PC. Modem is DCE.

I tried a cross over connection, didn't work.

newguy wrote:
]To get one slave to speak to the other (PIC board --> modem) you'll need a null modem serial cable. A null modem cable is not a straight pass-through. Among other things, the most important switch is pin 2 -> pin 3 and pin 3 -> pin 2. This allows one slave's TX to be routed to the other's RX and vice-versa.


Do you understand what I was trying to say in my post? Eventually the PIC is to control the modem. However what I did was connect the PIC to PC to see I was getting the correct AT commands. I also connected the PC to modem to issue those commands and compared the hex output both ways. On connecting the PIC to modem I don't get anything.

Quote:
The board and modem are both DCE's. The PC is the DTE. And you are correct!

:'( noo PC is DTE, PIC is DTE, modem is DCE. This is a sticky from the manufacturer of my modems forum. http://www.modem-gsm.de/forum/showthread.php?id=17
rberek



Joined: 10 Jan 2005
Posts: 207
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Tue Mar 21, 2006 12:19 pm     Reply with quote

Please help me understand this.

Leaving terminology aside for a moment, it would seem that both the modem and PIC board can talk to the PC. Assuming you are using a regular RS232 cable, that means that they are both using the same pin to transmit to the PC (pin 2 or 3, I can't remember). If that is so, then they won't be able to talk to each other without a null modem, since you would be connecting Tx to Tx and Rx to Rx.

What am I missing from your description?
qleyo



Joined: 23 Aug 2005
Posts: 22

View user's profile Send private message

PostPosted: Tue Mar 21, 2006 5:14 pm     Reply with quote

So does the PC cross over on the inside? How come a straight connected cable works with PC. Also what I said was I did try a null connection and that did not work either, infact I had a null connection till my lecturer came and said to make it straight (not that that solved my problem) :(
Eugeneo



Joined: 30 Aug 2005
Posts: 155
Location: Calgary, AB

View user's profile Send private message

Re: Please help! Modem <-> RS232 <-> 18F452
PostPosted: Tue Mar 21, 2006 6:05 pm     Reply with quote

If you say:

Modem = Male
Pic = Male
PC = Female

Modem to PC is straight
Pic to PC is straight
Pic to Modem, well that's not straight so you need a null modem

delay_ms(1000) works as long as you don't use a long register but you may loose some bytes since your not using the interrupts.
rberek



Joined: 10 Jan 2005
Posts: 207
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Tue Mar 21, 2006 7:45 pm     Reply with quote

Nothing crosses over in the PC. It will always transmit on pin 3 of the cable and receive on pin 2. That means, with a straight-thru cable, the modem and the PIC board must always receive on pin3 and transmit on pin 2.

If they are connected together with a straight thru cable, they will both be transmitting to each other on pin 2 and receiving on pin 3. This is a collision and nothing will happen,
qleyo



Joined: 23 Aug 2005
Posts: 22

View user's profile Send private message

PostPosted: Wed Mar 22, 2006 2:18 am     Reply with quote

Oh I see what you are saying. I was thinking about DTE and DCE in terms of who is "controlling". So you are saying that if my modem and PIC worked with my PC, they must be acting and configured as DCE devices.

I'm on the same page now, (hmm...but it didn't work with null connection :( ) ok I'm going to do a lot of probing today. And swap the PIC to modem connection again. I'll let you know if I get anything.

Quote:
Modem = Male
Pic = Male
PC = Female


Yes that is how it is, because right now I have to use a female to female header to connect the PIC and modem. Right I'm clear on the connection issue, let me swap cables (and leave it that way), do alot of probing and update everyone before the end of today. Thank you.
qleyo



Joined: 23 Aug 2005
Posts: 22

View user's profile Send private message

PostPosted: Wed Mar 22, 2006 5:17 am     Reply with quote

Ok i'm back, i've now done the cross over connection. RTS still grounded. I modified my code to check for khbit() from the mode. And i've stopped sending commands to the modem. All I do now is send it a text message and the modem sends data on RX stating it has received a message.

I've tested 3 text messages, and they all worked, so my connection is definitely fine now. However the modem still does not respond to AT commands. Here is the working program that waits for RX data from the modem.

Code:
#include <18F452.h>
#include <string.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOPUT
#use delay(clock=4000000)
#use rs232 (BAUD=9600,parity=N,XMIT=PIN_C6,RCV=PIN_C7,ERRORS,bits=8)

void delay_sec (void)
{
   delay_ms(200);
   delay_ms(200);
   delay_ms(200);
   delay_ms(200);
   delay_ms(200);
}

void flash()
{
   delay_sec();
   output_low(PIN_B2);
   delay_sec();
   output_high(PIN_B2);
   delay_sec();
   output_low(PIN_B2);   
}

void flash3()
{
   delay_sec();
   output_low(PIN_B3);
   delay_sec();
   output_high(PIN_B3);
   delay_sec();
   output_low(PIN_B3);   
}



int main()
{
   /***start GPRS connection sequence***/

   char gprs_msg[25];
   while(1)
   {
      while(!kbhit())
      flash();

      flash3();

      delay_sec();
      gets(gprs_msg);   
      flash3();
   }
   
   return 0;
}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Mar 22, 2006 8:20 am     Reply with quote

Try this. I didn't test it but it compiles just fine.
Code:

#include <18F452.h>
#include <string.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232 (BAUD=9600,parity=N,XMIT=PIN_C6,RCV=PIN_C7,ERRORS,bits=8)

#ifndef NULL
  #define NULL      0
#endif

/* *************************************************************************
  DESCRIPTION Waits for a string for the specified timeout
  RETURN: none
  ALGORITHM:  none
  NOTES:  Passing a 0 for the timeout will wait forever
 *************************************************************************** */
static int *WaitFor(
  int    *s,         /* String that we are looking for */
  int16  timeout)    /* How long to wait in miliseconds */
{
  int  *p;
  int index = 0;
  int buf[15];       /* increase the size of the buffer to suit your needs */

  while (TRUE)
  {
    if (kbhit())
    {
      buf[index] = getc();
      index++;
      if (index > sizeof(buf))
        return(NULL);
      p = strstr(buf, s);
      if (p)
        return (p);
    }
    delay_ms(1);
    if (timeout)
    {   
      timeout--;
      if (!timeout)
        return (NULL);
    }
  }
}

void main()
{

  int buf[] = { "OK" };

  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  setup_spi(FALSE);
  setup_wdt(WDT_OFF);

  /***start test sequence***/


  /* reset the modem */
  printf("ATZ\r");
  (void)WaitFor(buf, 4000);

  /* Configure the modem */
  printf("AT&FE0&C0&D0S0=0\r");
  (void)WaitFor(buf, 4000);

  /* make a phone call */
  printf("ATD 07745691189\r");

  while(TRUE)
  {

  }

}
qleyo



Joined: 23 Aug 2005
Posts: 22

View user's profile Send private message

PostPosted: Wed Mar 22, 2006 10:00 am     Reply with quote

waheeeyyyy I got a phone call!!!! :D i'm skipping skipping and more skips :D <tears of joy in between>

I thought CCS couldn't take pointers, obviously wrong.

Thank you!
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Mar 22, 2006 11:54 am     Reply with quote

CCS cannot take pointers to constants but pointers are okay. However, you can pass a constant string to a function. CCS will just break the string up into individual bytes and do multiple calls to the function.
qleyo



Joined: 23 Aug 2005
Posts: 22

View user's profile Send private message

PostPosted: Sat Mar 25, 2006 8:40 am     Reply with quote

Hi Mark, I'm stuck on something else. What i've done is connected another COM port to HyperTerminal to print messages. (Could not be asked with setting up LCD)

Now the modem always seems to get OK even after AT#SKTOP which should return CONNECT, would it be a smart move to clear the buffer before calling the function again (I would have thought it would simply overwrite), also I added a statement to print each character after adding it to the buffer.


Code:
     
buf[index] = getc();
fprintf(PC,"%c",buf[index]);


But I don't seem to get anything (I wanted to be able to see the actual modem echo's and responses)

I also added a printf before issues each AT command to print the current AT command to hyperterminal which works fine (its not in this piece of code below as I didn't manage to e-mail myself the updated version before the labs shut, plus its trivial)

lastly would it be a smart move to terminate the current buffer with a NULL before doing strstr. e.g.

Code:
     
buf[index] = getc();
buf[index+1] = '\0';
fprintf(PC,"%c",buf[index]);


Heres the modified code, Thanks again

Code:

#include <18F452.h>
#include <string.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT
#use delay(clock=4000000)
#use rs232 (BAUD=9600,parity=N,XMIT=PIN_C6,RCV=PIN_C7,ERRORS,bits=8,stream=GPRS)
#use rs232 (BAUD=9600,parity=N,XMIT=PIN_C5,ERRORS,bits=8,stream=PC)

#ifndef NULL
  #define NULL      0
#endif


void delay_sec (void)
{
   delay_ms(200);
   delay_ms(200);
   delay_ms(200);
   delay_ms(200);
   delay_ms(200);
}

void flash()
{
   delay_sec();
   output_low(PIN_B2);
   delay_sec();
   output_high(PIN_B2);
   delay_sec();
   output_low(PIN_B2);
}


/* *************************************************************************
  DESCRIPTION Waits for a string for the specified timeout
  RETURN: none
  ALGORITHM:  none
  NOTES:  Passing a 0 for the timeout will wait forever
 *************************************************************************** */
static int *gprs_response(int16  timeout)   // How long to wait in miliseconds
{
  int index = 0;
  char buf[25];       // increase the size of the buffer to suit your needs
  char character;

  int ok[] = { "OK" };
  int connect[] = { "CONNECT" };

  while (TRUE) {
    if (kbhit()) {
      buf[index] = getc();
      fprintf(PC,"%c",buf[index]);
      index++;

      if (index > sizeof(buf))
      {
         fprintf(PC,"\r\nError reading GPRS data");
         return(NULL);
      }
      else if (strstr(buf, ok))
      {
         fprintf(PC,"\r\nGPRS response - OK");
         return (TRUE); //drop out of function
      }
      else if (strstr(buf, connect))
      {
         fprintf(PC,"\r\nGPRS response - CONNECT");
         return (TRUE); //drop out of function
      }

    }

    delay_ms(1);

    if (timeout) {
      timeout--;

      if (!timeout) {
         fprintf(PC,"\r\nGPRS Timeout - no valid response");
         return (NULL);
      }
    }
  }
}

/***still buggy do not use yet***/

static int *server_response(int16  timeout)    // How long to wait in miliseconds
{
  int index = 0;
  char  *p;
  char buf[15];       // increase the size of the buffer to suit your needs
  char character;

  while (TRUE)
  {
    if (kbhit())
    {
      buf[index] = getc();
      fprintf(PC,"%c",buf[index]);
      index++;

      if (index > sizeof(buf))
      {
         fprintf(PC,"\r\nError reading GPRS data");
         return(NULL);
      }
    }

    delay_ms(1);

    if (timeout)
    {
      timeout--;
      if (!timeout)
      {
         fprintf(PC,"\r\nTime out error");
         return (NULL);
      }
    }
  }
}

void main()
{

  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  setup_spi(FALSE);
  setup_wdt(WDT_OFF);

  /***start test sequence***/
   while (1)
   {
     delay_sec();
     fprintf(PC,"\r\n***Program started***\n");
     /* reset the modem */
     fprintf(GPRS,"ATZ\r");
     (void)gprs_response(8000);
     flash();

     /* Configure the modem */
     fprintf(GPRS,"AT&FE0&C0&D0S0=0\r");
     (void)gprs_response(8000);
     flash();

     fprintf(GPRS,"AT&K0\r");
     (void)gprs_response(8000);
     flash();

     /* set socket data */
     fprintf(GPRS,"at#SKTSET= 0,80,\"www.someurl.co.uk\",0,0;\r");
     (void)gprs_response(8000);
     flash();
   
     /* set user ID */
     fprintf(GPRS,"at#userid=\"wap\"\r");
     (void)gprs_response(4000);
     flash();
   
     /* set user password */
     fprintf(GPRS,"at#passw=\"wap\"\r");
     (void)gprs_response(8000);
     flash();
   
     /* activate GPRS context, modem should respond with IP address */
     fprintf(GPRS,"at#gprs=1\r");
     (void)gprs_response(8000);
     flash();
   
     /* save settings */
     fprintf(GPRS,"at#sktsav\r");
     (void)gprs_response(8000);
     flash();
   
     /* open socket connection, modem should respond with CONNECT */
     fprintf(GPRS,"at#sktop\r");
     (void)gprs_response(100000);
     flash();
   
     /* HTML instructions */
     fprintf(GPRS,"GET /gprs.php?val=1 HTTP/1.0\r\n");
     delay_ms(1);   
     fprintf(GPRS,"Connection: keep-alive\r\n\r\n");
     (void)server_response(100000);

     delay_sec();     
     delay_sec();
     delay_sec();
     delay_sec();
     delay_sec();
     /* close connection */
     fprintf(GPRS,"+++"); 
     (void)gprs_response(100000);
     delay_sec();     
     delay_sec();
     delay_sec();
     delay_sec();
     delay_sec();
         
   }

}

Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sat Mar 25, 2006 10:23 am     Reply with quote

Quote:

Now the modem always seems to get OK even after AT#SKTOP which should return CONNECT, would it be a smart move to clear the buffer before calling the function again (I would have thought it would simply overwrite), also I added a statement to print each character after adding it to the buffer.


Code:

buf[index] = getc();
fprintf(PC,"%c",buf[index]);



You don't want to do any printing of chars while you are waiting. This might cause you to miss a char while you are sending one.


Quote:
lastly would it be a smart move to terminate the current buffer with a NULL before doing strstr. e.g.

Code:

buf[index] = getc();
buf[index+1] = '\0';


Most definitely! I converted this from some code that I use. My code used a global buffer where the data was received by an interrupt. I always terminated the string in the ISR.

Note that I added a /0 to the buffer at the start of the function. This would clear the buffer so to speak. The problem is most likely because nothing had been received and an old response was still in the buffer.


Code:
/* *************************************************************************
  DESCRIPTION Waits for a string for the specified timeout
  RETURN: none
  ALGORITHM:  none
  NOTES:  Passing a 0 for the timeout will wait forever
 *************************************************************************** */
static int *gprs_response(int16  timeout)   // How long to wait in miliseconds
{
  int index = 0;
  char buf[25];       // increase the size of the buffer to suit your needs
  char character;

  int ok[] = { "OK" };
  int connect[] = { "CONNECT" };

  // Clear any previous messages
  buf[0] = 0;

  while (TRUE) {
    if (kbhit()) {
      buf[index] = getc();
      index++;
      buf[index] = 0;

      if (index >= sizeof(buf)-1)
      {
         fprintf(PC,"\r\nError reading GPRS data");
         return(NULL);
      }
      else if (strstr(buf, ok))
      {
         fprintf(PC,"\r\nGPRS response - OK");
         return (TRUE); //drop out of function
      }
      else if (strstr(buf, connect))
      {
         fprintf(PC,"\r\nGPRS response - CONNECT");
         return (TRUE); //drop out of function
      }

    }

    delay_ms(1);

    if (timeout) {
      timeout--;

      if (!timeout) {
         fprintf(PC,"\r\nGPRS Timeout - no valid response");
         return (NULL);
      }
    }
  }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group