![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
UFAnders
Joined: 13 Apr 2005 Posts: 36 Location: Michigan
|
RS232 between 5v and 3.3v systems, FGETS() problem |
Posted: Mon Dec 05, 2005 4:25 pm |
|
|
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.
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! |
|
![](templates/subSilver/images/spacer.gif) |
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Mon Dec 05, 2005 5:46 pm |
|
|
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!! |
|
![](templates/subSilver/images/spacer.gif) |
UFAnders
Joined: 13 Apr 2005 Posts: 36 Location: Michigan
|
|
Posted: Mon Dec 05, 2005 6:30 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 05, 2005 6:35 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
UFAnders
Joined: 13 Apr 2005 Posts: 36 Location: Michigan
|
|
![](templates/subSilver/images/spacer.gif) |
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Mon Dec 05, 2005 7:19 pm |
|
|
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!! |
|
![](templates/subSilver/images/spacer.gif) |
UFAnders
Joined: 13 Apr 2005 Posts: 36 Location: Michigan
|
|
Posted: Mon Dec 05, 2005 7:35 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Mon Dec 05, 2005 8:03 pm |
|
|
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!! |
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Dec 05, 2005 10:05 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
UFAnders
Joined: 13 Apr 2005 Posts: 36 Location: Michigan
|
|
Posted: Tue Dec 06, 2005 2:43 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Tue Dec 06, 2005 3:51 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
UFAnders
Joined: 13 Apr 2005 Posts: 36 Location: Michigan
|
|
Posted: Tue Dec 06, 2005 9:19 am |
|
|
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? |
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Dec 06, 2005 10:07 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Tue Dec 06, 2005 2:54 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
UFAnders
Joined: 13 Apr 2005 Posts: 36 Location: Michigan
|
|
Posted: Tue Dec 06, 2005 4:13 pm |
|
|
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](images/smiles/icon_mrgreen.gif) |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|