Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 21:06 29 Apr 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 : MMBasic Flow Simulation

Author Message
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1328
Posted: 02:56am 18 Jan 2017
Copy link to clipboard 
Print this post

In the V5.3 "Reguests" thread here LouisG requested a flow simulation command. Some members suggested doing it in MMBasic was a good idea so I've improved the MMBasic V5.2 code I hashed up then and it now allows horizontal or vertical and forward or reverse code. This is running on an MX170 MM2 with an ILI9341 screen but should work with all other later variants because it uses just the basic graphics commands.

The code below is a demo to show how the subroutine works but it needs a technique to get rid of the PAUSE command that holds up the main program flow.

Can someone show how to do this but still be able to get back to the calling program with the simulation running since to use the subroutine, 'pipes' will variously need to be shut off/reversed etc while others keep 'running'.

It also needs a few symbols for valves, pumps etc which could be bitmaps or a special font set made using TassieJim's Font-Tweak utility. If it's useful that can be done later.

Greg

'FLUID FLOW SIMULATION - MMBasic V5.2 using the MX170 Micromite & ILI9341 LCD Display
' Greg Yaxley (paceman on TBS)
'-----------------------------------------------------------------------------------
cls
const white = rgb(white)
const red = rgb(red)
const blue = rgb(blue)
const Green = RGB(green)
const gray = RGB(gray)
const yellow = rgb(yellow)

dim integer stx,sty,finx,finy,diam
dim integer speed,direction

Main:
cls
BOX 70, 10, 60, 30, 2,white,blue
TEXT 72, 12, "HEADER",,,,yellow,blue
BOX 240, 80, 40, 50, 2,white,red
CIRCLE 260, 200, 20, 2,,white,yellow
speed = 20
do
flow(10,24,260,24,5,white,blue,speed,1)
flow(260,24,260,80,5,white,blue,speed,1)
flow(260,130,260,200,5,white,red,speed,1)
flow(100,200,260,200,5,white,red,speed,-1)
flow(100,105,100,200,5,white,red,speed,-1)
flow(10,105,240,105,8,blue,red,speed,-1)
loop
'----------------------------------------------
sub flow(stx,sty,finx,finy,diam,cull1%,cull2%,speed,direction)

'Fluid flow is indicated as alternate coloured segments - forward, reverse or stationary.
'Forward flow (direction) is the default and defined as left to right and top to bottom of screen.
'Reverse flow (direction = -1) is right to left or bottom to top of screen.
'Pipe start/finish positions must be entered left to right or top to bottom of screen.
'Flow simulation derives from the part-segment "offset" alternately displayed at the start of
'the "pipe" and the "speed" pause between segment movements.
'The segment length variable can be varied, or fixed in the code.

local integer tempx, tempy, segment=10, offset, count
local integer endfirstseg, stsecseg, endsecseg
if stx-finx and sty-finy <> 0 then print "Pipe must be vertical or horizontal": end
if stx>finx or sty>finy then print "Pipes must be defined left to right or top to bottom": end
offset = segment\2 'flow simulation is best when "offset" is about half the segment length
if stx = finx then goto Vertical 'test for vertical pipe

Horizontal:
tempx = stx
do
'Calc start & finish positions of two alternate coloured segments. Test for end of pipe before
'displaying each segment. Re-calculate positions after incrementing the start by two segments.
do
endfirstseg = stx + segment: stsecseg = endfirstseg+1: endsecseg = stsecseg + segment
if endfirstseg >= finx then LINE stx, sty, finx, finy, diam, cull1%: exit do
LINE stx, sty, endfirstseg, finy, diam, cull1%
if endsecseg >= finx then LINE stsecseg, sty, finx, finy, diam, cull2%: exit do
LINE stsecseg, sty, endsecseg, finy, diam, cull2%
stx = endsecseg + 1 'increment next segment-pair start position.
loop
if count = 3 then exit sub 'we're back to start condition
if speed = 0 then exit sub 'because flow is stopped, i.e. = 0
stx = tempx 'reset pipe start position
count = count+1 'flag to control whether the "offset" part-segment is needed next
Pause speed 'for the flow simulation
if direction = -1 then swap(cull1%,cull2%) 'for reverse flow to maintain correct simulation
if count < 2 or count = 3 then 'has pipe been re-filled after offset or from start?
line stx, sty, stx + offset, finy, diam, cull2% 'display the 'offset' segment in next colour
stx = stx + offset 'offset the start of 'normal' segment posns & re-fill (back to DO)
else
swap(cull1%,cull2%) 'no offset segment req'd, so change colour then re-fill pipe
endif
loop
exit sub

Vertical:
tempy = sty
do
do
endfirstseg = sty + segment: stsecseg = endfirstseg+1: endsecseg = stsecseg + segment
if endfirstseg >= finy then LINE stx, sty, finx, finy, diam, cull1%: exit do
line stx, sty, stx, endfirstseg, diam, cull1%
if endsecseg >= finy then LINE stx, stsecseg, finx, finy, diam, cull2%: exit do
LINE stx, stsecseg, finx, endsecseg, diam, cull2%
sty = endsecseg + 1 'increment next segment-pair start position
loop
if count = 3 then exit sub 'we're back to start condition
if speed = 0 then exit sub 'because flow is stopped, i.e. = 0
sty = tempy 'reset pipe start position
count = count+1 'flag to control whether the "offset" part-segment is needed next
Pause speed 'for the flow simulation
if direction = -1 then swap(cull1%,cull2%) 'for reverse flow to maintain correct simulation
if count < 2 or count = 3 then 'has pipe been re-filled after offset or from start?
line stx, sty, finx, sty + offset, diam, cull2% 'display the "offset" segment in next colour
sty = sty + offset 'offset start of seg "normal" segment posns & re-fill (back to DO)
else
swap(cull1%,cull2%) 'no offset segment req'd, so change colour then re-fill pipe
endif
loop
end sub
'----------------------
SUB Swap a%, b%
LOCAL t%
t% = a%: a% = b%: b% = t%
END SUB
'----------------------
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 844
Posted: 09:32pm 18 Jan 2017
Copy link to clipboard 
Print this post

Hi Greg,
I have had a play with this and have a SETTIMER updating in the background.
Touching the screen will reverse the flows as a simple demo of the touch interface.
The flow displays looks good, and with a few graphics using Jim's program I can see it could be quite a nice interface.
Well done.

Regards
Gerry




'FLUID FLOW SIMULATION - MMBasic V5.2 using the MX170 Micromite & ILI9341 LCD Display
' Greg Yaxley (paceman on TBS)
'-----------------------------------------------------------------------------------
'Modified to use SETTIMER to update the flows in the background. G.A.
'Touching the sreen will reverse the flows.


cls
const white = rgb(white)
const red = rgb(red)
const blue = rgb(blue)
const Green = RGB(green)
const gray = RGB(gray)
const yellow = rgb(yellow)

dim integer stx,sty,finx,finy,diam
dim integer speed,direction,speedcounter

'Setup arrays to hold data for the pipes
DIM INTEGER phase(10) 'The current write phase of each pipe display
Dim Integer pipespeed(10)= (0,0,0,0,0,0,0,0,0,0,0) ' speed divider for pipes. 0 is stopped, 1 is fastest. 9 is slowest
DIM INTEGER flowdirection(10)=(0,0,0,0,0,0,0,0,0,0,0) ' direction of flow. -1 is reverse anything else is forward or down

Main:
cls
BOX 70, 10, 60, 30, 2,white,blue
TEXT 72, 12, "HEADER",,,,yellow,blue
BOX 240, 80, 40, 50, 2,white,red
CIRCLE 260, 200, 20, 2,,white,yellow

' Start the settick timer to run as our update thread
SETTICK 10,BackGroundThread,4
T_IRQ=peek(byte peek(word &H9D000090) + 23) 'read the Touch Interupt
SetPin T_IRQ, INTL, TouchDown ' set interrupt to detect touch

'setup pipe initial direction and speed
flowdirection(3)=-1
flowdirection(4)=-1
flowdirection(5)=-1
pipespeed(0)=1
pipespeed(1)=2
pipespeed(2)=1
pipespeed(3)=4
pipespeed(4)=1
pipespeed(5)=5
do

Loop
END
'----------------------------------------------
SUB BackGroundThread
'disable the tick timer while its processing
SETTICK 0,0,4
speedcounter=speedcounter+1
' call each pipe and update if required
flow(0,10,24,260,24,5,white,blue)
flow(1,260,24,260,80,5,white,blue)
flow(2,260,130,260,200,5,white,red)
flow(3,100,200,260,200,10,white,red)
flow(4,100,105,100,200,5,white,red)
flow(5,10,105,240,105,8,blue,red)
're enable the tick timer
SETTICK 20,BackGroundThread,4
end sub

SUB TouchDown

'? touch(x)
for x =0 to 5
if flowdirection(x)=-1 then
flowdirection(x)=0
else
flowdirection(x)=-1
endif
next x
End Sub

sub flow(pipeno,stx,sty,finx,finy,diam,cull1%,cull2%)

