![]() |
Forum Index : Microcontroller and PC projects : Rounding FLOAT?
Author | Message | ||||
Phil23 Guru ![]() Joined: 27/03/2016 Location: AustraliaPosts: 1667 |
Is there no inbuilt Function to round floating variables? I know about STR$, but that's turning a Float into a String. I wanted to keep the virable as a floating number, but rounded to 2 decimals. What I had planned:- [Code] Sub SendData 'Output Data to Com port Print #1,"AirTemp=";TmpHpAir;":";(100-TmpHpAir);"#" Print #1,"EvaTemp=";TmpHpEva;";";(100-TmpHpEva);"#" Print #1,"CmpTemp=";TmpHpCmp;";";(100-TmpHpCmp);"#" Print #1,"InpTemp=";TmpHpInp;";";(100-TmpHpInp);"#" Print #1,"OutTemp=";TmpHpOut;";";(100-TmpHpOut);"#" End Sub [/code] The intention was to make a string that could be validated at the receiving end, (by adding the two values together & check they equal 100). Without rounding, I get numbers that don't add to the 100. [Code] 4.60315: 95.3969# 4.76138: 95.2386# 4.56357: 95.4364# 4.44473: 95.5553# 4.56357: 95.4364# 4.72183: 95.2782# [/code] I know there would be a long way around this, but is there a simple suggestion? Or alternative ideas on checking integrity of coms data. Thanks Phil. |
||||
cosmic frog Guru ![]() Joined: 09/02/2012 Location: United KingdomPosts: 302 |
Not sure if it's the right thing but couldn't you use the FIX() Function on page 75 of the Manual or am I barking up the wrong tree? Dave. |
||||
Phil23 Guru ![]() Joined: 27/03/2016 Location: AustraliaPosts: 1667 |
Hi Dave, Looked at FIX() & INT(), would need to multiply my numbers by 10 & then divide them to get 1 decimal precision, can do it, but just makes me wonder if anyone has written a cFunction to do it a bit quicker. Round seems to exist in some languages. It would make it easier to recognise valid strings. That's my real issue. Added a couple of HC-12's to my projects; One in the Heat Pump & the other on the Spa controller. All that was pretty straight forward, & it's sending data & receiving it Ok, but I've just seen the occasional block of data with dropped characters that I'd like to have a check in place for. Phil. |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6269 |
It will be easier to write a normal BASIC user function. You will need to decide which rounding rules you want to apply. Can you use CINT(), INT() or FIX() or do you need to get into more details. What do you do with 0.5? round up, round down, round towards zero, round to even etc. Depending on your use, there are some standards, but as usual, there are lots of standards to pick from. You also need to remember that if you are storing your results as floats, there will be some results that will not stay as you expect. Jim VK7JH MMedit |
||||
Phil23 Guru ![]() Joined: 27/03/2016 Location: AustraliaPosts: 1667 |
Maybe I need to rethink the whole thing; The primary requirement is to check data integrity. The HC-12's are working just fine, but really should have a check for the odd corruption. What general practices do others employ to confirm serial received data? Phil. |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6269 |
The usual method is to do a checksum for the full string. A simple CRC such as used in XMODEM is usually sufficient. This quicky keeps the CRC in readable form. The CRC$() function calculates the CRC and adds it onto the string in HEX The checkcrc() function recalculates the CRC on the string less the last 3 bytes and compares the calculated CRC with the last bytes and if they are the same, all is well in the world. report$= "$RP, T, Old: "+STR$(RND())+", "+STR$(RND()*234)+", New: "+DATE$+", "+TIME$ sendit$= crc$(report$) PRINT report$ PRINT sendit$ PRINT checkcrc(sendit$) ' should be OK (1) PRINT checkcrc(sendit$+" ") ' should give an error (0) FUNCTION crc$(txt$) LOCAL chksum FOR n = 1 TO LEN(txt$) chksum=chksum XOR ASC(MID$(report$,n,1)) NEXT n crc$=txt$+"*"+HEX$(chksum,2) END FUNCTION FUNCTION checkcrc(txt$) LOCAL chksum FOR n = 1 TO LEN(txt$)-3 chksum=chksum XOR ASC(MID$(report$,n,1)) NEXT n IF RIGHT$(txt$,3) = "*"+HEX$(chksum,2) THEN ' crc match checkcrc = 1 ENDIF END FUNCTION Jim VK7JH MMedit |
||||
Phil23 Guru ![]() Joined: 27/03/2016 Location: AustraliaPosts: 1667 |
Thanks Jim, I did look at CRC's, but kept coming up with things way to complicated. Didn't realise there was such a simple solution. How's it go? "Complex Problems sometime require only Simple Solutions". Phil. |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4036 |
CRCs are a bit more complex. To quibble a bit, the one above is a form of checksum (the clue's in the meaning of CRC!). If you're getting corruption can you cope with an occasional terminator (CR / LF) that's corrupted (i.e. missing)? Or with a char that's dropped or an extra one inserted? John |
||||
MicroBlocks![]() Guru ![]() Joined: 12/05/2012 Location: ThailandPosts: 2209 |
In the old days: [code] <SOH>[Timestamp][SequenceNumber][CRC][Length of data]<EOH><SOT>[CSV Data]<EOT> [/code] Basically a header followed by data. The header can contain as shown a Timestamp, Sequence number, CRC and the most important Length of data. This was(is) used a lot with unreliable serial connections. (TCP/IP or Ethernet does actually something similar, it just has more layers and is more obscure.) You 'sync' on the <SOH> and go from there. If you look at an ascii table you wil find the character values for the <SOH><EOH> etc. Only requirement to keep it simple is that the data does not contain any <SOH><EOH><SOT><EOT> characters as that will screw up the syncing. Rounding a number is done by multiplying it with 100 (for two decimals) add 0.5, convert it to an int, then divide by 100. [code] Roundedvalue = INT(value*100+0.5)/100 [/code] Microblocks. Build with logic. |
||||
isochronic Guru ![]() Joined: 21/01/2012 Location: AustraliaPosts: 689 |
errm... (ed). in standard maths, integer arithmetic is supposed to give an integer result eg 99.0 / 100.0 = 0.99 but 99 / 100 = 0 |
||||
MicroBlocks![]() Guru ![]() Joined: 12/05/2012 Location: ThailandPosts: 2209 |
In a program where everything is a float unless otherwise defined the return of INT divided by 100 will be a float. [code] a = 14.545 print INT(a*100+0.5)/100 [/code] The result will be: [code] 14.55 [/code] Microblocks. Build with logic. |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |