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

RS232 between 5v and 3.3v systems, FGETS() problem
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
UFAnders



Joined: 13 Apr 2005
Posts: 36
Location: Michigan

View user's profile Send private message Send e-mail Visit poster's website AIM Address

RS232 between 5v and 3.3v systems, FGETS() problem
PostPosted: Mon Dec 05, 2005 4:25 pm     Reply with quote

To whom it may concern-->

I am trying desperately to get communications between my BlueRadios RS232 Bluetooth module and my PIC 18F2520 to work. Here is my problem:

After sending a command string to the radio, If I use an int_RDA handler with FGETS() inside I can get full strings just fine. ("OK", "DONE", "CONNECT,xxxxxxxxxxxxxxxx, xxxxxxxxxxxxxxxx") However, if I instead send a command string and right after I use FGETS(), I can only get the first character, so any and all strcmp()'s don't work and I want to kill myself. Razz

What's uberstrange is that the fgets() must be getting a CR because the statements advance as if there is no problem! Instead of "OK" the received string only contains "" or "O".

Important info:

1. I am using the hardware UART direct to the BT module, through a 10k resistor because the BT module is not 5v tolerant.

2. I am using the internal oscillator at 8MHz

3. UART speed is 9600, 8N1. I am using ERRORS in the #use line.

4. I can get all commands/replies to work if I connect my PC through a MAX232 to the BT module. No errors whatsoever.

5. I am using PCH v3.217

Does anyone have experience with this? I can post my code if anyone thinks it will help. Thanks for looking!
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Dec 05, 2005 5:46 pm     Reply with quote

I am surprised you can get this to work at all. The RX input to the PIC is a Schmidtt trigger input with the minimum high voltage rated at 0.8*VDD which is 4V in your application. Your modem model is only outputting 3.3V to the PIC so the PIC in theory could never see a valid high input from the modem. You are going to need a level shifter betwen the modem Tx output and the PIC Rx input. This can be a simple 5 volt gate with TTL level input.

Also a 10K series resistor is not going to make the modem 5 volt tolerant unless the input has a diode clamp to the 3.3 volt rail. In which case I assume the 10K is meant to be sufficiently high in value to prevent input latch up. I suggest a voltage divider would be a better solution. If you cannot do this for some reason then I suggest you check the maximum input current of the device. It may meant increasing the 10K resistor to ensure you are outside the worst case input latchup scenario.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
UFAnders



Joined: 13 Apr 2005
Posts: 36
Location: Michigan

View user's profile Send private message Send e-mail Visit poster's website AIM Address

PostPosted: Mon Dec 05, 2005 6:30 pm     Reply with quote

Sir-->

Well, I tried using a standard NPN transistor to shift the levels to 5v, but no go. Although I very well may have wired it completely wrong, plus I'm not sure if TTL RS232 levels are idle LOW or HIGH. I tried hooking it up both ways, still nothing. It seems that I get transmission just fine from the radio and from the PIC with nothing in between. =|

I then just ran my PIC at 3.3 volts, from the same supply regulator as the BT radio with the same results. I have a feeling that it's fgets() that is not working properly because the first char is being received, and the final carriage return is as well. I am, of course, open to any and all suggestions! It's also important to know that when I use fgets() within the RDA interrupt handler, I get the whole reply string w/o problems. I'd just like to script this program w/o rs232 interrupts.

As soon as I can receive a whole CR delimited string and do comparisons internally, I'm home free!

Thanks for all of your help,

Anders
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Dec 05, 2005 6:35 pm     Reply with quote

Quote:
I'm not sure if TTL RS232 levels are idle LOW or HIGH.

Post the manufacturer, part number, and a link to the website where
the data sheet can be found for your Bluetooth module.
UFAnders



Joined: 13 Apr 2005
Posts: 36
Location: Michigan

View user's profile Send private message Send e-mail Visit poster's website AIM Address

PostPosted: Mon Dec 05, 2005 7:01 pm     Reply with quote

Fellows-->

Here are the details:

Manufacturer: BlueRadios http://www.blueradios.com
Model: BR-SC30A
http://www.blueradios.com/BR-SC30A_Rev2.0.pdf
http://www.andersknelson.com/Eros/BlueRadios_AT_Commands_Rev_2.8.1.4.0.pdf

This is all the information they give. Rolling Eyes

Gents, I am once again indebted to your infallible wisdom. Thank you for your time.

Anders
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Dec 05, 2005 7:19 pm     Reply with quote

Here is a 5v to 3.3V link from the site http://www.blueradios.com/BR_Ref_A_Schematic.pdf

It is my interpretation of this that the modem requires TTL level input from the PIC. I suspect the 10K series resistor is not good enough and you need to implement a proper level shifter or at least a voltage divider.

The schematic showns the TX line going directly form the modem to the MCU Rx input. This is not good enough for a PIC as mentioned previously. You will need to use a level converter. You mentioned you tried a standard NPN transistor however, if you configured this in a common emitter configuration this means it would have been an inverter which is not what you want. You either need to use a second stage to invert back again or some other solution such as per my original suggestion.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
UFAnders



Joined: 13 Apr 2005
Posts: 36
Location: Michigan

View user's profile Send private message Send e-mail Visit poster's website AIM Address

PostPosted: Mon Dec 05, 2005 7:35 pm     Reply with quote

Friends-->

Thanks for all of the sound advice - I had been running my PIC at 5v only because I thought my programmer wouldn't erase it any lower than at 5v. I have been flashing it recently with a VDD of 3.3v just fine (I spoke with meLabs about it), so I'm going to stick with that. This way we can eliminate (I hope) level shifting issues.

Is there anything else I should try? I really appreciate your ideas!

Anders
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Dec 05, 2005 8:03 pm     Reply with quote

If the PIC is running from 3.3V then all should be sweet.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Mark



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

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

PostPosted: Mon Dec 05, 2005 10:05 pm     Reply with quote

Sounds like the buffer is being overrun. You receive the first char okay but the rest get overwritten and the final char is <CR> which is read. Post a small test program that demonstrates the problem. It sounds like you are not using the INT_RDA and it fails but works when you do use the interrupt. You might have left the interrupt enabled without the handler which will cause you problems. Its hard to comment without the code.
UFAnders



Joined: 13 Apr 2005
Posts: 36
Location: Michigan

View user's profile Send private message Send e-mail Visit poster's website AIM Address

PostPosted: Tue Dec 06, 2005 2:43 am     Reply with quote

Comrades-->

OK, here is my demo program:
Code:
//Begin pre-processor directives//
#include <18F2520.h>
#include <string.h>
#fuses INTRC, NOWDT, NOLVP, PUT, NOPROTECT, WDT64
#use delay(clock=8000000)
#use i2c(MASTER, FORCE_HW, FAST, SCL=PIN_C3, SDA=PIN_C4)
#use rs232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7, STREAM=hwrs232, ERRORS/*, force_sw*/)
#use rs232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_A1, RCV=PIN_A2, STREAM=swrs232, INVERT)

#DEFINE UUID "1101"
#DEFINE COD "00000001"
#DEFINE RTS PIN_C0
#DEFINE CTS PIN_C1
#DEFINE RESET PIN_C2

#ZERO_RAM
//End pre-processor directives//

int1 replyFlag=0;
signed int8 replyCounter=0;
int8 i,j,k;
int16 i16,j16,k16;
char replyStr[64], strTemp[16];

int8 processReplies(int8);

void main()
{
   //Begin startup routine//
   SETUP_ADC_PORTS(NO_ANALOGS);
   setup_oscillator(OSC_8MHZ);
   output_low(PIN_C2);
   delay_ms(250);
      
   output_high(PIN_C2);   //reset the BT module
   delay_ms(10);
   output_low(PIN_C2);
   delay_ms(500);
   
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   
   fprintf(swrs232, "\r\n\n<Program started>\r\n\n");
   
   fprintf(hwrs232, "AT\r");

   while(replyFlag == 0);   //wait until full reply is received
   //fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   output_B(processReplies(1));
   replyFlag=0;
   
   delay_ms(250);
   fprintf(hwrs232, "ATSN,Eros123\r");
      
   while(replyFlag == 0);
   //fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   output_B(processReplies(1));
   replyFlag=0;
   
   delay_ms(250);
   fprintf(hwrs232, "ATSI,2\r");
   
   while(replyFlag == 0);
   //fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   output_B(processReplies(1));
   replyFlag=0;
   
   delay_ms(250);
   fprintf(hwrs232, "ATSC,00000001\r");
   
   while(replyFlag == 0);
   //fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   output_B(processReplies(1));
   replyFlag=0;
   
   delay_ms(250);
   fprintf(hwrs232, "ATUCL\r");
   
   while(replyFlag == 0);
   //fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   output_B(processReplies(1));
   replyFlag=0;
   
   delay_ms(250);
   fprintf(hwrs232, "ATDI,1,00000000\r");
      
   while(replyFlag == 0);
   //fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   output_B(processReplies(1));
   replyFlag=0;
   
   while(replyFlag == 0);
   //fgets(replyStr, hwrs232);
   output_B(processReplies(2));
   replyFlag=0;
   
   while(replyFlag == 0);
   //fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   output_B(processReplies(2));
   replyFlag=0;
   
   //End startup routine//
   
   fprintf(swrs232, "\r\n\n<Program finished>\r\n\n");
   
   while(1)
   {
      output_high(PIN_A0);
      delay_ms(250);
      output_low(PIN_A0);
      delay_ms(250);
   }
}

#int_RDA
void RDA_ISR()
{
   disable_interrupts(int_rda);

   fgets(replyStr, hwrs232);
   //fprintf(swrs232, "%s\r\n", replyStr);
   fgetc(hwrs232);
   replyCounter++;
   replyFlag =1;
   
   enable_interrupts(int_rda);
}

int8 processReplies(int8 expected)
{
   signed int8 temp;
   
   if(expected == 1)
   {
      strcpy(strTemp, "OK");
      //fprintf(swrs232, "%s\r\n", strTemp);
      temp = strncmp(strTemp, replyStr, 2);
      fprintf(swrs232, "%d\r\n", temp);
   }
   else if(expected == 2)
   {
      strcpy(strTemp, "DONE");
      //fprintf(swrs232, "%s\r\n", strTemp);
      temp = strncmp(strTemp, replyStr, 4);
      fprintf(swrs232, "%d\r\n", temp);
   }
   return temp;
}


I am expecting to get the following output on HyperTerminal:
Quote:
<Program started>
OK
0
OK
0
OK
0
Eros123
1
OK
0
OK
0
<Gibberish, because it receives "DONE" while transmitting the line that should go here, about 48 characters>
0
<Program finished>


Now here is what I get:
Quote:
<Program started>


0

0

0
Eros123
1
OK
0
OK
0

1


Another strange thing about this involves the LED flashing at the end, but I get no "<Program finished>" output.

Now to run it how I want to, I just comment the interrupt enables and waits for replyFlag then uncomment the fgets() in each block. Here is what I get in HyperTerminal:
Quote:
<Program started>


1

O
1

O
1

O
1

O
1

O
1
1

00A096111E53,00000001,Eros001
1


<Program finished>


Gentlemen, I am dumbfounded.
Ttelmah
Guest







PostPosted: Tue Dec 06, 2005 3:51 am     Reply with quote

Yetch.
Get rid of using gets, in the RS232 interrupt handler to begin with. Have a look at the ex_sisr.c file, for an example of how to use interrupt driven serial. Your code loses all advantage of using interrupts at all!. You might as well just wait for the required string, and not use interrupts...
A a general comment beyond this, I'd clear the flag, _before_ sending the next instruction. Some modems will start responding as soon as the text is sent, and before the carriage return/line feed. As written, if the reply starts 'early',the flag will be cleared to late.
Your wiring still sounds very 'dubious' for reliability. Serial using logic levels, idles high. I'd suspect the input to the PIC is not reliably getting to the high level, so garbage is being seen.

Best Wishes
UFAnders



Joined: 13 Apr 2005
Posts: 36
Location: Michigan

View user's profile Send private message Send e-mail Visit poster's website AIM Address

PostPosted: Tue Dec 06, 2005 9:19 am     Reply with quote

hamletT-->

You are absolutely right about the ISR - I only used it because fgets() wouldn't work otherwise. I'd MUCH rather not use the interrupt for this purpose. Also, it seems that you refer to my previous issue with 3.3v to 5v rs232 signals - I a now running the PIC at a straight 3.3v to eliminate this problem.

Thanks for your suggestions! Does anyone have an idea as to why fgets() wouldn't work? Do I need to manually clear some flag somewhere?
Mark



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

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

PostPosted: Tue Dec 06, 2005 10:07 am     Reply with quote

You probably need a MAX232 between the PIC and the PC. Sometimes you can get away with it but running the PIC at 3.3 volts I doubt it. Remember to remove the "INVERT" if you do use the transceiver.
kender



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Tue Dec 06, 2005 2:54 pm     Reply with quote

Mark wrote:
You probably need a MAX232 between the PIC and the PC. Sometimes you can get away with it but running the PIC at 3.3 volts I doubt it.


Or for a mere demo you can send the serial back through the ICD. Pin B3 needs to be hooked up and you need to add this directive directive:

Code:
 #use rs232(DEBUGGER, stream=dbg)


The serial output will appear in the Monitor tab of the debugger.
UFAnders



Joined: 13 Apr 2005
Posts: 36
Location: Michigan

View user's profile Send private message Send e-mail Visit poster's website AIM Address

PostPosted: Tue Dec 06, 2005 4:13 pm     Reply with quote

Friends-->

I put the swrs232 stream through a MAX232, and I get the same results. Also, I am using the meLabs serial programmer, which is not an ICD.

Since my usage of FGETS() is in a non-interrupt driven fashion (when the code is altered - mentioned near the bottom of my code post), it seems to me that some buffering within that function is not operating properly, or some hardware flag isn't being reset. This is because my "OK"s are being displayed as "O" and the strcmp() comes out as 1 (0 = match), which would indicate that the string in RAM is actually "O" and not "OK".

Perhaps I should try a different chip model? Has anyone Dr. Kevorkian's number? What are your thoughts?

Thanks! Mr. Green
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