Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 03:45 28 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Possible bug in CONST operation.

Author Message
Andy-g0poy
Regular Member

Joined: 07/03/2023
Location: United Kingdom
Posts: 59
Posted: 12:24am 30 Jul 2023
Copy link to clipboard 
Print this post

I seem to have run into a buggette with the use of CONST

I have been converting a state machine version of a rotary encoder program to mmbasic,
which is working fine. (I just did not use the const type)

To keep things tidy, I decided to put the various setups and inits in a subroutine, and just call that subroutine from the main program. This keeps the clutter in the main program down, and showed up the problem.


A short test program running mmbasic V5.0707 on pico


start:
init_enc

print " in start  dt is " dt%
print " clk start is " clk%
print " state% is" ,state%
end


sub init_enc
const dt%  = 19 'gp14
const clk% = 20 'gp15

SetPin clk%, DIN
SetPin dt%, Din

print "in sub dt is ",dt%
print "in sub clk is ",clk%
state% = port(dt%,2)
end sub

output is:


RUN
in sub dt is    19
in sub clk is   20
in start  dt is  0
clk start is  0
state% is      0

The value of the constants clk and dt have NOT been passed back to the main program.

Remove the const declaration

and the output is as expected.

in sub dt is    19
in sub clk is   20
in start  dt is  19
clk start is  20
state% is      0


it's as if the const is acting as a local variable within the subroutine.
I don't think I am doing anything silly...


Andy
 
toml_12953
Guru

Joined: 13/02/2015
Location: United States
Posts: 339
Posted: 02:40am 30 Jul 2023
Copy link to clipboard 
Print this post

  Andy-g0poy said  I seem to have run into a buggette with the use of CONST

I have been converting a state machine version of a rotary encoder program to mmbasic,
which is working fine. (I just did not use the const type)

To keep things tidy, I decided to put the various setups and inits in a subroutine, and just call that subroutine from the main program. This keeps the clutter in the main program down, and showed up the problem.


I would expect that if you define them in a sub, they're local to the sub, constants or not. If you want them to be global, you have to define them in the main program.
Edited 2023-07-30 12:40 by toml_12953
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2136
Posted: 05:08am 30 Jul 2023
Copy link to clipboard 
Print this post

  Latest Manual p89 said  A constant defined outside a sub or function is global and can be seen throughout the program.
A constant defined inside a sub or function is local to that routine and will hide a global constant with the same name

Edited 2023-07-30 15:09 by phil99
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6798
Posted: 06:59am 30 Jul 2023
Copy link to clipboard 
Print this post

If you are wanting to set CONST values conditionally then why not put them in a subroutine and use GOSUB? It may be considered old-fashioned but it works with globals. You can use labels:

'k% selects the set to use. It is only set once and cannot be changed within the program.

const k%=1

if k%=0 then gosub cz1 else gosub cz2

main:
DO
........
LOOP

END

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

cz1:
const speed = 45
const led = RGB(blue)
return

cz2:
const speed = 33.33
const led = RGB(red)
return

.
Edited 2023-07-30 17:00 by Mixtel90
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
flip
Senior Member

Joined: 18/07/2016
Location: Australia
Posts: 114
Posted: 07:49am 30 Jul 2023
Copy link to clipboard 
Print this post

That's a neat idea Mick .. a structured way of achieving multiple config settings within same file... excellent case for keeping GOSUB...RETURN.

I will be using that idea a lot once I make it work OK - doesn't seem to work for me in MM for DOS - after RETURNing from Sub, it loses the CONST value...will keep trying

EDIT: I could be dreaming but I recall that some change was done to GOSUB...RETURN that made it behave differently so this capability was lost...maybe Geoff or Peter can confirm...and (hopefully please) reinstate?...but I don't trust my memory on this

Phil
Edited 2023-07-30 18:48 by flip
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6798
Posted: 08:46am 30 Jul 2023
Copy link to clipboard 
Print this post

I must admit that I didn't test it. I can't see why the CONST values should be lost though. That doesn't make sense - unless GOSUB is being simulated by the SUB mechanism of MMBasic.

Tested:
You're quite right. It doesn't work for setting CONST values, but it does work with globals. Nasty gotcha.

Easy enough to put a conditional jump at the beginning of the prog with several sets of CONST statements, I suppose. Not as neat though.
Edited 2023-07-30 19:00 by Mixtel90
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3150
Posted: 12:09pm 30 Jul 2023
Copy link to clipboard 
Print this post

  Mixtel90 said  Easy enough to put a conditional jump at the beginning of the prog with several sets of CONST statements, I suppose. Not as neat though.


This is what I did in a program I worked on with Paul_L. We wrote very different parts--he wrote the guts and I wrote the interface. The parts were very separable, and to keep from mixing our constants and variables, in the initialization phase I put a goto with a return to main.


 goto LBDefinitions ' can't gosub--definitions would be local; returns with goto Main:
 
Main: '=========================================================================


Otherwise I'm a pretty strict "Go-to statement considered harmful" guy.

~
Edited 2023-07-30 22:11 by lizby
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6798
Posted: 12:24pm 30 Jul 2023
Copy link to clipboard 
Print this post

I don't mind GOTO and GOSUB providing they are used sensibly. They can even be used in structured programming if not abused.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
toml_12953
Guru

Joined: 13/02/2015
Location: United States
Posts: 339
Posted: 11:28pm 30 Jul 2023
Copy link to clipboard 
Print this post

  lizby said  
  Mixtel90 said  Easy enough to put a conditional jump at the beginning of

 goto LBDefinitions ' can't gosub--definitions would be local; returns with goto Main:
 


~


Only CONST values are affected. Regular assignments are global in a subroutine called by GOSUB, which is consistent with the way BASIC has always worked. Traditionally, BASIC never had CONST so there was no conflict with original BASIC there.

10 A=4
20 GOSUB 100
30 PRINT A
40 END
100 A=99
110 RETURN


will print 99 rather than 4.
 
Andy-g0poy
Regular Member

Joined: 07/03/2023
Location: United Kingdom
Posts: 59
Posted: 11:17am 01 Aug 2023
Copy link to clipboard 
Print this post

  phil99 said  
  Latest Manual p89 said  A constant defined outside a sub or function is global and can be seen throughout the program.
A constant defined inside a sub or function is local to that routine and will hide a global constant with the same name


Thanks, did not spot that bit I was looking at page 24 Variables and expressions.


Andy
 
Andy-g0poy
Regular Member

Joined: 07/03/2023
Location: United Kingdom
Posts: 59
Posted: 11:34am 01 Aug 2023
Copy link to clipboard 
Print this post

  Mixtel90 said  
Tested:
You're quite right. It doesn't work for setting CONST values, but it does work with globals. Nasty gotcha.

Easy enough to put a conditional jump at the beginning of the prog with several sets of CONST statements, I suppose. Not as neat though.


It threw me for a while, mainly because I did not spot that this was the way it worked in the detail of the CONST (p89) I assumed that anything not tagged with LOCAL would be global even if in a subroutine.  Dangers of making an assumption.

What I wanted to do was create a method that would hold the setup info for a particular module which would keep it out of the way. The next module will be for a Si5351 and that will have a load of setup to do.

Keeping the setup in a sub works fine, I will just have to remember not to use CONSTs  

Andy
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9128
Posted: 11:46am 01 Aug 2023
Copy link to clipboard 
Print this post

You can put constants in the library, then they will always be available when you run your program as the library is run before other commands in your program
Edited 2023-08-01 21:47 by matherp
 
Andy-g0poy
Regular Member

Joined: 07/03/2023
Location: United Kingdom
Posts: 59
Posted: 03:26pm 01 Aug 2023
Copy link to clipboard 
Print this post

  matherp said  You can put constants in the library, then they will always be available when you run your program as the library is run before other commands in your program


Maybe, but not what I really want.  I've not looked at libraries much, and so far I cannot see how to load things into them externally, apart for write a program then convert it too a library and it all happens.

Some of the code I've developing may well be used by others (it's a VFO for Amateur Radio use. So it is likely that different users will need to make various modifications to cater for how they build things and so on. So having each module with it's own setup is a much easier way to work. I don't think the library system is built with that use in mind.

This all started when someone on the GQRP (low power communications)  group posted a link to the pico VGA, I then discovered that there was a standard type  mmbasic for the pico. I've been trying it out as a possible development system, and so far it's proving to be very good for  general projects. It's turning out to be fast and very easy. (I can't stand Python generally, it gets be cursing at it in minutes,
mainly due to the tab delimited blocks system so mmbasic looks to be a much better bet).  

This CONST issue is the first real hiccup that caught me out. It's very minor. I was using TWO constants only. As pointed out earlier basic did not have CONSTS so it's no real problem just to avoid using them - it was just a safety feature to prevent unintentional changes.  

Andy
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6798
Posted: 03:37pm 01 Aug 2023
Copy link to clipboard 
Print this post

How about using a config file and loading the variables that you need from that?
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
Andy-g0poy
Regular Member

Joined: 07/03/2023
Location: United Kingdom
Posts: 59
Posted: 12:31pm 02 Aug 2023
Copy link to clipboard 
Print this post

  Mixtel90 said  How about using a config file and loading the variables that you need from that?


Messy, and asking for trouble I think. It's not just variables. It just so happened that I used a CONST to define the pins assuming that this would be global, and if anyone tried to use the same name that they would get an error. I then found that the constant was local to the subroutine, hence this thread...  

I would use a config file if it was a lot of data, something that you would edit with a text editor such as memory channels (radio stuff) and read them into the program from an SD card. Which will happen later, as will various things for the GUI when I get around to it. This is really about config for various bit's of hardware etc.

I started with the rotary encoder - now got that running nicely as a finite state machine with the improved table method.

See: (last example in article)

https://www.best-microcontroller-projects.com/rotary-encoder.html

That needs:

pins defined and interrupts to use
a couple of variables
the state table

Once set up that's it, you would not normally need to touch it again.

However someone else may need to use different pins or even a different encoder (this one is a half step) So a little tweaking would be needed.

I was just trying for something that would be pretty much self contained and easy to use. (I dislike cluttering up the start of programs with loads of setup which you then have to skip over to get to the actual program)

Another option inspired by the conversation here would be to use a set of gotos: Would need careful management, but could be done then all things would work. However using a subroutine call is a lot easier to manage. So I'll stick with that and avoid using CONSTs in it :-)

Andy
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6798
Posted: 01:27pm 02 Aug 2023
Copy link to clipboard 
Print this post

Idea?


'Initialisation at end of program
GOTO INIT

Main:
Do
 everything
Loop

End

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

INIT:
'change the following to the encoder pins used
 CONST EncPinA = 1
 CONST EncPinB = 2
'if elephants fly change the following to INIT2
 GOTO INIT1
INIT1:
 something special here
 GOTO MAIN
INIT2:
 something alternative
 GOTO MAIN

.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4043
Posted: 01:56pm 02 Aug 2023
Copy link to clipboard 
Print this post

Untested, but if you were feeling crazy I believe you could read the CONST statements as strings from DATA and then EXECUTE them, something like:

Const config$ = "init1"
Dim cmd$
Restore config$
Do
 Read cmd$
 If cmd$ = "" Then Exit Do
 Execute cmd$
Loop

...

End

init1:
DATA "CONST EncPinA = 1"
DATA "CONST EncPinB = 2"
DATA ""


Best wishes,

Tom
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
Andy-g0poy
Regular Member

Joined: 07/03/2023
Location: United Kingdom
Posts: 59
Posted: 05:53pm 02 Aug 2023
Copy link to clipboard 
Print this post

  Mixtel90 said  Idea?


'Initialisation at end of program
GOTO INIT

Main:
Do
 everything
Loop

End

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

INIT:
'change the following to the encoder pins used
 CONST EncPinA = 1
 CONST EncPinB = 2
'if elephants fly change the following to INIT2
 GOTO INIT1
INIT1:
 something special here
 GOTO MAIN
INIT2:
 something alternative
 GOTO MAIN

.





Yes I was thinking of something similar.

goto init_thing1
init_thing1_done:

goto init_thing2
init_thing2_done:


Main:
Do
 everything
Loop

End



init_thing1:
do this that and the other
goto init_thing1_done

init_thing2:
do this that and the other
goto init_thing2_done


This way you don't have to chain the various inits in a specific order. Just goto the name and the next line has a label that they come back to.

But yes deffo for some time when feeling crazy.. mind you the SI5351 datasheets is enough to make your head spin :-)

Andy
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024