![]() |
Forum Index : Microcontroller and PC projects : Newie got a few questions
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4036 |
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. John |
||||
lew247![]() Guru ![]() Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
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 KingdomPosts: 10215 |
just use AND IF condition AND condition OR condition .... then .... ENDIF |
||||
lew247![]() Guru ![]() Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
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: AustraliaPosts: 306 |
lew247 I have only checked this last page and I don't know if you copy and past code to forum 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. |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6269 |
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 KingdomPosts: 1702 |
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,* |
||||
MicroBlocks![]() Guru ![]() Joined: 12/05/2012 Location: ThailandPosts: 2209 |
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. Microblocks. Build with logic. |
||||
disco4now![]() Guru ![]() Joined: 18/12/2014 Location: AustraliaPosts: 1000 |
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 KingdomPosts: 1702 |
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 KingdomPosts: 1702 |
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 KingdomPosts: 10215 |
Left$ and right$ only have 2 parameters. MID$ starts at the wrong place in the string |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2431 |
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 KingdomPosts: 1702 |
Thanks both of you Peter you got my brain working again ![]() 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: AustraliaPosts: 1667 |
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 KingdomPosts: 1702 |
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 KingdomPosts: 4036 |
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 KingdomPosts: 1702 |
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 KingdomPosts: 4036 |
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? John |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2431 |
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 :-) |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |