PDA

View Full Version : pic16f88 Serial questions (hserin/hserout, etc.)



harralk
- 22nd October 2012, 17:33
I'm trying to send a decimal number (0-999) from an arduino (mega2560, not important) to a pic 16f88 via serial.

I'm new to this, but the pic doesn't seem to be receiving and/or processing the data. I've already looked around the forums for details on this, but I can't find what I'm looking for.

Here's my pic code:


DEFINE OSC 8
OSCCON.4 = 1
OSCCON.5 = 1
OSCCON.6 = 1
ANSEL = 0

DEFINE hser_rcsta 90h 'set receive register to receiver enabled
define hser_txsta 20h 'set transmit register to transmitter enabled
define hser_baud 9600 'set baud rate
portb.0 = 0
portb.1 = 0
portb.3 = 0
portb.4 = 0
portb.6 = 0
portb.7 = 0
porta.0 = 0
porta.1 = 0

motor1 var portb.0 'assign main motor 1 to pin 6
motor2 var portb.1 'assign main motor 2 to pin 7
thr1 var portb.3 'assign thruster motor 1 to pin 9
thr2 var portb.4 'assign thruster motor 2 to pin 10
thr3 var portb.6 'assign thruster motor 3 to pin 12
thr4 var portb.7 'assign thruster motor 4 to pin 13
tempout var porta.0 'assign temperature sensor output to pin 17
voltout var porta.1 'assign control battery (not flight batteries) voltage sense output to pin 18


joy1v var word
joy1h var word
joy2v var word
joy2h var word

serial:
hserin [wait ("A"), dec joy1v]
hserin [wait ("B"), dec joy1h]
hserin [wait ("C"), dec joy2v]
hserin [wait ("D"), dec joy2h]
return

thrusters:
if (joy1v>600) then
high thr1
'Pauseus 500
'Low thr1
'Pauseus 1500
endif
if (joy1v<400) then
low thr1
endif
if (joy1v<400) then
high thr2
'Pauseus 500
'Low thr2
'Pauseus 1500
endif
if (joy1v>600) then
low thr2
endif
gosub serial
end


The serial data being sent to the pic looks like: A123B12C945D3. Am I using HSERIN correctly?

Thanks in advance.

Demon
- 22nd October 2012, 22:23
Have you checked out Mister E's Multicalc "free" utility?

I get these DEFINES for 9600 baud at 8 MHz.


DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 12 ' 9600 Baud @ 8MHz, 0,16%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

There is a slight difference with your defines.

Robert

Mister E's Multi-calc utillity: http://www.picbasic.co.uk/forum/showthread.php?t=4994

harralk
- 23rd October 2012, 23:18
Thanks for the reply. I made the changes, but unfortunately it still doesn't look like it's working.

Does the RX pin (pin 8) need to be shorted to INT (pin 6)? I've seen schematics where the pins are shorted, but nothing in the documentation I've seen says this needs to be the case for what I'm doing.

Archangel
- 23rd October 2012, 23:23
Hello harralk,
put all this code in UPPERCASE letters


DEFINE hser_rcsta 90h 'set receive register to receiver enabled
define hser_txsta 20h 'set transmit register to transmitter enabled
define hser_baud 9600 'set baud rate
make sure your arduino is sending data TRUE not inverted, you CAN invert it with a single transistor, be sure to pull up the Rx input with about 4.7k resistor. I know there PICs in the family which are not so fussy, but don't know which ones they are.


Does the RX pin (pin 8) need to be shorted to INT (pin 6)? I've seen schematics where the pins are shorted, but nothing in the documentation I've seen says this needs to be the case for what I'm doing.
No that's a different interrupt, & on the subject of interrupts, I suggest you get some, try ON_INTERRUPT goto serial then set your intcon register . . . or use Darrel's instant interrupts and let them do all that brain damage for you and get free use of mighty fast assembly interrupts (THANKS DARREL) !.

Archangel
- 24th October 2012, 00:31
I do not have an 16f88 on hand, here is your code with a little bit changed. I do not know what you have for configs as you did not post any



DEFINE OSC 8
OSCCON.4 = 1
OSCCON.5 = 1
OSCCON.6 = 1
ANSEL = 0

DEFINE HSER_RCSTA 90h 'set receive register to receiver enabled
DEFINE HSER_TXSTA 20h 'set transmit register to transmitter enabled
DEFINE HSER_BAUD 9600 'set baud rate
DEFINE HSER_CLROERR 1 ;CLEAR OVERFLOW ERRORS

ON INTERRUPT GOTO serial
INTCON = %1100100
PIE1 = %00100000
PIR1 = %00000000
RCIF VAR PIR1.5


motor1 var portb.0 'assign main motor 1 to pin 6
motor2 var portb.1 'assign main motor 2 to pin 7
thr1 var portb.3 'assign thruster motor 1 to pin 9
thr2 var portb.4 'assign thruster motor 2 to pin 10
thr3 var portb.6 'assign thruster motor 3 to pin 12
thr4 var portb.7 'assign thruster motor 4 to pin 13
tempout var porta.0 'assign temperature sensor output to pin 17
voltout var porta.1 'assign control battery (not flight batteries) voltage sense output to pin 18

joy1v var word
joy1h var word
joy2v var word
joy2h var word
portb.0 = 0
portb.1 = 0
portb.3 = 0
portb.4 = 0
portb.6 = 0
portb.7 = 0
porta.0 = 0
porta.1 = 0

TRISA = %11111100 ;set PA 0 & 1 as outputs
TRISB = %00100100 ;set pb.2 & 5 as inputs


Main: ; Loop to keep your code from running down and dripping all into your other routines
while 1
thrusters:
if (joy1v>600) then
high thr1
'Pauseus 500
'Low thr1
'Pauseus 1500
endif
if (joy1v<400) then
low thr1
endif
if (joy1v<400) then
high thr2
'Pauseus 500
'Low thr2
'Pauseus 1500
endif
if (joy1v>600) then
low thr2
endif

wend


serial:
hserin [wait ("A"), dec joy1v] : RCIF = 0
hserin [wait ("B"), dec joy1h] : RCIF = 0
hserin [wait ("C"), dec joy2v] : RCIF = 0
hserin [wait ("D"), dec joy2h] : RCIF = 0
return


end

I have a concern that this code may hang up in the serial routine waiting for an A or B . . . .

Archangel
- 24th October 2012, 05:14
Here is a program I made to control some things via serial port, tested & working on a microchip demo board using a 16F690.No interrupts no hardware serial port hassels, and of course no hardware serial port advantages either. I want to think I might have looked over some of Bruce's code while making this, it's been a while.
To use this send 3 bytes in hex (esp if using pickit2 to communicate) FF 01 01 turns on relay 1, FF 00 01 turns it off. . . .


@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _CP_OFF
DEFINE OSC 4


DEFINE DEBUG_MODE 0 ' Debug sending True serial data
DEFINE DEBUG_REG_PORTA ' Debug Port = PortA as required by PICKIT2 serial Monitor
DEFINE DEBUG_BIT 0 ' Debug.bit = PortA.0
DEFINE DEBUG_BAUD 9600 ' Default baud rate = 9600
DEFINE DEBUGIN_REG PORTA' Debug Port = PortA as required by PICKIT2 serial Monitor
DEFINE DEBUGIN_BIT 1 ' Debugin bit PortA.1
DEFINE DEBUGIN_BAUD 9600' Default baud rate = 9600
DEFINE DEBUGIN_MODE 0 ' Debugin receiving data true = 0 inverted = 1
relay var byte 'relay number storage variable
state var byte 'relay state of ON/OFF variable

state = 0
relay = 0
PORTC = 0
ANSEL=0
ANSELH=0
ADCON0 = 0
ADCON1 = 0
CCP1CON = %10001100 ;Dual PWM 10xx11xx P1A/RC5 P1B/RC4 RC3/AN7 RC2/AN6
TRISA = %00001110
TRISB = %00000000
TrisC = %00000000

main:
DEBUGIN [WAIT($FF),state,RELAY]
PAUSE 30


ON RELAY GOSUB RELAY0,RELAY1,RELAY2,RELAY3,RELAY4


DEBUG state,RELAY
;TOGGLE PORTC.0




goto main

RELAY0:
IF state = 1 THEN
PORTC.0 = 1
ELSE
PORTC.0 = 0
ENDIF
RETURN

RELAY1:
IF state = 1 THEN
PORTC.1 = 1
ELSE
PORTC.1 = 0
ENDIF
RETURN


RELAY2:
IF state = 1 THEN
PORTC.2 = 1
ELSE
PORTC.2 = 0
ENDIF
RETURN


RELAY3:
IF state = 1 THEN
PORTC.3 = 1
ELSE
PORTC.3 = 0
ENDIF
RETURN

RELAY4: 'controls all ports simultaneously
IF state = 1 THEN
PORTC = 15
ELSE
PORTC = 0
ENDIF
RETURN

end

harralk
- 27th October 2012, 17:54
Thanks for the help, but it still isn't doing anything. I even tried eliminating the joystick input to the arduino and just send a series of 0's and 1's to make an LED blink - nothing.

Just to double-check my methods, when you say add a pull-up resistor you mean add a resistor in series with the incoming serial line (TX from sender)? Or add a pull-up resistor off the +5V? I have tried both methods, by the way, just making sure I leave it the correct way. Also, elsewhere I see that the data into the pic16f88 should be inverted instead of true.....there was something mentioned in the PBP manual, can't remember off-hand exactly where I saw it.

I have the serial monitor open for the arduino and it looks like it's sending the correct data. I have also changed the arduino code to just send a 0 or 1 instead of dec. 0-999. Here's the updated (and highly revised) pic code I'm using.



#CONFIG
__CONFIG _CONFIG1, _INTRC_IO & _PWRTE_ON & _MCLR_OFF & _LVP_OFF
#ENDCONFIG


DEFINE OSC 8
OSCCON.4 = 1
OSCCON.5 = 1
OSCCON.6 = 1
ANSEL = 0

DEFINE HSER_RCSTA 90h 'set receive register to receiver enabled
DEFINE HSER_TXSTA 20h 'set transmit register to transmitter enabled
DEFINE HSER_BAUD 9600 'set baud rate
DEFINE HSER_CLROERR 1 ;CLEAR OVERFLOW ERRORS

ON INTERRUPT GOTO serial
INTCON = %1100100
PIE1 = %00100000
PIR1 = %00000000
RCIF VAR PIR1.5


motor1 var portb.0 'assign main motor 1 to pin 6
motor2 var portb.1 'assign main motor 2 to pin 7
thr1 var portb.3 'assign thruster motor 1 to pin 9
thr2 var portb.4 'assign thruster motor 2 to pin 10
thr3 var portb.6 'assign thruster motor 3 to pin 12
thr4 var portb.7 'assign thruster motor 4 to pin 13
tempout var porta.0 'assign temperature sensor output to pin 17
voltout var porta.1 'assign control battery (not flight batteries) voltage sense output to pin 18

joy1v var word
joy1h var word
joy2v var word
joy2h var word
portb.0 = 0
portb.1 = 0
portb.3 = 0
portb.4 = 0
portb.6 = 0
portb.7 = 0
porta.0 = 0
porta.1 = 0

TRISA = %11111100 ;set PA 0 & 1 as outputs
TRISB = %00100100 ;set pb.2 & 5 as inputs


Main: ; Loop to keep your code from running down and dripping all into your other routines
while 1
thrusters:
if (joy1v>600) then
high thr1
'Pauseus 500
'Low thr1
'Pauseus 1500
endif
if (joy1v<400) then
low thr1
endif
if (joy1v<400) then
high thr2
'Pauseus 500
'Low thr2
'Pauseus 1500
endif
if (joy1v>600) then
low thr2
endif

wend


serial:
hserin [wait ("A"), dec joy1v] : RCIF = 0
hserin [wait ("B"), dec joy1h] : RCIF = 0
hserin [wait ("C"), dec joy2v] : RCIF = 0
hserin [wait ("D"), dec joy2h] : RCIF = 0
return


end


And just yesterday I tried using serin instead of hserin, here's that code:



#CONFIG
__CONFIG _CONFIG1, _INTRC_IO & _PWRTE_ON & _MCLR_OFF & _LVP_OFF
#ENDCONFIG

DEFINE OSC 8
OSCCON.4 = 1
OSCCON.5 = 1
OSCCON.6 = 1

ANSEL = 0
CMCON=7

INCLUDE "modedefs.bas"

'DEFINE HSER_RCSTA 90h 'set receive register to receiver enabled
'EFINE HSER_TXSTA 20h 'set transmit register to transmitter enabled
'DEFINE HSER_BAUD 9600 'set baud rate
'DEFINE HSER_CLROERR 1 'clear overflow errors

ON INTERRUPT GOTO serial

'INTCON = %1100100
'PIE1 = %00100000
'PIR1 = %00000000
'RCIF VAR PIR1.5


'motor1 = portb.0 'assign main motor 1 to pin 6
'motor2 = portb.1 'assign main motor 2 to pin 7
'thr1 = portb.3 'assign thruster motor 1 to pin 9
'thr2 = portb.4 'assign thruster motor 2 to pin 10
'thr3 var portb.6 'assign thruster motor 3 to pin 12
'thr4 var portb.7 'assign thruster motor 4 to pin 13
'tempout var porta.0 'assign temperature sensor output to pin 17
'voltout var porta.1 'assign thruster battery (not main batteries)
'voltage sense output to pin 18

joy1v var word
joy1h var word
joy2v var word
joy2h var word
mode con 2

thr1vin var portb.2
thr1hin var portb.1

thr1vout var portb.6


'portb.0 = 0
'portb.1 = 0
'portb.3 = 0
'portb.4 = 0
'portb.6 = 0
'portb.7 = 0
'porta.0 = 0
'porta.1 = 0

TRISA = %11111100 'set RA 0 & 1 as outputs
TRISB = %00100100 'set RB 2 & 5 as inputs


Main: 'Loop to keep your code from running down and dripping all into your other routines
while 1
thrusters:
if (joy1v==1) then
high portb.3
Pause 250
Low portb.3
Pause 250
endif

if (joy1v==0) then
low portb.3
endif

if (joy1h==1) then
high portb.4
Pauseus 250
Low portb.4
Pauseus 250
endif

if (joy1h==0) then
low portb.4
endif

wend

serial:
serin thr1vin, 2, ["A"], joy1v
serout thr1vout, 2, joy1v
return

end


Could it possibly be that the pic is expecting to see a certain number of bits, and I'm not send them (I'm not using parity or stop bits, I don't think).

I apologize for my absolute noobieness when it comes to serial, but I've been struggling with this for a couple weeks now and I just have no idea what it could be.

Thanks again.

Archangel
- 28th October 2012, 00:29
Check this thread:http://www.picbasic.co.uk/forum/content.php?r=171-LCD-serial-backpacks

PBP does not natively import strings like C does and arduino uses C more or less. In the backpack code hserin is used to load an array and then the array is outputted to an LCD. It is set up to use DTs interrupts and works well.
edit:
as I UNDERSTAND ARDUINO: the serial data sent out is inverted, and I don't see a way in code to make it send true. You could use an NPN transistor to invert it back to true, or use debug as I did in my program for switching relays. Or us a another PIC instead of the Arduino. Or use a pic(if one exists) which allows inverted on the usart ( I vaguely remember getting beaten up over this once ;P)