PropBASIC - Page 2 — Parallax Forums

# PropBASIC

• Posts: 14,650
edited 2018-07-17 04:24
Bean wrote: »
.... I am the developer of PropBasic and I use it everyday.
If you have any further questions feel free to ask on the forums and I will help as much as I can.

There has been some fixes to PropBasic and I'll have to post a new version since it looks like at least some people as still using it.

Given this thread, I had a quick check of PropBASIC and commands / error parsing.

I find a quirk in the file-name parsing, where a full/absolute file is ok, but in a batch file a partial name-only fails ?

ie This works
..\src\PropBasic "%~dp0Freq Counter3.pbas"
where %~dp0 is fixup bandaid,
but this fails, seems to lack a \ between constructed path and file name ?
..\src\PropBasic "Freq Counter3.pbas"

Most editor params will be of either the $(FULL_CURRENT_PATH) type, or of$(NAME_PART)

I also had a quick trial of NppExec, which is a console error parser for NotePad++, and I can get that to work with FreeBasic error format, which is
COM4_Test.bas(50) error 14: Expected identifier, found 'StringTT' in 'Dim b As StringTT'
COM4_Test.bas(98) error 180: Invalid assignment/conversion in 'b = Input(LOC(1), 1)'

There is an active FreeBASIC IDE called poseidonFB here https://www.freebasic.net/forum/viewtopic.php?t=23935

That seems quite active, and keywords look easy to modify.
It also seems to parse the FreeBASIC error outputs of the form, and nicely inserts red error tag lines in the source window.
COM4_Test.bas(50) error 14: Expected identifier, found 'StringTT' in 'Dim b As StringTT'
COM4_Test.bas(98) error 180: Invalid assignment/conversion in 'b = Input(LOC(1), 1)'

using this filter:
%FILE%(%LINE%) *error*

(and it can also use %CHAR% to char locate the error cursor too.)

However, PropBASIC seems to export differently to the console
Using /Q I can reduce to

ERROR 23 COULD NOT READ SOURCE FILE "/Q" ;
ERROR 18 NO "PROGRAM" COMMAND USED ;
- but that lacks File name, Line, Char index info.

By using /VP param, I can get this in an error file
ERROR,C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.bas,26,10,UNKNOWN COMMAND "DOx"
ERROR,C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.bas,116,16,LOOP WITHOUT DO "LOOP"

Similar, but different... & neither NppExec nor poseidonFB.exe can read error files, they expect to grab the console output.

26 & 116 here look to be the %LINE% info NppExec can swallow, not sure what 10 & 16 are - not quite char positions ? - perhaps are error code # ?

An educated guess of a NppExec parser for that file-reported-to-console would be
ERROR,%ABSFILE%,%LINE%,


My suggestion would be to add an option to report errors in FreeBASIC error message format, so the various FreeBASIC IDE's can be trialed for Prop BASIC
• Posts: 14,650
edited 2018-07-17 04:36
Some small correction & examples to have PropBASIC callable from within Notepad++, (Using NppExec plugin) and to have click-error-jump work

This filter allows NppExec to click-jump-to-error-line, which is highlights in the console capture window
ERROR,%ABSFILE%,%LINE%,*


and this NppExec param calls a batch file..
C:\Lazarus\PropBASIC\RecipCounter\Npp_PropBASIC.BAT "$(CURRENT_DIRECTORY)\$(NAME_PART)"


works with this Npp_PropBASIC.BAT batch file, in the source dir,
CD %~dp0
C:\Lazarus\PropBASIC\src\PropBasic.exe %1.pbas /VP
TYPE %1.err


creates this C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.err ( Exec when Active Editor Window is Freq Counter3.pbas )
ERROR,C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.pbas,34,10,UNKNOWN COMMAND "DOy"
ERROR,C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.pbas,116,16,LOOP WITHOUT DO "LOOP"


and the total Notepad++ console report is this
C:\Lazarus\PropBASIC\RecipCounter\Npp_PropBASIC.BAT "C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3"
Process started (PID=13792) >>>

1  ' Frequency counter (0.5 Hz to 40 MHz)
2  ' Counts frequency on P0, sends ASCII to PC at 115200 Baud
3  ' 1.0 Second gate time (gate time will be longer if frequency is < 2 Hz)
4  '
5  DEVICE   P8X32A, XTAL1, PLL16X
6  XIN      5_000_000
7
8  BAUD     CON "T115200"   ' Baud rate for PC communications
9
10  Signal   PIN 0 INPUT     ' Input pin for signal
11  TX       PIN 30 HIGH     ' Output pin for PC communications
12
13  cntStart VAR LONG        ' "cnt" value at start of measurement
14  cntTime  VAR LONG        ' elapsed "cnt" clocks
15  sigCnt   VAR LONG        ' count of how many input pulses have been received
16  temp     VAR LONG        ' loop counter
17  digit    VAR LONG        ' current digit
18  digitSum VAR LONG        ' Used for leading zero removal
19  ascii    HUB STRING (20) ' Holds ascii representation of frequency
20
21  PROGRAM Start            ' Start program at label "Start:"
22
23
24  Start:
25    COUNTERA 80, 0, 0, 1, 0 ' Count positive edges on pin 0
26    DO
27      ' Wait for a signal pulse to syncronize to the system counter
28      WAITPNE Signal, Signal
29      WAITPEQ Signal, Signal
30      phsa = 0
31      cntStart = cnt - 4
32
33      ' Count input pulses until 1.0 seconds have elapsed
34      DOy
ERROR 10  UNKNOWN COMMAND "DOy"  ;     DOy
35        WAITPNE Signal, Signal
36        WAITPEQ Signal, Signal
37        sigCnt = phsa
38        cntTime = cnt - cntStart
39      LOOP UNTIL cntTime > 80_000_000 ' 1.0 Second gate time
40      cntTime = cntTime - 4 ' To account for "sigCnt = phsa" instruction
41
42      ' Calculate  frequency if >= 0.5 Hz
43      IF cntTime <= 160_000_000 THEN
44
45        ' Since cntTime is in 80MHz units, the frequency is sigCnt / (cntTime / 80_000_000) = Hertz
46        ' Rearranged this can be written as (sigCnt * 80_000_000) / cntTime = Hertz
47        '
48        ' We want the result in milliHertz (1/1000 of a hertz) so we need to use:
49        ' (sigCnt * 80_000_000_000) / cntTime = milliHertz
50        '
51        ' Okay, now we have a problem, 80_000_000_000 cannot even be represented in 32 bits. Hmmm
52        ' What if we calculate the answer one digit at a time...
53        '
54        ' The leftmost digit is MegaHertz and that digit can be calculated as:
55        ' (sigCnt * 80) / cntTime = MegaHertz. This we can do easily.
56        '
57        ' Now the "trick" is how do we get the next digit ?
58        ' We take the remainder from the division, multiply it by 10 and divide again.
59        '  by repeating this process of taking the remainder and multipling by 10 we
60        '  can get as many digits as we need until we run out of precision.
61        '
62        digitSum = 0                 ' Sum of all digits so far. Used to create replace leading zeros with spaces
63        ascii = ""
64        sigCnt = sigCnt * 8          ' Scale signal count to get MegaHertz digit
65
66        FOR temp = 0 TO 13           ' 7 digits + decimal point + 3 digits = 11 digits
67
68          digit = sigCnt / cntTime   ' Calculate this digit of result
69          sigCnt = __remainder       ' Keep remainder for next digit
70
71          __temp1 = sigCnt * 2       ' sigCnt = sigCnt * 10
72          sigCnt = sigCnt * 8        ' Scale signal count for next digit
73          sigCnt = sigCnt + __temp1
74
75
76          INC digitSum, digit        ' Add this digit's value to sum
77          digit = digit + "0"        ' Convert digit to an ascii digit
78
79
80          ' If this is a leading zero, make it a space
81          IF temp < 9 AND            ' Only use leading spaces for digits higher than the units digit
82           digitSum = 0 THEN         ' If the sum is zero, then we have only had "0" digits so far
83            digit = " "              '  so use a space instead of a "0" for this digit.
84          ENDIF
85
86          WRBYTE ascii(temp), digit  ' Put digit into the result string
87
88          ' Insert a comma if needed
89          IF temp = 1 OR
90           temp = 5 THEN
91            INC temp
92            IF digitSum = 0 THEN
93              WRBYTE ascii(temp), " "
94            ELSE
95              WRBYTE ascii(temp), ","
96            ENDIF
97          ENDIF
98
99          ' Insert decimal point at proper place
100          IF temp = 9 THEN           ' If we just processed the units digit,
101            INC temp                 '  move pointer to the next character in the result string
102            WRBYTE ascii(temp), "."  '  and make it a decimal point
103          ENDIF
104
105        NEXT                         ' Process all digits
106
107        WRBYTE ascii(14), " ", "H", "z", 13, 0
108
109      ELSE
110        ascii = "Too low (< 0.5Hz)"
111        ascii = ascii + 13
112      ENDIF
113
114      SEROUT TX, BAUD, ascii       ' Send frequency to terminal
115
116    LOOP                           ' Repeat forever
ERROR 16  LOOP WITHOUT DO "LOOP"  ;   LOOP                           ' Repeat forever
117
118  SetDAC SUB 1
119  SetDAC 1
120  SUB SetDAC
121  ' code to set DAC
122  value VAR LONG
123  value = 100
124  Again:
125    HIGH TX
126    LOW TX
127  DJNZ value, Again
128
129  ENDSUB
130
131  SetDAC_ FUNC 1
132  'myVar = Calc 1
133  FUNC SetDAC_
134  __param1 = __param1 + 1
135  RETURN __param1
136  ENDFUNC
137  END

PropBasic Version 00.01.44 Jul 13, 2014
Finished Compile. 137 Lines Read, 258 Lines Generated,  0 Warnings, 2 Errors.
ERROR,C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.pbas,34,10,UNKNOWN COMMAND "DOy"
ERROR,C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.pbas,116,16,LOOP WITHOUT DO "LOOP"
<<< Process finished (PID=13792). (Exit code 0)


The two ERROR, lines are highlighted in red, and mouse click jumps to that source line, in the editor window.
• Posts: 14,650
jmg wrote: »
There is an active FreeBASIC IDE called poseidonFB here https://www.freebasic.net/forum/viewtopic.php?t=23935

That seems quite active, and keywords look easy to modify.
It also seems to parse the FreeBASIC error outputs of the form, and nicely inserts red error tag lines in the source window.
COM4_Test.bas(50) error 14: Expected identifier, found 'StringTT' in 'Dim b As StringTT'
COM4_Test.bas(98) error 180: Invalid assignment/conversion in 'b = Input(LOC(1), 1)'
I tested this PoseidonFB IDE some more, and replace the FBC.EXE compiler path with a PropBASIC build batch file.

That works, but reveals that the PoseidonFB IDE does not use errorlevel tests for success, instead it uses the inbuilt console error parser.
If it extracts no error lines, it reports no errors.

With the fixed console or error file reporting, this batch file should work, under Compile File.
PoseidonFB IDE calls as Parameters -b,"C:/Lazarus/PropBASIC/RecipCounter/Freq Counter3.pbas"
CD %~dp0
C:\Lazarus\PropBASIC\src\PropBasic.exe %2 /VP
IF %ERRORLEVEL% NEQ 0 (
TYPE "%~dpn2.err"
) ELSE (
)


• Posts: 445
@ JonnyMac
I don't publish my code for fear of embarrassment and mockery from the language wars pseudo intellectuals.
That made me giggle. I wish you would share code -- it would probably benefit people like me who favor something else and may have missed an opportunity. Maybe we just need to be shown the way.

I think we should use the tools we feel comfortable with no matter what others think. If we get satisfactory results that way (and you certainly do) then what is the problem. Certainly there are many on this message board that have a greater/ faster/ ability to absorb and implement new ways than I. My very first language was tiny basic then 8080 assembler, then assembler in 8051, 6502, Z8, 68000, avr etc but ALL the time was using Basic in its various incarnations as a high level language. For a while had success with Arduino 'C', but wasn't comfortable.
I recently retry'd working with python. I started to get results but then wanted to get a key from the keyboard. Oh boy. What a can of worms that turned out to be- I searched hi and lo googled all over the place and eventually gave up. Life's too short. Now there is NOTHING WRONG with Python- it just doesn't fit in with my set in ways of thinking. So I use what works for me.
To my way of thinking ANYTHING that works for you is good.

Jon- you clearly have more smarts than me- I don't think I can show you the way- you are clearly successful doing what you do.

But I do love PropBasic; its the only way for ME to achieve useful results in reasonable time on the Prop.

Dave

• Posts: 8,122
jmg, I am open to supporting some kind of IDE. But I am really busy at work.
If you could let me know exactly what would need modified to support any particular IDE.

Bean
• Posts: 3,544
I just tried the toggle LED program on the FLiP module, for pin 26 and then 27, they did not work. And then just to very the program, I tried it on the Activity Board, that worked.

Not sure why it is not working with the FLiP module. Can somebody verify this.

Ray
• Posts: 2,360
For reference, this is the code that worked for me with the FLiP module

flash-led.pbas
DEVICE P8X32A

LED PIN 26 OUTPUT

PROGRAM Start

Start:
TOGGLE LED
PAUSE 1000
GOTO Start

• Posts: 14,650
edited 2018-07-17 22:45
Bean wrote: »
jmg, I am open to supporting some kind of IDE. But I am really busy at work.
If you could let me know exactly what would need modified to support any particular IDE.

Sure.
1) as user gh-jmg, I've uploaded changes to github PropBASIC to add /FB switch, that seems to work ok. PoseidonFB IDE now extracts reported errors

2) Less critical, is the bug fix to the command line, where a filename.bas fails, in current dir, but c:\full\path\to\file.pbas is ok - I'll look at that later.

Addit: fixed 2), so this line now compiles ok
..\src\PropBasic.exe "Freq Counter3.pbas" /FB

• Posts: 14,650
PoseidonFB IDE screen grab
• Posts: 4,159
edited 2018-07-18 01:44
@tritonium - Many here have encouraged me to publish my code without fear. If it works, it works.

Studying other people's code and having them study and comment on yours can help us all learn!

Glad to see Bean still supporting PropBASIC - I am UP for any way into using the Propeller - Spin, PASM, C, PropBASIC, or now BlocklyProp!

That is one of the reasons I enjoy BlocklyProp so much - Easy access for beginners - All the fun of programming without the worries of exact syntax!
• Posts: 575
I downloaded the contents of several PropBASIC libraries that were referenced above for study but all of them, except for the basic shells, require additional code loaded from libraries that I could not locate.

I am interested in teaching myself to use mathematics on one COG, servo controls on another, and One-Wire data acquisition on a third for example.

I acquired a laptop that is dedicated to PropBASIC program development so I would like to download all the necessary libraries that support my teaching interests.

Sincerely,

Discovery
• Posts: 575
Bean and McPhalen,

I began my pBASIC language learning program by running the LED toggle program including other features on my Propeller Activity Board. Then I began entering library programs suggested by forum users which include Delays, I2C, One-Wire, Keyboard and others. My approach is to get each of the suggested libraries working by calling them into the LED toggle program and using them.

My first library attempt is the Delay Library by Jon McPhalen. The compiler spits out ERROR 5 INVALID PARAMETER for the following line of code: PAUSE __parameter1. The compiler also spits out the same error for PAUSEUS __param1 in the Subroutines.

What should be the actual code?

Sincerely,

Discovery
• Posts: 7,554
edited 2018-07-23 04:50
As I told you, I haven't used PropBASIC in a long time. Those libraries worked when I wrote them -- things have changed, most certainly for the better, but I haven't adapted. I think that Bean said somewhere that the PAUSE commands were already turned into subroutines, so that library may be useless at this point. Back when I wrote that code, every PropBASIC command was compiled in place; I created the libraries to reduce redundant code.

I just started a new job so I don't know when I'll be able to try PropBASIC again.
• Posts: 1,856
Discovery wrote: »
Bean and McPhalen,

I began my pBASIC language learning program by running the LED toggle program including other features on my Propeller Activity Board. Then I began entering library programs suggested by forum users which include Delays, I2C, One-Wire, Keyboard and others. My approach is to get each of the suggested libraries working by calling them into the LED toggle program and using them.

My first library attempt is the Delay Library by Jon McPhalen. The compiler spits out ERROR 5 INVALID PARAMETER for the following line of code: PAUSE __parameter1. The compiler also spits out the same error for PAUSEUS __param1 in the Subroutines.

What should be the actual code?

Sincerely,

Discovery

Don't have my Prop system with me but you are passing a value to Delay, right?

• Posts: 575
Jon...no problem.

Mickster...that's what I was expecting to take place.

If someone uses pBasic regularly and has loadable, workable libraries that include one-wire, I2C, and mathematics...it would be helpful to gain access to those libraries.

Sincerely,

Discovery
• Posts: 8,122
Discovery,
I am really busy at work right now, so I don't have time to make any libraries.
I would suggest just using the built-in 1-wire and I2C commands to get more comfortable with how PropBasic works.
If you run out of code space you can switch to LMM mode (large memory model) by simply putting LMM on the PROGRAM line like:
PROGRAM Start LMM


Bean
• Posts: 575
Hi Bean,

I understand you are really busy at the moment. I will use the built-in I2C and One-Wire commands and get familiar with writing code into the Large Memory Mode.

When you are less busy, would you address a library of sine, cosine, exponential, etc. math functions?

Sincerely,

Discovery
• Posts: 575
This is Terrific!

For the first time, I am able to program the Propeller in the Basic Programming Language. Several programs were written to control machinery and devices such as an HVAC unit by setting value1 to be below Low Level Set Point, above the High Level Set Point, or between the two. value1 VAR LONG

This type variable can only handle integers...how can I set variables to handle real numbers such as 25.4 for example?

Sincerely,

Discovery
• Posts: 8,122
Use "Fixed Point Format".

You just multiply everything by a set amount.
For example your variable might hold 1/100 of a volt instead of 1 volt.
So for example 100 would be 1 volt, and 123 would be 1.23 volts.
You just need to remember to multiply everything by the same amount.

