PDA

View Full Version : RS232 serial commands



pxidr84
- 22nd August 2011, 11:16
Hi everyone,

It's maybe a dumbass question, but how to convert these incorrect commands:


IF HSERIN ["start"]=1 then
HIGH PORTD.4
ENDIF

into a correct syntax?

It's a very simple program, when I send the word "start" from HyperTerminal, I would turn on a LED connected on the PORTD.4.

Notice that my communications between my PC and the PIC works already in both ways (receive/transmit).
Thanks for your help.

Charles Linquis
- 22nd August 2011, 13:47
It depends a lot on whether or not your program is going to wait around for
the input, or if it needs to do something else while waiting. Or whether or not your input will come from a keyboard (time between characters) or all at once.

One way would be to -





LookForStart:


FoundStart = 0


HSERIN 1000,NoData,[WAIT ("start")] : FoundStart=1


Return





NoData:


Return


FoundStart will = 1 if the "start" was received after waiting for 1 second.

pxidr84
- 22nd August 2011, 14:40
It depends a lot on whether or not your program is going to wait around for
the input, or if it needs to do something else while waiting. Or whether or not your input will come from a keyboard (time between characters) or all at once.

One way would be to -


LookForStart:


FoundStart = 0


HSERIN 1000,NoData,[WAIT ("start")] : FoundStart=1


Return





NoData:


Return


FoundStart will = 1 if the "start" was received after waiting for 1 second.

I use this :


DEFINE OSC 40
DEFINE LCD_DREG PORTD
DEFINE LCD_EREG PORTB
DEFINE LCD_RSREG PORTB
DEFINE LCD_EBIT 6
DEFINE LCD_RSBIT 7
DEFINE ADC_BITS 10
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 9600
DEFINE HSER_SPBRG 64


char var WORD
foundstart var bit


pause 1000
HIGH PORTE.2
LCDOUT $fe,1
Hserout ["Program has started."]
pause 1000


LookForStart:

FoundStart = 0

HSERIN 5000,noData,[WAIT ("start")] : FoundStart=1

Return


nodata:

if FoundStart=1 then
HIGH PORTD.4
Lcdout $fe,2,"Backlight ON."
ENDIF

Return

And it doesn't work, every 5 seconds I receive "Program has started".
Now I'm using Terminal v1.9b by Bray, it's far better because I can send a word at once. So no time between characters.

And yeah, my program have a lot things to do (interrupts, etc.) during this time. Here I'm using a very simple program to get started.

mister_e
- 22nd August 2011, 15:34
try something like that

DEFINE OSC 40
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 9600
DEFINE HSER_SPBRG 64

Start:
Hserout ["Program has started.",13,10]
gosub LookForStart
Goto Start

LookForStart:
HSERIN 5000,noData,[WAIT ("start")]
hserout ["Got it! Backlight ON",13,10]
Return

nodata:
HSEROUT ["NOPE... Life's so cruel...",13,10]
Return

pxidr84
- 22nd August 2011, 20:07
try something like that

DEFINE OSC 40
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 9600
DEFINE HSER_SPBRG 64

Start:
Hserout ["Program has started.",13,10]
gosub LookForStart
Goto Start

LookForStart:
HSERIN 5000,noData,[WAIT ("start")]
hserout ["Got it! Backlight ON",13,10]
Return

nodata:
HSEROUT ["NOPE... Life's so cruel...",13,10]
Return

Thanks!

HSERIN command remind me the BUTTON command (with the label).

So I use this :


DEFINE OSC 40
DEFINE LCD_DREG PORTD
DEFINE LCD_EREG PORTB
DEFINE LCD_RSREG PORTB
DEFINE LCD_EBIT 6
DEFINE LCD_RSBIT 7
DEFINE ADC_BITS 10
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 9600
DEFINE HSER_SPBRG 64

Hserout ["Varidrive V2011.00 has started"]

mainlp:

LCDOUT $fe,2,"Main loop"

HSERIN ret,[WAIT ("blon")]
HIGH PORTD.4
ret:

HSERIN ret1,[WAIT ("bloff")]
LOW PORTD.4
ret1:

Goto mainlp

And it works flawlessly.

However, when I type "blonn" instead of "blon", the backlight is activated.
Same thing with "blofffff" instead off "bloff", the backlight is disabled.

So I need a stop bit or something like that?

mister_e
- 22nd August 2011, 20:27
OK, so you need to check a couple of different Strings possibilities and act upon right?

Is this really need to be string? Did you built the "Transmitting unit" or it's just for learning purpose?

Most common and easiest way to implement such thing is to wait for a specific header and then use the next Byte for specific command.
ex:
Transmitter send: "NextCommandIs", 10
Receiver Wait for "NextCommandIs" and store 10 in a byte variable. Depending the value of that Byte Variable, it process various task.

So Easy as
Transmitter Side:
HSEROUT ["NextCommandIs", 10]

Receiver Side:
HSERIN [WAIT ("NextCommandIs"), ByteA]
SELECT CASE ByteA
'
'
'
'

Should you really need to wait for a specific String, then you'll need to build a string with each single character you receive parse them. Not hard, just a tad longer to implement.

mister_e
- 22nd August 2011, 20:31
Also, depending of how you send the whole thing, you may also check for a "end" character. If the string is right but the next character/byte is false, you discard the result.

All the time, you want to implement a structured "serial data message" on both side.

mister_e
- 22nd August 2011, 21:38
Here's some inspiration, not 100% efficient but easy to follow.


DEFINE OSC 40
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 9600
DEFINE HSER_SPBRG 64
WaitFor var byte [4]
CounterA VAR BYTE
clear
Hserout ["Varidrive V2011.00 has started",13,10]

main:
GOSUB ClearArray
HSEROUT ["Main loop",13,10]
HSERIN 5000, main,[WAIT ("blo")]
HSERIN 500, testit, [str waitFor\3]
testit:
SELECT CASE WaitFor[0]
CASE "n"
if WaitFor[1]=0 then
HIGH PORTD.4
HSEROUT ["ON",13,10]
else
GOSUB FAIL
endif

CASE "f"
if WaitFor[1]="f" then
if WaitFor[2]=0 then
LOW PORTD.4
HSEROUT ["OFF",13,10]
else
GOSUB FAIL
ENDIF
endif
CASE ELSE
GOSUB FAIL
END SELECT
goto main

ClearArray:
FOR CounterA = 0 TO 3
WaitFor[CounterA]=0
next
RETURN

FAIL:
HSEROUT ["FAIL!",13,10]
RETURN

mister_e
- 22nd August 2011, 22:20
Another Variant...


DEFINE OSC 40
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 9600
DEFINE HSER_SPBRG 64

WaitFor var byte [6]
CounterA VAR BYTE
clear
PORTD = 0
TRISD = 0
Hserout ["Varidrive V2011.00 has started",13,10]

main:
GOSUB ClearArray
HSEROUT ["Main loop",13,10]
HSERIN 1000,Test_bloff,[str waitFor\6]

Test_bloff:
ARRAYREAD WaitFor,6, Test_blon,[WAIT ("bloff",0)]
LOW PORTD.4
HSEROUT ["OFF",13,10]
goto main

Test_blon:
ARRAYREAD WaitFor,6, FAIL,[WAIT ("blon",0)]
HIGH PORTD.4
HSEROUT ["ON",13,10]
goto main

FAIL:
HSEROUT ["FAIL!",13,10]
GOTO main

ClearArray:
FOR CounterA = 0 TO 5
WaitFor[CounterA]=0
next
RETURN

now tell me it's not hard :)

Charles Linquis
- 23rd August 2011, 00:12
Wow! Next time I need some code written, I'll just state what I want to do, and let you guys write it.http://www.picbasic.co.uk/forum/images/editor/smilie.png

mister_e
- 23rd August 2011, 01:24
:D good karma... that is :D

pxidr84
- 24th August 2011, 09:53
Another Variant...


DEFINE OSC 40
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 9600
DEFINE HSER_SPBRG 64

WaitFor var byte [6]
CounterA VAR BYTE
clear
PORTD = 0
TRISD = 0
Hserout ["Varidrive V2011.00 has started",13,10]

main:
GOSUB ClearArray
HSEROUT ["Main loop",13,10]
HSERIN 1000,Test_bloff,[str waitFor\6]

Test_bloff:
ARRAYREAD WaitFor,6, Test_blon,[WAIT ("bloff",0)]
LOW PORTD.4
HSEROUT ["OFF",13,10]
goto main

Test_blon:
ARRAYREAD WaitFor,6, FAIL,[WAIT ("blon",0)]
HIGH PORTD.4
HSEROUT ["ON",13,10]
goto main

FAIL:
HSEROUT ["FAIL!",13,10]
GOTO main

ClearArray:
FOR CounterA = 0 TO 5
WaitFor[CounterA]=0
next
RETURN

now tell me it's not hard :)

Thanks a lot, your code is perfectly understandable.

mister_e
- 24th August 2011, 18:34
... And have a deliberate small mistake in before receiving the bomb-proof approval... but this... i'll let you the pleasure find it ;)

Enjoy!

Charles Linquis
- 25th August 2011, 01:04
Steve.... I put lots of "deliberate" mistakes in my code as well.

mister_e
- 25th August 2011, 01:13
Good grief, nice to know some of them are in Orbit :D

Charles Linquis
- 25th August 2011, 02:59
Or at least they are supposed to be....