PDA

View Full Version : PIC - PIC Comm



dgcarter
- 1st February 2009, 19:04
I've been working on a little robot project in PIC Pro Basic.

I'm trying to establish some sort of communication between two PIC Microprocessors. 1 being a PIC16F84A with a keypad, the other a PIC16F877A controling the robot.

The PIC16F84A scans the kaypad and stores the key pressed into a variable. The PIC16F877A needs to recieve this value and store it in its own variable.

I've experimented with RS232 (SERIN, SEROUT) but I jus can't seem to get it working. There is 1 meter of cable between the two pics so could that be the reason?

Any suggestions as to what I can do to achieve communication between these two pics?

mister_e
- 1st February 2009, 19:26
Try one thing first.

Connect your PIC16F84 to your PC and send some data to any terminal softare (hyperterminal, TeraTerm, RealTerm, Microcode Serial communicator) and see if you receive any data.

do the same but From your PC to your 16F877,

once both work, try your PIC to PIC communication on small distance, then move on with long cable run. You may want to use RS232 driver for longer run.

Archangel
- 1st February 2009, 19:36
OUT) but I jus can't seem to get it working. There is 1 meter of cable between the two pics so could that be the reason?

Any suggestions as to what I can do to achieve communication between these two pics?
Hello dgcarter, and welcome.
Since this is your first post, we know nothing about you, so I must ask, is this your first project, or do you have some experience? Have you tried the basic blinking LED yet? 1 meter should work easily, so if you would post your code using the code tags as shown in Mister_e's signature, (shown in green) let's get started.

dgcarter
- 1st February 2009, 20:15
Hello again...

I've been using PBP for a while now, I've blinked many many LED's, Swiched lights on and off with my PC and a PIC via RS232, and now I have a robot which follows a black line.

Essentially I have a PIC 16F84A on a 4x3 keypad, I've tried getting it to communicate via RS232 with my Robot (PIC16F877).

Heres the Keypads code...


INCLUDE "modedefs.bas"

' Declare Variables...
Col1 VAR PORTA.0
Col2 VAR PORTA.1
Col3 VAR PORTA.2

Row1 VAR PORTB.4
Row2 VAR PORTB.5
Row3 VAR PORTB.6
Row4 VAR PORTB.7

LED var PORTB.1
SERTX var PORTB.2
SERoK var PORTB.3

Key var word

' Setup Ports

input row1 : input row2 : input row3 : input row4
output col1 : output col2 : output col3 : output SERTX

' Setup Var

key = 20

' Program Start
Boot:
high led
pause 500
low led
pause 100
high led
pause 100
low led
pause 2000
high serok
goto main

Main:
gosub ScanKeys
if key != 20 then gosub transmit
goto main

ScanKeys:
high col1
pause 50
if row1 = 1 then Key = 1
if row2 = 1 then Key = 4
if row3 = 1 then Key = 7
if row4 = 1 then Key = 10
low col1

high col2
pause 50
if row1 = 1 then Key = 2
if row2 = 1 then Key = 5
if row3 = 1 then Key = 8
if row4 = 1 then Key = 0
low col2

high col3
pause 50
if row1 = 1 then Key = 3
if row2 = 1 then Key = 6
if row3 = 1 then Key = 9
if row4 = 1 then Key = 11
low col3

return

Transmit:
gosub flash
serout sertx,4,[55,key]
pause 50
key = 20
low led
return

Flash:
high led
pause 50
low led
pause 50
high led
pause 50
return

end

Ok, so the PIC16F84A raises SERoK to logic 1 which tells the PIC16F877A to accept serial communication.

PIC16F877A Code:


INCLUDE "modedefs.bas"

' Define LCD registers and bits
Define LCD_DREG PORTA
Define LCD_DBIT 0
Define LCD_RSREG PORTA
Define LCD_RSBIT 4
Define LCD_EREG PORTA
Define LCD_EBIT 5
DEFINE LCD_LINES 4

'Define Aliases
RHF var PORTB.0
RHB VAR PORTB.1
LHF VAR PORTB.2
LHB VAR PORTB.3
LineCom var PORTB.4
LEDS var PORTB.5
SERoK var PORTB.7
SERRX var PORTB.6

'Define Vars
Dat var byte

ADCON1 = 7

'Begin program
Boot:
dat = 20
Pause 500 ' Wait for LCD to startup
gosub display
low leds
repeat
Lcdout $FE, $C0, "!! Insert Ctrl !!"
Lcdout $FE, $94, "Waiting..."
pause 100
until serok = 1
goto modeselect

ModeSelect:
Lcdout $FE, $C0, "!! Select Mode !!"
Lcdout $FE, $94, "Waiting..."
serin SERRX,4,[55],Dat
pause 50
Discon:
Lcdout $FE, $94, "Pls Discon..."
if serok = 0 then GoMode
goto discon

GoMode:
if dat <> 20 then
select case dat
case 20
goto boot
case 2
goto linefollow
end select
endif
goto boot

Display:
Lcdout $fe, 1 ' Clear LCD screen
Lcdout "PIC-Bot... v1.0"
Lcdout $FE, $94, "Pls Wait..."
Pause 1000
return

'Check for controler
ChkCtrl:
if serok = 1 then modeselect
return

'Line Follow loop
LineFollow:
Lcdout $FE, $C0, "~~ LiNe FoLlOw ~~"
Lcdout $FE, $94, "...Scan Line..."
low RHF
low LHF
PWM LHF,60,18
pause 100
if linecom = 0 then gosub moveleft
low RHF
low LHF
PWM RHF,60,18
pause 100
if linecom = 0 then gosub moveright
gosub chkctrl
goto linefollow

MoveLeft:
Lcdout $FE, $94, "Correct Left"
repeat
low RHF
low LHF
PWM RHF,60,20
PWM LHb,60,20
pause 100
until linecom = 1
pause 50
low RHF
low LHF
PWM RHF,60,18
return

MoveRight:
Lcdout $FE, $94, "Correct Right"
repeat
low RHF
low LHF
PWM LHF,60,20
PWM rHb,60,20
pause 100
until linecom = 1
pause 50
low RHF
low LHF
PWM LHF,60,18
return

end

Now the Robot waits until the keypad unit is pluged in, then it waits until the digit 2 is sent serially (by pressing 2 on the keypad), then it askes you to dicconnect the keypad unit (SERoK changes from logic 1 to logic 0) and it executes the program IF 2 was pressed.:D

mister_e
- 1st February 2009, 20:27
When a PIC have a built-in USART use it.. PIC16F877A have it, switch to HSERIN

SEROUT on one side
HSERIN on the other side

Begin with it, then add some sugar around...

dgcarter
- 1st February 2009, 20:43
When a PIC have a built-in USART use it.. PIC16F877A have it, switch to HSERIN

SEROUT on one side
HSERIN on the other side

Begin with it, then add some sugar around...

I assume then I use PIN 26, labled RX on the PIC?

mister_e
- 1st February 2009, 20:47
yes indeed, and you may need to add some DEFINEs at the top of your code as well.

Well, by default @4MHz it's already set @2400 baud, so... humm... you may not need any Define at all... it's just good programming :D

dgcarter
- 1st February 2009, 21:59
Cool, theres deff communication because I've got the LCD to display the value of the Dat variable, only problem is, when I press 1 on the keypad I get 10 on the display, and for 2 I get 40 and then it changes to 60 when I press 2 again, so something strange is going on... any ideas?


Keypad:

INCLUDE "modedefs.bas"

' Declare Variables...
Col1 VAR PORTA.0
Col2 VAR PORTA.1
Col3 VAR PORTA.2

Row1 VAR PORTB.4
Row2 VAR PORTB.5
Row3 VAR PORTB.6
Row4 VAR PORTB.7

LED var PORTB.1
SERTX var PORTB.2
SERoK var PORTB.3

Key var byte

' Setup Ports

input row1 : input row2 : input row3 : input row4
output col1 : output col2 : output col3 : output SERTX

' Setup Var

key = 20

' Program Start
Boot:
high led
pause 500
low led
pause 100
high led
pause 100
low led
pause 2000
high serok
goto main

