Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 19:04 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 : Newie got a few questions

     Page 15 of 25    
Author Message
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 12:36am 12 Dec 2016
Copy link to clipboard 
Print this post

Sorry Phil
The problem this time was I was overthinking, getting confused yet again by the integers, strings and so on.
I now finally have it correct
Thanks for the help and sorry everyone for asking so many "stupid" questions
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2932
Posted: 12:47am 12 Dec 2016
Copy link to clipboard 
Print this post

No question is 'stupid' - and this forum is a great place to be able to ask ANYTHING!

Glad that its working now for you. So have you got all of it as you need?
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 01:20am 12 Dec 2016
Copy link to clipboard 
Print this post

Almost

I'm having problems "decoding" the data received on the indoor unit

[code]
SUB SERIAL1 'Com1 data
Local B$
B$ = Input$(254, #1) 'Suck everything in buffer out
N = GetFieldArray(B$)
D$ = FieldArray$(0) 'Start or Time
F$ = FieldArray$(3) 'Year
G$ = FieldArray$(5) 'Month
H$ = FieldArray$(7) 'Day
z$ = FieldArray$(9) 'Hour
J$ = FieldArray$(11) 'Min
K$ = FieldArray$(13) 'Sec
If D$ = "Time" Then
PRINT B$

RTC SETtime F$,",",G$,",",H$,",",z$,",",J$,",",K$ 'Set RTC to correct local time and date

RTC GETTIME 'read the time from MM
Text 90,215, DOW$(DayOfWeek(Year, Month, Day)), CM, 1, 2, RGB(BLACK), RGB(63, 133, 195) 'Print the Day of week Under Big Ben
Text 90,270, Date$, CM, 1, 2, RGB(BLACK), RGB(63, 133, 195) 'Date
END SUB
secs=Val(Right$(Time$,2)) 'for setting the clock on the display
mins=Val(Mid$(Time$,4,2)) 'for setting the clock on the display
hours=Val(Left$(Time$,2)) 'for setting the clock on the display
ELSE T6
END SUB[/code]

Basically I want to check the data received, IF it starts with "TIME" then it carries on and sets the MM clock
IF it has anything else it carries on to T6 which is another sub

Just off to work so I'll come back to it when I get home tonight
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2932
Posted: 01:37am 12 Dec 2016
Copy link to clipboard 
Print this post

I believe you need to Put 'T6' on its own line i.e. immediately below the ELSE.
Also add an ENDIF


IF D$ = "Time" Then
....
ELSE
T6
ENDIF
 
erbp
Senior Member

Joined: 03/05/2016
Location: Australia
Posts: 195
Posted: 06:42pm 12 Dec 2016
Copy link to clipboard 
Print this post

It also looks like there is an extra END SUB in the middle of the IF statement - see below:


Text 90,270, Date$, CM, 1, 2, RGB(BLACK), RGB(63, 133, 195) 'Date
END SUB
secs=Val(Right$(Time$,2)) 'for setting the clock on the display
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 12:36am 13 Dec 2016
Copy link to clipboard 
Print this post

Thanks erbp, I did spot that and had changed it but thanks anyway

I have found the problem, it's with a Function to seperate comma seperated values
[code]Function GetFieldArray( Record$, Delimiter$, KeepQuotes ) 'Function to get array from COM port
Local Index, Char, InQuote, Count
InQuote = 0
Count = 0
FieldArray$(Count) = ""
If Delimiter$ = "" Then Delimiter$ = ","
For Index = 1 To Len(Record$)
Char = Asc(Mid$(Record$, Index, 1))
If Char = 34 Then InQuote = Not InQuote
If Not InQuote And Instr(Delimiter$, Chr$(char)) >= 1 Then
Count = Count + 1
FieldArray$(Count) = ""
Else
If Char <> 34 Or KeepQuotes Then
FieldArray$(Count) = FieldArray$(Count) + Chr$(char)
EndIf
EndIf
Next
GetFieldArray = Count + 1
End Function [/code]

Here's the "relevant" sections of code that is going wrong
[quote]IF LOC(#1) > 0 THEN SERIAL1 'If data in COM1 then GOSUB Serial1
END IF
SUB SERIAL1 'Com1 data
Local B$, Local D$
B$ = Input$(254, #1) 'Suck everything in buffer out
N = GetFieldArray(B$)
D$ = FieldArray$(0) 'Start or Time
F$ = FieldArray$(3) 'Start or Time
If D$ = "Time" Then
T10
ELSE
T6
[/quote]


What is happening is the function is working perfectly, and it does what I want it to do, it finds the 1st and 3rd values of the comma seperated string perfectly
However, when the serial port sends different data, the Function still has the original string in it's "memory" and isn't seeing the "new data" being received by the com port

Hope that made sense as I'm hopeless at explaining what I can see in my mind

Basically I need a way to clear the com port buffer, or what the Function has in it's memory every time the serial port receives new data

The serial ports sends 2 lines
One begins with "Start" and the 2nd one begins with "TIME"
It's never sees the "TIME" line because it still has "Start" in it's memory.

If I end the line with a ,"*" I can search for the * character, Is there a way to clear the "memory".buffer/Function memory" when it detects the end of receive character (*)

Hope that also made sense

Edit: to put it simply
The Function is seeing the first line from the Com port that starts with "START"
BUT
It's NOT seeing the next input from the serial port that begins with "TIME"

Edited by lew247 2016-12-14
 
panky

Guru

Joined: 02/10/2012
Location: Australia
Posts: 1114
Posted: 12:57am 13 Dec 2016
Copy link to clipboard 
Print this post

Lew, seems to me that you may have a timing/sequence issue here.
You wait on a character appearing in the COM port (the LOC(#1) > 0 function) but then data is still coming in when you go to the function to analyse the data.
You should probably set your LOC function to wait for the number of characters you expect in the line before you try to read it in with the INPUT$ function.

BTW, the INPUT$ character will read and remove any and all characters up to the number of characters you specify in the function. Eg. INPUT$(256,ANY$) will attempt to read and remove 256 characters but with your LOC(#1) > 0 command you will try to start taking characters out sometime after the first character - how many will depend on baud rate and the code between the LOC function and the INPUT$ function.

Hope that makes sense.

I sent you a PM with a suggested interrupt driven code snippet to handle this situation the other day.
Cheers,
panky.

PS. For testing, put a PRINT B$ in after your INPUT$ function to confirm what you are receiving?Edited by panky 2016-12-14
... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it!
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 01:03am 13 Dec 2016
Copy link to clipboard 
Print this post

Thanks Doug, I didn't actually see the message the other day, just looked at it now, am off to work so I'll "digest it" when I get home
Thanks

btw I did do a Print B$ and it does receive the complete string, but it doesn't clear before the next input from the com port, maybe I need to close the com port once I've done what I need it to do and then reopen it after
(you might have suggested that in your message, I'll read it properly when I'm home again)
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 03:59am 13 Dec 2016
Copy link to clipboard 
Print this post

Lew the function clears the data it returns. Also the count that tells how many fields there are is working correct.
Always check the count before doing further processing to make sure you have all the fields you need.
[code]
N = GetFieldArray(B$)
IF N = 13 THEN 'change this number to the exact number of fields you expect
'All fields accounted for
ELSE
'Not all fields available
ENDIF
[/code]
Also check the string you get from the COM port to make sure you provide the function with new data.


Microblocks. Build with logic.
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9590
Posted: 08:41am 13 Dec 2016
Copy link to clipboard 
Print this post

Congratulations Lew - you have a 25-page thread.
No easy task.
Obviously plenty of interest in the newbie questions.
Smoke makes things work. When the smoke gets out, it stops!
 
Phil23
Guru

Joined: 27/03/2016
Location: Australia
Posts: 1667
Posted: 10:17am 13 Dec 2016
Copy link to clipboard 
Print this post

  panky said   Lew, seems to me that you may have a timing/sequence issue here.
You wait on a character appearing in the COM port (the LOC(#1) > 0 function) but then data is still coming in when you go to the function to analyse the data.
You should probably set your LOC function to wait for the number of characters you expect in the line before you try to read it in with the INPUT$ function.


I had a similar situation with timing & a variable length string being received.

Initially I used LOC(#1)>140 then had a 50ms pause to allow the buffer to completely fill. That sort of worked but still had issues occasionally when 2 transmissions randomly overlapped.

Ended up fixing it by adding a test to see if the buffer is growing (about 1.04mS per character @9600), after the point the interrupt was triggered at the 140 character mark..

Code was something like this:-

[Code]
Do
BuffLength=LOC(#1)
Pause 5
Loop Until LOC(#1)=BuffLength
[/code]

Phil
 
panky

Guru

Joined: 02/10/2012
Location: Australia
Posts: 1114
Posted: 12:32pm 13 Dec 2016
Copy link to clipboard 
Print this post

Lew,

Looking at your code I think I see the problem. My comments are in bold


IF LOC(#1) > 0 THEN SERIAL1 'If data in COM1 then GOSUB Serial1
END IF

SUB SERIAL1 'Com1 data
Local B$, Local D$ 'here you declare a local variable B$
B$ = Input$(254, #1) 'Suck everything in buffer out
N = GetFieldArray(B$) ' here you call an external function using
' the local variable B$ - don't think that will work

D$ = FieldArray$(0) 'Start or Time
F$ = FieldArray$(3) 'Start or Time
If D$ = "Time" Then
T10
ELSE
T6
' missing endif and end sub but that may just be where you cut off
' the sample 'code. BTW, if you indent as I have above it is very
' simple to see missing 'endifs or end subs etc.




I tested the above scenario with this simple bit of code to check on the passing of local variables

Print "testing"
Test_B

Sub Test_B ' create a local variable
Local B$="123"
Test_A
End Sub

Sub Test_A
Print B$ ' try to use the local variable above
End Sub


Running the above code will not print the contents of B$ as you would suspect. I think your program is setting your field array at some stage with the input data and this is then staying there and never being updated by your INPUT$ function.

Again, hope this helps

panky
... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it!
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 03:39pm 13 Dec 2016
Copy link to clipboard 
Print this post

When a function is called the data that is contained in the variable is 'copied' to the functions parameter. In the function it is available under the parameter name.
It does not have to be a global variable.


Microblocks. Build with logic.
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 12:32am 14 Dec 2016
Copy link to clipboard 
Print this post

Thanks everyone
Panky, I didn't put the END SUB and END IF in the code snippet above, but it is in the actual full code

Jean, thanks, I now know what N does and I can do something similar to
IF D$ = FieldArray$(0) = "START" and N = 20 THEN
sub1 'subroutine to do something when "START" is the first word received
END IF
IF D$ = FieldArray$(0) = "TIME" and N = 12 THEN
sub2 'Subroutine to do something when "TIME" is the first word received
END IF

That "should" work I think because there are only ever 2 sentences being received by the com port and they begin with either "start" or "TIME" and I know how many fields are in each sentence (N = number of fields)

Unfortunately I can't work on this now until Friday due to work, but hopefully I can sort it now I understand what N is


EDIT: What I would like to do if it's possible is close the com port once it receives the character *

is there a way to do this by doing something like

B$ = Input$(254, #1) 'Suck everything in buffer out
IF B$ (contains "*") then close com port ?
Edited by lew247 2016-12-15
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2932
Posted: 11:14am 14 Dec 2016
Copy link to clipboard 
Print this post

IF INSTR$(B$,"*") THEN
CLOSE #1 'change to relevant file number you wish to close (note: this is NOT necessarily the COM Port Number
ENDIF
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 11:41am 14 Dec 2016
Copy link to clipboard 
Print this post

Thanks Phil, that's exactly what I needed, I think you did tell me before but I'd forgotten sorry
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 12:06am 17 Dec 2016
Copy link to clipboard 
Print this post

I've just found the time to come back to this again
[code]Open "COM1:19200" As #1 'Open port for HC-12 TX/RX

IF LOC(#1) > 0 THEN SERIAL1 'If data in COM1 then GOSUB Serial1
END IF

SUB SERIAL1 'Com1 data
Local B$, Local D$
B$ = Input$(254, #1) 'Suck everything in buffer out
IF INSTR$(B$,"*") THEN
CLOSE #1 'change to relevant file number you wish to close (note: this is NOT necessarily the COM Port Number
ENDIF
N = GetFieldArray(B$)
D$ = FieldArray$(0) 'Start or Time
If D$ = "Time" Then
T10
ELSE
T6
END IF
END SUB[/code]

[218] If INSTR$(B$,"*") Then
Error: Expected a number

I tried changing IF INSTR$(B$,"*") to IF INSTR$(B$,CHR$(42))

but this didn't work either

What I want to do is
1: detect the * process the GetFieldArray(B$) 'Fieldarray function works perfectly
2: detect either "START" or Time" as the 1st comma seperated value 'D$ which works
3: If Time is detected then go to sub T10
4: or if START is detected go to sun T6

I have been working on this when I came home eveery night this week, but I think the problem is I've actually confused myself to the state now where this is something so simple that I can't see the solution


 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10216
Posted: 12:11am 17 Dec 2016
Copy link to clipboard 
Print this post

INSTR is the correct command and not INSTR$

INSTR returns a number and hence it doesn't have a $ in the function name. It happens to take a string as the parameter

if you wrote your own version then the function definition would be

FUNCTION INSTR(A$ as STRING) AS INTEGER
...
END FUNCTION
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4036
Posted: 12:11am 17 Dec 2016
Copy link to clipboard 
Print this post

INSTR returns a number so has no final $

John
edit: d'oh beaten to it!Edited by JohnS 2016-12-18
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 12:20am 17 Dec 2016
Copy link to clipboard 
Print this post

Thank you both of you

A 2nd question if you dont mind

If I have something like
[code]
B$ = Input$(254, #1) 'Suck everything in buffer out
IF INSTR(B$,"*") THEN
CLOSE #1 'change to relevant file number you wish to close (note: this is NOT necessarily the COM Port Number
[/code]

And I then process B$ so it goes to one of 3 subroutines

Is there a way to detect IF a com port is closed before I reopen it??

because once * is detected I am closing the com port as this will clear the com buffer
But once I have done what I need to do I want to open the com port again ready for the next set of data

I could put open com 1 etc at the end of the subs, but it "may" cause a problem If I happen to use both subs sometime
 
     Page 15 of 25    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025