PDA

View Full Version : Looking for Basic Pic-to-Pic Serial Example



greensasquatch
- 11th November 2008, 01:06
I've been looking for an example that would allow me to connect two PICs with one wire and send asychronous data between them. Ideally I want to have 4 buttons on one PIC, press a button and have one of 4 corresponding LED's light on another PIC. Either software serial or hardware method would be fine as long as the code is fairly stripped down and commented. I've used serout a few times but haven't got the hang of serin yet (not many simple examples to be found).

I've been wading through search results for about 2 hours and have found only partially useful code. A lot of comments on read the manual haven't helped.

What I mostly find is that someone asks why their code doesn't work (and give a small snippit of uncommented code). At this point suggestions are offered and then they post "thanks I figured it out" with no indication to what actually worked.

Perhaps someone can post some commented sample code (PIC BASIC PRO preferred) that shows what I am looking for, or knows of some already posted code that my not have been readily apparent?

Also, I'd be happy to take my finished program and schematics and place them in the Code Examples forum when done.

Thanks

mackrackit
- 11th November 2008, 03:01
Send code:


BUT1 VAR PORTB.1 'vars for switches
BUT2 VAR PORTB.2
BUT3 VAR PORTB.3
BUT4 VAR PORTB.4
LOOP:
IF BUT1 = 1 THEN SEROUT PORTA.0,T2400,[9,1] 'sends 9 and 1 if but1 is high
IF BUT1 = 2 THEN SEROUT PORTA.0,T2400,[9,2]
IF BUT1 = 3 THEN SEROUT PORTA.0,T2400,[9,3]
IF BUT1 = 4 THEN SEROUT PORTA.0,T2400,[9,4]
GOTO LOOP


receive code:


NET VAR BYTE 'holding var
LOOP:
SERIN PORTB.5,T2400,[9],NET
IF NET = 1 THEN HIGH PORTA.4 'waits for "9" and writes the next value to vaR net
IF NET = 2 THEN HIGH PORTA.5
IF NET = 3 THEN HIGH PORTA.6
IF NET = 4 THEN HIGH PORTA.7
GOTO LOOP


Change PORTs and BAUD as needed.

greensasquatch
- 11th November 2008, 03:47
Dave, you are the man.

I'll play with the code tonight and post back when I get things rolling.

Thanks

mister_e
- 11th November 2008, 03:58
Not a bad idea to set the SerialOut pin to it's idle state before the first time you'll use it... unless the first character might be screwed-up...

BUT1 VAR PORTB.1 'vars for switches
BUT2 VAR PORTB.2
BUT3 VAR PORTB.3
BUT4 VAR PORTB.4
HIGH PORTA.0 ' set to normal idle state (1 for True, 0 for Inverted)
PAUSE 50 'settle delay

LOOP:
IF BUT1 = 1 THEN SEROUT PORTA.0,T2400,[9,1] 'sends 9 and 1 if but1 is high
IF BUT1 = 2 THEN SEROUT PORTA.0,T2400,[9,2]
IF BUT1 = 3 THEN SEROUT PORTA.0,T2400,[9,3]
IF BUT1 = 4 THEN SEROUT PORTA.0,T2400,[9,4]
GOTO LOOP

greensasquatch
- 11th November 2008, 08:19
So this is what I have so far, <b>it works</b>. When I press a button the corresponding LED lights up and stays alight until another button is pressed.

I'm not so sure why each LED goes out when the next one is lighted, following the code it seems like it should stay lit until eventually after pressing all the buttons all are alight, at which point the device would have to be reset to turn them off.

The PIC with Buttons


'************************************************* ***************
'* Name : Output1.pbp *
'* Author : Greensasquatch *
'* Date : 10/11/2008 *
'* Chip : PIC16F628A *
'* Version : 1.0 *
'* Notes : To output a number corresponding to which button *
'* : was pressed via serial communication *
'************************************************* ***************
'* This Program is part 1 of 2. The other half receives a
'* number and lights a corresponding LED.
'************************************************* ***************
'*
'* Connections are as follows:
'*
'* N/C -01-|####|-18- Green Power LED
'* N/C -02-|####|-17- SEROUT Line
'* N/C -03-|####|-16- N/C
'* MCLR 10K to V+ -04-|####|-15- N/C
'* Gnd -05-|####|-14- V+
'* Butt1 -06-|####|-13- N/C
'* Butt1 -07-|####|-12- N/C
'* Butt1 -08-|####|-11- N/C
'* Butt1 -09-|####|-10- N/C
'*
'************************************************* ***************

INCLUDE "MODEDEFS.BAS"

'uses internal oscillator (should use crystal but I ran out)
@ DEVICE pic16F628A, INTRC_OSC_NOCLKOUT

GreenLED var PORTB.4

Butt1 var PORTB.0
Butt2 var PORTB.1
Butt3 var PORTB.2
Butt4 var PORTB.3

Pause 2000 'wait to begin
high greenled 'turn on status light

Loop:
IF BUTt1 = 1 THEN SEROUT PORTA.0,T1200,[9,1] 'sends 9 and 1 if butt1 is high
IF BUTt2 = 1 THEN SEROUT PORTA.0,T1200,[9,2] 'sends 9 and 2 if butt2 is high
IF BUTt3 = 1 THEN SEROUT PORTA.0,T1200,[9,3] 'sends 9 and 3 if butt3 is high
IF BUTt4 = 1 THEN SEROUT PORTA.0,T1200,[9,4] 'sends 9 and 4 if butt4 is high
GOTO LOOP

end


The PIC with LEDs


'************************************************* ***************
'* Name : Input1.pbp *
'* Author : Greensasquatch *
'* Date : 10/11/2008 *
'* Chip : PIC16F628A *
'* Version : 1.0 *
'* Notes : To read a number via serial communication and *
'* : light a corresponding LED *
'************************************************* ***************
'* This Program is part 2 of 2. The other half sends a
'* number corresponding to a button state.
'************************************************* ***************
'*
'* Connections are as follows:
'*
'* LED3 -01-|####|-18- LED2
'* LED4 -02-|####|-17- LED1
'* N/C -03-|####|-16- N/C
'* MCLR 10K to V+ -04-|####|-15- N/C
'* Gnd -05-|####|-14- V+
'* Serial In -06-|####|-13- N/C
'* Green Power LED -07-|####|-12- N/C
'* N/C -08-|####|-11- N/C
'* N/C -09-|####|-10- N/C
'*
'************************************************* ***************

INCLUDE "MODEDEFS.BAS"

'uses internal oscillator (should use crystal but ran out)
@ DEVICE pic16F628A, INTRC_OSC_NOCLKOUT

GreenLED var PORTB.1

LED1 var PORTA.0
LED2 var PORTA.1
LED3 var PORTA.2
LED4 var PORTA.3

NET var byte 'holding variable for input

Pause 2000 'wait to begin
high greenled 'turn on status light

Loop:
SERIN PORTB.0,T1200,[9],NET 'waits for a "9" and writes the next value to NET
IF NET = 1 THEN HIGH led1
IF NET = 2 THEN HIGH led2
IF NET = 3 THEN HIGH led3
IF NET = 4 THEN HIGH led4
GOTO LOOP

end


Now I'm just going to look into how to make it so that the LED only stays lit as long as the button is held down.


Any comments would be great as the finished code will be posted in code examples (with proper credits of course).

In response to Steve's comment:
I left out setting the idle state for now, it works, so I won't change anything until I fully understand why. I had always thought that TTL idle was low and Inverted (and RS232) idle was high. I'm hoping to make this into a wireless setup somewhere down the road, in which case I would want the idle state to be low so the device does not transmit when there is now data. I see I have more research to do.

Bruce
- 11th November 2008, 15:28
Place CMCON=7 in the top section of your code to disable analog comparators.

With A0, A1, A2 and A3 configured for analog, each pin returns 0 when the port
is read.

HIGH & LOW are read-modify-write instructions. HIGH led1 reads the whole port,
all analog pins are read-in as 0, the bit associated with led1 is set, and the whole
8-bit value is writen back to the port. So only 1 LED will ever be on.

aratti
- 12th November 2008, 16:39
Correct your code as per Bruce indication, than if you modify your code as below, the leds will go off when you release the push-button.
If delay too high or too low adjust timeout (500) to fit your need.

Al.



Loop:
SERIN PORTB.0,T1200,500,OffLed,[9],NET
IF NET = 1 THEN HIGH led1
IF NET = 2 THEN HIGH led2
IF NET = 3 THEN HIGH led3
IF NET = 4 THEN HIGH led4
GOTO LOOP

OffLed:
low led1
low led2
low led3
low led4
GOTO LOOP

End

Charles Linquis
- 12th November 2008, 18:43
I don't have time to post any code right now, but if you use the USART, you don't have to sit in a loop waiting for data to come in. You can occasionally check if PIR1.5 is set, and if so, do a HSERIN and read up to two bytes.
Useful if your "slave" has more to do than control LEDs.

greensasquatch
- 13th November 2008, 07:21
I have updated the code as per Bruce and Al's suggestions.

The lights stay on for a short period after the last button is released then go out.

I am interested in reading the value of RB0-RB3 only from PORTB to a byte variable on the first PIC, then sending that over the wire to be written to PORTA on the second PIC.
I ONLY want to read RB0-RB3 though, and ONLY want to write to RA0-RA3. Is there a statement that will allow this?

Charles, I am very interested in using HSERIN in a future version of the project as it would be nice to let the PIC do something else besides wait for a signal. If you can point me at any example code it would be very much appreciated.


Anyway, this is the code so far:


'************************************************* ***************
'* Name : Output15.pbp *
'* Author : Greensasquatch *
'* Date : 10/11/2008 *
'* Chip : PIC16F628A *
'* Version : 1.5 *
'* Notes : To output a number corresponding to which button *
'* : was pressed via serial communication *
'************************************************* ***************
'* This Program is part 1 of 2. The other half receives a
'* number and lights a corresponding LED.
'************************************************* ***************
'* REVISIONS: comparators disabled
'*
'*
'************************************************* ***************
'*
'* Connections are as follows:
'*
'* N/C -01-|####|-18- N/C
'* N/C -02-|####|-17- SEROUT Line
'* N/C -03-|####|-16- N/C
'* MCLR 10K to V+ -04-|####|-15- N/C
'* Gnd -05-|####|-14- V+
'* Butt1 -06-|####|-13- N/C
'* Butt1 -07-|####|-12- N/C
'* Butt1 -08-|####|-11- N/C
'* Butt1 -09-|####|-10- Green Power LED
'*
'************************************************* ***************

INCLUDE "MODEDEFS.BAS"

'uses internal oscillator (should use crystal but ran out)
@ DEVICE pic16F628A, INTRC_OSC_NOCLKOUT

CMCON=7 'disable comparators

GreenLED var PORTB.4

Butt1 var PORTB.0
Butt2 var PORTB.1
Butt3 var PORTB.2
Butt4 var PORTB.3


Pause 2000 'wait to begin
high greenled 'turn on status light

Loop:
IF BUTt1 = 1 THEN SEROUT PORTA.0,T1200,[9,1] 'sends 9 and 1 if butt1 is high
IF BUTt2 = 1 THEN SEROUT PORTA.0,T1200,[9,2] 'sends 9 and 2 if butt2 is high
IF BUTt3 = 1 THEN SEROUT PORTA.0,T1200,[9,3] 'sends 9 and 3 if butt3 is high
IF BUTt4 = 1 THEN SEROUT PORTA.0,T1200,[9,4] 'sends 9 and 4 if butt4 is high
GOTO LOOP

end

And


'************************************************* ***************
'* Name : Input15.pbp *
'* Author : Greensasquatch *
'* Date : 10/11/2008 *
'* Chip : PIC16F628A *
'* Version : 1.5 *
'* Notes : To read a number via serial communication and *
'* : light a corresponding LED *
'************************************************* ***************
'* This Program is part 2 of 2. The other half sends a
'* number corresponding to a button state.
'************************************************* ***************
'* REVISIONS: comparators disabled, lights out if no signal received
'*
'*
'************************************************* ***************
'*
'* Connections are as follows:
'*
'* LED3 -01-|####|-18- LED2
'* LED4 -02-|####|-17- LED1
'* N/C -03-|####|-16- N/C
'* MCLR 10K to V+ -04-|####|-15- N/C
'* Gnd -05-|####|-14- V+
'* Serial In -06-|####|-13- N/C
'* Green Power LED -07-|####|-12- N/C
'* N/C -08-|####|-11- N/C
'* N/C -09-|####|-10- N/C
'*
'************************************************* ***************

INCLUDE "MODEDEFS.BAS"

'uses internal oscillator (should use crystal but ran out)
@ DEVICE pic16F628A, INTRC_OSC_NOCLKOUT

CMCON=7 'disable comparators

