|
|
View previous topic :: View next topic |
Author |
Message |
John Morley
Joined: 09 Aug 2004 Posts: 97
|
Trouble getting two PICs to communicate via "RS232" |
Posted: Tue Sep 21, 2004 3:14 pm |
|
|
Hi,
I'm trying to get two PICs to communicate via "RS232". The software serial port of a 12F675 is sending a string of data to the hardware UART of a 16F628, but the string is not being received correctly. Prior to directly connecting the PICs, I connected a serial LCD to the output of the 12F675, so I know that it is sending data correctly, and I used a MAX232 and Hyperterminal to verify that the 16F628 is receiving strings correctly. When I connect the Tx output of the 12F675 directly to the Rx input of the 16F628, however, the string data is not received.
Here is the pertinent transmitter code:
Code: |
#define Data_Output PIN_A4
#use rs232(baud=1200, xmit=Data_Output, invert) // for the Linx xmitter module....
// The format is: T1:1234,V1:1234
printf("T1:%04lu,V1:%04lu", TValue, VValue);
|
Here is the pertinent receiver code:
Code: |
#define Console_Out PIN_A2 // Software RS232 Output to Terminal
#define Linx_In PIN_B1 // Hardware RS232 Input from Lynx Module
#use rs232(baud=9600, xmit=Console_Out, rcv=Console_In, ERRORS, STREAM=Console)
#use rs232(baud=1200, xmit=Linx_Out, rcv=Linx_In, ERRORS, STREAM=Wireless)
// Here we wait for a character to show up in the Rcv buffer, and then read the received string
if (kbhit(Wireless))
{
fprintf(Console,"Here inside kbhit.......\n\r");
fgets(Rcv_String,Wireless);
fprintf(Console,"Here after fgets.......\n\r");
fprintf(Console,"%s\n\r", Rcv_String);
}
|
If I put a 'scope on the Rx input pin of the 16F628, the data being sent from the 12F675 looks OK. I thought it might be a baud rate issue, so I slowed everything down to 1200 baud, but that didn't help. I also thought that I might need to use the "invert" option on the transmit end, but that didn't solve the problem either.
Without the invert option on the Tx end, when I run the code, I see the following on Hyperterminal:
"Here at the start.......", followed by "Here inside kbhit......." when the data is sent.
With the invert option on the Tx end, when I run the code, I see the following on Hyperterminal:
"Here at the start.......", followed immediately by "Here inside kbhit......."
Any ideas why this isn't working?
Thanks, _________________ John Morley |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
One thing I see... |
Posted: Tue Sep 21, 2004 3:26 pm |
|
|
As soon as you see the start bit you spend a bunch of time in the fprintf() printing a string and by the time you are done your RS232 input is gone.
Why don't you use the Pin BO and set up an interrupt driven receive? |
|
|
John Morley
Joined: 09 Aug 2004 Posts: 97
|
|
Posted: Tue Sep 21, 2004 3:48 pm |
|
|
Hi,
OK, I added the fprintf as a diagnostic after I determined that the code wasn't working as intended. I just wanted to get some idea of what was going on! This code does work with an input from Hyperterminal, so what's the difference if the data source is another PIC instead?
Thanks! _________________ John Morley |
|
|
languer
Joined: 09 Jan 2004 Posts: 144 Location: USA
|
|
Posted: Tue Sep 21, 2004 5:09 pm |
|
|
You're sending data as such:
Code: | printf("T1:%04lu,V1:%04lu", TValue, VValue); |
and receiving as:
Code: | fgets(Rcv_String,Wireless); |
You are sending characters and expecting a string (terminated by ASCII 13). Per the manual, fgets waits until RETURN is sent to terminate the string:
Quote: | Reads characters (using GETC()) into the string until a RETURN (value 13) is encountered. |
I believe this is your problem. The fgets function is hung waiting for the string termination (RETURN / ASCII-13), but the transmitter never sends it.
As for the invert/non-invert option, since you're going PIC-PIC, you must keep them the same. In your example, the first option Quote: | Without the invert option on the Tx | gave you the correct behavior (you get to the kbhit when the data is sent). In short, the MAX232 inverts the signal; if you are transmitting to one you must invert the transmission, if you're not you do not invert the transmission.
Hope this helps. |
|
|
John Morley
Joined: 09 Aug 2004 Posts: 97
|
|
Posted: Wed Sep 22, 2004 8:28 am |
|
|
Hi,
I modified my transmit code as follows to send the CR:
Code: |
printf("T1:%04lu,V1:%04lu\r", TValue, VValue);
|
Here is the receive code:
Code: |
if (kbhit(Wireless))
{
fgets(Rcv_String,Wireless);
fprintf(Console,"Here after fgets.......\n\r");
fprintf(Console,"Here is the string: %s\n\r", Rcv_String);
}
|
The receive routines now seem to wait at the kbhit statement until data is sent, and then I see the following on the Hypeterminal screen:
Here after fgets........
Here is the string:
This repeats every time the data is sent from the transmitter, but no data ever shows up in the Rcv_String??
Thanks! _________________ John Morley |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Wed Sep 22, 2004 9:27 am |
|
|
Hi John,
You have not posted enough of the code to actually see what is happeing. The sample you gave originally obviously did not work as per your description because of the invert line so the code did not match the test. Therefore I can't tell what other code was changed since the test condition. To debug the program, intead of doing an fgets do a getc and echo it character by character to the console. |
|
|
BMaxwell
Joined: 07 May 2004 Posts: 20
|
Known problems I have had. |
Posted: Wed Sep 22, 2004 12:30 pm |
|
|
Hey sounds familiar. I would try turning off watchdog timer if ya can. Also try using getc(). Lastly make sure both are TTL levels. Sounds like one of your pics has a uart, that may be different levels than ttl and hence you may need a rs232 chip in between the pics. Good luck.
Bryan |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Sep 22, 2004 5:36 pm |
|
|
How is Rcv_String declared? |
|
|
John Morley
Joined: 09 Aug 2004 Posts: 97
|
|
Posted: Thu Sep 23, 2004 7:16 am |
|
|
Here is the code for the receive part of my project:
Code: |
#include <16f628.h>
#include <stdlib.h>
#fuses HS, NOWDT, NOPROTECT
//-----< Compiler use statements >-----
// Tell compiler clock speed is 20.00 MHZ Crystal
#use delay(clock=20000000)
//-----< General Program Defines >-----
#define Console_Out PIN_A2 // Software RS232 Output to Terminal
#define Console_In PIN_A3 // Software RS232 Input from Terminal
#define Linx_Out PIN_B2 // Hardware RS232 Output to Lynx Module
#define Linx_In PIN_B1 // Hardware RS232 Input from Lynx Module
#define DOOMSDAY 0 // Not here yet!
//-----< Serial Port Definition >-----
#use rs232(baud=9600, xmit=Console_Out, rcv=Console_In, ERRORS, STREAM=Console)
#use rs232(baud=1200, xmit=Linx_Out, rcv=Linx_In, ERRORS, STREAM=Wireless)
Main()
{
// Here we define our variables. Remember to include the extra byte for the strings for the null terminator.
char Rcv_String[16];
fprintf(Console,"Here at the start.......\n\r");
while(1)
{
// Here we wait for a character to show up in the Rcv buffer, and then read the received string
While (kbhit(Wireless))
{
fgets(Rcv_String,Wireless);
fprintf(Console,"Here after fgets.......\n\r");
fprintf(Console,"Here is the string: %s\n\r", Rcv_String);
}
}
}
|
One thing that may be a problem is that that transmit circuit and the receive circuit are on different boards with independent +5V power supplies. The only common connections between the boards are the data connection and ground. Without some kind of buffering, I wonder if this might cause a problem? Ultimately, this will not be the case as the final "link" between the transmitter and the receiver is going to be wireless using Lynx Tx/Rx modules. I just thought it would be prudent to get my code working with a direct connection first, but maybe that is causing the problem?!
Thanks guys! _________________ John Morley |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Thu Sep 23, 2004 7:52 am |
|
|
Hi John,
Software - I think your string is one character too short.
Hardware - this is a good way to cook eggs for breakfast.
Running from independant 5 volt supplies can lead to latchup problems in both PICs. This is due to the following reasons:
1. There may be a 0.6 volt differential between both 5 volt rails
2. Power supply rise times may be different for the two supplies which can result in out of spec voltages being applied to the inputs (you can destroy a PIC this way).
3. As for 2 but with decay of the voltage rails when power is removed.
I suggest powering both systems from the same 5 volt source or using a small series resistor (1K to 10K) between the Tx of one pic and Rx of the other PIC. This means you will have two resistors connecting these PICs together. |
|
|
languer
Joined: 09 Jan 2004 Posts: 144 Location: USA
|
|
Posted: Thu Sep 23, 2004 2:25 pm |
|
|
1) Debugging the RS232 link over wire before wireless will save you loads of time (keep it that way).
2) You do not need to worry much about two different supplies in different PWBs, after all this is no different that any other RS232 connection you do (e.g. PC, ICD, etc). You should however have some carbon everytime a signal leaves or enters the PWB (this is a golden rule to keep whenever possible). Call it a current limiting resistor or whatever, but what's outside your PWB you can't control so you must condition. Bottom line, you should use resistors (as noted on a previous post) to connect RXD and TXD lines (is just good safe practice).
3) Your Rcv_String[16] is one(1) character short (as noted on a previous post), the fgets() will append a null termination (0) to it. This maybe where your problem lies, printf is looking for the null termination on the variable you 'casted' as string but it does not find it. Try using Rcv_String[17] instead.
Tell us how it goes. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Thu Sep 23, 2004 6:58 pm |
|
|
languer wrote: | 2) You do not need to worry much about two different supplies in different PWBs, after all this is no different that any other RS232 connection you do (e.g. PC, ICD, etc). You should however have some carbon everytime a signal leaves or enters the PWB (this is a golden rule to keep whenever possible). Call it a current limiting resistor or whatever, but what's outside your PWB you can't control so you must condition. Bottom line, you should use resistors (as noted on a previous post) to connect RXD and TXD lines (is just good safe practice). |
John is not using line drivers and transceivers. he is connecting the digital inputs and outputs directly. Different supply voltages and / or different rise and fall times WILL lead to latchup condition. I have killed PICs this way. |
|
|
John Morley
Joined: 09 Aug 2004 Posts: 97
|
Got it to work! |
Posted: Fri Sep 24, 2004 12:45 pm |
|
|
Hi all,
I finally got my 12F675 and my 16F628 PICs to communicate serially while hard-wired, and then wirelessly using a Lynx Tx/Rx pair! The basic problem was that the transmit circuit was not sending the string I thought it was! I'm not sure why, but when I hooked a serial LCD up to the transmit pin of the 12F675, the strings looked perfect. When I connected a MAX232 to the output and looked at the transmit string using Hyperterminal, however, it was a mix of the right data and a bunch of gibberish.........
I do two A/D conversions before formating and sending the string, and commenting out either of the conversions seems to cure the problem! I suspect that there may be some interaction with the WDT on the 12F675, but I'm not sure yet. I still can't figure out why things look good with the serial LCD, and why the data appears different when using Hyperterminal? Whatever problem I have, I would expect it to behave the same regardless of the method I use to view the transmitted data!
Thanks for the input, guys! _________________ John Morley |
|
|
|
|
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
|