PDA

View Full Version : Pic to Pic communication



fignewt
- 19th June 2009, 21:00
I am a newbie so thanks in advance for the support.

I am trying to communicate between two pics and I am having trouble finding a solid method for doing this. I am using the latest version of PICBasic pro.

I am using two 16F684 only because I happen to have 10 of them.
If I understand correctly I can't use serin or serout because the 16F684 doesn't support UART. I have been look into the Shiftin in and out but with no luck at all.

My question is, is there any other method to communicate between these two pics or is shiftin and out the only way? Also is there someplace I can find an example of how this would work.

ruijc
- 19th June 2009, 21:10
Hi there,

Check the DEBUG/DEBUGIN instructions in your PBP manual.

These instructions are very easy to work with, very stable with low osc values and fast speeds and the DEFINES are very straightforward.

My best regards
Rui

Melanie
- 19th June 2009, 21:16
Yes, you can use SERIN and SEROUT (provided you are using a Resonator or Xtal), it's HSERIN and HSEROUT that require a USART.

BrianT
- 19th June 2009, 23:42
I have a system with 5 PICs all doing separate tasks in separate boxes. The PICs are in a peer to peer system with no master. All have equal priority and lose only a few microseconds checking bus activity every time through their main software loops. If a message is pending, all PICs need about 2 mSecs to work out if the message is for them.

The hardware has a 10 way ribbon cable linking all PICs over about 2 metres and only using a few pins. 4 PICs are 18F4620 @ 20 MHz and one is a 16F88 @ 4 MHz. Each PIC has a different ID stored in location 0 of the EEPROM. All comms is at 9600 bps. Slow man is the 16F88 @ 4 MHz. With just the 18F4620 I can get a reliable 50 kilobits.

I use 3 signal lines, plus power and ground. There is an ATTention line, and ACKnowledge line and a MeSsaGe line. ATT, ACK and MSG are tied to +5 volts with 10 K resistors and the PIC pins driving the communications bus are set as inputs. I have 220 ohm resistors on every PIC pin connecting to the comms bus to prevent damage if the software inadvertently sets rival pins to outputs. The 220 ohms also act as good line termination and suppress ringing.

In normal operation, when each PIC is doing its own job and not communicating, the MSG, ATT and ACK lines are all floating high with those pins set as inputs. The software in each PIC checks for comms activity at least once per loop.

When a PIC wants to send it checks that ATT and ACK are both high meaning the comms bus is free. If the bus is free it stakes a claim by setting the ATT pin to an output and pulling the ATT line low. That PIC immediately sends a continuous stream of address polls on the comms bus for as long as it takes for the target to finish it's own tasks and get around to checking the comms bus, or a timeout occurs.

Whenever any PIC sees the ATT line go low it checks the message line for their address. If the address does not match their own ID that PIC goes back to its normal tasks. The PIC that does match the ID being polled pulls the ACK line low. The sender sees ACK go low so it knows the target PIC is ready to receive. The sender stops sending the Destination ID and now sends the message. The sender keeps sending until it sees the ACK line go high. This means the receiver has a clean copy of the message. All messages are error protected with simple CheckSums.

The system works a treat. There are no interrupts needed.

HTH
BrianT

Archangel
- 20th June 2009, 01:58
Also is there someplace I can find an example of how this would work.
Welcome newbie, the link posted below is not a factitious gesture it is a "Special" Google link that will if the check box is ticked, search just this forum. Lots of serial com. examples in here, and as Melanie pointed out USART uses Hserin/out, so you are free to use serin,serin2, shiftin, . . .

http://www.google.com/custom?hl=en&cof=AH%3Aleft%3BS%3Ahttp%3A%2F%2Fwww.picbasic.co.u k%2Fforum%3BL%3Ahttp%3A%2F%2Fwww.crownhill.co.uk%2 Flogo.gif%3BLH%3A37%3BLW%3A174%3B&domains=picbasic.co.uk&q=&btnG=Search&sitesearch=picbasic.co.uk

fignewt
- 24th June 2009, 02:47
Using the below code and two PIC 16F684s I don't get the results I am looking for.

The DEBUGIN doesn't appear to be working. What have I missed?


'----MASTER CODE-------
DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 2
DEFINE DEBUG_BAUD 2400
DEFINE DEBUG_MODE 0
bvar var byte

Pause 2000
bvar = 1

Loop:
DEBUG bvar
Goto Loop:


'----SLAVE CODE-------

DEFINE LOADER_USED 1
DEFINE DEBUGIN_REG PORTC
DEFINE DEBUGIN_BIT 2
DEFINE DEBUG_BAUD 2400
DEFINE DEBUGIN_MODE 0

bvar var byte

TRISA = %001000
PORTA = %000001

Pause 2000

Loop:
DEBUGIN 4000, timesup, [bvar]
IF (bvar = 1) then
PORTA = %000010
Pause 4000
ENDIF
Pause 2000
PORTA = %000100
Pause 2000
PORTA = %100000
Pause 2000

Goto Loop:

timesup:
PORTA = %010000
Pause 2000
PORTA = %000001
Return

mackrackit
- 24th June 2009, 04:11
Using the below code and two PIC 16F684s I don't get the results I am looking for.

But you are getting something?
What are you using for an oscillator and how are your configs set?