Another example is using cents instead of dollars, so if something is \$12.34 the variable would hold 1234.

If the units can be whatever you want, it is easiest to make the units multiples of a power of 2. A common one is 256.
So if you were using volts 1.23V would be stored as 315 (1.23 * 256). This way displaying the value is easier.
You shift right by 8 and print the whole value, then print the ".", then AND the original value with 255, multiply by 100 and shift right by 8 and print.

Bean
• Posts: 575
Excellent Bean,

How do I print?

Discovery
• Posts: 2,360
You might want a serout command. Have you seen this library? It contains tx-rx commands...

http://forums.parallax.com/discussion/163372/propbasic-libraries

• Posts: 575
Thank you,

That should solve my problem.

Discovery
• Posts: 1,856
Discovery wrote: »
This is Terrific!

Tell me about it...But don't tell anyone else because it's our secret weapon

TerryHittific?

• Posts: 1,856
edited 2018-07-26 23:09
Discovery wrote: »
Hi Bean,

I understand you are really busy at the moment. I will use the built-in I2C and One-Wire commands and get familiar with writing code into the Large Memory Mode.

When you are less busy, would you address a library of sine, cosine, exponential, etc. math functions?

Sincerely,

Discovery

Just came across this...
• Posts: 575
Mickster,

Thanks for the information. My self-learning course on pBASIC has reached the point of loading LIBRARY files. Just for grins I ran the compiler on the DELAY library and got errors on the __param1 variable but noticed that it was not defined as such in the library code.
When I ran the source program with the load DELAY library...the library file loaded fine but the compiler called out the same error in the library code that was inserted into the source program code. I think it is neat that the pBASIC loads the library codes then does the error check on each one.
So, am I correct in assuming that the library codes must be altered so that the variables used in the library code match those in the calling routine source program or are defined in the calling routine?

Discovery
• Posts: 575
Bean,
What is the significance of double underlined variables such as __param1 in libraries other than global variables?

Discovery
• Posts: 8,122
Discovery wrote: »
Bean,
What is the significance of double underlined variables such as __param1 in libraries other than global variables?

Discovery

They are system declared variables. They exist even though you haven't declared them.
They are prefixed with a double underline so that they don't conflict with your programs variable names.

Bean
• Posts: 575
Thank you...I though so but wondered if they had any other properties.

Discovery
• Posts: 1,856
Discovery wrote: »
Mickster,

Thanks for the information. My self-learning course on pBASIC has reached the point of loading LIBRARY files. Just for grins I ran the compiler on the DELAY library and got errors on the __param1 variable but noticed that it was not defined as such in the library code.
When I ran the source program with the load DELAY library...the library file loaded fine but the compiler called out the same error in the library code that was inserted into the source program code. I think it is neat that the pBASIC loads the library codes then does the error check on each one.
So, am I correct in assuming that the library codes must be altered so that the variables used in the library code match those in the calling routine source program or are defined in the calling routine?

Discovery

I haven't used libraries or any sample code, for that matter. Just my own code and I use Viewport for my editor/debugger. The built in scope is a HUGE help.
• Posts: 8,122
Discovery wrote: »
Thank you...I though so but wondered if they had any other properties.

Discovery

__temp1, __temp2, __temp3, __temp4 are used by some PropBasic commands. Be very careful about using these...

__param1, __param2, __param3, __param4 as used to pass parameters to subroutines and functions.

You can use __param as temporary variables as long as you don't call any subroutines or functions.

A common pitfall is using __param1 in a subroutine, but if that subroutines calls another subroutine (with parameters) it will lose it's value.

For example:
SUB SendStr
' __param1 holds address of the string
DO
RDBYTE __param1, __param2 ' Get a character from the string
IF __param2 = 0 THEN EXIT
SendChar __param2
INC __param1
LOOP
ENDSUB


The reason the above code will not work, is when you call "SendChar __param2" the SendChar subroutine needs the character in __param1, so the compiler will generate.
  MOV __param1,__param2
CALL SendChar


So the value in __param1 will be lost during the first call to SendChar.

The solution is to to this:
SUB SendStr
__param2 = __param1
' __param2 holds address of the string
DO
RDBYTE __param2, __param1 ' Get a character from the string
IF __param1 = 0 THEN EXIT
SendChar __param1
INC __param2
LOOP
ENDSUB


Also __temp4 is aliased as __remainder and holds the remainder from any division operation.

There is also __paramcnt which is used for subroutines that can have a variable number of parameters. These are rare, so this is probably the safest one to use for temporary use.

Bean