GreenLED var PORTB.1

LED1 var PORTA.0
LED2 var PORTA.1
LED3 var PORTA.2
LED4 var PORTA.3

NET var byte 'holding variable for input

Pause 2000 'wait to begin
high greenled 'turn on status light

Loop:
'waits for a "9" and writes the next value to NET, turn off LEDs if no signal
SERIN PORTB.0,T1200,500,OffLed,[9],NET
IF NET = 1 THEN HIGH led1
IF NET = 2 THEN HIGH led2
IF NET = 3 THEN HIGH led3
IF NET = 4 THEN HIGH led4
GOTO LOOP

OffLED:
low led1
low led2
low led3
low led4
Goto Loop

end


And thanks again to all who have contributed.

mackrackit
- 13th November 2008, 08:18
These should help in the port read write department:
http://www.picbasic.co.uk/forum/showthread.php?t=66&highlight=read+port
http://www.picbasic.co.uk/forum/showthread.php?p=63851
http://www.picbasic.co.uk/forum/showthread.php?t=8734

mackrackit
- 13th November 2008, 08:57
Here is a simple hardware sample to receive and send serially.
It will echo from a terminal program.
If I remember correctly mister E posted this a long time ago.
Works well for testing a setup.


DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 129 ' 2400 Baud @ 20MHz, 0.17%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_EVEN 1
DEFINE HSER_BITS 7

RCIF VAR PIR1.5
SERIALDATA VAR BYTE

PAUSE 100

MAIN:
IF RCIF THEN
HSERIN [SERIALDATA]
HSEROUT [SERIALDATA]
ENDIF
GOTO MAIN

greensasquatch
- 13th November 2008, 09:20
Thanks for the links, I found the third one to be the most help so far. The HSERIN info looks great too, I'm going to have to do some reading tomorrow on the defines.

I've updated the code again a bit. It's now broken. I've set it up so that I read the lower 4 bits of PORTB and if they are greater than 0 a button must have been pushed so the data is sent via SEROUT. I've also set the TRIS registers, although I may have set them wrong since the chips no longer wait 2 seconds to light the Green Status LED, they just turn on right away. Also 3/4 of the indicator LEDs come on automatically and pushing buttons does nothing.

I'm certain it's something to do with the TRIS registers but I haven't done anything different from the example in link 3 (that I can see) except to use BIN instead of HEX.

It's late, I might be missing something obvious, I'll check to code again tomorrow night. For now I'll post what I have.



'************************************************* ***************
'* Title : One Wire Serial Control *
'* File : Output17.pbp *
'* Author : Greensasquatch *
'* Date : 10/13/2008 *
'* Chip : PIC16F628A *
'* Version : 1.7 *
'* Notes : To output a number corresponding to which button *
'* : was pressed via serial communication *
'************************************************* ***************
'* This Program is part 1 of 2. The other half receives a
'* number and lights a corresponding LED.
'************************************************* ***************
'* REVISIONS:
'* -comparators disabled
'* -read RB0-RB3 to a byte and send this
'* -TRIS registers set
'************************************************* ***************
'*
'* Connections are as follows:
'*
'* N/C -01-|####|-18- N/C
'* N/C -02-|####|-17- SEROUT Line
'* N/C -03-|####|-16- N/C
'* MCLR 10K to V+ -04-|####|-15- N/C
'* Gnd -05-|####|-14- V+
'* Butt1 -06-|####|-13- N/C
'* Butt1 -07-|####|-12- N/C
'* Butt1 -08-|####|-11- N/C
'* Butt1 -09-|####|-10- Green Power LED
'*
'************************************************* ***************

INCLUDE "MODEDEFS.BAS"

'uses internal oscillator (should use crystal but ran out)
@ DEVICE pic16F628A, INTRC_OSC_NOCLKOUT

CMCON = 7 'disable comparators
TRISB = %00001111 'RB0-RB3 Inputs, all others output
TRISA = 0 'set portA as output

GreenLED var PORTB.4 'alias RB4 to GreenLED
Butt1 var PORTB.0 'alias Butt1 to RB0
Butt2 var PORTB.1 'alias Butt2 to RB1
Butt3 var PORTB.2 'alias Butt3 to RB2
Butt4 var PORTB.3 'alias Butt4 to RBZ
ButStat Var Byte 'Variable for button status

Pause 2000 'wait to begin

high greenled 'turn on status light

Loop:
ButStat = PORTA & %00001111 'isolate lower 4 bits of portA & write to ButStat

'If ButStat has value greater than 0, then buttons must have been pushed,
'then send 9 and the value of ButStat
IF Butstat > 0 THEN SEROUT PORTA.0,T1200,[9,Butstat]
GOTO LOOP

end


and



'************************************************* ***************
'* Title : One Wire Serial Control *
'* File : Input17.pbp *
'* Author : Greensasquatch *
'* Date : 10/13/2008 *
'* Chip : PIC16F628A *
'* Version : 1.7 *
'* Notes : To read a number via serial communication and *
'* : light a corresponding LED *
'************************************************* ***************
'* This Program is part 2 of 2. The other half sends a
'* number corresponding to a button state.
'************************************************* ***************
'* REVISIONS:
'* -comparators disabled, turn out lights when no signal
'* -receive a byte and output to portA
'* -set TRIS registers
'************************************************* ***************
'*
'* Connections are as follows:
'*
'* LED3 -01-|####|-18- LED2
'* LED4 -02-|####|-17- LED1
'* N/C -03-|####|-16- N/C
'* MCLR 10K to V+ -04-|####|-15- N/C
'* Gnd -05-|####|-14- V+
'* Serial In -06-|####|-13- N/C
'* Green Power LED -07-|####|-12- N/C
'* N/C -08-|####|-11- N/C
'* N/C -09-|####|-10- N/C
'*
'************************************************* ***************

INCLUDE "MODEDEFS.BAS"

'uses internal oscillator (should use crystal but ran out)
@ DEVICE pic16F628A, INTRC_OSC_NOCLKOUT

CMCON=7 'disable comparators
TRISA = %11110000 'set RA0-RA3 as output, rest as input
TRISB = %00000001 'set RB0 as input, rest as output

GreenLED var PORTB.1 'alias RB1 to GreenLED

NET var byte 'holding variable for input

Pause 2000 'wait to begin
high greenled 'turn on status light

Loop:
'waits for a "9" and writes the next value to NET
'turn off LEDs if no signal after 200ms
SERIN PORTB.0,T1200,200,OffLed,[9],NET
PORTA = NET 'set PORTA to NET value
GOTO LOOP

OffLED:
PORTA=0 'set porta pins low
Goto Loop

end

mackrackit
- 14th November 2008, 06:04
Did you read this one? It was a link from one ot the links.
http://www.picbasic.co.uk/forum/showthread.php?t=7529
Bruce and Steve explain.

greensasquatch
- 20th November 2008, 17:49
I read the links through and through. Picked up on a few tip but haven't been able to get my code working. When I went back to a previous version where it HAD been working it now doesn't work. I'm thinking the internal OSC is just not stable enough for this application. I'll resume work on the project next week when I get new parts.
Thanks to all who have contributed so far.

Leonardo
- 20th November 2008, 18:04
Here is a simple hardware sample to receive and send serially.
It will echo from a terminal program.
If I remember correctly mister E posted this a long time ago.
Works well for testing a setup.


DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 129 ' 2400 Baud @ 20MHz, 0.17%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_EVEN 1
DEFINE HSER_BITS 7

RCIF VAR PIR1.5
SERIALDATA VAR BYTE

PAUSE 100

MAIN:
IF RCIF THEN
HSERIN [SERIALDATA]
HSEROUT [SERIALDATA]
ENDIF
GOTO MAIN

Hello mackrackit,

With this code can test the operation of a port rs232 with a pic?, I can say that pic would be used and the configuration of the pins is very interesting!.

Thank you

mister_e
- 20th November 2008, 18:08
Could be... but @1200 baud, you shouldn't have much problem.

However, could you also try few things
1. Make sure your circuit is properly filtered, no noise on your Vdd line (decoupling caps here and there)
2. Change SERIN/SEROUT for DEBUGIN/DEBUG
3. Try with HSERIN/HSEROUT with the proper DEFINEs.

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 51 ' 1200 Baud @ 4MHz, 0.17%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

mackrackit
- 20th November 2008, 19:43
Hello mackrackit,

With this code can test the operation of a port rs232 with a pic?, I can say that pic would be used and the configuration of the pins is very interesting!.

Thank you
You will need a level converter (max232) between the PIC and PC.
Also the code was to show how to setup for different bits and so forth.
Sorry if it confused things.