Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 19:52 07 Jul 2025 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 : NY Geothermal Communication Code Snippets

Author Message
Paul_L
Guru

Joined: 03/03/2016
Location: United States
Posts: 769
Posted: 05:51pm 15 Jul 2016
Copy link to clipboard 
Print this post

I've finally gotten some code whipped into some sort of shape. I'd appreciate it if you guys would see if you can find my screw-ups. This is my first MMBasic code and I don't have a chip to play with.

These routines are intended to provide direct serial transfer of data between two processors (possibly Explore 64s) mounted on the same mother board. The MAIN program sends data to the USER program. The USER program sends operator settings to the MAIN program. The programs communicate using dedicated control pins similar to RS485 CTS and RTS pins. Actual communication does not start until MAIN is ready to send data.

Let me know how badly I screwed up.

Paul



''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' GeoMainCommProcs.bas v0.1, P Lepkowski, 07/15/2016
' Part of GeoMain.bas
' Global declarations are not in this file.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

MAINmainline:
''''''''''''''''''''''''''''''''''''''''
' a time critical loop which must not be delayed
' handshaking in the communication routines ensures that
' it doesn't get stuck waiting for anything
''''''''''''''''''''''''''''''''''''''''
do
GOSUB MAINreceiveSettings
GOSUB MAINreadSensors
GOSUB MAINsetoq
GOSUB MAINsetfq
' set relay outputs
GOSUB MAINsendData
loop
END

sub MAINreceiveSettings
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' MAIN is not listening
' USER must be alive and listening
' tell USER that MAIN is listening
' open com1 for receive
' wait for USER to stop listening
' receive lines into tr$(1>24)
' wait for USER to finish talking then receive last line into tr$(25)
' close com1
' tell USER that MAIN is finished listening
' extract from tr$() lines T(1>8,2>10), Z(1>11,2>10), M(5,3), MODE, ManBlr
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
LOCAL i=1, j=0, k=0, v$="", csv$="", delim$=",", tr$(25) length 60 ' 1500 bytes
if PIN(PuserAlive)=1 then ' the USER module must be alive
do : loop until PIN(UserListen)=1 ' USER must be listening
OPEN "COM1:4800,1280" AS #1 ' open serial for receive
PIN(PmainListen)=1 ' tell USER that MAIN is listening
do : loop until PIN(PuserListen)=0 ' waits for USER to start talking
do ' receive 19 58 byte strings into tr$() array
' wait for 58 bytes to arrive then load them into tr$(i)
do : loop until loc(1)>58 : INPUT #1, tr$(i) : i=i+1
loop until i>19
do ' receive 5 16 byte strings into tr$(i) array
' wait for 16 bytes to arrive then load them into tr$(i)
do : loop until loc(1)>16 : INPUT #1, tr$(i) : i=i+1
loop until i>24
do : loop until PIN(PuserListen)=1 ' wait until USER is finished talking
do : loop until loc(1)>4 ' wait for the last 4 bytes to arrive
INPUT #1, tr$(i) ' load the last string into tr$(i)
CLOSE #1 ' close serial
PIN(PmainListen)=0 ' MAIN is done listening
' extract tr$() contents into arrays S(8,9), Zs(11,9), M(5,3), and vars MODE and ManBlr
for i = 1 to 25
' the format of tr$() for the different arrays is as follows
' "S88,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4" 4+(9*6)=58 *9=522B
' "Z88,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4" 4+(9*6)=58 *11=638B
' "M88,123,123,123" 4+4+4+3=16 *5=80B
' "@12,0" 1+3+1=5B == 1245B
v$=left$(tr$(i),1) : csv$=mid$(tr$(i),2) : j=cit()
if v$="S" then 'i=1 to 8, S(1>8,1>9), 4*8*9=288B
k=0 : do while len(csv$)>0 : k=k+1 : Z(j,k)=cit() : loop
elseif v$="Z" then 'Zs(1>11,1>9), 4*11*8=352B
k=0 : do while len(csv$)>0 : k=k+1 : Z(j,k)=cit() : loop
elseif v$="M" then '1=20 to 24
k=0 : do while len(csv$)>0 : k=k+1 : M(j,k)=cit() : loop
else 'v$="@" 'i=25
MODE=val(mid$(v$,2)) : ManBlr=val(mid$(v$,5))
endif
next 'i
end if
end sub 'MAINreceiveSettings

sub MAINsendData
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' USER must be alive
' build elements tr$(1>4) from arrays T(1>8), Zt(1>11), Tgain(1>5) and 20 vars
' wait for USER to be listening
' tell USER that MAIN is talking
' open #1 for output : send tr$(1>4) : close #1
' tell USER that main is finished talking
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
LOCAL i=1, j=0, k=0, m=1, csv$="", tr$(4) length 70 ' 280 bytes
if PIN(PuserAlive)=1 then
' build tr$(1) from T(1>8)
' "T,001.4,002.4,003.4,004.4,005.4,006.4,007.4,008.4" 2+(8*6)=50B
csv$="T":for j=1 to 8:csv$=csv$+","+str$(T(j),3,1):next:tr$(m)=csv$:m=m+1 'm=2

' build tr$(2) from Zt(1>11)
' "Z,001.4,002.4,003.4,004.4,005.4,006.4,007.4,008.4,009.4,010.4,011.4" 2+(11*6)=68B
csv$="Z":for j=1 to 11:csv$=csv$+","+str$(Zt(j),3,1):next:tr$(m)=csv$:m=m+1 'm=3

' build tr$(3) from Tgain(1>5)
' "G,001.4,002.4,003.4,004.4,005.4" 3+(5*6)=33B
csv$="G":for j=1 to 5:csv$=csv$+","+str$(Tgain(j),3,1):next:tr$(m)=csv$:m=m+1 'm=4

' build tr$(4) from these 20 vars
' oq=0, fq=0, Qutilfail, Qgenon, Qfrnheatgo, Qfrncoolgo, Qfrnstop, Qpumpsgo
' Qcomp, Qrevvlv, Qyrdp, Qtnkp, Qdp1, Qdp2, Qdp3, Qdp4, Qdp5, Qdp6, Qdpah, Qblr
' "@,##,##,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#" 1+(2*3)+(2*17)+1=42B == 193B
csv$="@,"+str$(oq,2)+","+str$(fq,2)
csv$=csv$+","+str$(Qutilfail,1)+","+str$(Qgenon,1)
csv$=csv$+","+str$(Qfrnheatgo,1)+","+str$(Qfrncoolgo,1)
csv$=csv$+","+str$(Qfrnstop,1)+","+str$(Qpumpsgo,1)
csv$=csv$+","+str$(Qcomp,1)+","+str$(Qrevvlv,1)+","+str$(Qyrdp,1)+","+str$(Qtnkp,1)
csv$=csv$+","+str$(Qdp1,1)+","+str$(Qdp2,1)+","+str$(Qdp3,1)+","+str$(Qdp4,1)+","+str$(Qdp5,1)
csv$=csv$+","+str$(Qdp6,1)+","+str$(Qdpah,1)+","+str$(Qblr,1)
tr$(m)=csv$ 'm=4

do : loop until PIN(PuserListen)=1 ' wait for USER to listen
PIN(PmainListen)=0 ' tell USER that MAIN is talking
OPEN "COM1:4800" AS #1 ' open serial for transmit
for i=1 to 4
PRINT #1, tr$(i) ' send 4 strings
next 'i
CLOSE #1 ' close serial
PIN(PmainListen)=1 ' tell USER that MAIN is finished talking
end if
end sub 'MAINsendData

function cit ' csv$, c
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' inherits locals csv$ and delim$ from calling routine
' csv$ == "88,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4", delim$=","
' returns val(csv$) as cit and remainder of csv$ after first delimiter
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
local zpos, part$
if instr(csv$,delim$) then ' found the delimiter
zpos=instr(csv$,delim$) ' delimiter location
part$=left(csv$,zpos-1) ' left of delimiter
csv$=mid$(csv$,zpos+1) ' right of delimiter
cit=val(part$) ' return value
else
cit=val(csv$) ' return value
csv$="" ' nothing left
end if
end function


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' GeoUserCommProcs.bas v0.1, P Lepkowski, 07/15/2016
' Part of GeoUser.bas
' Global declarations are not in this file.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

USERmainline:
''''''''''''''''''''''''''''''''''''''''
' interrupts in this program will trigger touch screen data input
''''''''''''''''''''''''''''''''''''''''
PuserAlive=1
do
GOSUB USERreceiveData
GOSUB USERdisplayData
GOSUB USERrelayOutputs
GOSUB USERsendSettings
GOSUB USERbuildDataFile
loop
END

sub USERsendSettings
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' USER is listening
' builds tr$(1>25) array strings from arrays and vars
' tr$(1>8) from S(1>8,1>9),
' tr$(9>19) from Zs(1>11,1>9),
' tr$(20>24) from M(1>5,1>3),
' tr$(25) from vars MODE and ManBlr
' wait for MAIN to listen, tell MAIN that USER is talking,
' open #1 for transmit, send tr$(1>25), close #1, tell MAIN that USER is done talking
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
LOCAL i=0, j=0, k=1, csv$="", tr$(25) length 60 ' 1500 bytes
for i=1 to 8 'S(1>8,1>9)
csv$="S"+str$(i,2):for j=1 to 9:csv$=csv$+","+str$(T(i,j),3,1):next:tr$(k)=csv$:k=k+1
' "S88,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4" 4+(9*6)=58 *9=522B
next 'k=9
for i=1 to 11 'Zs(1>11,1>9)
csv$="Z"+str$(i,2):for j=1 to 9:csv$=csv$+","+str$(Z(i,j),3,1):next:tr$(k)=csv$:k=k+1
' "Z88,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4" 4+(9*6)=58 *11=638B
next 'k=19
for i=1 to 5 'M(1>5,1>3)
csv$="M"+str$(i,2):for j=1 to 3:csv$=csv$+","+str$(M(i,j),3):next:tr$(k)=csv$:k=k+1
' "M88,123,123,123" 4+4+4+3=16 *5=80B
next 'k=24
csv$="@"+str$(MODE,2)+","+str$(ManBlr,1):tr$(k)=csv$ ' "@12,0" 1+3+1=5B == 1245B k=25
do : loop until PIN(PmainListen)=1 ' wait for MAIN to listen
PIN(PuserListen)=0 ' tell MAIN that USER is talking
OPEN "COM1:4800,1280" AS #1 ' open serial for transmit
for i=1 to 25
print #1, tr$(i) ' send 25 strings
next ' 1430 bytes
CLOSE #1 ' close serial
PIN(PuserListen)=1 ' tell MAIN that USER is finished talking
end sub 'USERsendSettings

sub USERreceiveData
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' tell MAIN that USER is listening
'
' wait for PmainListen=0 then open com1 : set PuserListen=1
' receive lines into tr$(1>3)
' wait for PmainListen=1 then receive last line into tr$(4), close com1, set PuserListen=0
' extract from tr$() lines T(1>8,2>10), Z(1>11,2>10), M(5,3), MODE, ManBlr
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
LOCAL i=1, j=0, k=0, v$="", csv$="", delim$=",", tr$(4) length 70 ' 280B
do : loop until PIN(PmainListen)=1 ' MAIN must be listening
OPEN "COM1:4800,1024" AS #1 ' open serial for receive
PIN(PuserListen)=1 ' tell MAIN that USER is listening
do : loop until PIN(PmainListen)=0 ' wait for MAIN to start talking
' receive 50 byte string into tr$(1)
do : loop until loc(#1)>50 : INPUT #1, tr$(i) : i=i+1
' receive 69 byte string into tr$(2)
do : loop until loc(#1)>69 : INPUT #1, tr$(i) : i=i+1
' receive 33 byte string into tr$(3)
do : loop until loc(#1)>33 : INPUT #1, tr$(i) : i=i+1
' receive 42 byte string into tr$(4)
' oq=0, fq=0, Qutilfail, Qgenon, Qfrnheatgo, Qfrncoolgo, Qfrnstop, Qpumpsgo
' Qcomp, Qrevvlv, Qyrdp, Qtnkp, Qdp1, Qdp2, Qdp3, Qdp4, Qdp5, Qdp6, Qdpah, Qblr
' "@##,##,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#" 1+(2*3)+(2*17)+1=42B == 193B
do : loop until loc(#1)>41 : INPUT #1, tr$(i)
CLOSE #1 ' close serial
PIN(PuserListen)=0 ' tell MAIN that USER is finished talking
' extract tr$() contents into arrays T(8), Zt(11), Tgain(5), and vars MODE and ManBlr
for i=1 to 4 'tr$(4), T(1>8), Zt(1>11), Tgain(1>5)
csv$=mid$(tr$(i),3)
if left$(tr$(i),1)="T" then ' extract T(1>8) from tr$(1)
'"T,001.4,002.4,003.4,004.4,005.4,006.4,007.4,008.4" 2+(8*6)=50B
k=0 : do while len(csv$)>0 : k=k+1 : T(k)=cit() : loop
else if left$(tr$(i),1)="Z" then ' extract Zt(1>11) from tr$(2)
'"Z,001.4,002.4,003.4,004.4,005.4,006.4,007.4,008.4,009.4,010.4,011.4" 2+(11*6)=68B
k=0 : do while len(csv$)>0 : k=k+1 : Zt(k)=cit() : loop
else if left$(tr$(i),1)="G" then ' extract Tgain(1>5) from tr$(3)
'"G,001.4,002.4,003.4,004.4,005.4" 3+(5*6)=33B
k=0 : do while len(csv$)>0 : k=k+1 : Tgain(k)=cit() : loop
else '"@"
' extract these 20 vars from tr$(4)
' oq=0, fq=0, Qutilfail, Qgenon, Qfrnheatgo, Qfrncoolgo, Qfrnstop, Qpumpsgo
' Qcomp, Qrevvlv, Qyrdp, Qtnkp, Qdp1, Qdp2, Qdp3, Qdp4, Qdp5, Qdp6, Qdpah, Qblr
' "@,##,##,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#" 1+(2*3)+(2*17)+1=42B == 193B
oq=cit():fq=cit():Qutilfail=cit():Qgenon=cit():Qfrnheatgo=cit():Qfrncoolgo=cit()
Qfrnstop=cit():Qpumpsgo:Qcomp=cit():Qrevvlv=cit():Qyrdp=cit():Qtnkp=cit()
Qdp1=cit():Qdp2=cit():Qdp3=cit():Qdp4=cit():Qdp5=cit():Qdp6=cit():Qdpah=cit():Qblr=cit()
end if
next 'i
end sub 'USERreceiveData

function cit ' csv$, c
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' inherits locals csv$ and delim$ from calling routine
' csv$ == "88,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4", delim$=","
' returns val(csv$) as cit and remainder of csv$ after first delimiter
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
local zpos, part$
if instr(csv$,delim$) then ' found the delimiter
zpos=instr(csv$,delim$) ' delimiter location
part$=left(csv$,zpos-1) ' left of delimiter
csv$=mid$(csv$,zpos+1) ' right of delimiter
cit=val(part$) ' return value
else
cit=val(csv$) ' return value
csv$="" ' nothing left
end if
end function


 
Paul_L
Guru

Joined: 03/03/2016
Location: United States
Posts: 769
Posted: 06:20pm 15 Jul 2016
Copy link to clipboard 
Print this post

Hmpppff, this web site uglifies the code!

Here are the original files so that your eyes don't go screwy reading it!

Paul
2016-07-16_041927_GeoMainCommProcs.zip
2016-07-16_041948_GeoUserCommProcs.zip
 
ajkw
Senior Member

Joined: 29/06/2011
Location: Australia
Posts: 290
Posted: 09:32pm 15 Jul 2016
Copy link to clipboard 
Print this post

  Quote  Hmpppff, this web site uglifies the code!


Try using the forum "code" formatting button



DO
STUFF
IF STUFF THEN
MORE STUFF
ENDIF
LOOP

[ /CODE] ' WITHOUT THE SPACE


 
Phil23
Guru

Joined: 27/03/2016
Location: Australia
Posts: 1667
Posted: 11:51pm 15 Jul 2016
Copy link to clipboard 
Print this post

I'd probably drop the GOSUB's & use the more current syntax.

[Code]
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' GeoMainCommProcs.bas v0.1, P Lepkowski, 07/15/2016
' Part of GeoMain.bas
' Global declarations are not in this file.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

MAINmainline:
''''''''''''''''''''''''''''''''''''''''
' a time critical loop which must not be delayed
' handshaking in the communication routines ensures that
' it doesn't get stuck waiting for anything
''''''''''''''''''''''''''''''''''''''''
do
MAINreceiveSettings
MAINreadSensors
MAINsetoq
MAINsetfq
' set relay outputs
MAINsendData
loop
END

sub MAINreceiveSettings
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' MAIN is not listening
' USER must be alive and listening
' tell USER that MAIN is listening
' open com1 for receive
' wait for USER to stop listening
' receive lines into tr$(1>24)
' wait for USER to finish talking then receive last line into tr$(25)
' close com1
' tell USER that MAIN is finished listening
' extract from tr$() lines T(1>8,2>10), Z(1>11,2>10), M(5,3), MODE, ManBlr
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' [/code]

Noticed an apostrophe here too I wasn't sure about.
First line.

[Code]
function cit ' csv$, c
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' inherits locals csv$ and delim$ from calling routine
' csv$ == "88,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4", delim$=","
' returns val(csv$) as cit and remainder of csv$ after first delimiter
[/code]

Cheers.
 
Paul_L
Guru

Joined: 03/03/2016
Location: United States
Posts: 769
Posted: 11:46am 17 Jul 2016
Copy link to clipboard 
Print this post

@ajkw,

Thanks for pointing me to the code button!

@Phil,

I wasn't aware that the GOSUB is not optional. I'll cut them out.

That apostrophe on the label line,

function cit ' csv$, c

is my way of telling myself that function cit will use inherited variables csv$ and c without sticking them in as actual passed parameters like this

function cit(csv$,c)

The referenced variable c is in error, it should have referenced delim$ like this

function cit ' csv$, delim$

Will the remark interfere with the label line?

Will a procedure or function inherit variables declared as LOCAL in a calling procedure like this?

sub labelA
LOCAL csv$, delim$=","
csv$="something"
labelB ' this is a GOSUB
end sub 'label A

sub labelB
' do something with csv$ and delim$
csv$=csv$+delim$
end sub 'labelB

Edited by Paul_L 2016-07-18
 
Paul_L
Guru

Joined: 03/03/2016
Location: United States
Posts: 769
Posted: 12:04pm 17 Jul 2016
Copy link to clipboard 
Print this post

I think I just spotted one of my screw-ups myself.

In both sub MAINreceiveSettings and sub USERreceiveData I said something like

do : loop until loc(1)>41 : INPUT #1, tr$(i)

but the string has a format something like

' "S88,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4"

which would cause INPUT #1 to stop reading at the first delimiter "," I think.

I think I should have used LINE INPUT #1, tr$(I) like this

do : loop until loc(1)>41 : LINE INPUT #1, tr$(i)


Am I correct???????

 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6269
Posted: 01:18pm 17 Jul 2016
Copy link to clipboard 
Print this post

Using LINE INPUT is OK but what happens if your sending device fails?
You will be stuck in a loop waiting for the 41 characters or waiting for the complete line to arrive.

It is more robust to check for the number of characters available and read that number only. Add the received character onto the end of a buffer$ and check for your 'end of data' character (which could be CR/LF)


You can try much of the code yourself, but not serial comms.
Using TeraTerm (or MMEdit) connect using telnet via TCPIP to tassyjim.ddns.net port 3002
This is a MX170 with MMBasic V5.2
It has a DHT22 temperature/humidity module on pin 26
A DS18B20 temperature module on pin 24
a LED on pin 23 as an output
and a BMP085 pressure module on I2C

You are free to experiment.
I reload my software on a regular basis so deleting what's there is OK.

My power is supposed to be off for 6 - 7 hours today so if you can't connect, that's why.


Jim
VK7JH
MMedit
 
Paul_L
Guru

Joined: 03/03/2016
Location: United States
Posts: 769
Posted: 11:50pm 21 Jul 2016
Copy link to clipboard 
Print this post

  TassyJim said   Using LINE INPUT is OK but what happens if your sending device fails?
You will be stuck in a loop waiting for the 41 characters or waiting for the complete line to arrive.

It is more robust to check for the number of characters available and read that number only. Add the received character onto the end of a buffer$ and check for your 'end of data' character (which could be CR/LF)


You can try much of the code yourself, but not serial comms.
Using TeraTerm (or MMEdit) connect using telnet via TCPIP to tassyjim.ddns.net port 3002
This is a MX170 with MMBasic V5.2
It has a DHT22 temperature/humidity module on pin 26
A DS18B20 temperature module on pin 24
a LED on pin 23 as an output
and a BMP085 pressure module on I2C

You are free to experiment.
I reload my software on a regular basis so deleting what's there is OK.

My power is supposed to be off for 6 - 7 hours today so if you can't connect, that's why.


Jim


Thanks Jim! I don't want to get stuck in any loops. I don't like the idea of repeated calling LOC() and concatenating characters onto a string. I think it would be better to add USERdone and MAINdone flags and wait for the transmitting cpu to finish before trying to read any of the strings. I have implemented this idea in the following code.

Telneting half way around the globe to play in your MX170 seems like a bad idea to me. After all, I'm a POLACK and I will probably find a way to burn your house down. I will try to find whatever bugs I can find by inspection. I'll also attempt to run it under Windoze.

Testing this thing thoroughly will be nearly impossible. It is dependent on the slowly changing temperature readings from all those sensors. It probably won't be tested thoroughly until it is actually hooked up to the machinery. It reminds me of trying to test 747 Autopilot computers without hooking them up to the aircraft and actually flying the thing.

Anyway here's newer code for the communication routines. I'd appreciate it if you guys could take another look at it.

Paul



''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' GeoUser2Main.bas v0.3, P Lepkowski, 07/22/2016
'' Test USER to MAIN data transfer
'' Global declarations are not in this file.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

sub USERsendSettings
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The arrays that must be copied from USER to MAIN are
' S(8,9) holds settings of the freon and water loops, 480B, ~USER>MAIN
' Zs(11,9) holds settings from the USER module, 660B ~USER>MAIN
' M(5,3) holds time limit settings in seconds, 130B ~USER>MAIN
' Q(9) holds command flags, 33B ~USER>MAIN == 1303B
'
' initially USER is listening
' builds tr$(1>25) array strings from arrays and vars
' tr$(1>8) from S(1>8,1>9),
' tr$(9>19) from Zs(1>11,1>9),
' tr$(20>24) from M(1>5,1>3),
' tr$(25) from Q(1>9)
' wait for MAIN to listen, tell MAIN that USER is not listening
' open #1 for transmit, send tr$(1>25), close #1, tell MAIN that USER is listening
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
LOCAL i=0, j=0, c$="", d$=",",tr$(25) length 60 ' 1500 bytes

' build tr$(25)

' build tr$(1>8) from S(1>8,1>9)
' "S,##,001.4,002.4,003.4,004.4,005.4,006.4,007.4,008.4,009.4" 60B * 8 = 480B
for i=1 to 8
c$="S,"+str$(i,2)
for j=1 to 9
c$=c$+d$+str$(S(i,j),3,1)
next 'j
tr$(i)=c$
next 'i tr$(1>8) filled

' build tr$(9>19) from Z(1>11,1>9)
' "Z,##,001.4,002.4,003.4,004.4,005.4,006.4,007.4,008.4,009.4" 60B * 11 = 660B
for i=1 to 11
c$="Z,"+str$(i,2)
for j=1 to 9
c$=c$+d$+str$(Z(i,j),3,1)
next 'j
tr$(i+8)=c$
next 'i tr$(1>19) filled

for i=1 to 5 'build tr$(20>24) from M(1>5,1>3) "M,##,001,002,003,004,005" 26B * 5 = 130B
c$="M,"+str$(i,2)
for j=1 to 3
c$=c$+d$+str$(M(i,j),3)
next 'i
tr$(i+19)=c$
next 'i tr$(1>24) filled

c$="Q,00" ' build tr$(25) from Q(1>9) "Q,##,01,02,03,04,05,06,07,08,09" 33B
for j=1 to 9
c$=c$+d$+str$(Q(i),2)
next 'i
tr$(25)=c$

' tr$(1>25) is now 1303B including cr/lf pairs.

do : loop until PIN(PmainListen)=1 ' wait for MAIN to listen
PIN(PuserListen)=0 ' tell MAIN that USER is not listening
OPEN "COM1:9600,1350" AS #1 ' open serial for transmit buffer 2816B
for i=1 to 25 : print #1, tr$(i) : next ' i ' send 25 strings 2570B = 20560b = 2.15 sec
CLOSE #1
PIN(PuserDone)=1 : PIN(PuserListen)=1 ' tell MAIN that USER is finished talking
do : loop until PIN(PmainListen)=0 : PIN(PuserDone)=0 ' MAIN acknowledges receipt after 2.15 sec
end sub 'USERsendSettings

sub MAINreceiveSettings
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The arrays that must be copied from USER to MAIN are
' S(8,9) holds settings of the freon and water loops, 480B, ~USER>MAIN
' Zs(11,9) holds settings from the USER module, 660B ~USER>MAIN
' M(5,3) holds time limit settings in seconds, 130B ~USER>MAIN
' Q(9) holds command flags, 33B ~USER>MAIN == 1303B
'
' initially USER must be listening, MAIN is not done, MAIN is listening
' USER will stop listening, send tr$(1>25), begin listening, announce done
' open com1 for receive
' wait for USER to stop listening
' receive lines into tr$(1>24)
' wait for USER to finish talking then receive last line into tr$(25)
' close com1
' tell USER that MAIN is finished listening
' extract from tr$() lines T(1>8,2>10), Z(1>11,2>10), M(5,3), MODE, ManBlr
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
LOCAL i=1, j=0, k=0, v$="", c$="", d$=",", tr$(25) length 60 ' 1500 bytes
if PIN(PuserListen)=1 then ' the USER module is listening so it must be alive
OPEN "COM1:9600,1350" AS #1
PIN(PmainListen)=1 ' tell USER that MAIN is listening
do : loop until PIN(PuserListen)=0 ' waits for USER to start talking
do : loop until PIN(PuserDone)=1 ' waits for USER to finish talking then read 25 strings
for i=1 to 25
LINE INPUT #1, tr$(i)
next ' i read 25 strings 2570B = 20560b = 2.15 sec
CLOSE #1
PIN(PmainListen)=0 ' MAIN acknowledges receipt after 2.15 sec USER sets PuserDone=0

for i = 1 to 25 ' extract tr$() contents into arrays S(8,9), Zs(11,9), M(5,3), Q(9)
' the format of tr$() is as follows
' S(1>8,1>9) "S,##,001.4,002.4,003.4,004.4,005.4,006.4,007.4,008.4,009.4" 60B * 8 = 480B
' Z(1>11,1>9) "Z,##,001.4,002.4,003.4,004.4,005.4,006.4,007.4,008.4,009.4" 60B * 11 = 660B
' M(1>5,1>3) "M,##,001,002,003,004,005" 26B * 5 = 130B
' Q(1>9) "Q,##,01,02,03,04,05,06,07,08,09" 33B
c$=tr$(i) : j=val(mid$(c$,3,2)) : v$=left$(c$,1) : c$=mid$(tr$(i),6)
if v$="S" then 'S(1>8,1>9) i=1 to 8
k=0 : do while len(c$)>0 : k=k+1 : Z(j,k)=cx() : loop
elseif v$="Z" then 'Zs(1>11,1>9) i=9 to 19
k=0 : do while len(c$)>0 : k=k+1 : Z(j,k)=cx() : loop
elseif v$="M" then 'M(1>5,1>3) i=20 to 24
k=0 : do while len(c$)>0 : k=k+1 : M(j,k)=cx() : loop
else 'v$="Q" 'Q(1>9) i=25
k=0 : do while len(c$)>0 : k=k+1 : Q(k) =cx() : loop
end if
next 'i
end if
end sub 'MAINreceiveSettings

sub MAINsendData
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The arrays that must be copied from MAIN to USER are
' T(8) holds temperatures of the freon and water loops, 54B, ~MAIN>USER
' Zt(11) holds air temperatures, 72B, ~MAIN>USER
' Tgain(5) holds differential temperatures for the freon and water loops, 36B ~MAIN>USER
' C(14) holds status flags, 34B ~MAIN>USER
' X(12) holds trip flags, 30B ~MAIN>USER
' Mt(14,3) holds time totals, 228B ~MAIN>USER == 454B
'
' USER must be alive
' build elements tr$(1>4) from arrays T(1>8), Zt(1>11), Tgain(1>5) and 20 vars
' wait for USER to be listening
' tell USER that MAIN is talking
' open #1 for output : send tr$(1>4) : close #1
' tell USER that main is finished talking
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
if PIN(PuserListen)=1 then
LOCAL i=1, j=0, k=0, m=1, c$="", d$=",", tr$(8) length 80 ' 640 bytes
' build tr$(8)

' build tr$(1) from T(1>8)
' "T,00,001.4,002.4,003.4,004.4,005.4,006.4,007.4,008.4" 54B
c$="T,00"
for j=1 to 8 : c$=c$+d$+str$(T(j),3,1) : next : tr$(1)=c$

' build tr$(2) from Zt(1>11)
' "Z,00,001.4,002.4,003.4,004.4,005.4,006.4,007.4,008.4,009.4,010.4,011.4" 72B
c$="Z,00"
for j=1 to 11 : c$=c$+d$+str$(Zt(j),3,1) : next : tr$(2)=c$

' build tr$(3) from Tgain(1>5) "G,00,001.4,002.4,003.4,004.4,005.4" 36B
c$="G,00"
for j=1 to 5 : c$=c$+d$+str$(Tgain(j),3,1): next : tr$(3)=c$

' build tr$(4) from C(1>14) "C,00,1,2,3,4,5,6,7,8,9,0,1,2,3,4" 5+(13*2)+1=34B
c$="C,00"
for j=1 to 14 : c$=c$+d$+str$(C(j),1) : next : tr$(4)=c$

' build tr$(5) from X(1>12) "X,00,1,2,3,4,5,6,7,8,9,0,1,2" 30B
c$="X,00"
for j=1 to 12 : c$=c$+d$+str$(X(j),1) : next : tr$(5)=c$

' build tr$(6>8) from Mt(14,3)
' "M,ii,0001,0002,0003,0004,0005,0006,0007,0008,0009,0010,0011,0012,0013,0014" 76B * 3 = 228B
for i=1 to 3
c$="M"+d$+str$(i,2)
for j=1 to 14 : c$=c$+d$+str$(Mt(j,i),4) : next : tr$(i)=c$
next 'i

' tr$(1>8) is now 454B including the cr/lf pairs
' USER is listening
PIN(PmainListen)=0 ' tell USER that MAIN is not listening
OPEN "COM1:9600,512" AS #1 ' open serial for transmit buffer 512B
for i=1 to 8 : PRINT #1, tr$(i) : next 'i send 8 strings, 438B = 3504b = 0.365 sec
CLOSE #1
PIN(PmainDone)=1 : PIN(PmainListen)=1 ' tell USER that MAIN is finished talking
do : loop until PIN(PuserListen)=0 : PIN(PmainDone)=0 ' USER acks receipt after 0.365 sec
end if
end sub 'MAINsendData

sub USERreceiveData
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The arrays that must be copied from MAIN to USER are
' T(8) holds temperatures of the freon and water loops, 54B, ~MAIN>USER
' Zt(11) holds air temperatures, 72B, ~MAIN>USER
' Tgain(5) holds differential temperatures for the freon and water loops, 36B ~MAIN>USER
' C(14) holds status flags, 34B ~MAIN>USER
' X(12) holds trip flags, 30B ~MAIN>USER
' Mt(14,3) holds time totals, 228B ~MAIN>USER == 454B
'
' USER is listening, open com1 for receive, wait for MAIN to talk
' receive lines into tr$(1>3)
' wait for PmainListen=1 then receive last line into tr$(4), close com1, set PuserListen=0
' extract from tr$() lines T(1>8,2>10), Z(1>11,2>10), M(5,3), MODE, ManBlr
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
LOCAL i=1, j=0, k=0, v$="", c$="", d$=",", tr$(8) length 80 ' 280B
OPEN "COM1:9600,512" AS #1 ' open serial for receive
PIN(PuserListen)=1 ' tell MAIN that USER is listening
do : loop until PIN(PmainListen)=0 ' wait for MAIN to start talking
do : loop until PIN(PmainDone)=1 ' waits for USER to finish talking then read 8 strings
for i=1 to 8
LINE INPUT #1, tr$(i)
next ' i read 8 strings, 454B = 3632b = 0.378 sec
CLOSE #1
PIN(PuserListen)=0 ' USER acks receipt after 0.378 sec MAIN then sets PmainDone=0

for i=1 to 8 ' extract tr$(8) into arrays T(8), Zt(11), Tgain(5), C(14), X(12), Mt(14,3)
' T(8) "T,00,001.4,002.4,003.4,004.4,005.4,006.4,007.4,008.4" 54B
' Zt(11) "Z,00,001.4,002.4,003.4,004.4,005.4,006.4,007.4,008.4,00.4,010.4,011.4" 72B
' Tgain(5) "G,00,001.4,002.4,003.4,004.4,005.4" 36B
' C(14) "C,00,1,2,3,4,5,6,7,8,9,0,1,2,3,4" 34B
' X(12) "X,00,1,2,3,4,5,6,7,8,9,0,1,2" 30B
' Mt(14,3) "M,ii,0001,0002,0003,0004,0005,0006,0007,0008,0009,0010,0011,0012,0013,0014" 76B

c$=tr$(i) : j=val(mid$(c$,3,2)) : v$=left$(c$,1) : c$=mid$(tr$(i),6)
if v$="T" then ' extract T(1>8) from c$
k=0 : do while len(c$)>0 : k=k+1 : T(k)=cx() : loop
else if v$="Z" then ' extract Zt(1>11) from c$
k=0 : do while len(c$)>0 : k=k+1 : Zt(k)=cx() : loop
else if v$="G" then ' extract Tgain(1>5) from c$
k=0 : do while len(c$)>0 : k=k+1 : Tgain(k)=cx() : loop
else if v$="C" then ' extract C(1>14) from c$
k=0 : do while len(c$)>0 : k=k+1 : C(k)=cx() : loop
else if v$="X" then ' extract X(1>12) from c$
k=0 : do while len(c$)>0 : k=k+1 : X(k)=cx() : loop
else ' v$="M" extract M(1>14,1>3) from c$
k=0 : do while len(c$)>0 : k=k+1 : M(k,j)=cx() : loop
end if
next 'i
end sub 'USERreceiveData

function cx ' inherits c$, d$
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' c$ == "88,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4,123.4", d$=","
' returns val(c$) as cx and remainder of c$ after first delimiter
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
local zpos, part$
if instr(c$,d$) then ' found the delimiter
zpos=instr(c$,d$) ' delimiter location
part$=left(c$,zpos-1) ' left of delimiter
c$=mid$(c$,zpos+1) ' right of delimiter
cx=val(part$) ' return value
else
cx=val(c$) ' return value
c$="" ' nothing left
end if
end function


 
Print this page


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

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025