'Fluid flow is indicated as alternate coloured segments - forward, reverse or stationary.
'Forward flow (direction) is the default and defined as left to right and top to bottom of screen.
'Reverse flow (direction = -1) is right to left or bottom to top of screen.
'Pipe start/finish positions must be entered left to right or top to bottom of screen.
'Flow simulation derives from the part-segment "offset" alternately displayed at the start of
'the "pipe" and the "speed" pause between segment movements.
'The segment length variable can be varied, or fixed in the code.


local integer tempx, tempy, segment=10, offset, count
local integer endfirstseg, stsecseg, endsecseg
'get current count for this pipe
count=phase(pipeno)
speed=pipespeed(pipeno)
direction=flowdirection(pipeno)

if speed <> 0 then
if speedcounter\speed<>speedcounter/speed Then exit sub
else
count=0
end if




if stx-finx and sty-finy <> 0 then print "Pipe must be vertical or horizontal": end
if stx>finx or sty>finy then print "Pipes must be defined left to right or top to bottom": end
offset = segment\2 'flow simulation is best when "offset" is about half the segment length
if stx = finx then goto Vertical 'test for vertical pipe

Horizontal:
tempx = stx

if direction = -1 then
if count=1 or count=3 then
swap(cull1%,cull2%) 'for reverse flow to maintain correct simulation
END IF
end IF

stx = stx + count*offset 'offset the start of 'normal' segment posns
' write the pipe segements
do
endfirstseg = stx + segment: stsecseg = endfirstseg+1: endsecseg = stsecseg + segment
if endfirstseg >= finx then LINE stx, sty, finx, finy, diam, cull1%: exit do
LINE stx, sty, endfirstseg, finy, diam, cull1%
if endsecseg >= finx then LINE stsecseg, sty, finx, finy, diam, cull2%: exit do
LINE stsecseg, sty, endsecseg, finy, diam, cull2%
stx = endsecseg + 1 'increment next segment-pair start position.
loop
' now fix up the first segement
stx = tempx
if direction = -1 then
if count = 1 or count = 2 then
line stx, sty, stx + count*offset, finy, diam, cull2%
END IF
if count=3 then
line stx, sty, stx + offset, finy, diam, cull1%
line stx+offset, sty, stx + count*offset, finy, diam, cull2%
END IF
ELSE
if count = 1 or count = 2 then
line stx, sty, stx + count*offset, finy, diam, cull2%
end if
if count = 3 then
line stx, sty, stx + offset, finy, diam, cull1%
line stx+offset, sty, stx + count*offset, finy, diam, cull2%
end if
end if


'setup for next write
count=count+1
if count=4 then count=0
phase(pipeno)=count

exit sub

Vertical:
tempy = sty
if direction = -1 then
if count=1 or count=3 then
swap(cull1%,cull2%) 'for reverse flow to maintain correct simulation
END IF
end IF

sty = sty + count*offset 'offset the start of 'normal' segment posns
' write the pipe segements
do
endfirstseg = sty + segment: stsecseg = endfirstseg+1: endsecseg = stsecseg + segment
if endfirstseg >= finy then LINE stx, sty, finx, finy, diam, cull1%: exit do
line stx, sty, stx, endfirstseg, diam, cull1%
if endsecseg >= finy then LINE stx, stsecseg, finx, finy, diam, cull2%: exit do
LINE stx, stsecseg, finx, endsecseg, diam, cull2%
sty = endsecseg + 1 'increment next segment-pair start position
loop

' now fix up the first segement
sty = tempy
if direction = -1 then
if count = 1 or count = 2 then
line stx, sty, finx , sty+ count*offset, diam, cull2%
END IF
if count=3 then
line stx, sty, finx, sty + offset, diam, cull1%
line stx, sty+offset , finx, sty + count*offset, diam, cull2%
END IF
ELSE
if count = 1 or count = 2 then
line stx, sty, finx, sty + count*offset, diam, cull2%
end if
if count = 3 then
line stx, sty, finx, sty + offset, diam, cull1%
line stx, sty+offset, finx, sty + count*offset, diam, cull2%
end if
end if

'setup for next write
count=count+1
if count=4 then count=0
phase(pipeno)=count


end sub
'----------------------
sub flowORG(stx,sty,finx,finy,diam,cull1%,cull2%,speed,direction)

'Fluid flow is indicated as alternate coloured segments - forward, reverse or stationary.
'Forward flow (direction) is the default and defined as left to right and top to bottom of screen.
'Reverse flow (direction = -1) is right to left or bottom to top of screen.
'Pipe start/finish positions must be entered left to right or top to bottom of screen.
'Flow simulation derives from the part-segment "offset" alternately displayed at the start of
'the "pipe" and the "speed" pause between segment movements.
'The segment length variable can be varied, or fixed in the code.

local integer tempx, tempy, segment=10, offset, count
local integer endfirstseg, stsecseg, endsecseg
if stx-finx and sty-finy <> 0 then print "Pipe must be vertical or horizontal": end
if stx>finx or sty>finy then print "Pipes must be defined left to right or top to bottom": end
offset = segment\2 'flow simulation is best when "offset" is about half the segment length
if stx = finx then goto Vertical 'test for vertical pipe

Horizontal:
tempx = stx
do
'Calc start & finish positions of two alternate coloured segments. Test for end of pipe before
'displaying each segment. Re-calculate positions after incrementing the start by two segments.
do
endfirstseg = stx + segment: stsecseg = endfirstseg+1: endsecseg = stsecseg + segment
if endfirstseg >= finx then LINE stx, sty, finx, finy, diam, cull1%: exit do
LINE stx, sty, endfirstseg, finy, diam, cull1%
if endsecseg >= finx then LINE stsecseg, sty, finx, finy, diam, cull2%: exit do
LINE stsecseg, sty, endsecseg, finy, diam, cull2%
stx = endsecseg + 1 'increment next segment-pair start position.
loop
if count = 3 then exit sub 'we're back to start condition
if speed = 0 then exit sub 'because flow is stopped, i.e. = 0
stx = tempx 'reset pipe start position
count = count+1 'flag to control whether the "offset" part-segment is needed next
Pause speed 'for the flow simulation
if direction = -1 then swap(cull1%,cull2%) 'for reverse flow to maintain correct simulation
if count < 2 or count = 3 then 'has pipe been re-filled after offset or from start?
line stx, sty, stx + offset, finy, diam, cull2% 'display the 'offset' segment in next colour
stx = stx + offset 'offset the start of 'normal' segment posns & re-fill (back to DO)
else
swap(cull1%,cull2%) 'no offset segment req'd, so change colour then re-fill pipe
endif
loop
exit sub

Vertical:
tempy = sty
do
do
endfirstseg = sty + segment: stsecseg = endfirstseg+1: endsecseg = stsecseg + segment
if endfirstseg >= finy then LINE stx, sty, finx, finy, diam, cull1%: exit do
line stx, sty, stx, endfirstseg, diam, cull1%
if endsecseg >= finy then LINE stx, stsecseg, finx, finy, diam, cull2%: exit do
LINE stx, stsecseg, finx, endsecseg, diam, cull2%
sty = endsecseg + 1 'increment next segment-pair start position
loop
if count = 3 then exit sub 'we're back to start condition
if speed = 0 then exit sub 'because flow is stopped, i.e. = 0
sty = tempy 'reset pipe start position
count = count+1 'flag to control whether the "offset" part-segment is needed next
Pause speed 'for the flow simulation
if direction = -1 then swap(cull1%,cull2%) 'for reverse flow to maintain correct simulation
if count < 2 or count = 3 then 'has pipe been re-filled after offset or from start?
line stx, sty, finx, sty + offset, diam, cull2% 'display the "offset" segment in next colour
sty = sty + offset 'offset start of seg "normal" segment posns & re-fill (back to DO)
else
swap(cull1%,cull2%) 'no offset segment req'd, so change colour then re-fill pipe
endif
loop
end sub
'----------------------
SUB Swap a%, b%
LOCAL t%
t% = a%: a% = b%: b% = t%
END SUB
'----------------------


Latest F4 Latest H7
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1328
Posted: 01:17am 19 Jan 2017
Copy link to clipboard 
Print this post

Thanks for taking the time with this Gerry, yours is a lot better, it's nicely smoother and fixes the PAUSE problem. I knew that a SETTICK was going to have to be involved but couldn't figure how to incorporate it - and a "background" subroutine was something that didn't even occur to me. I think I was hung up on a "simple" solution and that obviously wasn't going to happen! Now I just need a day or two to really check out what your code's doing - my programming skills are pretty limited and very rusty.

The "touch" reverse is a nifty demo (love your "read touch interrupt" line ) . It would work well with say a valve or a pump graphic but would need to be specific to a given pipe. A quick look says your code can probably do that - I need to study it.

As you say, I think this simulation could be useful, especially if people need to, or want to stick with the smaller (DIP) processor. Geoff hasn't put a flow simulation as a "control" yet on the Micromite+ firmware so the more advanced Micromites could benefit too.

I've played with Jim's FontTweak but have yet to get round to actually displaying a "graphic" I've created. I'll have to remedy that, maybe some valves in different orientations and similar for pump symbols - I should look up some standard Chem Eng symbols for ideas.

Thanks again for looking at it - I nearly drove myself nuts trying to get it to work!

Greg

 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024