Main:
gosub ScanKeys
if key <> 20 then gosub transmit
goto main

ScanKeys:
high col1
pause 50
if row1 = 1 then Key = 1
if row2 = 1 then Key = 4
if row3 = 1 then Key = 7
if row4 = 1 then Key = 10
low col1

high col2
pause 50
if row1 = 1 then Key = 2
if row2 = 1 then Key = 5
if row3 = 1 then Key = 8
if row4 = 1 then Key = 0
low col2

high col3
pause 50
if row1 = 1 then Key = 3
if row2 = 1 then Key = 6
if row3 = 1 then Key = 9
if row4 = 1 then Key = 11
low col3

return

Transmit:
gosub flash
serout sertx,T2400,[key]
pause 50
key = 20
low led
return

Flash:
high led
pause 50
low led
pause 50
high led
pause 50
return

end

Robot:

INCLUDE "modedefs.bas"

' Define LCD registers and bits
Define LCD_DREG PORTA
Define LCD_DBIT 0
Define LCD_RSREG PORTA
Define LCD_RSBIT 4
Define LCD_EREG PORTA
Define LCD_EBIT 5
DEFINE LCD_LINES 4

' Define HSER Registers
' Set receive register to receiver enabled
DEFINE HSER_RCSTA 90h
' Set baud rate
DEFINE HSER_BAUD 2400

'Define Aliases
RHF var PORTB.0
RHB VAR PORTB.1
LHF VAR PORTB.2
LHB VAR PORTB.3
LineCom var PORTB.4
LEDS var PORTB.5
SERoK var PORTB.7
SERRX var PORTB.6

'Define Vars
Dat var byte

ADCON1 = 7

'Begin program
Boot:
dat = 20
Pause 500 ' Wait for LCD to startup
gosub display
low leds
repeat
Lcdout $FE, $C0, "!! Insert Ctrl !!"
Lcdout $FE, $94, "Waiting..."
Lcdout $FE, $D4, "Dat = ",#Dat
pause 100
until serok = 1
goto modeselect

ModeSelect:
Lcdout $FE, $C0, "!! Select Mode !!"
Lcdout $FE, $94, "Waiting..."
Lcdout $FE, $D4, "Dat = ",#Dat
gosub commrx
if dat <> 20 then
goto discon
else
goto modeselect
endif
Discon:
Lcdout $FE, $94, "Pls Discon..."
Lcdout $FE, $D4, "Dat = ",#Dat
if serok = 0 then GoMode
goto discon

CommRX:
HSERIN [Dat]
return

GoMode:
if dat <> 20 then
select case dat
case 20
goto boot
case 2
goto linefollow
end select
endif
goto boot

Display:
Lcdout $fe, 1 ' Clear LCD screen
Lcdout "PIC-Bot... v1.0"
Lcdout $FE, $94, "Pls Wait..."
Pause 1000
return

'Check for controler
ChkCtrl:
if serok = 1 then modeselect
return

'Line Follow loop
LineFollow:
Lcdout $FE, $C0, "~~ LiNe FoLlOw ~~"
Lcdout $FE, $94, "...Scan Line..."
low RHF
low LHF
PWM LHF,60,18
pause 100
if linecom = 0 then gosub moveleft
low RHF
low LHF
PWM RHF,60,18
pause 100
if linecom = 0 then gosub moveright
gosub chkctrl
goto linefollow

MoveLeft:
Lcdout $FE, $94, "Correct Left"
repeat
low RHF
low LHF
PWM RHF,60,20
PWM LHb,60,20
pause 100
until linecom = 1
pause 50
low RHF
low LHF
PWM RHF,60,18
return

MoveRight:
Lcdout $FE, $94, "Correct Right"
repeat
low RHF
low LHF
PWM LHF,60,20
PWM rHb,60,20
pause 100
until linecom = 1
pause 50
low RHF
low LHF
PWM LHF,60,18
return

end

mister_e
- 1st February 2009, 22:19
There's probably some timing issue... no I haven't got to far in your code. But your first one had this preamble stuff which I suggest you to add in your current one...

serout sertx,T2400,["plahplahplah",55,key]

HSERIN [Wait(55), key]