Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Timing Question (semi-newbie, please help!)

Status
Not open for further replies.

mingo7707

Programmer
Jun 4, 2002
5
US
Hello, this is my first posting here and I must admit I have quite a little problem on my hands. I'm not sure if this is just a simple solution or if it is a hard one. I have a device that interfaces to the computer via a parallel port. Depending on what data the device recieves, it switches on 64 lamps. (so, if the device recieves a "1" through the parallel port, lamp 1 turns on, and so forth)

To give the appearance that all the lamps are on, I created a loop that individualy turns on each lamp in turn. Because the human eye can only percieve flicker over about 50hz, the lamps appear to all be on.

My problem is this: The loop works fine by itself, but I want to have other stuff (other loops, sound, etc) running at the same time. Would it be possible to make a loop that ran in the background of the rest of the Qbasic program? The status of each bulb is stored in an 64bit array. During the run of the program, the values for different lamps are almost always changing. So i would need to make a loop that ran in the background and took in the new data with each loop. Is this possible in Qbasic? Could someone advise me of a way to do it with, say, a C loop? (i don't know C mind you...)

Second, If i decide i want each lamp pulsed for, say, 2ms, what can I add to the loop to make the program time each pulse?

Thank you in advance, I hope all of this is very clear, if not, please tell me!

Thanks!
mingo

mingo7707@yahoo.com.ar
 
Well... QBasic not a best tool for that task (QuickBasic would be "quicker"), you can design your program as event-driven, so, main loop will check events and perform dedicated procedures, when needed. For less or more exact timing, you can try ON TIMER condition (but, it's intervals measured in seconds). In draft:
DIM s AS STRING
DIM i AS LONG
DIM event AS boolean
CONST eKey = 1'Event number one - key
CONST eTicker = 2'Event number two - "timer"
'wait for the second edge, than measure "timer"
i = 0
s = TIME$
DO: LOOP UNTIL s <> TIME$
s = TIME$
DO
i = i + 1
If 1=1 then i=i'empty condition
LOOP UNTIL s <> TIME$
PRINT &quot;One second=&quot;; i; &quot;ticks&quot;
'remember,that ticks between events is about 1000, because program has some work to do
event = false
mytimer = 0
ON TIMER(1) GOSUB OnTimer'will be set ticks to zero every second
TIMER ON
ON KEY(15) GOSUB OnKey15'User Key - must be defined!
KEY(15) ON
ON KEY(16) GOSUB OnKey16
KEY(16) ON ' and so on...
DO
'&quot;Timer&quot; loop:
DO
mytimer = mytimer + 1
IF mytimer MOD 1000 > 0 THEN
event = true
EventKind = eTicker
END IF
LOOP UNTIL event
SELECT CASE EventKind
CASE eTicker: TimerEvent
CASE eKey: KeyEvent
END SELECT
event = false
LOOP UNTIL EventKind = eExit
END
OnTimer:
mytimer = 0
RETURN
OnKey15:
event = true
EventKind = eKey
KeyNum = 15
RETURN
OnKey16:
event = true
eventKind = eKey
KeyNum = 16
RETURN
 
You want more than one loop at once huh? That is hard. You are asking Qbasic to multitask. I would just put everything in the same loop, but if you insist on doing this. (Its a little far out, but it will work)

DIM loopp$(3, number of commands in loop)
put all of the commands into the strings
DIM comm(3)
DO
FOR aa = 1 TO 3
command$ = UCASE$(loopp$(aa, comm(aa)))
comm(aa) = comm(aa) + 1
IF comm(aa) > number of commands in loop THEN comm = 1
'here goes a scripting language
'you will need to put in all commands you plan to use
IF command$ = &quot;SOUND&quot; THEN...
IF command$ = &quot;LET&quot; THEN...
NEXT
LOOP

The loops go all at the same time, not in the background like you wanted, but it is the best &quot;multitasking&quot; that Qbasic can do
 
thanks a lot for your help. I will try those ideas, it will (hopefully) help me tremendously. For the sake of asking, what is an example of a programming language that IS multitask? Are there any relatively easy ones to learn with a small learning curve? Thanks,

Mingo

mingo7707@yahoo.com.ar
 
NOPIK's code is actually very close to being functional. There is an error in the code which generates the timer event, in that it fires every single time through the loop, rather than after one millisecond has passed. The line which currently looks like this:
[tt]
IF mytimer MOD 1000 > 0 THEN
[/tt]
..should be changed to this:
[tt]
IF mytimer * 1000 > i THEN
[/tt]
This will make it fire whenever [tt]mytimer[/tt]'s value is greater than 1/1000th of [tt]i[/tt], which contains the number of &quot;ticks&quot; that were counted in one second. You can also avoid the [tt]ON KEY[/tt] system -- which is very slow, I might add -- by adding this to BOTH the timing loop that counts the value of [tt]i[/tt] AND the loop that counts and checks the value of [tt]mytimer[/tt]:
[tt]
IF INKEY$ <> &quot;&quot; THEN event = true: EventKind = eKey
[/tt]
I would personally change the design a little bit, but my changes would be mostly cosmetic: rather than using two variables to store whether an event had occurred and what event, I'd add another [tt]CONST[/tt] to the top defining [tt]eNone%[/tt] to equal [tt]0[/tt]. Then, I would loop as long as [tt]event[/tt] was equal to [tt]eNone%[/tt], and when an event occured, I'd set it to [tt]eKey%[/tt] or [tt]eTimer%[/tt], as appropriate, directly. This would break out of the loop on its own.

There is one problem with the code, and it is a minor one: in QuickBASIC, there is no predefined constant [tt]TRUE[/tt]. I recommend the following:
[tt]
CONST FALSE% = 0
CONST TRUE% = NOT FALSE%
[/tt]
They should definitely be defined in this order, since the only value [tt]x%[/tt] for which [tt]NOT x%[/tt] evaluates to a conditional 'false' is -1, which is not entirely intuitive. Setting [tt]FALSE%[/tt] to 0, however, is.
 
Also note that when running the program under Windows or some other multitasking operating system, your program does not get all the CPU time, and thus appears to speed up and slow down as it is running. This totally breaks this kind of &quot;spinning&quot; delay loop. If you need accurate timing on this scale, I recommend you look into C and an operating system called QNX, which, I have heard, is very good for such &quot;real-time&quot; operations.
 
language not so critical - many OS have time events, but QBasic itself can't proper operate with PC timer. You still can change Timing slice, and read it directly from timer, but it make DOS&BIOS time (and disk!!!) functions incorrect. If you don't need real word time or file operations during program execution - you can go this way.
But, more applicable - use Windows, OS/2 (may be, better choice for RealTime), Unix. They have system and user timer events and allow you control time with good resolution without any special skills.
For BASIC you can choose Windows+VisualBasic, Windows+XBasic, Linux+XBasic. XBasic (xbasic.sourceforge.net) - free Windows/Linux basic compiler and if some bugs in it non-critical to you - it can help (Lunix+XBasic - example of freeware solution).
Or, you can stay in DOS - but choose compiler, which allow to use interrupts (it's hardware/software conditions, which cause processor to call dedicated routines).

2 logiclrd: I use ON KEY, because inkey takes time in the &quot;timing&quot; loop. Yes, it work slow, and allow only 31 keys in the same time, but human's reaction not so fast, and with the task conditions, number of other events,controlled by time, in hundreds times greater, than key pressings.
 
Using [tt]ON KEY[/tt] results in QuickBASIC checking for a new key between every single statement. It kills your program's performance. It is FAR preferable to check for [tt]INKEY$[/tt] in the timing loop. As long as you also do it in the initialization loop in exactly the same way, then both loops will execute at the same speed.

As for those other operating systems you listed, NONE of them are real-time (with the exception of a couple of the unices which can be explicitly compiled to operate in that way (like SGI's IRIX)). The main characteristic of a real-time operating system is that it allows tasks to sleep for very precise amounts of time. Under Windows, OS/2 and most Unices, the Sleep function (Sleep(milliseconds) in Windows) is actually extremely granular and guarantees only that your code will be inactive for at least the specified amount of time. However, if you call Sleep(1) in Windows, your program will not get another time slice for at least 10 milliseconds. QNX, and other specifically real-time operating systems, do their very best to accomodate such requests accurately, to the point of interrupting other tasks' time slices early in order to allow a realtime process to get its time.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top