Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 03:13 24 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 : Newbie

     Page 3 of 7    
Author Message
Bob

Regular Member

Joined: 11/08/2011
Location: United Kingdom
Posts: 41
Posted: 10:13am 14 Aug 2011
Copy link to clipboard 
Print this post

  Bob said  
using SETPIN pin,0 doesn't unconfigure the interrupting, so counts continue to accumulate and the 2nd & subsequent operations give silly numbers. Maybe SETPIN 0,0 would stop it,


Whoops, sorry, that should be "Maybe SETPIN pin,0,0 would stop it"

Bob
Bob Dalley
http://www.m0rjd.co.uk
 
Bob

Regular Member

Joined: 11/08/2011
Location: United Kingdom
Posts: 41
Posted: 11:28am 14 Aug 2011
Copy link to clipboard 
Print this post

Testing is done!

Executive summary: It all does what it says on the tin. The changes to pin-interrupts, video update speed and addition of inverse video are all very satisfactory. Thanks Gerard.

Description of test

The test accumulates the values of MM.PCNT using an interrupt line over a period. I chose 10s, to make any small effects of the MMBasic starting and stopping the actions have a smaller percentage effect on the result.

Here is the test-programme:
100 'timed test for Gerard's interrupt mods
110 'accumulates count of MM.PCNT over TIME
120 TIME = 10000 '10 seconds in milliseconds
130 INVERT 0
140 ' can write black on white in latest test-code
150 x=0 : c=0 'init things. x is a flag, c is accumulator.
160 pin=2 'the pin to use for the test
170 SETTICK TIME, 1010: SETPIN pin,6,1000
180 PRINT "now we have let rip..."
190 IF x=0 THEN 190
200 'the count in c is the accumulation of inputs seen
210 ' after TIME ms.
220 PRINT "after"; TIME; "ms we counted";c;" pulses on pin"; pin
230 ? "Equivalent input frequency measured as";
240 INVERT 1 : PRINT c*1000 / time; : INVERT 0: PRINT "Hz"
250 RUN
1000 c = c+MM.PCNT : IRETURN
1010 SETPIN pin,8 'stop the accumulation of input
1020 ' setpin pin,0 doesn't seem to stop it interrupting.
2000 x=1 : IRETURN 'flag complete and exit
2010 END 'of programme


I used an analogue AF signal generator producing a square-wave test signal, fed through 1k (for protection) into the chosen pin - I used Pin 2 but checked a few others, which behaved the same way. For verification of frequency I used a 'real' timer/counter, but I am aware that the stability of the sig-gen was barely sufficient for this test, making it more difficult to correlate results.

Anyway, here are the results:


(dammit, the courier font doesn't display as fixed spacing - sorry: it does it correctly in the reply editor)
Maximite | Timer/counter
------------|--------------
91.2(3) Hz | 91.25Hz
200.1,200.2 | 200.17Hz
300.2 | 300.17Hz

503.2(3) | 503.2Hz
752.8 | 752.8Hz
10090,10092 | 10091Hz

15095 | 15095Hz
20122 | 20122Hz
25045 | 25045Hz (both wander but correspond)

30540 | 30539Hz
40068 | 40079Hz [-11] (onset of low Maximite readings)
45018 | 45033Hz [-15]

50204 | 50215Hz [-11]
60485 | 61135Hz [-650]
44665 | 8kHz, way out now as expected
24269 | 10kHz (ditto)

Note that for frequencies of 1.5kHz up I have ignored the tenths of Hz, which are not stable enough to be meaningful (this is due only to the signal generator).

The differences in [square brackets] also ignore the least significant digit (tenths of Hz) - the actual count differences are approximately ten times the figure shown.

Conclusion
With a single interrupting pin, the firmware corresponds well with a timer/counter up until the square-wave frequency is above 3kHz.
It may be good above that, but seems to drop a few edges until at or above 5kHz.
At 6kHz and above, it drops oodles of events.
This behaviour is excellent and indicates that the modification to the interrupt code will certainly be good up to 3Khz. The theoretical maximum is 5kHz, but I saw some input transitions dropped at frequencies between 3kHz and 5kHz.
Above 5kHz the internal firmware sampling-rate is inadequate, resulting in many missed events exactly as expected.

The unexpected differences that I saw at frequencies between 3kHz and 5kHz may be due to the difference in behaviour between the Maximite and the timer/counter.
I will see if I can clarify this later.

So, it all works very well Gerard! Great work. Now we must hope that Geoff incorporates it - if not, we will all be asking you for copies that do!

The speed-up of video handling is also very welcome and seems to be a Good Thing; as is the inverse video mode. I would like to see these incorporated in the next release as well.
(Proviso: the inverse video only works on the built-in display types, of course).

Regards,
Bob
Bob Dalley
http://www.m0rjd.co.uk
 
Bob

Regular Member

Joined: 11/08/2011
Location: United Kingdom
Posts: 41
Posted: 11:35am 14 Aug 2011
Copy link to clipboard 
Print this post

Hi Dinosaur,

  Dinosaur said   Hi all

Bob, you hit it right on the head.
If it is out of tolerance, and you know about it, you can report an
out of tolerance batch.
Typically I have an early cutoff that learns from the last event, so it gets closer
to the target each time. And the target is the actual target - tolerance.

Regards


From my measurements it seems OK for you to use the revised interrupt method that Gerard has so kindly written.
Obviously you will need to bear in mind the overall latency of the MMBasic, and the effect of pin interrupt priority on your programme. But all-in-all it seems that you need not worry about losing count of interrupt events now.

I will modify my test-programme (previous post) to put some very busy stuff in the waiting period rather than just a 'goto self' loop, to see if it still gives correct totals. There's no reason why it shouldn't, but it's always nice to see it happen!

Regards,
Bob
Bob Dalley
http://www.m0rjd.co.uk
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 12:16pm 14 Aug 2011
Copy link to clipboard 
Print this post

  Bob said  Odd behaviour that I didn't expect is that using SETPIN pin,0 doesn't unconfigure the interrupting, so counts continue to accumulate and the 2nd & subsequent operations give silly numbers. Maybe SETPIN 0,0 would stop it, but for now I have used SETPIN 8 to configure the pin as an output at the end of the measurement, which works well. It might introduce an extra count as it updates pin mode, who knows!

Trimmed....

Regards,
Bob


Hi Bob.

I have had a quick look at the code and the issue of not stopping executing the pin change interrupts is a bug that was in the original code - I just kept it!!

I have modified the firmware to fix the issue - SETPIN x, cfg with cfg equal to anything except 6 or 7 should now stop the interrupts being called. Same link as before: Maximite_PinInt.hex

The reason that SETPIN x,8 worked for you is that it set the pin to output, therefore there was no change on the pin.... But the interrupt check was still being done.

You could expect 1 more call to the pin change interrupt after issuing the SETPIN x,0 command as transitions may have occurred since the last time the interrupt was called and before the SETPIN command was issued.


Regards

Gerard (vk3cg/vk3grs)
 
Bob

Regular Member

Joined: 11/08/2011
Location: United Kingdom
Posts: 41
Posted: 12:29pm 14 Aug 2011
Copy link to clipboard 
Print this post

Hi All,

  Bob said  
I will modify my test-programme (previous post) to put some very busy stuff in the waiting period rather than just a 'goto self' loop, to see if it still gives correct totals. There's no reason why it shouldn't, but it's always nice to see it happen!


Easier than I thought!

With a busy line added into the wait loop:


184 FOR n = 0 TO 1000: m=(SIN(3)+SQR(27)-TAN(0.345))^0.8 :NEXT n
186 ' the parser only checks for interrupt conditions at the
187 ' end of a numbered line, so the above line will prevent
188 ' the interrupt being actioned for a good while.
190 ' the downside is that the overall timer will be affected
192 ' also, so our overall accumulation time may be longer
194 ' than expected and will jitter from run to run
195 '

The sum in line 184 is quite busy! It takes 320ms to execute the line.

The final result is almost identical to before, i.e. no interrupts are missed from the count in MM.PCNT even though at, say, 1kHz there are 320 of them occurring while line 184 (above) is executing.
If, as I understand it, the pin-interrupt proper is locked out during the execution of this long line, then not only are the events properly counted, but it gives the correct result:

Programme: 2560.4Hz
Tmr/ctr : 2560.4Hz

But remember that "the long execution time" of that line above may give grief in a real programme, where a latency of 320ms would be important!

Probably the lower readings in the previous report were due to the sig-gen bottles warming up; it reads a lot steadier now!

All in all a 100% successful enhancement. Thanks, Gerard.

Regards,
Bob
Bob Dalley
http://www.m0rjd.co.uk
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 12:38pm 14 Aug 2011
Copy link to clipboard 
Print this post

Hi Bob.

A quick question - do you have a PC attached to the Maximite via USB when you are doing these tests?

Regards

Gerard (vk3cg/vk3grs)
 
Bob

Regular Member

Joined: 11/08/2011
Location: United Kingdom
Posts: 41
Posted: 12:45pm 14 Aug 2011
Copy link to clipboard 
Print this post

  seco61 said  
Hi Bob.

I have had a quick look at the code and the issue of not stopping executing the pin change interrupts is a bug that was in the original code - I just kept it!!

I have modified the firmware to fix the issue - SETPIN x, cfg with cfg equal to anything except 6 or 7 should now stop the interrupts being called. Same link as before: Maximite_PinInt.hex

The reason that SETPIN x,8 worked for you is that it set the pin to output, therefore there was no change on the pin.... But the interrupt check was still being done.

You could expect 1 more call to the pin change interrupt after issuing the SETPIN x,0 command as transitions may have occurred since the last time the interrupt was called and before the SETPIN command was issued.


There's a thing, then (as my dear old Mum used to say).

Well found Gerard; it's a good thing you retained the bug or I wouldn't have found it <grin>.
Will you inform Geoff's buglist of this one? Better if it's you, since you have the cure as well.

I think you are saying that, even after the pin is no longer an interrupter, an interrupt that was 'up the spout' could occur? We could get one further call to the interrupt destination at the end of the line that disables the interrupt? It doesn't seem to be an earth-shattering problem, but is something for us to watch out for in our programmes, maybe.
Could the SETPIN kill any impending interrupt?

Regards,
Bob


Bob Dalley
http://www.m0rjd.co.uk
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 12:53pm 14 Aug 2011
Copy link to clipboard 
Print this post

  Bob said  I think you are saying that, even after the pin is no longer an interrupter, an interrupt that was 'up the spout' could occur? We could get one further call to the interrupt destination at the end of the line that disables the interrupt? It doesn't seem to be an earth-shattering problem, but is something for us to watch out for in our programmes, maybe.
Could the SETPIN kill any impending interrupt?

Regards,
Bob


Hi Bob.

Yes, the SETPIN could be changed to clear any additional counts and therefore stop any interrupt from occurring - but would you want the additional counts? As they have validly occurred up till the SETPIN command was executed would you want to process them?

I think I will leave it as it is - if you do not want any additional interrupts processed then set a flag just before the SETPIN command and check the flag in the pin change interrupt routine - if set just return...


Regards

Gerard (vk3cg/vk3grs)
 
Bob

Regular Member

Joined: 11/08/2011
Location: United Kingdom
Posts: 41
Posted: 12:55pm 14 Aug 2011
Copy link to clipboard 
Print this post

  seco61 said   Hi Bob.

A quick question - do you have a PC attached to the Maximite via USB when you are doing these tests?


Yes I do; the keyboard translation in Maximite is poor for a UK keyboard and I have to remember to transpose the " and @ keys. I don't remember - This results in a lot of editing! So I use GtkTerm (in Linux) which solves that problem.

It does mean that the USB code is outputting to the terminal while the VGA is displaying, which might not give as much VGA update speed as possible, but it is still noticeably faster.

The latest programmes don't actually output to the screen during the count acquisition, and the first one (of which I showed screen captures) is bugged anyway - I forgot to use a semaphore to synchronise it to the interrupts.

Regards,
Bob
Bob Dalley
http://www.m0rjd.co.uk
 
Gizmo

Admin Group

Joined: 05/06/2004
Location: Australia
Posts: 5078
Posted: 01:06pm 14 Aug 2011
Copy link to clipboard 
Print this post

  Bob said  

(dammit, the courier font doesn't display as fixed spacing - sorry: it does it correctly in the reply editor)


Yeah thats a HTML formatting thing, even with Courier. Any more than once space is ignored. The CODE window gets around it by replacing spaces with a special HTML character called the "non breaking space", but it cant be implemented in the normal test window sorry.

Glenn
The best time to plant a tree was twenty years ago, the second best time is right now.
JAQ
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 01:07pm 14 Aug 2011
Copy link to clipboard 
Print this post

Hi Bob.

Thanks for the answer, I would be interested in the results if you could run your test programs again without the USB connected. The reason being that if the USB is connected, routines to check for data on the USB run every 31.7uS - and I do not know what the overhead is. I am very curious to find out if there is any observable effect.


Regards

Gerard (vk3cg/vk3grs)
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 01:26pm 14 Aug 2011
Copy link to clipboard 
Print this post

Hi Bob.

I have probably answered my own question after running a few tests here.

If the USB port is connected but not doing anything, then I found the MMBasic interpreter to be a little bit faster than when the USB is unconnected.

Looking through the code I can see that this is because of a "kludge" (Geoff's own description) to get around a DMA timing issue that is in the video code. When the USB is unconnected, an extra timing loop is run to compensate - and this takes a bit longer than the standard USB check.


Regards

Gerard (vk3cg/vk3grs)
 
Bob

Regular Member

Joined: 11/08/2011
Location: United Kingdom
Posts: 41
Posted: 01:41pm 14 Aug 2011
Copy link to clipboard 
Print this post

Hi Gerard,

  seco61 said   Hi Bob.

I have probably answered my own question after running a few tests here.

If the USB port is connected but not doing anything, then I found the MMBasic interpreter to be a little bit faster than when the USB is unconnected.

Looking through the code I can see that this is because of a "kludge" (Geoff's own description) to get around a DMA timing issue that is in the video code. When the USB is unconnected, an extra timing loop is run to compensate - and this takes a bit longer than the standard USB check.


Ah, yes, your answer is the same as mine:

Timing that long (320ms) line that prints nothing:
With USB active (as terminal but no traffic), 320 or 321ms.
With USB powered but idling, 312ms
With USB unplugged, 329 or 330ms.

Regards,
Bob
Bob Dalley
http://www.m0rjd.co.uk
 
Bob

Regular Member

Joined: 11/08/2011
Location: United Kingdom
Posts: 41
Posted: 06:49pm 14 Aug 2011
Copy link to clipboard 
Print this post

  seco61 said  
Hi Bob.

Yes, the SETPIN could be changed to clear any additional counts and therefore stop any interrupt from occurring - but would you want the additional counts? As they have validly occurred up till the SETPIN command was executed would you want to process them?

I think I will leave it as it is - if you do not want any additional interrupts processed then set a flag just before the SETPIN command and check the flag in the pin change interrupt routine - if set just return...


OK, that certainly isn't a problem for anyone and is easy enough for them to do.

Regards,
Bob
Bob Dalley
http://www.m0rjd.co.uk
 
Bob

Regular Member

Joined: 11/08/2011
Location: United Kingdom
Posts: 41
Posted: 07:45pm 14 Aug 2011
Copy link to clipboard 
Print this post

Hi Glenn,

  Gizmo said  
  Bob said  

(dammit, the courier font doesn't display as fixed spacing - sorry: it does it correctly in the reply editor)


Yeah thats a HTML formatting thing, even with Courier. Any more than once space is ignored. The CODE window gets around it by replacing spaces with a special HTML character called the "non breaking space", but it cant be implemented in the normal test window sorry.

Glenn


Sorry Glenn, I meant to acknowledge your information sooner but it slipped the remnants of my mind.

Thanks for the confirmation.
I'll use the CODE method next time;
It Works just as you said!

Regards,
Bob
Bob Dalley
http://www.m0rjd.co.uk
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 08:58pm 14 Aug 2011
Copy link to clipboard 
Print this post

  Gadget said  Gerard,

I would love to see your source code for this

Terry


Hi Terry.

I have uploaded a copy of the source to Source v2.5 - GS.zip

Be aware that I am continuously "hacking" bits of the code, so that the source is likely to (does!) contain various changes that are still incomplete.

And when Geoff releases a new official version I will be using that as a base.

You will observe that in some places in the code (particularly in interrupts) that I will trade lengthier code for compact code (ie un-rolling loops etc) to improve the speed.

Regards

Gerard (vk3cg/vk3grs)
 
Dinosaur

Guru

Joined: 12/08/2011
Location: Australia
Posts: 311
Posted: 05:30am 16 Aug 2011
Copy link to clipboard 
Print this post

Hi all

I haven't received my board yet, but have spent some time writing a little program to do the function.
Now, I am used to a hi end basic with all the commands and functions, so it was quite a shock to write a program with Line Numbers and no Select Case and many other commands. Additionally memory is never a problem, execution time is. So this is my first attempt and looking for comments (constructive ones) to point out areas of improvements. In FreeBasic all my apps are written so that I don't use Do/Loop's or While/Wend's. This method makes the scan of all functions repeatable in time consumed and you can guarantee the critical items get attention at regualr intervals.
Same with this program.
'=========================================================== =========
' Maximite program to replace 8254 Liquid control board.
' This board will control Stop, Start and Count pulses.
' RxCmnd$ = Counter,Value,Command
' "00,00000,00"
' Possible Commands:
' Reset = 1 Single Counter Reset
' Set = 2 Set Target Count
' Start = 3 Start the Counter & Pump
' Input = 10 Get Value for that Counter
' Stop = Stop the pump, but leave the count as is.
' Other then Main Loop, don't hang around anywhere.
'=========================================================== =========
10 Option Base 1
20 SetPin 1,6,10000 'Pulse 1 Input Lo to Hi
30 SetPin 2,6,20000 'Pulse 2 ditto
40 SetPin 3,6,30000 ' etc
50 SetPin 4,6,40000
60 SetPin 5,6,50000
70 SetPin 6,6,60000
80 For Xq = 7 To 20
90 SetPin Xq,8 'All outputs
100 Next Xq
110 Dim StepNbr(6) 'Program Step for each Pulser
120 Dim Counter(6) 'Current Count "
130 Dim Target(6) 'Target Count "
140 Dim StartTime(6) '
150 Dim OldCount(6) 'Detect Liq leaking after stop
160 Dim Value(6) 'value to send to steps
170 '--------Declare Line Number for each Sub, then later Nbr the lines-----
180 CntStat = 1220:RcvData = 1010:TxData = 2000 'Sub routine Addresses
190 Do 'Main Loop
200 GoSub RcvData 'See if any transmissions
210 For Cnt = 1 To 6 'Attend to each Pulser
220 GoSub CntStat '
230 Next Cnt
240 GoSub TxData
250 Loop
251 GoTo 190 'just in case
1000 'Sub RcvData (Here Target Counter is unknown)
1010 Line Input RcvBuffer$
1020 If Len(RcvBuffer$) >= 12 Then
1030 C = Val(Left$(RcvBuffer$,2)) 'Counter Nbr
1040 V = Val(Mid$(RcvBuffer$,4,5)) 'Value
1050 I = Val(Mid$,RcvBuffer$,10,2)) 'Instruction Nbr
1060 EndIf
1070 If C > 0 Then 'GW doesn't allow ?
1080 If C < 7 Then 'If C > 0 AND C < 7
1090 If I > 0 Then 'If we have a Counter Nbr
1100 If I < 10 Then 'and a Instruction
1110 StepNbr(C) = I 'then assign them
1120 Value(C) = V
1130 RcvBuffer$ = "" 'get rid of the rest
1140 C = 0:V = 0:I = 0 'reset
1150 EndIf
1160 EndIf
1170 EndIf
1180 EndIf
1190 Return
1200 'End Sub
1210 'Sub CntStat (Called with Target Counter)
1220 If StepNbr(Cnt) = 0 Then 'Task complete or None (Waiting)
1230 Return
1240 ElseIf StepNbr(Cnt) = 1 Then 'Release STOP (allows remote Start)
1250 Pin(Cnt + 6) = 0 'Pin 7 = Stop for Cnt 1
1260 StepNbr(Cnt) = 0 'next step on next visit here.
1270 Return
1280 ElseIf StepNbr(Cnt) = 2 Then 'SET Target Value
1290 Target(Cnt) = Value(Cnt)
1300 Counter(Cnt) = 0 'Starting Value
1310 StepNbr(Cnt) = 0
1320 Return
1330 ElseIf StepNbr(Cnt) = 3 Then 'START the pump, and counting
1340 Pin(Cnt + 6) = 0 'make sure STOP OFF
1350 Pin(Cnt + 7) = 1 'Start pump
1360 StartTime(Cnt) = Timer 'signal Timer
1370 StepNbr(Cnt) = 4
1380 Return
1390 ElseIf StepNbr(Cnt) = 4 Then
1400 If Timer - StartTime(Cnt) > 450 Then
1410 Pin(Cnt + 7) = 0 'Turn the Start Relay Off
1420 StepNbr(Cnt) = 5 '
1430 Return
1440 EndIf
1450 ElseIf StepNbr(Cnt) = 5 Then 'Wait for Target
1460 If Counter(Cnt) >= Target(Cnt)
1470 Pin(Cnt + 6) = 1 'Stop pump, and Hold it Stopped.
1480 StartTime(Cnt) = Timer 'preventing Manual remote start.
1490 StepNbr(Cnt) = 6
1500 Return
1510 EndIf
1520 ElseIf StepNbr(Cnt) = 6 Then 'Wait for Liq. to Stop dribbling.
1530 If Timer - StartTime(Cnt) > 450 Then
1540 OldCount(Cnt) = Counter(Cnt)
1550 StartTime(Cnt) = Timer 'Next Step
1560 StepNbr(Cnt) = 7
1570 Return
1580 EndIf
1590 ElseIf StepNbr(Cnt) = 7 Then 'Wait for Stable count
1600 If Counter(Cnt) > OldCount(Cnt) Then
1610 OldCount(Cnt) = Counter(Cnt)'
1620 StartTime(Cnt) = Timer
1630 EndIf 'No pulses after 1 Sec, then accept
1640 If Timer - StartTime(Cnt) > 1000 Then Return 'this count as final.
1650 Else
1660 'StepNbr(Cnt) = 0
1670 Return
1680 EndIf
1690 'End Sub
2000 'Sub TxData
2010 If StepNbr(Cnt) = 10 Then
2020 Count$ = Str(Counter(Cnt)
2030 Do
2040 Count$ = "0" + Count$
2050 Loop While Len(Count$) < 5
2060 Temp$ = "0" + Str(Cnt) + "," + Count$ + "," + "10" + Chr(&H0D)
2070 Print Counter
2080 EndIf
2090 'End Sub
10000 Counter(1) = Counter(1) + MM.PCNT:IReturn
20000 Counter(2) = Counter(2) + MM.PCNT:IReturn
30000 Counter(3) = Counter(3) + MM.PCNT:IReturn
40000 Counter(4) = Counter(4) + MM.PCNT:IReturn
50000 Counter(5) = Counter(5) + MM.PCNT:IReturn
60000 Counter(6) = Counter(6) + MM.PCNT:IReturn
Regards
EDIT: Ignoring the logical mistake in line 1640, should be
1640 If Timer - StartTime(Cnt) > 1000 Then StepNbr(Cnt) = 0
1645 ReturnEdited by Dinosaur 2011-08-17
Regards
Hervey Bay Qld.
 
Dinosaur

Guru

Joined: 12/08/2011
Location: Australia
Posts: 311
Posted: 05:02am 23 Aug 2011
Copy link to clipboard 
Print this post

Hi all

The test program in the previous post was not tested for syntax, but now I have my Maximite board and loaded the latest Firmware. I have tested the code below for proper functioning, but can't test the actual count input's until I install it with a number of pulsers.When I run it, it very quickly reports a huge count, which I assume is due to the count inputs being left floating.

So, I was hoping if SKS can test this for me. It uses Pin 1 to 6 for counters and uses pin 7 to 12 as the Stop signal.
'=========================================================== =========
' Maximite program to replace 8254 Liquid control board.
' This board will control Stop, Start and Count pulses.
' Reset output to Manu Meter must be created from the Master PC
' Rx Cmnd$ = Counter,Value,Command This format must be adhered to.
' "C0,00000,0"
' Tx Cmnd$ = "0,00000,0,OK" Print Statements break this Format
' Possible Commands:
' Release = 1 Release STOP
' Target = 2 Set Target Count to achieve.
' Start = 3 Start the Counter & Pump (Runs to Step 6)
' Input = 9 Get Value for that Counter
' Stop = Stop the pump, but leave the count as is.
' Other then Main Loop, don't hang around anywhere.
' To Test send "C1,12345,2 to set the Target Count on Counter 1
' "C1,00000,3 to start Counting.
'=========================================================== =========
10 Option Base 1
20 SetPin 1,6,10000 'Pulse 1 Input Lo to Hi
30 SetPin 2,6,20000 'Pulse 2 ditto
40 SetPin 3,6,30000 ' etc
50 SetPin 4,6,40000
60 SetPin 5,6,50000
70 SetPin 6,6,60000
80 For Xq = 7 To 20
90 SetPin Xq,8 'All outputs
100 Next Xq
110 Dim StepNbr(6) 'Program Step for each Pulser
120 Dim Counter(6) 'Current Count "
130 Dim Target(6) 'Target Count "
140 Dim StartTime(6) '
150 Dim OldCount(6) 'Detect Liq leaking after stop
155 Dim Value(6)
160 Dim RxValue(6) 'value to send to steps
170 Dim RxStep(6) 'If usb Request, this step is used
172 Dim OldStep(6)
180 TxData = 2000 'Sub routine Addresses
190 K$ = InKey$
200 If K$ <> "" Then
210 If K$ = "C" Then
215 Line Input RcvBuffer$ 'Here Target Counter is unknown.
220 Endif
230 Else
240 GoTo 370
250 EndIf
260 If Len(RcvBuffer$) >= 8 Then
265 C = Val(Left$(RcvBuffer$,1))
270 If C < 7 Then 'Limit of 6
280 I = Val(Right$(RcvBuffer$,1)) 'Instruction Nbr
290 If I > 0 And I < 10 Then
300 RxValue(C) = Val(Mid$(RcvBuffer$,2,5)) 'Value
310 RxStep(C) = I
320 EndIf
330 EndIf
340 EndIf '
350 RcvBuffer$ = "" 'get rid of the rest
360 C = 0:V = 0:I = 0 'reset, now check on 6 counters
370 For Cnt = 1 To 6 'Attend to each Pulser
380 If StepNbr(Cnt) < 5 Then 'Not currently counting
390 If RxStep(Cnt) > 0 Then 'If we have Rcvd a Command
400 StepNbr(Cnt) = RxStep(Cnt) 'Use it
410 RxStep(Cnt) = 0 'reset recvd
420 Value(Cnt) = RxValue(Cnt) 'use Value recvd
430 RxValue(Cnt) = 0 'reset recvd
440 EndIf
450 EndIf
460 GoSub 1200
470 If StepNbr(Cnt) <> OldStep(Cnt) Then
480 Print "StepNbr Counter;" + Str$(Cnt) + ";" + Str$(StepNbr(Cnt))
490 OldStep(Cnt) = StepNbr(Cnt)
500 EndIf
510 Next Cnt
520 GoTo 190
1200 If Cnt > 6 Then Cnt = 1
1205 If StepNbr(Cnt) = -1 Then
1206 Return '
1210 ElseIf StepNbr(Cnt) = 0 Then 'Bootup Test
1215 StepNbr(Cnt) = -1
1220 Print "0,00000," + Str$(StepNbr(Cnt)) + ",OK" + Chr$(&H0D)
1230 Return
1240 ElseIf StepNbr(Cnt) = 1 Then 'Release STOP (allows remote Start)
1250 B = Cnt + 6:Pin(B) = 0 'Pin 7 = Stop for Cnt 1
1260 StepNbr(Cnt) = -1 'next step on next visit here.
1265 Print Str$(Cnt) + "," + Str$(Value(Cnt)) + "," + Str$(StepNbr(Cnt)) + ",OK" + Chr$(&H0D)
1270 Return
1280 ElseIf StepNbr(Cnt) = 2 Then 'SET Target Value
1290 Target(Cnt) = Value(Cnt)
1300 Counter(Cnt) = 0 'Starting Value
1310 StepNbr(Cnt) = -1
1315 Print Str$(Cnt) + "," + Str$(Target(Cnt)) + "," + Str$(StepNbr(Cnt)) + ",OK" + Chr$(&H0D)
1320 Return
1330 ElseIf StepNbr(Cnt) = 3 Then 'START the pump, and counting
1340 Pin(Cnt + 6) = 0 'make sure STOP OFF
1350 Pin(Cnt + 7) = 1 'Start pump
1360 StartTime(Cnt) = Timer 'signal Timer
1365 Print Str$(Cnt) + "," + Str$(StartTime(Cnt)) + "," + Str$(StepNbr(Cnt)) + ",OK" + Chr$(&H0D)
1370 StepNbr(Cnt) = 4
1380 Return
1390 ElseIf StepNbr(Cnt) = 4 Then
1400 If Timer - StartTime(Cnt) > 450 Then
1410 Pin(Cnt + 7) = 0 'Turn the Start Relay Off
1420 StartTime(Cnt) = Timer 'TxData Timer
1430 StepNbr(Cnt) = 5 '
1440 EndIf
1450 Return
1460 ElseIf StepNbr(Cnt) = 5 Then 'Wait for Target
1470 If Timer - StartTime(Cnt) > 2000 Then'Every 2 sec's
1480 GoSub TxData 'send counts to Master
1490 StartTime(Cnt) = Timer 'reset the timer
1500 EndIf
1510 If Counter(Cnt) >= Target(Cnt) Then
1520 Pin(Cnt + 6) = 1 'Stop pump, and Hold it Stopped.
1530 StartTime(Cnt) = Timer 'preventing Manual remote start.
1540 StepNbr(Cnt) = 6
1550 EndIf
1560 Return
1570 ElseIf StepNbr(Cnt) = 6 Then 'Wait for Liq. to Stop dribbling.
1580 If Counter(Cnt) > OldCount(Cnt) Then
1590 OldCount(Cnt) = OldCount(Cnt) '
1600 StartTime(Cnt) = Timer
1610 EndIf 'No pulses after 1 Sec, then accept
1620 If Timer - StartTime(Cnt) > 1000 Then StepNbr(Cnt) = -1
1630 Return 'this count as final.
1640 ElseIf StepNbr(Cnt) = 7 Then 'Spare Step
1650 Return
1660 ElseIf StepNbr(Cnt) = 8 Then 'Spare Step
1670 Return
1680 ElseIf StepNbr(Cnt) = 9 Then 'RxData from Master
1690 GoSub TxData
1700 Return
1710 Else
1720 StepNbr(Cnt) = -1
1730 Return
1740 EndIf
1800 Return
1810 'SUB TxData=========================
2000 Count$ = Str$(Counter(Cnt))
2010 Temp$ = Str$(Cnt) + "," + Count$ + "," + "9" + "," + "OK"
2020 Print Temp$
2030 Return
2040 'END SUB===========================
10000 Counter(1) = Counter(1) + MM.PCNT:IReturn
20000 Counter(2) = Counter(2) + MM.PCNT:IReturn
30000 Counter(3) = Counter(3) + MM.PCNT:IReturn
40000 Counter(4) = Counter(4) + MM.PCNT:IReturn
50000 Counter(5) = Counter(5) + MM.PCNT:IReturn
60000 Counter(6) = Counter(6) + MM.PCNT:IReturn

One interesting side affect of pasting code with HyperTerminal is that lines removed from your program, are still there on the MM. So they get executed and create some strange faults.
The Counter should not return to Step -1 until the count has been stable (ie:stopped) for 1 Sec.

Regards
PS: SKS = Some Kind Soul
Regards
Hervey Bay Qld.
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 05:31am 23 Aug 2011
Copy link to clipboard 
Print this post

If execution time / program throughput is of importance, then reducing the size of each statement can make a significant difference to the program speed.

By this I mean remove all spaces or tabs not explicitly required by the syntax, remove all comments (especially those on a separate line by themselves), make variable names as short as possible and place multiple statements on a line if possible.

Of course, this makes the program a LOT harder to read and follow so it is horses for courses.

One option may be to develop the code in a more descriptive way and then "compress" it once it is working as desired.

And also, whenever pasting code to the MM from a terminal emulator it is best to issue a NEW command first to clear out the MM program memory - unless you are explicitly updating the existing code.

Regards

Gerard (vk3cg/vk3grs)
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 05:40am 23 Aug 2011
Copy link to clipboard 
Print this post

Also,

If relying on the USB "serial" output, and you send data at a very fast rate, then it would be worth running my latest firmware as there is a bug in the standard MM firmware that allows the output to be corrupted.


Regards

Gerard (vk3cg/vk3grs)
 
     Page 3 of 7    
Print this page
© JAQ Software 2024