Array Size Limits /AH under WinXp

If you have questions about any aspect of QBasic programming, or would like to help fellow programmers solve their problems, check out this board!

Moderators: Pete, Mods

Post Reply
User avatar
Stevo22
Coder
Posts: 10
Joined: Wed Oct 15, 2008 6:38 am
Location: Melbourne, Australia

Array Size Limits /AH under WinXp

Post by Stevo22 »

Hi Guys,

I understand there is a size limit to Arrays.

I want to load up data from a file into elements of an array so I can access the data quicker but I get the "subscript out of range" error.

From what I have already read the max. array size is 64KB and the values range from -32768 to 32767. I need more than double this.

I've tried using the /AH switch, but it doen't seem to make any difference.

Perhaps because I'm running qb45 under windows xp.

Any ideas?

I'll try running it through DosBox (prolly should have tried b4 posting :)

Steve.
Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Post by Ralph »

Stevo22:

Using XP Home Editon with service pack 2 and QuickBASIC 4.5 with the 'ah switch, I got the maximum number of elements as 86999, due to the available memory. I don't know if I can get more memory for QB than this, or, if I can, how. Perhaps, you can obtain a higher number of elements for a two-dimensional array?

Code: Select all

CLS
FOR a = 80 TO 1000
  FOR b = 1 TO 1000
    REDIM A(a,b)
    PRINT a;b;a*b
'Out of memory error at a = 86, b = 999, or 86999 total array elemets
 
EDITED LATER:
Repeating the program above, with DEFINT, DEFLNG, DEFSNG, and DEFDBL, I get:
Integer: Overflow error, 32,767, elements or 32,767*2 = 65,534 bytes
Long or single: Out of memory error, 86,999 elements = 86,999*4 = 347,996 bytes
Double: Out of memory error, 43,988 elements = 43,988*8 = 351,904 bytes
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish
User avatar
burger2227
Veteran
Posts: 2466
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

Quicker?

Post by burger2227 »

My advice is to save as much memory as possible by not pushing Array limits! Reading data from a file is better than trying to load a "TON" of information all at once.

Usually you will not need all of the data at once either, so use the file and save yourself a lot of agony...........Learn to parse data info!

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0
User avatar
Stevo22
Coder
Posts: 10
Joined: Wed Oct 15, 2008 6:38 am
Location: Melbourne, Australia

Post by Stevo22 »

Ok thanks.

As usual, I tend to over complicate matters :wink:

DosBox didn't work either so I have since abandoned the idea of using arrays for this purpose and have (as Ted suggests) converted the data I had into a random access file so the data can be read off (using GET) at any location in the file. This seems to be working fine.

BTW: What's the difference between GET[#] and SEEK[#] it looks like it does the same thing. Is one method quicker?

Providing I can read the records off the file sequentially, and at any point(er), read them off in reverse order from that point(er), I'm in good shape, and I think I have achieved this.

My next challenge will be controlling the flow using conditionals and keyboard input.

Now I need to write down in "english" format exactly what has to happen, before I can determine which method is best - ie. INKEY$, ON(KEY) or INP() I've done some reading up but I'm still a bit confused, so when I work out exactly what I need to happen, I'll try myself first and if I get stuck I'll post some questions.

Steve.
User avatar
burger2227
Veteran
Posts: 2466
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

Post by burger2227 »

GET is used to read file information to a variable. You can GET consecutive data without a position reference if you are reading a Binary file from the start. Thus you can use GET #1, , variable for same types of data.

Random files use record fields of data. One line may hold many different types of data. Such as name$, address$, age%, etc.

There are two SEEK functions you can use. SEEK(1) returns the present record position, while SEEK #1, 32 goes to the 32nd record.

I normally use a TYPE definition for random files and grab the entire line of data using one TYPE variable. You can combine different variable types and find the data you need using DOT variables from the Type definition.
Such as: GET#1, 32, MyType. Then perhaps use MyType.Name to get a person's name.

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0
User avatar
Stevo22
Coder
Posts: 10
Joined: Wed Oct 15, 2008 6:38 am
Location: Melbourne, Australia

Post by Stevo22 »

Thanks Ted,

You must be burning the Midnight Oil :D

I think I understand now - that method would be appropriate for a database.

The file I'm reading the data off is simply an ascii text file containing approx. 12,500 lines of numbers (integers) These numbers (ranging from about 20 - 2000) are read into a variable in a for/next loop and when the next condition is reached, branches out to pulse the stepper. The next sequential number is read and so on...

Each number is different and that's how I get the acceleration for the stepper (as per the graph in my avatar) The file needs to be read backwards for the deceleration, and also read forward or backward in sequence at any position in the file depending on which key was pressed.

eg. Condition neutral, Left arrow key pressed, start acceleration, lift off left arrow key, decelerate from that position.

In other words, there is no point going through the entire acceleration phase if the key is lifted off half way through.

I was originally hoping I could use the ascci file as is but I couldn't get it to read backwards using INPUT [#]

Steve.
Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Post by Ralph »

Ted is the man! He will get you on the right track. However, I have a question...

From yourvarios possts, I got theimpression that you need to process more than twice the 64K array limit you postulated. From your need for acceleration and decelaration, I would venture to say that you only need a very few actual numbers, certainly under 50 pairs of coordinates, to produce a very accurate acceleration/de-celaration curve. I'm puzzled.
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish
User avatar
burger2227
Veteran
Posts: 2466
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

True Ralph

Post by burger2227 »

There should be some kind of algorithm to determine the values directly in the program without the need for all of that data.

After all, how did you create the graphical curve in the first place? How did you get the data for the file?

One problem is that QB can only time accurately down to .05 seconds. If you are just relying on counter loops to time it, the speed will vary on different speed machines. Today most programmers use TIMER loops to avoid that problem.

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0
markm
Coder
Posts: 14
Joined: Thu May 01, 2008 11:08 am

Stacks and Queues

Post by markm »

Stevo, if you don't have to back up too far, you could save the file in a circular queue in RAM as you go forwards, overwriting the oldest data as needed, then use the queue to back up.

Sorry, I don't have time to explain further today. I learned the techniques from a 30 or 40 year old dead-tree source, Knuth's Art of Computer Programming, the chapter on stacks and queues. See if you can find this or other reference material on the web.

One other thing you could do is to re-process your file to have fixed-length lines. Then you can SEEK one line back, or any number of lines either direction. It's like a "database" with one string per record.
User avatar
Stevo22
Coder
Posts: 10
Joined: Wed Oct 15, 2008 6:38 am
Location: Melbourne, Australia

Post by Stevo22 »

Ted wrote:There should be some kind of algorithm to determine the values directly in the program without the need for all of that data.
Yes indeed Ted, there should be an algorithm. I've been googling but are yet to find something usable. I think the algorithm/equation should solve for a parabola (or part of) Some stuff I've seen invloves quadratic equations (whatever they are :? ) and look very complicated.
Ted wrote:After all, how did you create the graphical curve in the first place? How did you get the data for the file?
The curve data was created as per the method below.
In a previous post I wrote:We have actually achieved this accel/decel curve using a rather unconventional "clever but lazy" method. We used Audio editing software and created a square wave from aprox. 2Hz to 2kHz - saved the file as raw data and imported it into a simple qb program that detects the leading edge of each square wave. This data is then used as reference to how many clock cycles the computer will do before giving the stepper a pulse - Works absolutely perfectly.
The timing can be fine tuned by using a multiplying number.
Ted wrote:One problem is that QB can only time accurately down to .05 seconds. If you are just relying on counter loops to time it, the speed will vary on different speed machines. Today most programmers use TIMER loops to avoid that problem.
No probs Ted, relying on the computers clock cycles is exactly what we are doing. (that's why we ditched windows)
The program is not for general release, so it doesn't matter that much - we have an old pentium just for the job. Nevertheless, the timing can be adjusted by the multiplying number, so it probably could be run on different computers. The critical part of the timing is the tracking speed and this was checked and adjusted using a frequency counter.
Ralph wrote:I would venture to say that you only need a very few actual numbers, certainly under 50 pairs of coordinates, to produce a very accurate acceleration/de-celaration curve.
I'm confused Ralph. The stepper motor we are using does 400 steps per revolution. 50 steps would give you an 8th of a turn (hardly going anywhere) My file has about 12500 numbers which equals approx 31 full revolutions - starting at approx. 1/2 a rev per sec, ramping up to about 5-6rps. The pulse width/timing is divided up as shown in my avatar graph.
It works perfect - nice and smooth - no sudden jumps.
Or am I misunderstanding what you are saying Ralph - I'm all for simplicity - Please elaborate.
markm wrote:One other thing you could do is to re-process your file to have fixed-length lines. Then you can SEEK one line back, or any number of lines either direction
Thanks markm, this sounds like it would work but I'm happy with the random access file method.

Cheers, Steve.
Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Post by Ralph »

Stevo22 wrote:
Ralph wrote:
I would venture to say that you only need a very few actual numbers, certainly under 50 pairs of coordinates, to produce a very accurate acceleration/de-celaration curve.
I'm confused Ralph. The stepper motor we are using does 400 steps per revolution. 50 steps would give you an 8th of a turn (hardly going anywhere) My file has about 12500 numbers which equals approx 31 full revolutions - starting at approx. 1/2 a rev per sec, ramping up to about 5-6rps. The pulse width/timing is divided up as shown in my avatar graph.
It works perfect - nice and smooth - no sudden jumps.
Or am I misunderstanding what you are saying Ralph - I'm all for simplicity - Please elaborate.
What i meant was taht, to draw the curve you dhow would probably take less than 50 pairs of coordinates.

However, only you can know what works for your specific need. For instance, you state that it takes agout 12,500 numbers for approx. 31 full revolutions. This information seems to me to be only a part of the problem, as you do not state how many refolutions you need to move your telescope a given angle. So, more pertinent would be something like, "It takes 1000 numbers to move the telescope one degree, and we need to have one, full 360 degree movement (or, maybe, ten days of 360 movement", or some such description of input and output.

You also state that you have achieved a nice, smoote movement, which I interpret as having achieved your goal. And, since you seem to indicate that you really need this program only for your own, private use, I would think that you would not want to put too much more time in it to obtain a more elegant solution or, even, some reduced code. But, of course, you just might want to perfect your code. In this case, you will undoubtedly be getting more responses to your questions.

If you think that a mathematical equation of a curve can be of help to you, you will have to post a sufficient number of data to submit to a "best fit" equatin-producing program. I have one that will give a result for a polynomial equation with a power as high as 14. My experience with that program has led me to believe that more than a power of 3 is most frequently impractical; Excel allows a solution of up to power 6. So, I, for one, wil be happy to see what kind of curve is obtainable with your data, and how accurate it represents the data. Just post the data!
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish
User avatar
burger2227
Veteran
Posts: 2466
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

Post by burger2227 »

Please don't post the data! It will take up too much space.

Since you are using the parallel port to drive the motor, you can use the 8 data pins for different speeds. Make sure that those bits are cleared at reboot! Otherwise the motor will start running perhaps. You could use the Control pin C3 to stop the circuit at startup. It goes high at startup, but is inverted to 0. A relay can be used to enable the circuit using an optical converter. An LPT cannot drive a relay! To enable your circuit just OUT 890, INP(890) XOR 8. To stop it use OUT 890, INP(890) OR 8.

Now for the speed. When a key is pressed, increase the data pin values.
OUT 888, 2 ^ speed where speed is an integer of 0 to 7. This converts that to binary bit values.

Now set up 8 timer circuits (555 or 556 dual) with increasing frequencies on a board.

Use AND gates to change the pulse speed by comparing the data pin voltage to the appropriate 555 timer output. When the key is lifted, decrease the exponents so that you end with OUT 888, 0. You can time the increases and decreases with a TIMER loop probably.

Ted

PS: Don't try using high currents on an LPT port.
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0
User avatar
Stevo22
Coder
Posts: 10
Joined: Wed Oct 15, 2008 6:38 am
Location: Melbourne, Australia

Post by Stevo22 »

Ralph wrote:If you think that a mathematical equation of a curve can be of help to you, you will have to post a sufficient number of data to submit to a "best fit" equatin-producing program. I have one that will give a result for a polynomial equation with a power as high as 14. My experience with that program has led me to believe that more than a power of 3 is most frequently impractical; Excel allows a solution of up to power 6. So, I, for one, wil be happy to see what kind of curve is obtainable with your data, and how accurate it represents the data. Just post the data!
Ok Ralph, here is a low resolution version of the data. It produces a similar graph (in qplot) but the start is not exactly the same angle (not as sharp) as the larger file. Hope this is of use - I'll be very interested to see what you come up with.

Code: Select all

0 128  227  311  385  451  513  570  624  674  723  769  813  856  897  937  975  1013  1049  1085  1119  1153  1186  1218  1250  1281  1312  1341  1371  1400  1428  1456  1483  1510  1537  1563  1589  1615  1640  1665  1690  1714  1738  1762  1785  1809  1831  1854  1877  1899  1921  1943  1964  1986  2007  2028  2049  2070  2090  2110  2131  2151  2170  2190  2210  2229  2248  2267  2286  2305  2324  2342  2361  2379  2397  2415  2433  2451  2468  2486  2503  2521  2538  2555  2572  2589  2606  2623  2639  2656  2672  2689  2705  2721  2737  2753  2769  2785  2801  2817  2832  2848  2863  2879  2894  2909  2925  2940  2955  2970  2985  3000  3014  3029  3044  3058  3073  3087  3102  3116  3130  3144  3159  3173  3187  3201  3215  3228  3242  3256  3270  3283  3297  3311  3324  3338  3351  3364  3378  3391  3404  3417  3430  3444  3457  3470  3483  3495  3508  3521  3534  3547  3559  3572  3585  3597  3610  3622  3635  3647  3659  3672  3684  3696  3708  3721  3733  3745  3757  3769  3781  3793  3805  3817  3829  3840  3852  3864  3876  3887  3899  3911  3922  3934  3945  3957  3968  3980  3991  4003  4014  4025  4037  4048  4059  4070  4082  4093  4104  4115  4126
Thanks Ted for that info.

Sounds very interesting. I'm not that great on the electronics side of things so I'll see what my brother thinks since he's into electronics and he was the instigator of the project (I'm only doing the programming side).

One question though, you say "where speed is an integer of 0 to 7" - does that mean there are only 7 steps of different speeds, or do the timer circuits smooth this out?

Steve
User avatar
Stevo22
Coder
Posts: 10
Joined: Wed Oct 15, 2008 6:38 am
Location: Melbourne, Australia

Post by Stevo22 »

Whoops! - Sorry Ralph, I neglected to tell you that the data is "Y" data only. The "X" data would be 0-201. X Being steps of ???? time I think - Just Units is ok providing they are evenly spaced. I don't think that part matters too much. I also apologise that the data is space delimited, but I wanted to save space.

I've also included below the data that was used to create the last data.
The previous data is an incremental accumulation of this data, ie. 0 is added to 128, 128 is added to 99 and that number is added to the next and so on. Otherwise the Graph would not plot correctly.

The Acceleration Data below is the data used in the program for 'delay' before pulsing the stepper. Remember my original file (12500 steps) well this one is 201 steps - I'd be happy to email you that file if you wanted - I'd like someone to make some mathematical sense of it all. :P

It would be good to have an equation that I could use instead of the data. ... Not necessary -- but just good :wink:

Steve.

Code: Select all

 0 128 99 84 74 66 62 57 54 50 49 46 44 43 41 40 38 38 36 36 34 34 33 32 32 31 31 29 30 29 28 28 27 27 27 26 26 26 25 25 25 24 24 24 23 24 22 23 23 22 22 22 21 22 21 21 21 21 20 20 21 20 19 20 20 19 19 19 19 19 19 18 19 18 18 18 18 18 17 18 17 18 17 17 17 17 17 17 16 17 16 17 16 16 16 16 16 16 16 16 15 16 15 16 15 15 16 15 15 15 15 15 14 15 15 14 15 14 15 14 14 14 15 14 14 14 14 13 14 14 14 13 14 14 13 14 13 13 14 13 13 13 13 14 13 13 13 12 13 13 13 13 12 13 13 12 13 12 13 12 12 13 12 12 12 13 12 12 12 12 12 12 12 12 12 11 12 12 12 11 12 12 11 12 11 12 11 12 11 12 11 11 12 11 11 11 12 11 11 11 11
User avatar
burger2227
Veteran
Posts: 2466
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

Post by burger2227 »

Steve, if you count from 0 to 7 you get 8 numbers. You will have to remember that when working with 0 based arrays.

You would have 8 different speeds plus the OUT 888, 0 for stop. When all data pins are logic 0 (off) the motor stops. The acceleration and deceleration are incrimented in 8 square wave oscillators. Full speed is the pin 9 (D7) speed. Slowest is pin 2 (D0).

As the key is pressed longer, the speed increases toward max speed and when released decreases to all pins off. However you could time it so that a subsequent press would speed it up again. This would allow toggling of the speed by presses and releases.

You could set the timing for 1 second per speed change and use LED's on each data pin with some kind of resistor. Then you will see that only one pin is lit as it works up or down the cycle on a press or release. That is accomplished by using OUT 888, 2 ^ speed of 0 to 7. Stop could be speed = -1.

IF speed = -1 THEN OUT 888, 0

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0
Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Post by Ralph »

stevo22:
Everything below refers to your first group of 201 y-values, which I assumed correspond to the 201 x-values, 0-200.

1. Ploting the total group, from x=0 to x=200 gave a definite two-diimension type of curve. Establishing a rend line for a second-degree polynomial curve passing through the orign gave a not too nice fie, as too many large gaps were visible between the two curves, plus a large diference was observed in the slopes at the 0,0 point. Also, the data for the curve is definitely not that of a smooth, second-degree curve, so, I decided that was not what you wanted.

2. I plotted a series of curves, such that the curve an its trend line fit very closely together. The first trendline was passed through the 0,0 point, but not the others. These are the trendline equations I came up with:

For x=0 to x=5,Y = -7.7329*X^2 + 128.18*X
For x=5 to x=20, Y = -0.8757*X^2 + 150.18*X + 150.18
For x=20 to x=60, Y = -0.1604*X^2 + 37.902*X + 434.75
For x=60 to x=100, Y = -0.0557*X^2 + 26.24*X + 754.48
For x=100 to x=150,Y = -0.0282*X*X + 21.063*X + 1009.2
For x = 150 to 200, Y = -0.0166*X*X + 17.621*X + 1263.5

I testd all end points, such that the maximum x-value of one curve was used as the minimum x-value for the next curve, and the two y-values so obtained were compared; the match was very good, to me.

Let us know if this works for your proyect or not. The only thing I can add is to repeat that the trendlines fit the various curve-sections very well.

If you want the actual Excel spreadsheet U used to obtain the graphs, I'll be happy to send them to you, if you will send me a PM with your email address.
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish
Post Reply