fignewt
- 24th June 2009, 04:25
I am not using external OSC I assumed it used the internal OSC. I changed a few setting settings in my code and now see it is jumping to the timesup function. So it appears that the debugin is waiting but not recieving the anything and the jumps to the timesup function.

New code below:


'----------MASTER CODE------------
INCLUDE "modedefs.bas"
DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 2
DEFINE DEBUG_BAUD 2400
DEFINE DEBUG_MODE 1
bvar var byte

Pause 2000
bvar = 1

Loop:
DEBUG bvar
Goto Loop:


'----------SLAVE CODE------------
INCLUDE "modedefs.bas"
DEFINE DEBUGIN_REG PORTC
DEFINE DEBUGIN_BIT 2
DEFINE DEBUG_BAUD 2400
DEFINE DEBUGIN_MODE 1

bvar var byte

TRISA = %001000
PORTA = %000001

Pause 2000

Loop:
DEBUGIN 4000, timesup, [bvar]
IF (bvar = 1) then
PORTA = %000010
Pause 4000
ENDIF
Pause 2000
PORTA = %000100
Pause 2000
PORTA = %100000
Pause 2000

Goto Loop:

timesup:
PORTA = %010000
Pause 2000
PORTA = %000001
Return

mackrackit
- 24th June 2009, 04:36
Unfortunately the internal OSC may not be accurate enough for SERIAL.

You may try setting the internal to run at 4Mhz if you have not done so. I know, the data sheet says that is the default...
and add
DEFINE OSC 4
to your code. I know, another default...but why take chances?

Your best bet will be to use an external OSC.

Archangel
- 24th June 2009, 05:59
Your best bet will be to use an external OSC.
To clarify this statement, your choice of a crystal and caps, a 3 pin resonator, or an external oscillator. Or you might try a lower Baud rate with the internal to see if that works, it really depends how much and which way the intosc is off frequency. A big ALSO . . . make sure the analog stuff is turned off on those ports you are using . . . try these:


cmcon0 = 7
adcon0 = 0

PICs are funny, they default to almost everything turned on, whereas you would think it would default everything off.

ruijc
- 24th June 2009, 11:30
Hi fignewt,

a few thoughts you may try...

Since RC2 could be used as Analog, its important to set it as digital ( like Joe just told you ).
The Debug/Debugin DEFINES should place the pin output/input, but is never too much to declare it anyway.

Separate the RX from the TX and connect them to the PC and use the MicroCode Studio's serial communicator to see if each one is working before connecting them together.

I believe that it will work with the internal OSC, but you can try with an external osc and see, but...
Did not see any reference on the internal OSC speed. The default is 4Mhz, but use this:



osccon=%1100111
DEFINE OSC 4

EarlyBird2
- 30th June 2009, 08:38
A long time ago Bruce helped me with I2C comms between chips. I was having problems because it was so easy. As an example here is the slave code. I built a board with an address selector switch connected to port C so that I could place them on a Bus without having to reprogram them. The Slaves are monitoring inputs from Volt Free Contacts conected to Port B.


' PicBasic Pro I2C slave program - PIC16F72/PIC-X1
' bootloader and OSC settings
'DEFINE LOADER_USED 1 ' bootloader
DEFINE osc 20
INCLUDE "modedefs.bas"

' Alias pins
scl VAR PORTC.3 ' I2C clock input
sda VAR PORTC.4 ' I2C data input


' Define used register flags
SSPIF VAR PIR1.3 ' SSP (I2C) interrupt flag
BF VAR SSPSTAT.0 ' SSP (I2C) Buffer Full
R_W VAR SSPSTAT.2 ' SSP (I2C) Read/Write
D_A VAR SSPSTAT.5 ' SSP (I2C) Data/Address
CKP VAR SSPCON.4 ' SSP (I2C) SCK Release Control
SSPEN VAR SSPCON.5 ' SSP (I2C) Enable
SSPOV VAR SSPCON.6 ' SSP (I2C) Receive Overflow Indicator
WCOL VAR SSPCON.7 ' SSP (I2C) Write Collision Detect



' Allocate RAM
result VAR BYTE ' ADC result
datain VAR BYTE ' Data in
readcnt VAR BYTE ' I2C read count
I2Caddress VAR BYTE ' Our address


' Initialize ports and directions
TRISA = %11111111
TRISB = %11111111
TRISC = %11111111
' Initialize I2C slave mode reading inputs from hardware address settings
I2Caddress=0
IF PORTC.0=0 Then I2Caddress=I2Caddress+1
IF PORTC.1=0 Then I2Caddress=I2Caddress+2
IF PORTC.2=0 Then I2Caddress=I2Caddress+4
IF PORTC.5=0 Then I2Caddress=I2Caddress+8


SSPADD = I2Caddress ' Set our address
SSPCON = $36 ' Set to I2C slave with 7-bit address


While 1>0

While NOT SSPIF
Wend ' Check for I2C interrupt flag

SSPIF = 0 ' Clear interrupt flag
IF D_A = 0 Then
readcnt = 0 ' Mark as first read
EndIF


SSPBUF = PORTB ' Get data from array
CKP = 1 ' Release SCL line
readcnt = readcnt + 1 ' Move along read count
Wend

Steve