Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 12:15 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 16 of 25    
Author Message
JohnS
Guru

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

It's a bit weird to do it that way. You could clear the buffer with a simple loop - using the LOC function I think.

I suppose you could otherwise maintain a variable (maybe IsComxOpen) that tracks its open/closed status but a loop may be easier and more intuitive.

JohnEdited by JohnS 2016-12-18
 
lew247

Guru

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

I tried using
IF LOC(#1) > 0 AND IF INSTR(B$,"*") THEN
B$ = ""THEN SERIAL1 'If data in COM1 then GOSUB Serial1
END IF
and then at the end of the sub do B$ = 0

hoping that would work, but it wont let me do a AND IF
 
matherp
Guru

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

  Quote  but it wont let me do a AND IF


just use AND

IF condition AND condition OR condition .... then
....
ENDIF
 
lew247

Guru

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

I've basically given up on it because it just won't do what I want
So I've decided to start again with COM 1 on the indoor unit

This is what I want it to do

Open "COM2:9600" As #1 ' OPEN the GPS serial interface

Wait for Data

Put data in a buffer (maybe it already does as it's received?)

IF the data contains BOTH "START" AND "*" 'Start of Text AND End of Transmission THEN Put the data in a new buffer

IF FieldArray$(3) = "Searching" THEN PRINT "Searching for GPS LOCK"

OR

IF FieldArray$(3) = "TIME" THEN GOSUB TIME

OR

IF FieldArray$(3) = "Weather" THEN GOSUB WEATHER

CLEAR THE BUFFER for the COM PORT ready for next transmission/reception


I already have a brilliant function (FieldArray$) that separates comma separated values thanks to MicroBlocks so that part is done
But I've lost all hope of me ever being able to do the rest - anyone able to suggest some code that does what I need?

 
plover

Guru

Joined: 18/04/2013
Location: Australia
Posts: 306
Posted: 05:33pm 17 Dec 2016
Copy link to clipboard 
Print this post

lew247
I have only checked this last page and I don't know if you copy and past code to forum

  Quote  I tried using
IF LOC(#1) > 0 AND IF INSTR(B$,"*") THEN
B$ = ""THEN SERIAL1 'If data in COM1 then GOSUB Serial1
END IF
and then at the end of the sub do B$ = 0


Should you not have a space in above after the ""

So considering what matherp posted I have reworked your quote to:


IF LOC(#1) > 0 AND INSTR(B$,"*") THEN
B$ = "" THEN SERIAL1 'If data in COM1 then GOSUB Serial1
END IF


Mind you it does not make sense to me as somes must be missing but I am no longer familiar with MMBasic. Perhaps the last THEN should be OR.Edited by plover 2016-12-19
 
TassyJim

Guru

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

Lew,
If the COM port is closed when the outside unit decides to send data, that data is lost.
Keeping the COM port on the inside unit OPEN will let you collect the data as it is sent.
The built-in buffer will store up to 255 bytes of data (or more) so, provided you read the port often enough, nothing is lost.

You decide what the outdoor unit sends, so I assume it is all relevant.

I normally set an interrupt that will run a subroutine whenever there are x byte available. The subroutine reads all the data available and adds it onto the end of a second buffer.
I then look for the 'end of line' character and if it is present, extract the bytes up to that marker and send it to the processing routine(s).

How often does the outdoor send a line of data?
That information will help determine the best way of handling it.

Jim
VK7JH
MMedit
 
lew247

Guru

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

I changed the way I was doing it encompassing what was said above
[code]
Open "COM1:19200" As #1 'Open port for HC-12 TX/RX
Do
B$ = Input$(254, #1) 'Suck everything in buffer out
IF INSTR(B$,"START") AND INSTR(B$,"*") THEN 'IF com port contains BOTH "START" and "*"
SERIAL1 'goto SERIAL1
END IF
Loop


SUB SERIAL1 'Com 1
Local D$
N = GetFieldArray(B$)
D$ = FieldArray$(2) 'Start or Time
PRINT "I GOT TO SERIAL 1"
IF D$ = "Searching" THEN
PRINT B$;"GOT TO SEARCHING SUB
ELSE
IF D$ = "TIME" THEN
PRINT "GOT TO TIME SUB"
TIME1
ELSE
IF D$ = "Weather" THEN
PRINT "GOT TO WEATHER"
WEATHER
END IF
END IF
END IF
END SUB[/code]

It doesn't print anything

The data being received by the com port is this
[quote]
START,Searching for GPS lock,*
or
START,18:12:16:10:07:23,*
or
START,Weather,weather data,*Edited by lew247 2016-12-19
 
MicroBlocks

Guru

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

It not printing anything is in this case correct.
When you compare a string you should compare the whole string.
If you want to compare only a part of the string the use the LEFT$() function.
[code]
SUB SERIAL1   'Com 1 
  Local D$  
  N = GetFieldArray(B$)
  D$ = FieldArray$(2)                                            'Start or Time
  PRINT "I GOT TO SERIAL 1"
  IF LEFT$(D$,9) = "Searching" THEN
  PRINT B$;"GOT TO SEARCHING SUB
  ELSE
   IF LEFT$(D$,4) = "TIME" THEN 
   PRINT "GOT TO TIME SUB"
   TIME1
ELSE 
   IF LEFT$(D$,7) = "Weather" THEN
    PRINT "GOT TO WEATHER"
    WEATHER
   END IF
   END IF
  END IF
END SUB
[/code]
If you have control over what is send then you could make things simpler by using a single character to identify the type of message it is.
"S" for Searching, "T" for Time, "W" for weather etc.
The best way to transmit data is to use characters that are not contained in any data to signal the start and end of a message.
The ASCII set has these even defined.
You could use STX (Start Of Text), ETX (End of Text). Also very good to use is SOH (Start of Header), EOT (End of Transmission) etc..
You can find all of the codes here: http://www.theasciicode.com.ar/

What i normally use is this:
SOH{MessageType}{TimeStamp}{Length of text}STX{Data in Text/csv format}ETX

On the receiving end i check for the SOH character. If i have that then i check how many characters i have available to make sure i have the complete header.
Then i parse the header. Once parsed i know how many characters i have to have in the buffer to decide if i have to wait fo rthe rest to arrive or if all expected characters are received i can then read them from the comport.
To check the validity of the data i check that it starts with a STX and ends with a ETX. If those checks succeed i extract the text data and send it to be processed to a subroutine that is determined by the MessageType i already parsed in the header.

This will ensure that you only process messages that are complete.
For this to work all values contained in the header have to be fixed length. The header is then also fixed length and you can test for the availability of the right amount of data in the comport buffer.





Edited by MicroBlocks 2016-12-19
Microblocks. Build with logic.
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 1000
Posted: 12:25pm 18 Dec 2016
Copy link to clipboard 
Print this post




  lew247 said   I changed the way I was doing it encompassing what was said above
[code]
Open "COM1:19200" As #1 'Open port for HC-12 TX/RX
Do
B$ = Input$(254, #1) 'Suck everything in buffer out
IF INSTR(B$,"START") AND INSTR(B$,"*") THEN 'IF com port contains BOTH "START" and "*"
SERIAL1 'goto SERIAL1
END IF
Loop


SUB SERIAL1 'Com 1
Local D$
N = GetFieldArray(B$)
D$ = FieldArray$(2) 'Start or Time
PRINT "I GOT TO SERIAL 1"
IF D$ = "Searching" THEN
PRINT B$;"GOT TO SEARCHING SUB
ELSE
IF D$ = "TIME" THEN
PRINT "GOT TO TIME SUB"
TIME1
ELSE
IF D$ = "Weather" THEN
PRINT "GOT TO WEATHER"
WEATHER
END IF
END IF
END IF
END SUB[/code]


Hi Lewis,

The DO LOOP you have will be very fast in comparison to the speed the data is coming in. You are probably grabbing the data at one or two characters at a time and as the don't pass the test they are over written on the next Input$
Amend this line so the data is appended until you have it all.

B$ = B$+ Input$(254, #1) 'Suck everything in buffer out AND ADD TO B$


Then clear B$ when you are finished with it. by amending this bit of code.

IF INSTR(B$,"START") AND INSTR(B$,"*") THEN 'IF com port contains BOTH "START" and "*"
SERIAL1 'goto SERIAL1
B$="" ' Clear the string to started gathering the next message fresh.
END IF


Regards
Gerry
Latest F4 Latest H7 FotS
 
lew247

Guru

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

Thanks everyone, wont have time to try the suggestions until the weekend, but the minute I get chance I'll get this working
 
lew247

Guru

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

I've taken a step back with the com port code as I wasn't 200% certain the outdoor unit was sending the correct data even though I did test it several times

So ...

now I'm trying to send the actual time which when I print time$ I get 14:50:24

Then I tried this code which "should" work (it's just taking the Hour, Min and Secs and printing them)

Print #2,Left$(Time$,1,2),Mid$(Time$,3,2),Right$(Time$,1,2)

However I get Error: Invalid syntax
Obviously a stupid "newbie" mistake but can anyone see what it is?

 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10215
Posted: 05:35am 23 Dec 2016
Copy link to clipboard 
Print this post

Left$ and right$ only have 2 parameters. MID$ starts at the wrong place in the stringEdited by matherp 2016-12-24
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2431
Posted: 05:54am 23 Dec 2016
Copy link to clipboard 
Print this post

Do
a$=Time$
Print Left$(a$,2), Mid$(a$,4,2), Right$(a$,2)
Loop


left$(a$,n) extracts n characters from the start of a string,
right$(a$,n) extracts n characters from the end of a string,
mid$(a$,i,n) extracts a group of n characters from the middle of a string, starting at position i.

i did post some example code in another thread that should achieve 90% of what you have been struggling with.


cheers,
rob :-)
 
lew247

Guru

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

Thanks both of you
Peter you got my brain working again and I actually got it from the hint on where I went wrong

Left$(Time$, 2),",",Mid$(TIME$, 4,2),",",Right$(TIME$, 2) actually works fine for what I want it to do.

Now I know that is working, I'll get back to getting the rest working again
 
Phil23
Guru

Joined: 27/03/2016
Location: Australia
Posts: 1667
Posted: 09:01am 23 Dec 2016
Copy link to clipboard 
Print this post

  lew247 said  Left$(Time$, 2),",",Mid$(TIME$, 4,2),",",Right$(TIME$, 2) actually works fine for what I want it to do.


In some instances I've skipped LEFT & RIGHT all together & just used MID for the sake of readability. Particularly where longer strings are involved & length is fixes.

Not sure if it would add much overhead.

Mid$(Time$,1,2),",",Mid$(TIME$,4,2),",",Mid$(TIME$,7,2)

Maybe not necessary in this case.
 
lew247

Guru

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

This is really bugging me now, I've tried everything to get it working but it wont.

My receive code is this - dead simple all I want to do at the moment is print anything that comes from the com port and STARTS with "STX" and ends with "*"

[code]Open "COM1:19200" As #1
DO
B$ = B$+ Input$(254, #1) 'Suck everything in buffer out AND ADD TO B$
B$ = Input$(200, #1) 'Suck everything in buffer out AND ADD TO B$
IF Left$(B$, 3) = "STX" Then IF INSTR(B$,"*") THEN Print B$ 'IF com port contains STX and *
END IF
LOOP[/code]

It just wont work... and I've no idea why

The tx is sending the following strings with a 1sec delay between them
STXG,* 'STXG tells me it's looking for a GPS lock
STXT,16,12,23,19,46,32,* ' STXT = current date and time
STXW,weather data,* 'Weather data


What the outdoor unit is sending is this

Print #2, "STXG" , "," , "*" 'looking for gps lock

Print #2, "STXT " , "," , year,",",month,",",day,",",Left$(Time$, 2),",",Mid$(TIME$, 4,2),",",Right$(TIME$, 2),"*" ' Send correct date/time to Indoor unit

Print #2, "STXW " , "," , bme280_read_temp()",",pressure",",humidity",",wheading",",wSpeed",",wgust",",hgust",",mmrain",",mmrain2",",hightemp",",h ightemp2",",lowtemp",",lowtemp2",",UVindex",",batt,"*"


I know the outdoor unit is sending the correct data because I've printed the receive data so I can see everything coming from the outdoor unit
It's when I try and use the "STX" at the beginning and "*" at the end the com port routine fails miserably

I've spent almost the past 48 hours on it non stop it was bugging me that much but I just cant see why it's failing

Sorry I'm sure most of you are sick of seeing me post about this

 
JohnS
Guru

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

That code will add to B$ and then throw all of B$ away and read probably no chars.

Do you mean to discard the chars???

John
 
lew247

Guru

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

No
What I want is the characters to remain in B$ until the next set of "correct" data is received by the com port
because I want to do other things with the data than just print it eventually
 
JohnS
Guru

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

Remove the second line that has Input$
(or you could make it like the previous line and add to B$ but it's rather unlikely anything has arrived in the tiny time delay between the two lines)

Also, how do you plan to make sure the STX is at the start of the string?

JohnEdited by JohnS 2016-12-24
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2431
Posted: 11:44am 23 Dec 2016
Copy link to clipboard 
Print this post

are these lines seperated by a cariage return + line feed? ie, sent from the other device using a print statement without coma or semicolon at the end.


cheers,
rob :-)Edited by robert.rozee 2016-12-24
 
     Page 16 of 25    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025