Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 04:25 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 4 of 7    
Author Message
Dinosaur

Guru

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

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: Australia
Posts: 205
Posted: 06:34am 23 Aug 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 311
Posted: 07:35am 23 Aug 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 205
Posted: 11:37am 23 Aug 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 205
Posted: 11:45am 23 Aug 2011
Copy link to clipboard 
Print this post

  seco61 said   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.


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: Australia
Posts: 205
Posted: 01:29pm 23 Aug 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 205
Posted: 09:13pm 23 Aug 2011
Copy link to clipboard 
Print this post

  seco61 said  
  seco61 said   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.


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.


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: Australia
Posts: 311
Posted: 10:13pm 23 Aug 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 205
Posted: 11:15pm 23 Aug 2011
Copy link to clipboard 
Print this post

  Dinosaur said  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


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: Australia
Posts: 205
Posted: 11:22pm 23 Aug 2011
Copy link to clipboard 
Print this post

  Dinosaur said  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.


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: Australia
Posts: 311
Posted: 12:04am 24 Aug 2011
Copy link to clipboard 
Print this post

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: Romania
Posts: 1697
Posted: 12:24am 24 Aug 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 205
Posted: 12:36am 24 Aug 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 311
Posted: 01:00am 24 Aug 2011
Copy link to clipboard 
Print this post

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)Edited by Dinosaur 2011-08-25
Regards
Hervey Bay Qld.
 
sparkey

Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 819
Posted: 01:20am 24 Aug 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 311
Posted: 01:50am 24 Aug 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 311
Posted: 02:59am 24 Aug 2011
Copy link to clipboard 
Print this post

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.Edited by Dinosaur 2011-08-25
Regards
Hervey Bay Qld.
 
aargee
Senior Member

Joined: 21/08/2008
Location: Australia
Posts: 255
Posted: 04:09am 24 Aug 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 311
Posted: 05:01am 24 Aug 2011
Copy link to clipboard 
Print this post

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: Australia
Posts: 205
Posted: 06:04am 24 Aug 2011
Copy link to clipboard 
Print this post

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
© JAQ Software 2024