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 4 of 7 | |||||
Author | Message | ||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi all Thank you for those hints Gerard. I guess I am to used to Hi-End compilers which strip all that stuff out. I did download your update from yesterday, so am using the latest. Any comment on the "Floating input" ? Regards Regards Hervey Bay Qld. |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
Hi. There are (at least!) a couple of bugs in the program. First, statement 300 should read: 300 RxValue(C) = Val(Mid$(RcvBuffer$,3,5)) 'Value as the Mid$ function uses 1 as the position of the first character. Also, I added line 1695 to stop the loop when issuing command 9: 1695 StepNbr(Cnt) = -1 I can not test it properly at the moment as I am at work and am remotely controlling my home PC which is attached to a running Maximite! Regards Gerard (vk3cg/vk3grs) |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi all Grard, line 300 was not changed when I made another change. The Line Input hangs in there until it gets char's and so if nothing there; it waits. So, had to change to checking the port with Inkey$, which removes one Char. In FreeBasic I would normally check the port with "If Loc(FileNbr) > 0 Then" which doesn't remove any char's. Would be nice to have a non-destructive key buffer check. 1695 definitely an endless loop.Well done Regards Regards Hervey Bay Qld. |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
Hi. I am modifying your program a bit to handle interrupts correctly while you are performing input. I also need to understand the function of the 'STOP' output pin and the 'PUMP' output pin. Is there supposed to be one of each for each of the six counters? Regards Gerard (vk3cg/vk3grs) |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
A possible exception to the above performance suggestions is in the case where you have interrupt routines. In this case you want every statement (not in an interrupt routine) to be as short as possible - this means NO multiple commands on the one line so that the interrupt routine will be executed as soon as possible. The interrupt routine code itself though can use multiple commands on a line. Regards Gerard (vk3cg/vk3grs) |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
Hi. The following code handles input without stopping interrupts (the LINE INPUT command suspends interrupts). Also, the input string does not have to have 5 numerics for the 2nd parameter (1 - 5 numbers will be accepted). eg C1,0,9 But I have not updated the comments to reflect this. Also, PRINT commands will not "break" your chosen TX string if you utilise the Format$ function - see sample at line 2000. If a "Q" is typed then the program will quit. And I added command 8 (Cx,n,8) which will stop pumping immediately (if pumping is under way). This made it easier to test without hardware attached. I need to understand the STOP and START pins to program them correctly. '=========================================================== ========= ' 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 = 8 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) 175 Timer = 0 180 TxData = 2000 'Sub routine Addresses 190 KS = 0 'Input state ' Input routine 200 K$ = UCase$(InKey$) 205 If K$ <> "" Then 210 If K$ = "Q" Then End 215 If KS = 0 Then 220 If K$ = "C" Then 225 KS = 1 230 EndIf 235 ElseIf KS = 1 Then 240 C = Asc(K$) - Asc("0") 245 If C > 0 And C < 7 Then KS = 2 Else KS = 0 250 ElseIf KS = 2 Then 255 If K$ = "," Then KS = 3 : V = 0 Else KS = 0 260 ElseIf KS = 3 Then 265 T = Asc(K$) - Asc("0") 270 If T >= 0 And T <= 9 Then 275 V = V * 10 + T 280 If V > 99999 Then KS = 0 285 Else 290 If K$ = "," Then KS = 4 Else KS = 0 295 EndIf 300 ElseIf KS = 4 Then 305 I = Asc(K$) - Asc("0") 310 If I > 0 And I < 10 Then KS = 5 Else KS = 0 315 ElseIf KS = 5 Then 320 If Asc(K$) = &H0D Or Asc(K$) = &H0A Then 325 RxValue(C) = V 330 RxStep(C) = I 335 EndIf 340 KS = 0 345 Endif 350 Else 355 GoTo 370 360 EndIf ' Pulser processing routine 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 405 Value(Cnt) = RxValue(Cnt) 'use Value recvd 410 EndIf 415 ElseIf StepNbr(Cnt) = 5 Then 420 If RxStep(Cnt) = 8 Then 425 StepNbr(Cnt) = 8 430 EndIf 435 EndIf 440 RxStep(Cnt) = 0 'reset recvd 445 RxValue(Cnt) = 0 'reset recvd 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 200 ' Pulser state machine 1200 If StepNbr(Cnt) = -1 Then 1206 Return ' 1210 ElseIf StepNbr(Cnt) = 0 Then 'Bootup Test 1215 StepNbr(Cnt) = -1 1220 Print Format$(cnt,"%1.0f");",00000," + Str$(StepNbr(Cnt)) + ",OK" + Chr$(&H0D) 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) = -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 1331 If Target(Cnt) = 0 Then 'no point running if nothing to pump 1332 StepNbr(Cnt) = -1 1333 Print Str$(Cnt) + "," + Str$(StartTime(Cnt)) + "," + Str$(StepNbr(Cnt)) + ",OK" + Chr$(&H0D) 1334 GoSub TxData 'send counts to Master 1335 Return 1336 EndIf 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 1425 Print Str$(Cnt) + "," + Str$(StartTime(Cnt)) + "," + Str$(StepNbr(Cnt)) + ",OK" + Chr$(&H0D) 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 1560 Return 1570 ElseIf StepNbr(Cnt) = 6 Then 'Wait for Liq. to Stop dribbling. 1580 If Counter(Cnt) > OldCount(Cnt) Then 1590 OldCount(Cnt) = Counter(Cnt) ' 1600 StartTime(Cnt) = Timer 1610 EndIf 'No pulses after 1 Sec, then accept 1620 If Timer - StartTime(Cnt) > 1000 Then GoSub TxData: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 - Used to Stop Pumping 1665 Pin(7)=1:OldCount(1)=Counter(1):StartTime(1)=Timer:StepNbr(1 )=6 1670 Return 1680 ElseIf StepNbr(Cnt) = 9 Then 'RxData from Master 1690 GoSub TxData 1695 StepNbr(Cnt) = -1 1700 Return 1710 Else 1720 StepNbr(Cnt) = -1 1730 Return 1740 EndIf 1800 Return 1810 'SUB TxData========================= 2000 Print Format$(cnt,"%1.0f");",";Format$(Counter(Cnt),"%05.0f");",9, OK":Return '2000 Count$ = Str$(Counter(Cnt)) '2010 Temp$ = Str$(Cnt) + "," + Count$ + "," + "9" + "," + "OK" '2020 Print Temp$ 2030 Return 2040 'END SUB=========================== ' Counter interrupt routines. The check of the counts has been moved here to stop the pump as soon as possible 10000 Counter(1)=Counter(1)+MM.PCNT 10010 If StepNbr(1)=5 Then ' If target 1 reached - Stop pump, and Hold it Stopped, Save current count and timer and Set state 10020 If Counter(1)>=Target(1) Then Pin(7)=1:OldCount(1)=Counter(1):StartTime(1)=Timer:StepNbr(1 )=6 10030 EndIf 10090 IReturn 20000 Counter(2)=Counter(2)+MM.PCNT 20010 If StepNbr(2)=5 Then ' If target 2 reached - Stop pump, and Hold it Stopped, Save current count and timer and Set state 20020 If Counter(2)>=Target(2) Then Pin(8)=1:OldCount(2)=Counter(2):StartTime(2)=Timer:StepNbr(2 )=6 20030 EndIf 20090 IReturn 30000 Counter(3)=Counter(3)+MM.PCNT 30010 If StepNbr(3)=5 Then ' If target 3 reached - Stop pump, and Hold it Stopped, Save current count and timer and Set state 30020 If Counter(3)>=Target(3) Then Pin(9)=1:OldCount(3)=Counter(3):StartTime(3)=Timer:StepNbr(3 )=6 30030 EndIf 30090 IReturn 40000 Counter(4)=Counter(4)+MM.PCNT 40010 If StepNbr(4)=5 Then ' If target 4 reached - Stop pump, and Hold it Stopped, Save current count and timer and Set state 40020 If Counter(4)>=Target(4) Then Pin(10)=1:OldCount(4)=Counter(4):StartTime(4)=Timer:StepNbr( 4)=6 40030 EndIf 40090 IReturn 50000 Counter(5)=Counter(5)+MM.PCNT 50010 If StepNbr(5)=5 Then ' If target 5 reached - Stop pump, and Hold it Stopped, Save current count and timer and Set state 50020 If Counter(5)>=Target(5) Then Pin(11)=1:OldCount(5)=Counter(5):StartTime(5)=Timer:StepNbr( 5)=6 50030 EndIf 50090 IReturn 60000 Counter(6)=Counter(6)+MM.PCNT 60010 If StepNbr(6)=5 Then ' If target 6 reached - Stop pump, and Hold it Stopped, Save current count and timer and Set state 60020 If Counter(6)>=Target(6) Then Pin(12)=1:OldCount(6)=Counter(6):StartTime(6)=Timer:StepNbr( 6)=6 60030 EndIf 60090 IReturn Regards Gerard (vk3cg/vk3grs) |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
Oops.... Geoff has just sent me an email pointing out that the above statement (regarding when interrupts are checked) is not correct - MMBasic DOES do an interrupt check after each command, even when they are all on the one line separated by colons. And, of course, checking the code more thouroughly reveals that this is indeed the case. Regards Gerard (vk3cg/vk3grs) |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi all Gerard many thanks for those mod's. I understand all, except I have never used the Format Function, so will look at that further. The basic operation of the whole system involves a Counting instrument widely used in the Concrete industry by Manu Electronics. When the plant is computerised with my system I keep these counters in paralel with the computer.They also put a count on that counter as an "overflow limit". So if the computer shuts down or whatever, the Manu will stop the pump at it's preset limit. The computer resets the Manu counter and starts the Pump or opens a solonoid to start the liquid flowing.When the Target is reached (normally with a 8254) the output is used to close a Stop switch on the Manu. By holding that closed until the next load prevent the plant operator from putting more in without it being reported.Hope that explains it. Gerard, I didn't really want you to go through the trouble you have, I was just hoping for a functional check with a count input.(which I can't do at the moment)But being a novice with PIC's it is really appreciated. With regards to the program line layout: Are expanded lines equally as fast as multiple statement lines.? Do comments on the end of lines make any difference.? I notice you had some unnumbered lines, is that the way to add comments.? I would think that with Goto's and Gosub's these lines are just jumped over. Finally, is it possible to use a Peek statement to see if any Char's in the Key buffer, and would that be faster then Inkey$ on every loop.? Regards Regards Hervey Bay Qld. |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
Are expanded lines equally as fast as multiple statement lines.? Do comments on the end of lines make any difference.? I notice you had some unnumbered lines, is that the way to add comments.? I would think that with Goto's and Gosub's these lines are just jumped over. Finally, is it possible to use a Peek statement to see if any Char's in the Key buffer, and would that be faster then Inkey$ on every loop.? Regards Hi. First, as regards the use of PEEK instead of INKEY$, this would not be possible. Keyboard input (or input from the "serial" USB) is stored in a circular buffer. When the INKEY$ command executes it gets the next element from the buffer (if there is one) and then updates the pointer that keeps track of the elements. The "un-numbered" comment lines do not get stored in program memory, (and will not be shown by the LIST command). So they are great for commenting a program without impacting speed or code size - of course, this implies you are maintaining your program on the PC and uploading to the Maximite for execution. Comments on the end of a line will slow the program as the interpreter has to skip over them every time it executes that line. If by "expanded lines" you mean multiple commands on the one line, then expanded lines will be faster as the interpreter does not have skip as many characters (or line number tokens) to start the next command. The interpreter has to process each character on a line before it can get to the next line. And when a GOSUB or GOTO is issued, the interpreter scans all program memory from the beginning each time to locate the line you which to execute. Therefore, to maximise speed, it is best to place all subroutines at the begining of your program with the most often executed first. The program can start with a GOTO to the first line of the main program. This is also another reason why having the shortest possible lines speeds up execution. Fortunately, when an interrupt routine is executed, the address in program memory of the routine is stored by the command that activated the interrupt and program memory does not need to be scanned. Regards Gerard (vk3cg/vk3grs) |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
system I keep these counters in paralel with the computer.They also put a count on that counter as an "overflow limit". So if the computer shuts down or whatever, the Manu will stop the pump at it's preset limit. The computer resets the Manu counter and starts the Pump or opens a solonoid to start the liquid flowing.When the Target is reached (normally with a 8254) the output is used to close a Stop switch on the Manu. By holding that closed until the next load prevent the plant operator from putting more in without it being reported.Hope that explains it. Are there separate START/STOP enable controls and pump/solenoid start controls (ie one of each) for each of the six counter/pulsers? Do pumps and solenoids use the same startup sequence? (ie. from examining the program it appears that the pump controls have an enable/disable output and also a start relay output that initiates the pump) Regards Gerard (vk3cg/vk3grs) |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi all The Start signal pulls in a contactor that latches and holds itself in. This may directly run a pump, or power a Solonoid that opens a pressure line. That's why I only have the start signal ON for 450 mSec. Each Liquid has it's own Start / Stop, and they are all identical. So for the possible 6 liquids, I have 6 Start outputs from the MM, and 6 Stop outputs. The pulses created by the inline flow meter are shared between the MM and the Manu. The operator can see the counts incrementing on the Manu, and see the bargraph on the PC. If he decides while the liquid is flowing to stop , (truck not in place properly) he can then restart by pressing the Start button on the Manu. The computer will know nothing about this, other then it is waiting for the liquid to complete.If the pulses stop because the pump has stopped before the Target is reached then the Manu will beep and show a pulse fail light. The only improvement I can make to the MM program is to detect pulse fail. Regards Regards Hervey Bay Qld. |
||||
vasi Guru Joined: 23/03/2007 Location: RomaniaPosts: 1697 |
First known industrial usage of the Maximite? Hobbit name: Togo Toadfoot of Frogmorton Elvish name: Mablung Miriel Beyound Arduino Lang |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
Hi. One other implication of the way the interpreter executes a GOTO. If you use the GOTO command to create a program loop, the interpreter has to search program memory from the beginning to locate the target each time the GOTO is executed. On the other hand, if you use a DO or WHILE command, the interpreter saves the target location when it executes the DO or WHILE command and does not need to search program memory for the target location when the matching LOOP or WEND is executed. Regards Gerard (vk3cg/vk3grs) |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi all Vasi, the board has to prove itself before I am game to put it into an actual installation. Some of my plants are in very remote locations, and the ramifications of getting a failure would be very costly. Gerard, I have 2 Goto's in the program. Now knowing what you have noted I will re-write it to eliminate Goto's. If the guy's at FreeBasic saw this, they would be horrified, Goto's are a NO,NO. Regards EDIT: I can eliminate lines 350 & 355 to start with, and just let the program proceed to the next step.(370) Regards Hervey Bay Qld. |
||||
sparkey Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 819 |
could you elaberate as to why "goto" are a "no no" pls technicians do it with least resistance |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi all Sparkey, the purest consider Goto's as the first step towards spaghetti code. In the PC world the aim is to write portable code that is optimised into objects as in OOP (object oriented programming). Goto's make that harder to achieve. The Not So purest claim it can have it's uses. From what Gerard has explained, there is a speed consideration for not using it with MMBasic. Regards Regards Hervey Bay Qld. |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi all As I only have one Signal Generator, I have tested the board by bridging the signal to all 6 counters.(in reality only 2 or 3 will wotk at the same time) Running the pulser at 2khz, I stopped the pulses and looked at the difference between them. 1 = 3087 2 = 3095 3 = 3135 4 = 3085 5 = 3083 6 = 3083 Not a good test but will try again with 3. Regards EDIT: Same with 3, but conclude that I can't guarantee the same startup on each. So,really must test with 3 separate pulses which can deliver a known number of pulses. Also linking the 3 with 330 ohm resistors and injecting the pulses on one point creates another error. Regards Hervey Bay Qld. |
||||
aargee Senior Member Joined: 21/08/2008 Location: AustraliaPosts: 255 |
Dinosaur, I would not be considering the Maximite for any "Some of my plants are in very remote locations, and the ramifications of getting a failure would be very costly." type scenarios. If you are contemplating this, I would be looking at a tailor made commercial/industrial solution. I think these types of devices are really in the hobbyist/low impact arena for applications. - Rob. For crying out loud, all I wanted to do was flash this blasted LED. |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi all Rob,MicroChip might not agree. Currently I have UBW32's in factories operating 24/7 succesfully, and considering we are talking about the same PIC family, I cant see a problem. The ramifications I am talking about are the ones that mean the board doesn't operate as per design. IE:usb unreliable, I/O pins change state unpredictably etc. These are the ones I have to test for.These are also the ones that will more then likely be caused by MMBasic and not the PIC. Failures from electrical faults, or bad soldering etc are handled by the spares they carry on site. And looking at the MM from that point of view, it is professionally manufactured.Equally I could misread or ignore the spec's and burn out I/O. The only additional spec's that comes with "industrial" is the temperature range, and after hand soldering boards for the last 25 years with few failures, I think these boards are a good bet. But, it will sit on the bench until I am happy with it's reliability. Regards Regards Hervey Bay Qld. |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
Here is a somewhat more compact and faster version of the code. As the variables have been reduced to single characters, it is a bit harder to read! However, it does seem to work! Please note the pin assignments in the comments. I could speed it up a bit more by removing all indenting - but that can wait until it goes live!! '=========================================================== ========= ' 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. ' "Cp,n,c" ' where C = 'C' (The 'C' indicates the start of a command sequence) ' p = counter (1 - 6) ' n = target value (0 - 99999) ' c = command (1 - 9) ' ' Tx Cmnd$ = "0,00000,0,OK" ' ' Possible Commands: ' Release = 1 Release STOP ' Target = 2 Set Target Count to achieve. ' Start = 3 Start the Counter & Pump (Runs to Step 6) ' Stop = 8 Stop the pump, but leave the count as is. ' Input = 9 Get Value for that Counter ' ' Other then Main Loop, don't hang around anywhere. ' ' To Test send "C1,12345,2 to set the Target Count on Counter 1 ' "C1,0,3 to start Counting. ' "C1,0,9 to Tx current counter value '=========================================================== ========= new 10 Option Base 1 ' Set pins 1 - 6 to interrupt on low to high transition 20 SetPin 1,6,10000 21 SetPin 2,6,20000 22 SetPin 3,6,30000 23 SetPin 4,6,40000 24 SetPin 5,6,50000 25 SetPin 6,6,60000 ' Set remaining pins as digital output ' Pins 7-12 will be the STOP/DISABLE output ' Pins 13-18 will be the START output 30 For i=7 To 20 31 SetPin i,8 32 Next i 41 Dim C(6) ' C(): Current count 42 Dim T(6) ' T(): Target count 43 Dim R(6) ' R(): Start time 44 Dim O(6) ' O(): Old count 45 Dim V(6) ' V(): Value 46 Dim W(6) ' W(): Input value 47 Dim X(6) ' X(): Input step 48 Dim Z(6) ' Z(): Old step 50 M=0 ' Input state machine value 60 Timer=0 ' Start main loop 100 Do ' Command input routine start 110 K$=UCase$(InKey$) 120 If K$<>"" Then 130 If K$="Q" Then End 140 If M=0 Then 150 If K$="C" Then M=1 160 ElseIf M=1 Then 170 J=Asc(K$)-Asc("0") 180 If J>0 And J<7 Then M=2 Else M=0 190 ElseIf M=2 Then 200 If K$="," Then M=3:L=0 Else M=0 210 ElseIf M=3 Then 220 K=Asc(K$)-Asc("0") 230 If K>=0 And K<=9 Then 240 L=L*10+K:If L>99999 Then M=0 250 Else 260 If K$="," Then M=4 Else M=0 270 EndIf 280 ElseIf M=4 Then 290 N=Asc(K$)-Asc("0"):If N>0 And N<10 Then M=5 Else M=0 300 ElseIf M=5 Then 310 If Asc(K$)=13 Or Asc(K$)=10 Then W(J)=L:X(J)=N 320 M=0 330 Endif 340 EndIf ' Command input routine end ' Pulser processing routine 400 For i=1 To 6 410 If S(i)<5 Then 420 If X(i)>0 Then S(i)=X(i):V(i)=W(i) 430 ElseIf S(i)=5 Then 440 If X(i)=8 Then S(i)=8 450 EndIf 460 X(i)=0:W(i)=0 ' Pulser state machine processing start 500 Do 510 If S(i)=-1 Then 520 Exit 530 ElseIf S(i)=0 Then ' Bootup Test 540 S(i)=-1:? Format$(i,"%1.0f,00000,");Format$(S(i),"%1.0f,OK")+Chr$(13): Exit 550 ElseIf S(i)=1 Then ' Release STOP (allows remote Start) 560 Pin(i+6)=0:S(i)=-1:? Format$(i,"%1.0f,");Format$(V(i),"%1.0f,");Format$(S(i),"%1. 0f,OK")+Chr$(13):Exit 570 ElseIf S(i)=2 Then ' Set target value & reset counter to 0 580 T(i)=V(i):C(i)=0:S(i)=-1:? Format$(i,"%1.0f,");Format$(T(i),"%1.0f,");Format$(S(i),"%1. 0f,OK")+Chr$(13):Exit 590 ElseIf S(i)=3 Then ' START the pump, and counting if target > 0 600 If T(i)=0 Then 610 S(i)=-1:? Format$(i,"%1.0f,");Format$(R(i),"%1.0f,");Format$(S(i),"%1. 0f,OK")+Chr$(13):? Format$(i,"%1.0f,");Format$(C(i),"%05.0f,9,OK"):Exit 620 EndIf ' Make sure STOP off, START the pump and initialise start time 630 Pin(i+6)=0:Pin(i+12)=1:R(i)=Timer:? Format$(i,"%1.0f,");Format$(R(i),"%1.0f,");Format$(S(i),"%1. 0f,OK")+Chr$(13):S(i)=4:Exit 640 ElseIf S(i)=4 Then ' Turn the Start Relay Off after 450mS 650 If Timer-R(i)>450 Then Pin(i+12)=0:R(i)=Timer:? Format$(i,"%1.0f,");Format$(R(i),"%1.0f,");Format$(S(i),"%1. 0f,OK")+Chr$(13):S(i)=5 660 Exit 670 ElseIf S(i)=5 Then ' Send count updates to master every 2 seconds while pumping 680 If Timer-R(i)>2000 Then ? Format$(i,"%1.0f,");Format$(C(i),"%05.0f,9,OK"):R(i)=Timer 690 Exit 700 ElseIf S(i)=6 Then ' Wait for liquid to stop dribbling 710 If C(i)>O(i) Then O(i)=C(i):R(i)=Timer ' If no pulses after 1 Sec, then accept 720 If Timer-R(i)>1000 Then ? Format$(i,"%1.0f,");Format$(C(i),"%05.0f,9,OK"):S(i)=-1 730 Exit 740 ElseIf S(i)=7 Then ' Spare step 750 S(i)=-1:Exit 760 ElseIf S(i)=8 Then ' Stop pumping 770 Pin(i+6)=1:O(i)=C(i):Pin(i+12)=0:R(i)=Timer:S(i)=6:Exit 780 ElseIf S(i)=9 Then ' Send count to master 790 ? Format$(i,"%1.0f,");Format$(C(i),"%05.0f,9,OK"):S(i)=-1:Exit 800 Else 810 S(i)=-1:Exit 820 EndIf 830 Exit 840 Loop ' Pulser state machine processing end 900 If S(i)<>Z(i) Then ? "StepNbr Counter;";Format$(i,"%1.0f;");Format$(S(i),"%1.0f"):Z(i)=S(i ) 910 EndIf 920 Next i 930 Loop ' Counter interrupt routines. The check of the counts has been moved here to stop the pump as soon as possible ' If target reached - Stop pump, and Hold it Stopped, Save current count and timer and Set state 10000 C(1)=C(1)+MM.PCNT:If S(1)=5 Then 10020 If C(1)>=T(1) Then Pin(7)=1:O(1)=C(1):R(1)=Timer:S(1)=6 10030 EndIf:IReturn 20000 C(2)=C(2)+MM.PCNT:If S(2)=5 Then 20020 If C(2)>=T(2) Then Pin(8)=1:O(2)=C(2):R(2)=Timer:S(2)=6 20030 EndIf:IReturn 30000 C(3)=C(3)+MM.PCNT:If S(3)=5 Then 30020 If C(3)>=T(3) Then Pin(9)=1:O(3)=C(3):R(3)=Timer:S(3)=6 30030 EndIf:IReturn 40000 C(4)=C(4)+MM.PCNT:If S(4)=5 Then 40020 If C(4)>=T(4) Then Pin(10)=1:O(4)=C(4):R(4)=Timer:S(4)=6 40030 EndIf:IReturn 50000 C(5)=C(5)+MM.PCNT:If S(5)=5 Then 50020 If C(5)>=T(5) Then Pin(11)=1:O(5)=C(5):R(5)=Timer:S(5)=6 50030 EndIf:IReturn 60000 C(6)=C(6)+MM.PCNT:If S(6)=5 Then 60020 If C(6)>=T(6) Then Pin(12)=1:O(6)=C(6):R(6)=Timer:S(6)=6 60030 EndIf:IReturn Regards Gerard (vk3cg/vk3grs) |
||||
Page 4 of 7 |
Print this page |