PDA

View Full Version : Hserin parsing string...again?



kevlar129bp
- 29th October 2009, 01:18
Hello all,

This has probably been answered in a million different threads...all of which I have read, which leads me to my question.
What I'de like to do is receive a string into the usart similar to this:

ABC123

What I would like to do is store the ABC in a word var to send through a
select case statement and...
store the 123 in a byte var to use later in code.

The commands coming into the usart will always be this format, for ex:

ABC123
XYZ255
PQR002

LETTER-LETTER-LETTER-NUMBER-NUMBER-NUMBER

NUMBER-NUMBER-NUMBER not to exceed 256.

Any help parsing these from the RCREG or a 6 byte ring buffer?

Thanks to all,
Chris

kevlar129bp
- 29th October 2009, 02:12
Am I on the right track?


Ser_Cmd_Word var word
Ser_Cmd_Val var byte

Start:
...
If PIR1.5 = 1 Then Goto New_SerIn
...
GOTO Start

New_SerIn:
PIE1 = %00000000 'Disable interrupts
hserin [dec3 Ser_Cmd_Word, dec3 Ser_Cmd_Val]
LCDout $fe, 1, "COMMAND RECEIVED"
Lcdout $fe, $c0, "-----", Ser_Cmd_Word, Ser_Cmd_Val, "-----"
pause 3000 'Pause for 3 seconds for user viewing
PIE1 = %01110000 'Enable interrupts
Return

Thanks much

Darrel Taylor
- 29th October 2009, 03:14
3 letters won't fit in a word variable very easily.
Although it can be done, with limitations.

The second part ...
dec3 Ser_Cmd_Val
should work fine.

Is there a limit to the 3 letter sequences, or could it be anything?

Do you have PBP 2.60?
<br>

kevlar129bp
- 29th October 2009, 03:36
If I understand your question correctly...yes, 3 characters- no more - no less. I did discover the 16 bit word size after my post...newbie move, i admit :). How about me changing the command to:

LETTER LETTER NUMBER NUMBER NUMBER

Easier coding that way? The ultimate goal is to run the LETTER LETTER through
a select case statement like:

Chk_Cmd:
select case Ser_Cmd_word
case TT 'Torch Target
TTV_val = Ser_Cmd_Val
Case XX 'Another Command
'SomeByteVar = Ser_Cmd_Val
Case else
LCDout $fe, 1, " COMMAND NOT IN "
Lcdout $fe, $c0, " DEFINED SCOPE! "
END SELECT
RETURN

Am I on the right track?
Thanks again.

Darrel Taylor
- 29th October 2009, 17:39
Well, I was referring to how many 3-letter combinations, and if you have PBP 2.60 it could be done differently.
However, let's go with what you have ...

First, I'd recommend starting the command sequence with a known character, like "$". This can keep the data "synced" by making it easy to find the beginning of each "packet". Then use the WAIT("$") modifier in HSERIN.

If you only have a few different commands, they can be reduced to 1 letter, which makes it work well with the Select Case statement. Then the packets might look like ...

$T123
$P255

Also, don't enable interrupts.
HSERIN does not use interrupts. And enabling them without handler routines being defined will cause the program to lock up.

If you want to keep the 2-letter commands, that can be done too, but it's a little trickier.
<br>

kevlar129bp
- 30th October 2009, 01:25
Will this fly...nearest you can tell?


'PIC 16F917

'------------------------------------------------------------------------------------------

'Clock setup
Define OSC 20
'Interrupt setups
INTCON = %11000000 'Enable: Global interrupts, Peripheral interrupts
PIE1 = %01110000 'Enable: ADC interrupt, Rx interrupt, Tx interrupt
'Pin setups
ANSEL = %10000000 'Analog input on E.2/AN7, all others digital
TRISA = %11000000 'PortA: 0-5 = output, 6-7 = input
TRISB = %11111111 'PortB: 0-7 = input (defaults)
TRISC = %11011111 'PortC: 0-5&7 = input, 6 = output
TRISD = %11111111 'PortD: 0-7 = input (defaults)
TRISE = %00000100 'PortE: 0&1 = output, 2 = input, 3-7 = N/A
'Vref setups
VRCON = %10001111 'Enable Vref, set high range, set value (3.59 Vdc)
'Usart setups
SPBRG = %00011001 'Set 9600 baud w/20MHz clock
TXSTA = %00100110 'Enable transmit, set BRGH high
RCSTA = %10010000 'Enable Usart, enable receiver
'ADC setups
ADCON0 = %10011101 'Right justify (8 bit result in ADRESL), Select ch.7, enable ADC
ADCON1 = %00100000 'Set ADC clock to 625kHz

'------------------------------------------------------------------------------------------

'LCD setup (16 x 2 lines)
Define LCD_BITS 4 '4 data interface lines
Define LCD_DREG PORTA 'LCD data port
Define LCD_DBIT 0 'LCD data bits 0-4
Define LCD_RSREG PORTA 'LCD register select port
Define LCD_RSBIT 4 'LCD register select bit
Define LCD_EREG PORTA 'LCD enable port
Define LCD_EBIT 5 'LCD enable bit

'------------------------------------------------------------------------------------------
Ser_Cmd_Numb var byte
Ser_Cmd_Val var byte
THC_Enable_In var PORTC.0
TTV_Val var byte
HYS_Val var byte
Torch_V_Now var byte
Torch_Up var PORTE.0
Torch_Dn var PORTE.1
TTV_Val = 120
HYS_Val = 0

pause 1000 'Pause for 1 second for LCD warmup
LCDout $fe, 1, "---LCD WARMUP---"
Lcdout $fe, $40, "----FINISHED----"
pause 5000 'Pause for 5 seconds for user viewing

Start:
IF THC_Enable_In = 0 then
PIE1.6 = 0 'Turn off ADC interrupt
PIE1.5 = 1 'Turn on Rx interrupt
LCDout $fe, 1, "READY TO RECEIVE"
Lcdout $fe, $40, "COMMAND:C###V###"
If PIR1.5 = 1 Then Goto New_SerIn
PAUSE 500
GOTO START
ELSE
PIE1.6 = 1 'Turn on ADC interrupt
PIE1.5 = 0 'Turn off Rx interrupt
ADCON0.1 = 1 'Start ADC conversion
if PIR1.6 = 1 THEN GOTO New_ADC
LCDout $fe, 1, "TARGET VDC : ", dec TTV_Val
Lcdout $fe, $40, "PLASMA VDC : ", dec Torch_V_Now
select case Torch_V_Now
case Torch_V_Now > TTV_Val + hys_val
high torch_dn
low torch_up
case Torch_V_Now < TTV_Val - hys_val
high torch_up
low torch_dn
case else
low torch_up
low torch_dn
end select
endif
GOTO Start

New_ADC:
Torch_V_Now = ADRESL
PIR1.6 = 0
Return

New_SerIn:
'******Command structure is: C###V###
PIE1 = %00000000 'Disable interrupts
hserin 100, start, [wait ("C"),dec3 Ser_Cmd_numb]
hserin 100, start, [wait ("V"),dec3 Ser_Cmd_val]
LCDout $fe, 1, "COMMAND RECEIVED"
Lcdout $fe, $40, "-- C", dec Ser_Cmd_numb," V", dec Ser_Cmd_val, " --"
pause 3000 'Pause for 3 seconds for user viewing
GOTO Chk_Cmd
PIE1 = %01110000 'Enable interrupts
Return

Chk_Cmd:
select case Ser_Cmd_numb '001 to 256
case 1 'Torch Target Voltage
TTV_val = Ser_Cmd_Val
case 2 'Hysteresis Value
HYS_Val = Ser_Cmd_Val
Case else
LCDout $fe, 1, " COMMAND NOT IN "
Lcdout $fe, $40, " DEFINED SCOPE! "
END SELECT
RETURN

Cut and shuffle as you will :). Thanks guys.

Chris

kevlar129bp
- 31st October 2009, 21:29
Hello all,

Weird, I'm responding to my own thread :confused:. Well, I cut and shuffled my previous code for the better...I hope! Here it is, for the critique...


'PIC 16F76

'----------------------------------------------------------------------------

'Clock setup
Define OSC 20
'Interrupt setups
INTCON = %11000000 'Enable: Global interrupts, Peripheral interrupts
PIE1 = %01000000 'Enable: ADC interrupt
'ADC setups
ADCON0 = %10000001 'ADC CLOCK = 625kHz, Select ch.0, enable ADC
'Pin setups
TRISA = %00000001 'PortA: 1-5 = output, 0 = input, 6-7 = N/A
TRISB = %11111111 'PortB: 0-7 = input (defaults)
TRISC = %11111111 'PortC: 0-7 = input (defaults)
'Usart setups
SPBRG = %00011001 'Set 9600 baud w/20MHz clock
TXSTA = %00100110 'Enable transmit, set BRGH high
RCSTA = %10010000 'Enable Usart, enable receiver


'----------------------------------------------------------------------------

'LCD setup (16 x 4 lines)
DEFINE LCD_LINES 4
Define LCD_BITS 4 '4 data interface lines
Define LCD_DREG PORTB 'LCD data port
Define LCD_DBIT 4 'LCD data bits 0-4
Define LCD_RSREG PORTB 'LCD register select port
Define LCD_RSBIT 3 'LCD register select bit
Define LCD_EREG PORTB 'LCD enable port
Define LCD_EBIT 0 'LCD enable bit

'----------------------------------------------------------------------------
Setup_YN var byte
Torch_Lock_Val var byte
CNT VAR BYTE
CNT2 VAR BYTE
Hyst_Val var byte
First_Run var bit
Enable_In var PORTC.0
Torch_V_Now var byte
Torch_Up var PORTE.0
Torch_Dn var PORTE.1
Torch_Lock_Val = 120
Hyst_Val = 0
first_run = 1

low enable_in

pause 1000
LCDout $fe, 1
LCDout $fe, $03, "WELCOME TO THE"
Lcdout $fe, $42, "DOUBLE DOWN IND."
Lcdout $fe, $14, "TORCH HEIGHT CONTROL"
Lcdout $fe, $54, "LCD WARMING UP"
FOR CNT2 = 1 TO 5
FOR CNT = 0 TO 4
Lcdout $fe, $63 + CNT, "."
PAUSE 400
Lcdout $fe, $63 + CNT, $20
NEXT CNT
NEXT CNT2

Start:
IF Enable_In = 0 then
PIE1.6 = 0 'Turn off ADC interrupt
'***** START MSG1 *****
LCDout $fe, 1
LCDout $fe, $03, "CONTROL IS IN"
Lcdout $fe, $43, "STANDBY MODE."
LCDout $fe, $15, "WOULD YOU LIKE TO"
Lcdout $fe, $55, "RUN SETUP? (Y/N)"
Lcdout $fe, $66
LCDOUT $fe, $0F
'***** END MSG1 *****
HSERIN [Setup_YN]
if setup_yn != "Y" then goto start
Bad_Torch_Lock_Val:
'***** START MSG2 *****
LCDout $fe, 1
LCDout $fe, $01, "ENTER A ", $22, "LOCK TO", $22
Lcdout $fe, $40, "TORCH VOLTAGE VALUE:"
LCDout $fe, $17, $22, "X", $22, " TO EXIT OR"
Lcdout $fe, $56, "(000 - 256) ___"
Lcdout $fe, $63
LCDOUT $fe, $0F
'***** END MSG2 *****
HSERIN [DEC Torch_Lock_Val]
if (Torch_Lock_Val >= 0) and (Torch_Lock_Val <= 256) then goto Bad_Hyst_Val
if Torch_Lock_Val = "X" then goto start
'***** START ERR_MSG1 *****
LCDout $fe, 1
LCDout $fe, $02, "ONLY (000 - 256)"
Lcdout $fe, $40, "ALLOWED!"
LCDout $fe, $17, "PLEASE STANDBY"
FOR CNT = 0 TO 19
Lcdout $fe, $54 + CNT, "."
PAUSE 150
NEXT CNT
'***** END ERR_MSG1 *****
GOTO Bad_Torch_Lock_Val
Bad_Hyst_Val:
'***** START MSG3 *****
LCDout $fe, 1
LCDout $fe, $01, "ENTER A HYSTERESIS"
Lcdout $fe, $42, "+/- VOLTAGE VALUE:"
LCDout $fe, $17, $22, "X", $22, " TO EXIT OR"
Lcdout $fe, $58, "(0 - 5) _"
Lcdout $fe, $63
LCDOUT $fe, $0F
'***** END MSG3 *****
HSERIN [DEC hyst_Val]
if (hyst_Val >= 0) and (hyst_Val < 6) then
'***** START MSG4 *****
LCDout $fe, 1
LCDout $fe, $03, "SETUP COMPLETE"
Lcdout $fe, $40, "TORCH LOCK VALUE=", Torch_Lock_Val
LCDout $fe, $15, "HYSTERESIS VALUE=", hyst_Val
FOR CNT = 0 TO 19
Lcdout $fe, $54 + CNT, "."
PAUSE 300
NEXT CNT
'***** END MSG4 *****
goto start
endif
if hyst_Val = "X" then goto start
'***** START ERR_MSG2 *****
LCDout $fe, 1
LCDout $fe, $04, "ONLY (0 - 5)"
Lcdout $fe, $46, "ALLOWED!"
LCDout $fe, $17, "PLEASE STANDBY"
FOR CNT = 0 TO 19
Lcdout $fe, $54 + CNT, "."
PAUSE 150
NEXT CNT
'***** END ERR_MSG2 *****
GOTO Bad_Hyst_Val
first_run = 1
ELSE
PIE1.6 = 1 'Turn on ADC interrupt
ADCON0.2 = 1 'Start ADC conversion
if PIR1.6 = 1 THEN GOTO New_ADC 'New ADC interrupt flag
if first_run = 1 then
LCDout $fe, 1
Lcdout $fe, $01, "PLASMA VOLTAGE=", Torch_V_Now
Lcdout $fe, $40, "--------------------"
Lcdout $fe, $14, "TORCH LOCK VALUE=", Torch_Lock_Val
LCDout $fe, $55, "HYSTERESIS VALUE=", hyst_Val
FIRST_RUN = 0
ELSE
Lcdout $fe, $10, Torch_V_Now
ENDIF
select case Torch_V_Now
case Torch_V_Now > Torch_Lock_Val + hysT_val
high torch_dn
low torch_up
case Torch_V_Now < Torch_Lock_Val - hysT_val
high torch_up
low torch_dn
case else
low torch_up
low torch_dn
end select
endif
GOTO Start

New_ADC:
Torch_V_Now = ADRES 'Read ADC value into VAR
PIR1.6 = 0 'Clear ADC interrupt flag
Return

Does that seem to eliminate the string parsing gig altogether? I think I'm so stuck in the thinking of no LCD... First time I've messed with 'em. I think it just saved me a load of brain fry... I dunno?

Comments greatly appreciated!
Thanks all,
Chris

kevlar129bp
- 13th November 2009, 17:40
Can one of you fine folks look this revised code over to see if you think it'll do the trick. I heavily commented it for sake of keeping my head straight :confused: Anyhow, any thought are helpful thoughts at this point.
Thanks all,
Chris

'PIC 16F917

'----------------------------------------------------------------------------

'Clock setup
Define OSC 20
'Interrupt setups
INTCON = %11000000 'Enable: Global interrupts, Peripheral interrupts
PIE1 = %01100000 'Enable: ADC interrupt, Receive interrupt
'ADC setups
ADCON0 = %10100001 'Rt justified, VRef + pin, Select ch.0, enable ADC
ADCON1 = %00100000 'Fosc / 32
'Pin setups
ANSEL = %00000001 'Port A.0 = analog input
TRISA = %11101001 'PortA: 1,2,4 = output, 0,3,5,6,7 = input
TRISB = %11000000 'PortB: 0-5 = LCD output, 6,7 = ICSP input
TRISC = %11111111 'PortC: 0-7 = input (defaults)
TRISD = %11111111 'PortD: 0-7 = input (defaults)
TRISE = %11111111 'PortE: 0-2 = input (defaults), 3-7 = N/A
'Usart setups
SPBRG = %00011001 'Set 9600 baud w/20MHz clock
TXSTA = %00100110 'Enable transmit, set BRGH high
RCSTA = %10010000 'Enable Usart, enable receiver

'----------------------------------------------------------------------------

'LCD setup (16 x 4 lines)
DEFINE LCD_LINES 4
Define LCD_BITS 4 '4 data interface lines
Define LCD_DREG PORTD 'LCD data port
Define LCD_DBIT 4 'LCD data bits, pic starting pin 0 or 4
Define LCD_RSREG PORTD 'LCD register select port
Define LCD_RSBIT 2 'LCD register select bit
Define LCD_EREG PORTD 'LCD enable port
Define LCD_EBIT 3 'LCD enable bit

'----------------------------------------------------------------------------

'Variable setups
RxFlag VAR PIR1.5
RxInt var PIE1.5
ADCFlag var PIR1.6
ADCInt var PIE1.6
ADCGo var ADCON0.2
SerInStr var byte(25)
X VAR BYTE ' Holds "$" start position
Y VAR BYTE ' Holds "=" mid position
Z VAR BYTE ' Holds "*" end position
Index VAR BYTE ' Index pointer
B0 VAR WORD
B1 VAR WORD
TorchLockVal var word
CNT VAR BYTE
CNT2 VAR BYTE
TorchHystVal var byte
FirstRun var bit
TorchVNow var byte
ControlIsTracking var PORTA.1
TorchUp var PORTA.2
TorchDn var PORTA.4
EnableIn var PORTA.5
InMotion var PORTE.1

'Initial variable values
TorchLockVal = 120
TorchHystVal = 0
firstrun = 1


pause 1000
LCDout $fe, 1
LCDout $fe, $03, "WELCOME TO THE"
Lcdout $fe, $42, "DOUBLE D ENT."
Lcdout $fe, $14, "TORCH HEIGHT CONTROL"
Lcdout $fe, $54, "LCD WARMING UP"
FOR CNT2 = 1 TO 5
FOR CNT = 0 TO 4
Lcdout $fe, $63 + CNT, "."
PAUSE 400
Lcdout $fe, $63 + CNT, $20
NEXT CNT
NEXT CNT2

Start:

'Enter here if no Toolpath is running AND THC is not enabled

IF (EnableIn = 0) and (InMotion = 0) then
RxInt = 1 'Enable receive interrupt
ADCInt = 0 'Disable ADC interrupt
'***** START MSG1 *****
LCDout $fe, 1
LCDout $fe, $03, "CONTROL IS IN"
Lcdout $fe, $43, "STANDBY MODE."
LCDout $fe, $15, "READY TO RECEIVE"
Lcdout $fe, $55, "A COMMAND"
Lcdout $fe, $66
LCDOUT $fe, $0F
'***** END MSG1 *****
firstrun = 1

'Enter here if Toolpath is running OR THC is enabled OR both

ELSE
RxInt = 0 'Disable receive interrupt
ADCInt = 1 'Enable ADC interrupt
ADCGo = 1 'Start ADC conversion
if ADCFlag = 1 THEN GOTO NewADC 'New ADC interrupt flag

if firstrun = 1 then 'Write the entire message
LCDout $fe, 1
Lcdout $fe, $01, "PLASMA VOLTAGE=", TorchVNow
Lcdout $fe, $40, "--------------------"
Lcdout $fe, $14, "TORCH LOCK VALUE=", TorchLockVal
LCDout $fe, $55, "HYSTERESIS VALUE=", TorchhystVal
FIRSTRUN = 0
ELSE 'Write just the changed values
Lcdout $fe, $10, TorchVNow
ENDIF
select case TorchVNow
case TorchVNow > TorchLockVal + TorchhysTval 'Torch is too high, tell CNC to lower it
high torchdn
low torchup
case TorchVNow < TorchLockVal - TorchhysTval 'Torch is too low, tell CNC to raise it
high torchup
low torchdn
case else 'Torch is locked on, we're good
low torchup
low torchdn
end select
endif
GOTO Start

'ADC interrupt routine-------------------------------------------------------
NewADC:
TorchVNow = ADRESL 'Read ADC value into VAR
ADCFlag = 0 'Clear ADC interrupt flag
Return
'----------------------------------------------------------------------------


'Serial interrupt routine----------------------------------------------------
SerialInt:
'Command structure ex:
' $CommandWord=###*
RxInt = 0 'Disable receive interrupt
SerInStr = 0 'Clear the buffer
hserin[str SerInStr\25\42] 'Fill the buffer. Move on when "*" is found

'Thanks to Bruce: www.rentron.com for the parsing routine

Get_Start: 'X will hold the start "$" position
FOR X = 0 TO 24 'Iterate through the entire buffer
IF SerInStr[X] = "$" THEN Get_Mid 'We found it, move on to next find
NEXT X
GOTO Start 'Buffer is empty or improper Command string

Get_Mid: 'Y will hold the end "=" position
FOR Y = X+1 TO 24 'Iterate through the buffer from last found to end
IF SerInStr[Y] = "=" THEN Get_End 'We found it, move on to next find
NEXT Y
GOTO Start 'Buffer is empty or improper Command string

Get_End: 'Z will hold the end "*" position
FOR Z = Y+1 TO 24 'Iterate through the buffer from last found to end
IF SerInStr[Z] = "*" THEN ParseCommand 'We found it, now let's parse it
NEXT Z
GOTO Start 'Buffer is empty or improper Command string

Continued below... over 10000 characters... sorry:(

kevlar129bp
- 13th November 2009, 17:41
ParseCommand:
CmdLen var byte 'Declare byte var to hold "command word" string length
cmdlen = y-x-1 'Calc string length by: "=" position - "$" position -1
CmdWord var byte(cmdlen) 'Declare byte array based on string length
For Index = 0 to cmdlen-1
CmdWord[index] = SerInStr[index+x+1] 'Fill byte array with "command word"
next index
ValLen var byte 'Declare byte var to hold "command value" string length
ValLen = z-y-1 'Calc string length by: "*" position - "=" position -1
CmdVal var byte(ValLen) 'Declare byte array based on string length
For Index = 0 to ValLen-1
CmdVal[index] = (SerInStr[index+y+1]-"0") 'Fill byte array with "command value"
next index

if CmdWord = "SetTorchLockVal" then 'Compare variable "command word" with static string
select case ValLen 'Do math to get byte value based on "command value" length
case 1
TorchLockVal = CmdVal
case 2
TorchLockVal = (CmdVal[0] * 10) + CmdVal[1]
case 3
TorchLockVal = (CmdVal[0] * 100) + (CmdVal[1] * 10) + CmdVal[2]
case else
goto err_TorchLockVal
end select
if TorchLockVal > 255 then 'If we're NOT 8 bit, bad news
err_TorchLockVal:
'***** START ERR_MSG1 *****
LCDout $fe, 1
LCDout $fe, $02, "ONLY (000 - 255)"
Lcdout $fe, $40, "ALLOWED!"
LCDout $fe, $17, "PLEASE STANDBY"
FOR CNT = 0 TO 19
Lcdout $fe, $54 + CNT, "."
PAUSE 150
NEXT CNT
'***** END ERR_MSG1 *****
SerInStr = 0 'Flush the buffer
TorchLockVal = 0 'Flush the "Lock Value"
RxInt = 1 'Enable receive interrupt
GOTO Start 'Start over

ELSE 'We're 8 bit, good
'***** START MSG3 *****
LCDout $fe, 1
LCDout $fe, $01, "RECEIVED COMMAND:"
Lcdout $fe, $42, CmdWord, "=",TorchLockVal
LCDout $fe, $17, "TORCH LOCK VALUE"
Lcdout $fe, $58, "SET TO: ", TorchLockVal
'***** END MSG3 *****
SerInStr = 0 'Flush the buffer
PAUSE 5000 '5 second view of LCD confirmation
GOTO Start 'Start over
endif
endif

if CmdWord = "SetTorchHystVal" then
TorchHystVal = CmdVal
if TorchHystVal > 6 then
'***** START ERR_MSG2 *****
LCDout $fe, 1
LCDout $fe, $04, "ONLY (0 - 5)"
Lcdout $fe, $46, "ALLOWED!"
LCDout $fe, $17, "PLEASE STANDBY"
FOR CNT = 0 TO 19
Lcdout $fe, $54 + CNT, "."
PAUSE 150
NEXT CNT
'***** END ERR_MSG2 *****
SerInStr = 0
TorchHystVal = 0
RxInt = 1
GOTO Start
ELSE
'***** START MSG3 *****
LCDout $fe, 1
LCDout $fe, $01, "RECEIVED COMMAND:"
Lcdout $fe, $42, CmdWord, "=",TorchHystVal
LCDout $fe, $17, "TORCH HYST. VALUE"
Lcdout $fe, $58, "SET TO: ", TorchHystVal
'***** END MSG3 *****
SerInStr = 0
PAUSE 5000
GOTO Start
endif
endif
Return

kevlar129bp
- 13th November 2009, 18:02
Sorry guys for not compiling the above code before posting! Shame on me. I did fix all the errors with variables, with the exception of these:



...
CmdWord var byte(cmdlen)
'^^^^^Bad data type^^^^^
...
CmdVal var byte(ValLen)
'^^^^^Bad data type^^^^^
...
if CmdWord = "SetTorchLockVal" then
'^^^^^Bad expression^^^^^
...
if CmdWord = "SetTorchHystVal" then
'^^^^^Bad expression^^^^^


Any thoughts as to what I'm doing wrong? Probably a newbie mistake, I hope.
Thanks again all,
Chris

Darrel Taylor
- 14th November 2009, 02:36
...
CmdWord var byte(cmdlen)
'^^^^^Bad data type^^^^^
cmdlen is a variable.
Array sizes can't be changed at run-time.
It must be a constant.

CmdVal var byte(ValLen)
'^^^^^Bad data type^^^^^
ditto

if CmdWord = "SetTorchLockVal" then
'^^^^^Bad expression^^^^^
Do not pass GO, Do not collect $200.
Do not attempt to compare strings. PBP doesn't have them.


if CmdWord = "SetTorchHystVal" then
'^^^^^Bad expression^^^^^
ditto

kevlar129bp
- 14th November 2009, 16:28
Thanks DT,

I kinda thought that was the deal... So I think I'm going to go with the "KISS" method and do something like my original thought:

Command String...

C###V###



CmdWord VAR word
CmdVal VAR word

HSERIN(wait ("C"), DEC3 CmdWord)
HSERIN(wait ("V"), DEC3 CmdVal)


I think that will save me a load of code...I'll just have to write a command destruction manual so I know what command does what. Small price to pay, I think.

On a programming note: Say I want to make sure the CmdWord and CmdVal vars are within a byte sized var. I declare them as words, so I can compare later in code.
Would this be a simple way to do this...

If CmdWord < 255 Then
'We're good, do something with it
Else
'We are greater than 8 bit, bad command, start over
EndIf

Should I declare them as bytes right up front, and look for >255? What happens to the byte if say "500" is sent. Does it overflow to (500 - 255)... does the byte become "0" or "245". Hopefully that is not a way dumb question, just trying to not have to flash my chip a hundred times to change 1 line of code each time:o.

Thanks for your input DT,
Chris

Darrel Taylor
- 14th November 2009, 18:47
Yeah, I think they should be words.

If they were bytes, anything received over 255 would truncate and become a smaller number that you could not detect as an error.

And if you're worried about errors, the addition of a checksum to your packet might help too.
<br>

kevlar129bp
- 14th November 2009, 19:47
Thanks DT,

Good idea on the checksum. I'll run with it from here, and see what happens. Thanks a ton for your help!

'Til next time,
Chris

boroko
- 8th July 2012, 09:16
Hi All,
Can anyone offer an opinion on if this will work? I don't seem to be having much luck.

I'm trying to capture streaming data and there are a few sequences that I can key on to determine if I have a valid combination. So far the simplest is to look for the word "INVALID".
Here is one attempt:

' * * * * * * Interrupt handler *******
serialin: ' Buffer the character received
buffer[7] = buffer[5] ' get the newest character into the buffer
buffer[6] = buffer[5] ' and shift them into a sliding form
buffer[5] = buffer[4]
buffer[4] = buffer[3]
buffer[3] = buffer[2]
buffer[2] = buffer[1]
buffer[1] = buffer[0]
HSerin [buffer[0]] ' Read USART and store character in first position
IF buffer[0]="I" and buffer[1]="N" and buffer[2]="V" and buffer[3]="A" then
goto Freeze
endif
IF RCIF Then serialin ' Check for another character while we're here
@ INT_RETURN ; Return to program

I'm under the belief that by " "ing an alpha character that it will recognize it as the ASCII character and do the compare. Can anyone explain what I'm missing?

A related question is " how do I catch a STX ($02) and a ETX ($03) with a number (4) and a non control character (X)in the middle? The data stream is STX, 4, X, $FF and I'm struggling how to compare mixed forms. Can I just use the ASCII numbers and compare them?

Sorry for such a simple question, but it's kicking my butt.


Thanks
Bo

Charlie
- 8th July 2012, 13:13
If this is a cut and paste, you have a mistake in the first line (buffer[7] = buffer[5] should be buffer[7] = buffer[6])

Dave
- 8th July 2012, 22:24
I have a question.... Why not just move a pointer instead of copying all of the data each time a new character is received?
As far as comparing the data bytes, just compare the Hex or Decimal ascii equivelents? After all thats all your "buffer[0]="I" statement is doing, comparing the ASCII equivelent of the received byte.

boroko
- 9th July 2012, 01:52
Hi Guys,
Thanks for the replies.
The (buffer[7] = buffer[5] error was because it was 4 in the morning and I had worked on it way too long. The characters after the 5th weren't used in the compare, they were only for display so that I could get some idea on if it were successful. Thanks for seeing that.

Dave, I have looked at quite a few examples of compares and they are not yet clicking with me. The data is coming in @ 9600, so its not too fast, but I still manage to miss it.
I've looked at this (http://www.picbasic.co.uk/forum/showthread.php?t=717), this (http://www.picbasic.co.uk/forum/showthread.php?t=6963), and this (http://www.picbasic.co.uk/forum/showthread.php?t=6963). They all have good examples and I should be able to build something, but as of yet, no banana.

I think my best answer is to just try again and dissect these and try to code them for my use. I will have to understand this better.

Thanks
Bo

HenrikOlsson
- 9th July 2012, 06:22
Remember that it's all just numbers, if you want to check if a byte contains 'I' either of these will work

IF myByte = 73 THEN....
If myByte = "I" THEN....
IF myByte = $49 THEN....
IF myByte = %00110001 THEN...
They all do the same thing - they compare the content of myByte with the decimal value 73, which is the ASCII code for the letter 'I'.

Instead of using AND you might try something like:

IF Buffer[0] = "I" THEN
IF Buffer[1] = "N" THEN
IF Buffer[2] = "V" THEN
IF Buffer[3] = "A" THEN
GOTO Freeze
ENDIF
ENDIF
ENDIF
ENDIF

There's nothing wrong with the AND approach but I think using multiple IF statements will produce smaller code.

/Henrik.

boroko
- 9th July 2012, 11:02
Thanks Henrik,

I just needed a sanity check. Too many hours and poor results.

I'll have a look at it when I get back to the shop. Maybe something obvious after some sleep and a fresh look.

Bo

boroko
- 9th July 2012, 16:34
Dave, (and, of course, anyone else that care to respond)
I'm a bit confused about checking the data with a pointer. Do you mind explaining more?

I understand setting up a ring buffer similar to DT's serial LCD program. What I'm not sure is if I need to keep it cleaned out or something similar. If I just keep stepping the pointer around the loop, what happens when you fill the buffer? Does it just overwrite the previous data and keep circling the ring? After looking at that program for a long time, I finally believe that is what happens.

Still trying to work towards for that "Neo" moment when the Matrix just starts to come into focus....

Bo

boroko
- 9th July 2012, 16:35
Dave, (and, of course, anyone else that care to respond)
I'm a bit confused about checking the data with a pointer. Do you mind explaining more?

I understand setting up a ring buffer similar to DT's serial LCD program. What I'm not sure is if I need to keep it cleaned out or something similar. If I just keep stepping the pointer around the loop, what happens when you fill the buffer? Does it just overwrite the previous data and keep circling the ring? After looking at that program for a long time, I finally believe that is what happens.

Still trying to work towards for that "Neo" moment when the Matrix just starts to come into focus....

Bo