Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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
 
Hi C. Yes the only difference between proc's and functions is the return.

Byref is only necessary when the variable isn't global.

If said string is declared on the top of all code you can access the string without passing its reference.
All strings in Oshonsoft can be accessed by index. BUT!! I don't want to confuse you as strIX and str may be easier for you to manipulate.
 
Hi C. Yes the only difference between proc's and functions is the return.

Byref is only necessary when the variable isn't global.

If said string is declared on the top of all code you can access the string without passing its reference.
All strings in Oshonsoft can be accessed by index. BUT!! I don't want to confuse you as strIX and str may be easier for you to manipulate.
Hi I,
OK, thanks.
I'm always confused :)

This 'new' code has been written by my mate, but it doesn't compile!

I'll send him a short version of his program, that he can check, and send back to me, which I'll post.
C
 
Hello; "ByRef" can only be used with "Proc".

With "Function" you can only work with global variables or with memory addresses (pointers) that represent the variables involved.
 
I agree with Ian, so 2x for yes.

"All facts stated for procedures are valid for functions, also. Functions can be declared with FUNCTION statement. "

Passing a parameter "ByRef" is in effect passing a pointer to that parameter.
 
Hello; "ByRef" can only be used with "Proc".

With "Function" you can only work with global variables or with memory addresses (pointers) that represent the variables involved.
WOW... I was sure I could do both. I haven't used Oshosoft for quite some time.
But I would have used global variable anyway..
Reading the help file he does say ALL facts about procedures are the same for functions
 
WOW... I was sure I could do both. I haven't used Oshosoft for quite some time.
But I would have used global variable anyway..
Reading the help file he does say ALL facts about procedures are the same for functions
Hi,
Once I've checked the test code, I'll post it and perhaps you can check what's best
C
 
Last edited:
I would have preferred to just have "Function" and the programmer choose whether data is returned or not, like in C.

The problem with "ByRef" is that it works first by "value" and when exiting the procedure it copies the image over the original. This is not very efficient, if you work with microcontrollers with just enough memory it will cause problems.

For me it is more comfortable to work with "Function" so I wrote a library to work with memory addresses with the "String" type, or with normal arrays used as string.
 
I would have preferred to just have "Function" and the programmer choose whether data is returned or not, like in C.

The problem with "ByRef" is that it works first by "value" and when exiting the procedure it copies the image over the original. This is not very efficient, if you work with microcontrollers with just enough memory it will cause problems.

For me it is more comfortable to work with "Function" so I wrote a library to work with memory addresses with the "String" type, or with normal arrays used as string.

That's poor practice, typical of C :D

The Procedure/Function commands come from the more strict Pascal language.
 
I normally don't like passing a reference / pointer, but a pointer to a string is normal practice, we all do it all the time.

C was the best of the best in string manipulation, this is why we all follow that rule. Having said that passing a pointer to a structure rather than the entire structure itself is definitely a boon. It would cripple the stack otherwise..
 
I've always thought that passing byref passed a pointer to the variable so the function/subroutine can change it if required. If, as DogFlu66 says, it copies the value before exiting then that would be extremely inefficient and silly.

Mike.
 
With the same IDE you can see what I said.
In any case, the programmer can bypass the restrictions and work with memory addresses (pointers), it is just not as comfortable as in C.

For example:
Pointer(_address) , I think it is the only command that has not been updated, this means that it is not allowed to be used in conditionals and it does not allow simple operations to be performed with it.
For example:
While Pointer(_address + 1) = 0 ' Not allowed.
wend
The use is more complicated:
_address++
char = Pointer(_address)
while char = 0
char = Pointer(_address)
wend

But we can bypass the restrictions by creating the traditional Peek and Poke commands from Basic.

For example:

Funcitons Peek(_address as word) as byte
Symbol _Return = Peek
_Return = Pointer(_address)
End Functions

Now it can be done:
While Peek(_address +1) = 0
wend
 
Hi P and D,
I'm glad I'm supporting Oshonsoft and Vladimirs efforts as it's a project which is brilliant for a one man band to produce.
I wish I was clever enough to use other languages that don't need Osh, but as I said many times, I'm not, so here we are.
C
 
Hi,
My mate has re written the MATCH CODE, but is busy today, so I thought I'd post the CODE so far.
I notice he's used BYVAL instead of BYREF.
Does this look viable? Note that he's perhaps hampered by Oshonsoft and me in his ideas.
C.
Code:
'18F4431 32MHz XTL PCB8 BASE_SLAVE match 2 strings E 170123 short 2

Define CONFIG1L = 0x00
Define CONFIG1H = 0x06  '8mHz x4 =32
Define CONFIG2L = 0x0c
Define CONFIG2H = 0x20
Define CONFIG3L = 0x04
Define CONFIG3H = 0x80
Define CONFIG4L = 0x80  'Set for HVP
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40

'OSH config
Define CLOCK_FREQUENCY = 32
Define SINGLE_DECIMAL_PLACES = 2
Define STRING_MAX_LENGTH = 20
Define SEROUT_DELAYUS = 1000

'**********************************************************************
'*                                                                    *
'*      Register configuration                                        *
'*                                                                    *
'**********************************************************************

'------------- TARGET SETUP  ------------------
'Const PR2set = 125  'use this for the live board: gets 5ms per interrupt
Const PR2set = 2  'use this for fast timing to speed up simulator
Define SIMULATION_WAITMS_VALUE = 1  'Comment in for SIM out for PIC

'**********************************************************************
'*                                                                    *
'*          IO Port configuration                                     *
'*                                                                    *
'**********************************************************************
'IN or OUT
Const TRISAinit = %11011000  '7=OSC, 6=OSC, 4=QEIB 3=QEIA 2=TEMP SEROUT
Const TRISBinit = %00000000
Const TRISCinit = %11000100  '7=1-RX, 6=1-slave4431_cs, 2=MOSI'RX<<<<<<<<<<<<<<<<<<<<<
Const TRISDinit = %00100000  '6=led, 7=led, 5=synch'D2=MOSI ??£
Const TRISEinit = %00000000  '2=TEST INDICATOR, 0= S2M_BUF_FULL

TRISA = TRISAinit
TRISB = TRISBinit
TRISC = TRISCinit
TRISD = TRISDinit
TRISE = TRISEinit

'SET BITS ON/OFF before TRIS!
Const LATAinit = %00000000  'ON/OFF
Const LATBinit = %00000000
Const LATCinit = %00000000
Const LATDinit = %00000000
Const LATEinit = %00000000  'POSS MCLR RE3

Symbol yled = PORTD.6
Symbol rled = PORTD.7


'START UP LEDS
rled = 1
WaitMs 1000
rled = 0
WaitMs 1000
yled = 1
WaitMs 1000
yled = 0
WaitMs 1000

Dim to_match_str As String  ' the string to match
Dim gnrmc_str As String  ' the string used for test purposes
Dim position As Byte  ' the position in the main string to start from

main_loop:  '/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

Toggle rled

' set the string  to be checked (in this case called gnrmc_str)
gnrmc_str = "$gnrmc0.00A3723."
to_match_str = "gnrmc"
position = 1

'check For the id String
' I have called this funtion "match" - you can call it anything you like as long as the name is consistent

' match uses 3 inputs. The first is the string to be tested. I have used gnrmc_str but it can be any valid string variable
' The second input is the position to start checking from. in this case it is the numbber 1
' (arrays start at 0 so the second character in the array is 1)
' The third input is the string of characters to be checked against. I hane used gnrmc in
' this example but it could be robi, ROBI, bori, BORI etc

Call match(gnrmc_str, position, to_match_str)
'Break

If match = 1 Then
'Break

' if OK go to good string found
Else
'Break

'if not ok goto bad string found

Endif

Goto main_loop

End                                               

'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

    Dim match_str_len As Byte  'the number of characters to be match checked
    Dim position_counter As Byte  ' the index pointer for the character to be checked
    Dim position_ix As Byte
    Dim shortstring As Byte
    Dim shortposition As Byte
    
    position_ix = str_ix + match_str_len  'the position to start checking from
        
    match_str_len = Len(match_str)  ' find the length of the test string to be compared
    
    For position_counter = str_ix To position_ix
    shortstring = position_counter - match_str_len
'Break
        If input_str(position_counter) = match_str(shortposition) Then
            match = 1
        Else
            match = 0
            Exit  ' jump out of the loop
        Endif
    Next position_counter

End Function
 
I agree, the best language in this case, an environment with an integrated simulator, is the one that allows you to do what you want without getting bored. I have also been supporting this project for more than 15 years.

Another issue is that on a personal level I like to go deeper into the system, possibly to a level that is not necessary.
In any case, all languages have their problems, I have had quite a few problems working with C, until I was able to overcome the bugs and oddities that each compiler has.

Focusing on the topic:
ByVal: are all the variables that are declared by default. It is not necessary to put it. It is only used to clarify the code when mixed with ByRef and ByRefOut.
 
I agree, the best language in this case, an environment with an integrated simulator, is the one that allows you to do what you want without getting bored. I have also been supporting this project for more than 15 years.

Another issue is that on a personal level I like to go deeper into the system, possibly to a level that is not necessary.
In any case, all languages have their problems, I have had quite a few problems working with C, until I was able to overcome the bugs and oddities that each compiler has.

Focusing on the topic:
ByVal: are all the variables that are declared by default. It is not necessary to put it. It is only used to clarify the code when mixed with ByRef and ByRefOut.


I agree, the best language in this case, an environment with an integrated simulator, is the one that allows you to do what you want without getting bored. I have also been supporting this project for more than 15 years.
Hi D,
I'm too busy trying to get my programs to work, to ever get bored :)

ByVal: are all the variables that are declared by default. It is not necessary to put it. It is only used to clarify the code when mixed with ByRef and ByRefOut.
I understand that 'byval' etc are for pointing, but I couldn't use them in a program, as they are just beiyond my brain.
So far I've been using a MATCH CODE that doesn't use 'byref' etc, but my mate is trying to make it more efficient. Perhaps this is not possible using Oshonsoft BASIC?
Here is the FUNCTION section
C
Code:
'**************** Look for GNRMC, check if necessary************************

[If matchgnrmc("GNRMC", 1) = 1 Then]

'MATCHGNRMC GPS checks the 5x BYTES after the $ making sure they match GNRMC
Function matchgnrmc(gnrmc_str As String, BufIX As Byte) As Bit
    Dim gnrmc_str_char As Byte  'local variables
    Dim gnrmc_buf_char As Byte
    Dim StrIX As Byte

    StrIX = 0  'start at first char of passed string
   
    MatchLoop:  '<---
    'Break  '<<<<<<<<<<<<<<<<<<<
    gnrmc_str_char = gnrmc_str(StrIX)  'get str char
    If gnrmc_str_char = 0 Then  'if it is 0 then end of passed string and..
        matchgnrmc = 1  'All GNRMC CHARS are equal
        PORTE.2 = matchgnrmc  '<<<<<<<<<<for indication<<<<<<<<<<<<@
        Exit
    Else
        gnrmc_buf_char = gnrmc_buf(BufIX)  'else not end of string, get buf char and compare
        If gnrmc_str_char <> gnrmc_buf_char Then
            matchgnrmc = 0  'GNRMC CHARS are not equal
            PORTE.2 = matchgnrmc  '<<<<<<<<<<For indication<<<<<<<<<<<<@
            Exit
        Endif
    Endif

    StrIX = StrIX + 1  'else, not at end of string and no mismatch
    BufIX = BufIX + 1  'bump indexes and do next
    Goto MatchLoop  '-->

End Function
 
Last edited:
It can surely be done, I have not found anything that cannot be done.
But you have to specify what the function does to be able to take a look at it.

I imagine you want to search for one string within another, if this is it, I already have a function that does it, then I can pass it to you so you can compare it with yours.

Because no matter the language used, the problems are the same.
 
Last edited:

New Articles From Microcontroller Tips

Back
Top