Hserin parsing string...again?


Closed Thread
Results 1 to 22 of 22
  1. #1
    Join Date
    Dec 2005
    Location
    Salt Lake City, Ut, USA
    Posts
    108

    Question Hserin parsing string...again?

    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

  2. #2
    Join Date
    Dec 2005
    Location
    Salt Lake City, Ut, USA
    Posts
    108

    Default Follow up?

    Am I on the right track?

    Code:
    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

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    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?

    DT

  4. #4
    Join Date
    Dec 2005
    Location
    Salt Lake City, Ut, USA
    Posts
    108

    Default Thanks Darrel

    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:
    Code:
    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.

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    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.

    DT

  6. #6
    Join Date
    Dec 2005
    Location
    Salt Lake City, Ut, USA
    Posts
    108

    Default

    Will this fly...nearest you can tell?

    Code:
    '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

  7. #7
    Join Date
    Dec 2005
    Location
    Salt Lake City, Ut, USA
    Posts
    108

    Default

    Hello all,

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

    Code:
    '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

  8. #8
    Join Date
    Dec 2005
    Location
    Salt Lake City, Ut, USA
    Posts
    108

    Default

    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 Anyhow, any thought are helpful thoughts at this point.
    Thanks all,
    Chris
    Code:
    '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
    Last edited by kevlar129bp; - 13th November 2009 at 18:27. Reason: Fixed vars

  9. #9
    Join Date
    Dec 2005
    Location
    Salt Lake City, Ut, USA
    Posts
    108

    Default

    Code:
    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
    Last edited by kevlar129bp; - 13th November 2009 at 18:29. Reason: Fixed vars

  10. #10
    Join Date
    Dec 2005
    Location
    Salt Lake City, Ut, USA
    Posts
    108

    Default

    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:

    Code:
    ...
    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

  11. #11
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    Code:
    ...
    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
    DT

  12. #12
    Join Date
    Dec 2005
    Location
    Salt Lake City, Ut, USA
    Posts
    108

    Default

    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###

    Code:
    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.

    Thanks for your input DT,
    Chris

  13. #13
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    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.

    DT

  14. #14
    Join Date
    Dec 2005
    Location
    Salt Lake City, Ut, USA
    Posts
    108

    Default

    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

  15. #15
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231

    Default Re: Hserin parsing string...again?

    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:
    Code:
    ' * * * * * *  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

  16. #16
    Join Date
    Dec 2010
    Posts
    409

    Default Re: Hserin parsing string...again?

    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])

  17. #17
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166

    Default Re: Hserin parsing string...again?

    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.
    Dave Purola,
    N8NTA
    EN82fn

  18. #18
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231

    Default Re: Hserin parsing string...again?

    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, this, and this. 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

  19. #19
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521

    Default Re: Hserin parsing string...again?

    Remember that it's all just numbers, if you want to check if a byte contains 'I' either of these will work
    Code:
    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:
    Code:
    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.

  20. #20
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231

    Default Re: Hserin parsing string...again?

    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

  21. #21
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231

    Default Re: Hserin parsing string...again?

    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

  22. #22
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231

    Default Re: Hserin parsing string...again?

    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

Similar Threads

  1. HSERIN for variable length string
    By Pic2008 in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 19th February 2010, 05:58
  2. parsing string from hserin
    By xxxxxx in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 2nd April 2009, 18:42
  3. Visual Basic 6 & Access 2000
    By Demon in forum Off Topic
    Replies: 33
    Last Post: - 7th September 2006, 04:39
  4. String Parsing
    By eoasap in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 18th February 2006, 17:20
  5. serial string parsing
    By billybobbins in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 8th September 2004, 21:34

Members who have read this thread : 2

You do not have permission to view the list of names.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts