Can Oshonsoft use 'byref' in a FUNCTION? (Plus examples of CHAR MATCHING CODE)

camerart

Well-Known Member
Hi,
Here is a PROCEDURE from one of my programs:
'These extract characters from the raw RX buffer array to OSH string types
===================================
'AddChar: adds passed character to passed string at
'passed StrIx. Terminates result with 0 to keep it a string
Proc Addchar(ByRef str As String, ByRef StrIX As Byte, char As Byte)
str(StrIX) = char
StrIX = StrIX + 1
str(StrIX) = 0
End Proc
===================================
it uses 'byref'

I would like to know if 'byref' can also be used in an Oshonsoft FUNCTION please?
Camerart
 
The items searched for means that the code will only work in the northern and western hemispheres. A better solution would be to capture the entire string, check CRC and if OK then process it. A quick check at the start of the string could be done and invalid strings rejected earlier.

Mike.
 
If it finds the match it exits, if not it runs through the entire chain looking for it.

In this specific case, yours seems like the best choice.
Hi D,
Ok, thanks for helping me choose, for this case. This will also please my mate, who is time limited, do to his condition. I'll see him Saturday.

C
 
Hi,
D and P,
We are just using N and W while we solve this MATCH thing, but he has CODE for N.E.W.S. (Is this where News comes from?)
C
 
ByRef can only be used in procedures.

To do the same thing that ByRef does in the procedures you have to work with pointers in the functions, if you want later I will give an example and you can pass it on to your friend so that he can analyze it, it is not very difficult.
 
Hi D,
I told him about the exchanges here, so he switched to BYVAL in the latest CODE posted https://www.electro-tech-online.com...les-of-char-matching-code.165727/post-1446941, I think he understand no BYREF.

P.S. I hope to go to The https://en.wikipedia.org/wiki/Prime_meridian_(Greenwich)
To show a friend of mine the Harrison clocks, which are worth a visit.
I hope to take a PCB, and save the output on the E and W of the line.
C
 
Last edited:
I've been looking at some photographs of Harrison clocks and they really are impressive.
Hi D,
My grandad taught me about clocks many years ago, and I been interested since,
Here's a video about his plight with the authorities:
Note that he was a carpenter and his first very accurate clock was made of wood, and didn't need lubricating.
C
 
Curiosity: I have simplified the function, leaving this new version taking 1.47mSec to execute and yours taking 1.90mSec.

Input:
String1 = "!AIVDM,1,1"
String3 = "AIVDM"

'8Mhz
'The corresponding match function
Function match(ByVal input_str As String, ByVal str_ix As Byte, ByVal match_str As String) As Bit ' these variable names can be changes as wished
Symbol _Return = match
Dim position_counter As Byte ' the index pointer for the character to be checked
Dim shortposition As Byte 'the current position in the short string
position_counter = position_counter + str_ix
While match_str(shortposition) > 0
If input_str(position_counter) = match_str(shortposition) Then
_Return = 1 ' set the match indicator to valid
shortposition = shortposition + 1 ' increment the short string position counter
Else
_Return = 0 'set the match indicator To Not valid
Exit ' jump out of the loop
Endif
position_counter++
Wend
End Function'the corresponding match function
 
Last edited:
Hi D,
I tried it in the simulator, but it doesn't compile.
If anyone could try this in a SIM, I'm sure you will see why.
There's a Keyword, and I'm not sure if this is inentional, and sentences should be inputted or not?

The normal comparison may l;ook like this: '$GNRMC,000000.00,A,3723.02837,N,00150.39853,W,0.820,188.36,110706,,,A*74
and the MATCH would be for 'GNRMC' it would help me if this could be used in the CODE, so I know what we're comparing please?
C
 
I don't understand what you mean, I tried the following in the simulator:

'Amicus18
'***********************************************************************
'Match function
'Pic18F26k22, OshonSoft Pic18 Basic Compiler v5.17
'***********************************************************************
#define CLOCK_FREQUENCY = 64 'Clock 64Mhz
#define STRING_MAX_LENGTH = 100
#define SINGLE_DECIMAL_PLACES = 1
'#define SIMULATION_WAITMS_VALUE = 1
'***********************************************************************
'***********************************************************************
'Include "_FuncionesPic18F26K22.bas"
'Include "_SetUpAmicus18.bas"
'Include "_FuncionesTmrBase.bas"
'Include "_FuncionesUartRingBuffer.bas"
'Include "_Funciones_Buffer_RS232.Bas"
'***********************************************************************
main:
'********************************************************************
UART1_Init 115200
'UART2_Init 4800
WaitMs 1

Dim String1 As String
Dim String2 As String
Dim String3 As String

String1 = "$GNRMC,000000.00,A,3723.02837,N,00150.39853,W,0.820,188.36,110706,,,A*74"
String2 = "!AIVDO,1,1,,,100000?P?w<tSF0l4Q@>4?wv0000,0*53"
String3 = "GNRMC"

While True
UART_Write #match(String1, 1, String3), CrLf

If match(String1, 1, String3) > 0 Then
UART_Write "Ok"
Else
UART_Write "No Match"
Endif


While True
Wend
Wend

End
'The corresponding match function
Function match(input_str As String, str_ix As Byte, match_str As String) As Byte ' these variable names can be changes as wished
Symbol _Return = match
Dim position_counter As Byte ' the index pointer for the character to be checked
Dim shortposition As Byte 'the current position in the short string
position_counter = 0
shortposition = 0
position_counter = position_counter + str_ix
While match_str(shortposition) > 0
If input_str(position_counter) = match_str(shortposition) Then
_Return = 1 ' set the match indicator to valid
shortposition++ ' increment the short string position counter
Else
_Return = 0 'set the match indicator To Not valid
Exit ' jump out of the loop
Endif
position_counter++
Wend
End Function'the corresponding match function
 
Hi D,
The #50 program compiled and ran ok, but it had all of the set-up, and I didn't realise it needed it first time.
One problem is that I had to change PICs from the one I'm testing 18F4431, to a larger memory type 18F46K20, which was ok.
I'll look closer and see if I can get it to work on the 4431.
Thanks.
C
 
If you have to change, I recommend that you change to the Pic18F46K22. But you have to keep in mind that the simulator at the moment does not simulate all its internal modules.
 
You can also leave memory free by shortening the value of #define
STRING_MAX_LENGTH =
100. If the problem is lack of sram.
Hi D,
I use the 4431 as it has a Quadrature encoder, and it would be quite a lot of effort to change plus expense.

But you have to keep in mind that the simulator at the moment does not simulate all its internal modules.
This may answer why the latest 'my mate' prog sets MATCH after each CHAR instead of after all CHARS? I'm testing it in the full prog with the SIM.

I've been using
STRING_MAX_LENGTH =20 successfully, and I'd forgotten all about it.

Note This MATCH thing is the last to do for the project to be a tool to play with, so I don't want to rock the boat too much, just get one of the MATCH CODEs working. At the moment 'my mates' is in the full prog.
C.
 
Ok, anyway if you want to continue having the advantage of using Functions, you can switch to using pointers. It is not difficult, it is just getting used to the fact that the first element of the string is not zero, the first element is now the memory address of the first element and to access the memory addresses a command or a function is used.

I leave the example:

'Amicus18
'***********************************************************************
'Match function
'Pic18F26k22, OshonSoft Pic18 Basic Compiler v5.17
'***********************************************************************
#define CLOCK_FREQUENCY = 64 'Clock 64Mhz
#define STRING_MAX_LENGTH = 100
#define SINGLE_DECIMAL_PLACES = 1
'#define SIMULATION_WAITMS_VALUE = 1
'***********************************************************************
'***********************************************************************
'Include "_FuncionesPic18F26K22.bas"
'Include "_SetUpAmicus18.bas"
'Include "_FuncionesTmrBase.bas"
'Include "_FuncionesUartRingBuffer.bas"
'Include "_Funciones_Buffer_RS232.Bas"
'***********************************************************************
main:
'********************************************************************
UART1_Init 115200
'UART2_Init 4800
WaitMs 1

Dim String1 As String
Dim P_String1 As Word
Dim String2 As String
Dim P_String2 As Word
'Pointer assignment up to 12bit for Pic18 series
Dim _Address As Word
Symbol _Address_HB = _Address.HB
Symbol _Address_LB = _Address.LB
ASM: LFSR 2,String1
ASM: MOVFW FSR2H
ASM: MOVWF _Address_HB
ASM: MOVFW FSR2L
ASM: MOVWF _Address_LB
P_String1 = _Address '-> String1 (Array)
'Pointer assignment up to 12bit for Pic18 series
ASM: LFSR 2,String2
ASM: MOVFW FSR2H
ASM: MOVWF _Address_HB
ASM: MOVFW FSR2L
ASM: MOVWF _Address_LB
P_String2 = _Address '-> String2 (Array)

String1 = "$GNRMC,000000.00,A,3723.02837,N,00150.39853,W,0.820,188.36,110706,,,A*74"
String2 = "GNRMC"

While True
'UART_Write #match(String1, 1, String2), CrLf

If match(P_String1, 1, P_String2) > 0 Then
UART_Write "Ok"
Else
UART_Write "No Match"
Endif


While True
Wend
Wend

End
'The corresponding match function
Function match(input_str As Word, str_ix As Byte, match_str As Word) As Byte ' these variable names can be changes as wished
Symbol _Return = match
Symbol position_counter = input_str
Symbol shortposition = match_str
position_counter = input_str + str_ix
While Peek(shortposition) > 0
If Peek(position_counter) = Peek1(shortposition) Then
_Return = 1 'set the match indicator to valid
shortposition++ 'increment the short string position counter
Else
_Return = 0 'set the match indicator To Not valid
Exit 'jump out of the function
Endif
position_counter++
Wend
End Function 'the corresponding match function
'*******************************************************************************************
'Peek function of the traditional Basic language to work with memory addresses (read).
'*******************************************************************************************
'Returns the value (Byte) containing the specified memory address (Word).
'It can be used in compound conditional structures and mathematical operations.
'For example: If Peek(_Address) > 0 And PeeK(_Address + 1) = 0.
'Restrictions until v5.17 (PSI 18): cannot be used in simple conditionals with itselfs.
'For example: If Peek(_Address) = PeeK(_Address +1) -> in this type or similar (And, Or)
'always returns true.
'Bypassing restrictions: If Peek(_Address) = Peek1(_Address +1)
'********************************************************************************************
'Peek
Function Peek(_Address As Word) As Byte
Symbol _Return = Peek
_Return = Pointer(_Address)
End Function
'Peek1
Function Peek1(_Address As Word) As Byte
Symbol _Return = Peek1
_Return = Pointer(_Address)
End Function
 
Last edited:
Hi D,
To give you an idea of my thoughts when presented by CODE like this:
Hi D,
I'm afraid you've left me behind in the dust
Where you are CODE agile, something like what you have kindly presented, would take me weeks or months to follow.
I do appreciate what you are offering, but it's just lost on me, sorry.

I have almost got my mates CODE to integrate into the full program at the moment, so I am better employed finishing this first, then once it's all working, I can try to get some sort of flight out of the project, while I present all of your CODEs to my mate, who will understand it and see what he comes up with.

A lot of time is being spent on this MATCH section, but really, if the GPS is the correct type with a memory, it should only 'see' GNRMC sentences, and if the sentences between BASE and REMOTE are correct then those sentences should also be correct, so MATCH is only for a safeguard.
Thank you, C.
 
Hi,
I've added the CODE https://www.electro-tech-online.com...les-of-char-matching-code.165727/post-1446941
into the FULL program, and the MATCH section works as it should, however I don't know how to change the INPUT to compare the incoming sentences instead of the fixed STRING in the example?
C
Code:
On High Interrupt
Save System

'OVERRUN ERROR
If PIE1.RCIE = 1 Then  'EUSART Receive Interrupt Enable bit
    If RCSTA.OERR = 1 Then
        Gosub irqinitbuf  're-init buffer, discard bad sentence
        Goto RXIRQdone  'done, wait for next character
    Endif  'OERR

    'FRAMING ERROR
    If RCSTA.FERR = 1 Then
        dumpchar = RCREG  'Read char to clear RCIF and FERR
        Gosub irqinitbuf  'Re-init buffer, discard bad sentence
        Goto RXIRQdone  'wait for next
    Endif  'FERR

    'No UART errors, process character
    If PIR1.RCIF = 1 Then
        RXIRQchar = RCREG  'read the received char, clears RCIF

        'Look for $, start/restart filling buf when found
        If RXIRQchar = "$" Then  'Start (re)filling buf on any $
            'Gosub IRQinitBuf  'init buffer, index and flags@
            gnrmc_buf(gnrmcpsn) = RXIRQchar  'store $ $ ADDED instead of RXIRQchar, because no $ was being stored
            gnrmc_buf_filling = 1  'start storing the sentence
            Goto RXIRQdone  'done with this character
        Endif  'char was $

        'no UART errors and character was not $
        'If $ was found previously, process character looking for W and no buffer overflow.
        'If haven't found $ yet, just ignore character.

        If gnrmc_buf_filling = 1 Then  'if filling buffer, see if there is room in buf
            If gnrmcpsn >= (rxbufsize - 1) Then  'last char was at end of buf - buffer overflow so..
                Gosub irqinitbuf  'restart buffer, discard sentence
                RXerr = 1  'let main know that the buffer overflowed and is restarting
                Goto RXIRQdone  'done, resume looking for next $
            Endif  'buffer overflow
            gnrmcpsn = gnrmcpsn + 1  'else, there's room in buf so bump index and store character, might be W
            gnrmc_buf(gnrmcpsn) = RXIRQchar
               
            If RXIRQchar = "W" Then  'if end of sentence..
                RCSTA.CREN = 0  'shut down UART
                PIE1.RCIE = 0  'Enable off
                gnrmc_buf_filling = 0
                gnrmc_buf_full = 1
                Goto RXIRQdone  'and bye!
            Endif  'RXIRQchar was W
        Endif  'If gnrmc_buf_filling = 1
    Endif  'RCIF=1
Endif  'RCIE=1

    'Exit point for each RXinterrupt. Process timers
    RXIRQdone:

Resume
 
Hi D,
I just had a quick look at this CODE, and even my untrained eye can see it's good.
Thanks, I'm sure it will be adopted in time.
C
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…