Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Thread Tools Display Modes
Old 19th February 2007, 08:12 PM   (permalink)
Default Interesting PIC to PIC USART question

This could have you guys dumbfounded like I am, or it could just be a simple answer!

Basically I have 2 PIC 18F4520s powered independently from two 12V-mains-sourced 5V regulators. I have the USART serial pins of the two PICs connected to each other along with a common ground line, so both the supplies have a common ground even though they are actually independent.

I basically have them talking to each other with PIC-1 waiting for PIC-2 to ask for data, and then PIC-1 transmitting data to PIC-2. This goes on in a loop just for testing purposes. I've got both PICs hooked up to LCDs so I know whats going on.

Now heres the peculiar part. I should theoretically be able to power up PIC-1 and then PIC-2 and immediately have PIC-2 asking PIC-1 for data, PIC-1 responding and the loop continuing. But I can't get that to happen. PIC-1 just waits for data even after PIC-2 has powered on and acknowledged that it has asked PIC-1 for data.

The ONLY way I can currently get around this is if I power on both PICs (in any order), reload the hex file for PIC-1 first while still having the 12V power connected, and then reload the hex file for PIC-2 using the same process. PIC-1 then correctly receives PIC-2's request and sends data back and the loop continues without a hitch.

I'm guessing this is something to do with either the fact that I've got common ground for 2 independent supplies, or something wrong with my code. I plan to eventually have wireless USART using Nigel's tutorials and inverting the signals as opposed to Manchester coding as the communication will be short-range, so the common ground issue will become irrelevant later. I have posted the important bits of my code below:

PIC-1 code (master):

Quote:
while(1)
{
//approx 1 second delay before next sample and lcd update
for (n = 0; n <50; n++)
for( k= 0; k< twentyms; k++);
lcd_clr();
// initialise
TXSTA=0x26;
SPEN=1;
putch('?'); // Ask for data
LCDWrite('?', 1);
LCDWrite(' ', 1); //Acknowledge sent character to LCD
LCDWrite('s', 1);
LCDWrite('e', 1);
LCDWrite('n', 1);
LCDWrite('t', 1);

lcd_newline();
LCDWrite(getch(), 1); //Waiting...then write received character to LCD
LCDWrite(' ', 1); //Acknowledge receipt to LCD
LCDWrite('R', 1);
LCDWrite('c', 1);
LCDWrite('v', 1);
LCDWrite('d', 1);
}

PIC-2 code (slave):
Quote:
while(1)
{
lcd_clr();
LCDWrite(getch(), 1); //Waiting...then write received character to LCD
LCDWrite(' ', 1);
LCDWrite('R', 1); //Acknowledge receipt to LCD
LCDWrite('c', 1);
LCDWrite('v', 1);
LCDWrite('d', 1);

//approx 1 second delay before sending character back
for (n = 0; n <50; n++)
for( k= 0; k< twentyms; k++);
// initialise
TXSTA=0x26;
SPEN=1;
putch('F');// transmit the character

lcd_newline();
LCDWrite('F', 1);
LCDWrite(' ', 1); //Acknowledge sent character to LCD
LCDWrite('s', 1);
LCDWrite('e', 1);
LCDWrite('n', 1);
LCDWrite('t', 1);
for (n = 0; n <50; n++)
for( k= 0; k< twentyms; k++);

}
Both PICs have the following serial initialisation:
Quote:
/* Serial initialization */
void
init_comms(void)
{
SPBRG = DIVIDER;
TXSTA = (SPEED|NINE_BITS|0x20);
RCSTA = (NINE_BITS|0x90);
TRISC6=OUTPUT;
TRISC7=INPUT;
}
Another question: I can currently send one character reliably, what if I want to send a string? I'm planning to send int's and float's from the slave to the master with the master periodically polling the slave, so I was thinking of using sprintf() to append them to a string and then send the string.

Any insights would be appreciated!

p.s. I'm using the Hi-Tech PICC18 compiler and PICKit2 to load HEX files.
__________________
www.myspace.com/crimsonroadmap

Last edited by NJ Roadmap; 21st February 2007 at 06:38 PM.
NJ Roadmap is offline  
Reply With Quote
Old 19th February 2007, 11:36 PM   (permalink)
Default

Why do you have two seperate sets of code for a serial echo routine? The code for both PIC's should be identical you just wire the TX of one to the RX of the other and vice versa. Send char, wait for char with a random timeout delay. If a char isn't received by the time out delay send another char. If you don't have a time out ability in the getch routine all that needs to happen is a single bit transmit or receive error and it will wait forever. There's likley a timeing glitch on the TX/RX line when the PIC's powering on that's keeping the loop from starting when you come up from a cold start. The line could be floating high or load when the PIC starts up in it's natural High Z state. Causing a single bit to be transmitting which starts the getch routine and it just sits there waiting for the next bits which never come.
__________________
"Because I be what I be. I would tell you what you want to know if I
could, mum, but I be a cat, and no cat anywhere ever gave anyone a
straight answer, har har."
Sceadwian is offline  
Reply With Quote
Old 21st February 2007, 01:51 AM   (permalink)
Default

So this is a 3-wire system? Do you have a quickie schematic so that I can take a look at the entire scheme?
__________________
"Everything that is done in the world is done by hope." -Martin Luther
"There are two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle."-Albert Einstein
Analog is offline  
Reply With Quote
Old 21st February 2007, 01:37 PM   (permalink)
Default

Its literally 2 PIC18F4520's on independently-powered boards with each RX pin terminating at the other end at a TX pin (so that makes 2 wires) and the third wire is a ground wire, which is explained below.

The ground's of the two independently-powered boards are linked since the RX and TX levels on each board need to have the same reference, or atleast that's what I think.

I haven't actually tried it without the ground pins connected, but will do that tomorrow.

update: I have got the PIC sending strings via the USART to the other PIC by sending a character at a time. I am just wondering how I can implement error correction on a hardware USART if I'm just putting an ASCII char in the TXREG and getting an ASCII character out of the RXREG at the other end?

update 2: I have just had an idea: what if i convert each character in my string into binary, then add parity to it and then send this character as a 9-bit binary string? Or is there a way to do this more easily?
__________________
www.myspace.com/crimsonroadmap
NJ Roadmap is offline  
Reply With Quote
Old 21st February 2007, 02:22 PM   (permalink)
Default

Quote:
Originally Posted by NJ Roadmap
Its literally 2 PIC18F4520's on independently-powered boards with each RX pin terminating at the other end at a TX pin (so that makes 2 wires) and the third wire is a ground wire, which is explained below.

The ground's of the two independently-powered boards are linked since the RX and TX levels on each board need to have the same reference, or atleast that's what I think.

I haven't actually tried it without the ground pins connected, but will do that tomorrow.
It needs the ground connection, unless you already have one elsewhere?.

Quote:

update: I have got the PIC sending strings via the USART to the other PIC by sending a character at a time. I am just wondering how I can implement error correction on a hardware USART if I'm just putting an ASCII char in the TXREG and getting an ASCII character out of the RXREG at the other end?
For a simple wired connection there should really be no need?, but if you want to you should look at packet schemes.

Quote:

update 2: I have just had an idea: what if i convert each character in my string into binary, then add parity to it and then send this character as a 9-bit binary string? Or is there a way to do this more easily?
You can add parity to it anyway, I believe there's even a parity bit setting in the hardware?, but I've never had occasion to use it - a simple parity bit isn't a very good check though!.

How fast are you trying to send?, there really shouldn't be any problems doing this!.
__________________
PIC programmer software, and PIC Tutorials at:
http://www.winpicprog.co.uk
Nigel Goodwin is online now  
Reply With Quote
Old 21st February 2007, 03:09 PM   (permalink)
Default

It sounds very much to me like a software issue. I can't tell too much from your code, partly because you describe the two PICs as "PIC-1" and "PIC-2" in the text, and then label both code samples as "PIC-2", though I assume that "master" is PIC-2... And, I don't know the specifics of the getch() routine.

But, if the getch() routine is blocking (ie - it doesn't return until something is received), then all it would take is for the slave PIC to miss the "request" character a single time, and then both PICs would sit there in the 'getch()' routine waiting for data, stuck. This is a very poor setup - although if you're powering them up in the order you describe, in theory the slave shouldn't be missing that request, it would be significantly more robust to implement a better scheme where some kind of a timeout is used so that things don't get kicked into an infinite loop. And, if you're planning to actually have the slave DO anything other than constantly sit waiting for the master to request data, you're probably going to want to make use of the USART interrupt so it just jumps to an ISR any time data comes in, handles it, and jumps back to the main program. This could also work well on the master, allowing it to send a request, and go do other things until the response arrives.
__________________
EEgeek.net
evandude is offline  
Reply With Quote
Old 21st February 2007, 08:05 PM   (permalink)
Default

Quote:
Originally Posted by Nigel Goodwin
It needs the ground connection, unless you already have one elsewhere?.
I'm going to add RF capabilities tomorrow with a 433MHz AM module tomorrow, and obviously the 2 grounds will be isolated then. I'm guessing this isn't a problem as you have tried a similar mechanism in your tutorials?


Quote:
Originally Posted by Nigel Goodwin
For a simple wired connection there should really be no need?, but if you want to you should look at packet schemes
With USART over RF with simple signal inversion, it would be better if I have some form of error correction wouldn't it? I'd atleast like the receiving PIC to echo what it received to confirm that the data wasn't corrupted, and if it was, get the originally transmitting PIC to resend it? I'd rather not use this method though as even the echo-ed data may be corrupted.

Quote:
Originally Posted by Nigel Goodwin
You can add parity to it anyway, I believe there's even a parity bit setting in the hardware?, but I've never had occasion to use it - a simple parity bit isn't a very good check though!.
I know the USART has a ninth-bit setting but from what I read in the data sheet I'd have to manually load it, so I'm guessing this means I write the character into TXREG after writing the parity bit for that character into TX9D
(the 9th bit of transmit data). I know simple parity error-checking isn't very useful as theres still a chance that 2 bits may be wrong and hence parity would not be able to detect it, but is there a better solution?

Quote:
Originally Posted by Nigel Goodwin
How fast are you trying to send?, there really shouldn't be any problems doing this!.
Currently over wires at 9600bps, but I'm willing to take this down to as low as necessary when sending over RF in order to reduce error rates, considering I'm using the crude solution of signal inversion as opposed to Manchester Coding.
__________________
www.myspace.com/crimsonroadmap
NJ Roadmap is offline  
Reply With Quote
Old 21st February 2007, 08:09 PM   (permalink)
Exclamation

Quote:
Originally Posted by NJ Roadmap
I'm going to add RF capabilities tomorrow with a 433MHz AM module tomorrow, and obviously the 2 grounds will be isolated then. I'm guessing this isn't a problem as you have tried a similar mechanism in your tutorials?
you need a GND connection if there is no RF link between them. wire needs ground. if you make it wireless then no ground is needed. it's basic electronics. every thing must have a GND.


good luck with it
__________________
Need Help?
Press F1
If that doesn\'t help you, ask me... I might know better.
bloody-orc is offline  
Reply With Quote
Old 21st February 2007, 08:27 PM   (permalink)
Default

Quote:
Originally Posted by evandude
It sounds very much to me like a software issue. I can't tell too much from your code, partly because you describe the two PICs as "PIC-1" and "PIC-2" in the text, and then label both code samples as "PIC-2", though I assume that "master" is PIC-2... And, I don't know the specifics of the getch() routine.
Yeah sorry about that, my bad!

Quote:
void
putch(unsigned char byte)
{
/* output one byte */
while(!TRMT) /* set whilst TX in progress */
continue;
TXREG = byte;
}

unsigned char
getch() {
/* retrieve one byte */
while(!RCIF) /* set when register is not empty */
continue;
return RCREG;
}
Quote:
Originally Posted by evandude
But, if the getch() routine is blocking (ie - it doesn't return until something is received), then all it would take is for the slave PIC to miss the "request" character a single time, and then both PICs would sit there in the 'getch()' routine waiting for data, stuck. This is a very poor setup - although if you're powering them up in the order you describe, in theory the slave shouldn't be missing that request, it would be significantly more robust to implement a better scheme where some kind of a timeout is used so that things don't get kicked into an infinite loop. And, if you're planning to actually have the slave DO anything other than constantly sit waiting for the master to request data, you're probably going to want to make use of the USART interrupt so it just jumps to an ISR any time data comes in, handles it, and jumps back to the main program. This could also work well on the master, allowing it to send a request, and go do other things until the response arrives.
Yeah I realised that. The original code (which has now been expanded a lot) works pretty well but as you mention above it can go terribly wrong if a character has been missed. I am hence going use an ISR on the slave PIC to overcome this. My main issue now is how I can implement something better than just parity-checks (I haven't even found the need for this as the data received is pretty clean, but once I install RF capabilities tomorrow I probably will need it..)
__________________
www.myspace.com/crimsonroadmap
NJ Roadmap is offline  
Reply With Quote
Old 21st February 2007, 08:28 PM   (permalink)
Default

Also with respect to RF, I am using a RX module and a TX module at each end but they will both be operating at 433MHZ so I am planning to use a half-duplex process as follows. Please let me know if you think this will work:

Note: Master PIC will idle in TX mode and Slave PIC in RX mode

1. Master polls slave for data (some sort of query character(s)) and then switches to RX mode
2. Slave receives polling query and switches to TX mode
3. Slave sends sensor data to Master (preset number of characters) and switches to RX mode
4. Master receives preset number of characters and then switches back to TX mode

I expect the polling interval (step 1) to be about 5 mins as none of the sensor data is critical to the master and all control is done on the slave. The master is literally a dumb-terminal for data display and some user inputs which need to be transmitted to the slave. If this data is to be transmitted to the slave I plan to implement the following process, very similar to the above process for sensor data polling:

Note: Master PIC will idle in TX mode and Slave PIC in RX mode

1. Master send slave heads-up that it is sending user inputs (some sort of 'heads-up' characters) and switches to RX mode, waiting for ACK data
2. Slave receives 'heads-up' data and switches to TX mode
3. Slave sends ACK data and switches to RX mode
4. Master receives ACK data and then switches back to TX mode
5. Master sends user inputs (preset number of characters) to slave and STAYS in TX mode
6. Slave receives user inputs and STAYS in RX mode

I guess I could implement some sort of ACK packet sending at every step of the process. Can anyone see any flaws in the above processes?
__________________
www.myspace.com/crimsonroadmap
NJ Roadmap is offline  
Reply With Quote
Old 21st February 2007, 08:59 PM   (permalink)
Default

Major flaw is the RF link, as your UART is waiting for a start bit, then if the signal drops too weak it will generate false start bits, and false data. This is another advantage of the Manchester coding.

AM modules may not be as bad as FM though?, as with FM you get the white noise when the signal drops.

The modules I used have a signal strength output on an extra pin, you could monitor that, and only enable the UART if the signal is strong enough.
__________________
PIC programmer software, and PIC Tutorials at:
http://www.winpicprog.co.uk
Nigel Goodwin is online now  
Reply With Quote
Old 21st February 2007, 09:03 PM   (permalink)
Default

This module doesn't have a singal strength pin unfortunaltely. I chose AM because they were cheaper than the comparable FM module from the same company. It turns out that it may actually be better than FM for this application! The module outputs 3.6V for a high and 0.6V for a low. Will 3.6V be enough for the USART to detect a high?

Link to RF Solutions AM-HRR30-433 datasheet: http://www.farnell.com/datasheets/61126.pdf
__________________
www.myspace.com/crimsonroadmap
NJ Roadmap is offline  
Reply With Quote
Old 21st February 2007, 09:05 PM   (permalink)
Default

Quote:
Originally Posted by NJ Roadmap
This module doesn't have a singal strength pin unfortunaltely. I chose AM because they were cheaper than the comparable FM module from the same company. It turns out that it may actually be better than FM for this application! The module outputs 3.6V for a high and 0.6V for a low. Will 3.6V be enough for the USART to detect a high?
Should be fine, logic levels are generally VERY compatible with each other.
__________________
PIC programmer software, and PIC Tutorials at:
http://www.winpicprog.co.uk
Nigel Goodwin is online now  
Reply With Quote
Old 21st February 2007, 09:11 PM   (permalink)
Default

Quote:
Originally Posted by Nigel Goodwin
Major flaw is the RF link, as your UART is waiting for a start bit, then if the signal drops too weak it will generate false start bits, and false data. This is another advantage of the Manchester coding.

AM modules may not be as bad as FM though?, as with FM you get the white noise when the signal drops.
I am confused about this, can you elaborate a bit about when a signal may drop too weak? (whats confusing me is that i am using inversion so surely a drop in signal should keep it high?)

I am planning to use ZTX653 NPNs for the signal inversion and planning to transmit and receive at 300bps to start off with to reduce chances of errors. Hopefully this will work tomorrow!
__________________
www.myspace.com/crimsonroadmap
NJ Roadmap is offline  
Reply With Quote
Old 21st February 2007, 09:12 PM   (permalink)
Default

Heres a link where I'm getting my info for the transistor inverters:
http://www.kpsec.freeuk.com/trancirc.htm

Quote:
Any general purpose low power NPN transistor can be used. For general use RB = 10k and RC = 1k, then the inverter output can be connected to a device with an input impedance (resistance) of at least 10k such as a logic chip or a 555 timer (trigger and reset inputs)
For TX, the transistor output side will be connected to the DATA-IN of the TX module. Im not sure whether the input impedance will be high enough...any thoughts?

p.s. Thanks for the help so far!
__________________
www.myspace.com/crimsonroadmap

Last edited by NJ Roadmap; 21st February 2007 at 09:28 PM.
NJ Roadmap is offline  
Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Latest
18f452 usart (rs232) and pic BOBKA Micro Controllers 5 20th February 2007 05:17 AM
PIC USART: Help Please mortuzahasan Micro Controllers 2 11th February 2007 06:28 PM
Newcomers, please read! (PIC regarded) Upd. 0xD Jay.slovak Micro Controllers 0 17th April 2005 01:04 PM



All times are GMT. The time now is 01:42 PM.


Electronic Circuits  |  Electronics Wiki
Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.