PDA

View Full Version : How to Serial comm. wait for a string?



elcrcp
- 24th December 2015, 12:18
Hello guys,
I wan't to try something but can't figure out how to do it...
I want to connect a PIC to a raspbery over UART and want to send commands to PIC via serial using minicom. But I dont know how to identfy a string coming from serial.
Lets say; after starting program PIC will ask for an input;

HSEROUT ["Please Type An Input"]

I'll use RX interrupt and and when an input comes I'll try to identify that input, something like that;

HSERIN [input_var]

IF input_var == "ONE" then Label1 'I know there is no such statement but I want to do something like this
IF input_var == "TWO" then Label2

HSEROUT ["You typed",input_var,"now choose whatever"]

can you guys give me some hints how to do somethings like this? I remember seeing an AT&T protocol connection with pic somewhere on net so I'm sure its possible but just can't figure how =(

Heckler
- 24th December 2015, 14:55
Here is some code that allows a pic to recieve data from a GPS module.
It will wait for 3000 msec's and then if it does not recieve anything it will jump down to the "tmout" subroutine.

It parses the received serial data and places various parts of it into separate variables.

then it tests one of the values "fix" and jumps to a different subroutine based on its value.


SerIn2 PORTA.0,188,3000,tmout,[wait("$GPRMC,"),DEC2 hh,DEC2 mm,dec2 ss,_
wait(","),fix,wait(","),DEC2 latdeg,DEC2 latmin,wait("."),dec4 latminn,_
wait(","),NS,wait(","),DEC3 londeg,DEC2 lonmin,wait("."),dec4 lonminn,_
wait(","),EW,wait(","),dec knots,dec knotsten,dec course,_
wait(","),DEC2 dy,DEC2 mt,DEC2 yr]


if fix="V" then goto nofix


nofix:
lcdout $fe,1,"waiting for fix"
pause 1000
goto main
tmout:
LCDOUT $fe,1,"timeout"
PAUSE 1000
GOTO MAIN

might be something here you can use.

note: I do not believe you need to (nor can you) use the == way of assigning or testing equality. You may need to refer to the PBP manual.

good luck

Scampy
- 24th December 2015, 15:21
I use serial comms between a PC and PIC, but not sure if this is what you are after

This is in the main program loop, which looks to see if there is a character in the buffer from the PC



FOR TempWD = 0 TO 800
IF RCIF=1 THEN GOSUB coms ; Check to see id PC application connected
PAUSE 1
NEXT TempWD


I then have this routine which will either send a string to the PC application / terminal program, or reads in the string from the PC



coms:

HSERIN [nTest]
SELECT CASE nTest
CASE "Q" ; if Q then send data to PC
Goto Term_TX
CASE "S" ; if S then receive data from PC
goto Term_RX
return


Rx and Tx are simple HSERIN and HSEROUT commands with the variables that make up the string of data that is received or sent.

Hope that helps

elcrcp
- 25th December 2015, 08:03
Thanks for advices, I think I can go with Heckler's example. I'll give it a try .

correct me if I get it wrong, it waits for "$GPRMC," string, and then writes first byte to hh second to mm third to ss and then again waits for "," but there are dec4 and dec3 variables too, like latminn and longdeg, they can exceed 1 byte. So how 4 digits decimal value writed to latminn?

[QUOTE=Heckler;135804]


SerIn2 PORTA.0,188,3000,tmout,[wait("$GPRMC,"),DEC2 hh,DEC2 mm,dec2 ss,_
wait(","),fix,wait(","),DEC2 latdeg,DEC2 latmin,wait("."),dec4 latminn,_
wait(","),NS,wait(","),DEC3 londeg,DEC2 lonmin,wait("."),dec4 lonminn,_
wait(","),EW,wait(","),dec knots,dec knotsten,dec course,_
wait(","),DEC2 dy,DEC2 mt,DEC2 yr]


if fix="V" then goto nofix

amgen
- 25th December 2015, 17:16
for discussion purposes,I have been working on a general send/receive scheme to use for pic's. It is more like a module or object type of situation since you would always set up various registers, arrays and variables to accomplish the task. It uses interrupts so the main program can keep working while at the same time processing TX and RX's.
One of the first requirements I came up with was there needs to be a "start" and "end" character that will trigger the routines to either -reset counters/registers or tell the main program to process the captured serial.
Also I'm not sure how the hardware serial basic commands hold up program flow....
more if any thoughts.
Don

Heckler
- 25th December 2015, 19:41
Hi elcrcp,

If you look in the PBP manual under "serin2" you will find the "input modifiers" table...

DEC{1...10} allows you to specify how many decimal digits to receive into the next variable.
So DEC2 latdeg,DEC2 latmin,wait(".")
will receive the next 2 decimal digits into the variable "latdeg" and then the following 2 decimal digits into "latmin"

There is also a "SKIP n" parameter to ignore the next "n" digits, etc. etc.


GPRMC VAR BYTE[64]

hh VAR BYTE 'hours
mm VAR BYTE 'minutes
ss VAR BYTE 'seconds
sss var word 'milliseconds
fix VAR WORD 'GPS fix
latdeg VAR BYTE 'degrees latitude
latmin VAR BYTE 'minutes latitude
latminn var word 'fractional minutes latitude
NS VAR BYTE 'north or south
londeg VAR BYTE 'degrees longitude
lonmin VAR BYTE 'minutes longitude
lonminn var word 'fractional minutes longitude
EW VAR BYTE 'east or west
Knots VAR byte 'speed in knots (units)
Knotss var byte 'speed in fractional knots
course var word 'heading
dy VAR BYTE 'day
mt VAR BYTE 'month
yr VAR BYTE 'year

above is how I defined my varialbes...

so if the latdeg value is between 0-255 it will fit within the "byte" sized variable even if it is 1,2 or 3 digits (ie 99, 127, 08, etc)

PS. I may not have correctly sized all the varibles (bit, byte or word) so use your own judgment there... I wrote that code a couple of years ago.

Since "course" could be anything between 0-359 degrees it would need to be bigger than a byte as a byte can only hold up to 255

hope that helps

Art
- 28th December 2015, 03:29
Because you are typing, there will always be an enter character to terminate the string,
so you only need to fill a buffer, and check each byte for the enter character,
then you have all the time in the world for the program to look at the string
rather than trying to figure out what is going on in-between each byte being sent.

Same with GPS, I prefer to fill a buffer with the entire command, and count two bytes after the * char is received,
then look into the content after the entire sentence is received.

flotulopex
- 28th December 2015, 11:08
Hi,

This is the way time can be read "on the fly" from a serial GPS receiver module like this one
8138

GPGGA_Time:
SERIN2 GPSfrom,GPSbps,[WAIT("$GPGGA,"),STR GPS_D\6]
LCDOUT $FE,2,GPS_D(0),GPS_D(1),":",GPS_D(2),GPS_D(3),":",GPS_D(4),GPS_D(5)
GOTO MAIN:The PIC is waiting for the string $GPGGA, from the GPS module to arrive, then it fills an array with the 6 next incoming characters and displays them.

Art
- 29th December 2015, 10:25
Oh my, you’ll have a bunch of unneeded checking when the sentence could have been discarded for no fix or bad checksum.
Some GPS modules also put out a bad but valid time from their battery clocks until a position fix is acquired.
Not good if you were logging for a security system or something like that.

The thread isn’t necessarily about GPS, but it’s more or less the same thing.
You might has well make use of the UART if it’s present.

set a character counter to zero


charbuffer var byte[60]
character var byte
charcount var byte
charcount = 0


receive the serial with hserin with the smallest possible timeout so it will only give you a character if one is present in the buffer



‘pseudocode

hserin [character,lowesttimeout,timeoutlabel]
charbuffer[charcount] = character
charcount = charcount + 1

if character = enter or linefeed, etc. then
gosub investigate’ investigate the complete sentence and reset charcount
endif

timeoutlabel: