Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    Float to bytearray conversion for sigfox payload

    Scheduled Pinned Locked Moved Discussion
    sigfoxmicropythontypeerror
    23 Posts 4 Posters 3.8k Views 5 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • robert-hhR Offline
      robert-hh @tttadam
      last edited by

      @tttadam You use struct.pack() to put these two floats into an 8 byte array without converting them to a string. That results in the shortest possible message, not readable for human eyes withou doing an unpack.

      import ustruct
      lat =47.497132 
      lon =19.063296
      msg = ustruct.pack("ff", lat, lon)
      # ..
      # and unpack
      lat, lon = ustruct.unpack("ff", msg)
      
      T 1 Reply Last reply Reply Quote 2
      • T Offline
        tttadam @robert-hh
        last edited by

        @robert-hh said in Float to bytearray conversion for sigfox payload:

        ustruct.unpack("ff", msg)

        Nice, thank you.
        I think is still posible save some more space if cut the first caracter and the dot. (And then possible to include more information)
        Which I try and fail to doing here. I think the unpacked value is rounded somehow.

        >>> lat
        47.49713
        >>> lon
        19.0633
        >>> msg2 =int((str(lat*100000)[1:-2]+str(lon*100000)[1:-2]))
        >>> msg = ustruct.pack("ff", msg2)
        >>> ret = ustruct.unpack("ff", msg)
        >>> print(ret)
        (7.497139e+11, 0.0)
        
        J robert-hhR 2 Replies Last reply Reply Quote 0
        • J Offline
          jcaron @tttadam
          last edited by

          @tttadam What you are doing is covering two floats to strings, concatenating them, converting the total to an int, packing that in as a float, and unpacking.

          Forget about str. Just use pack directly with the original values: ustruct.pack("ff",lat,lon)

          Or if you want to avoid sending floats over the air, you may convert them to ints and pack than as such instead.

          1 Reply Last reply Reply Quote 2
          • robert-hhR Offline
            robert-hh @tttadam
            last edited by robert-hh

            @tttadam msg2 contains an single int. So you must not use "ff" for pack, since that tells, that two float numbers are supplied. You have to use "i", which will pack (and unpack) it into a 4 byte format.
            Please have a look at the documentation of struct: https://docs.python.org/3/library/struct.html

            T 1 Reply Last reply Reply Quote 1
            • T Offline
              tttadam @robert-hh
              last edited by

              @robert-hh said in Float to bytearray conversion for sigfox payload:

              I see now. Okay. But I think I am still missing some information. Because I can't get back the same number.

              >>> lat
              47.49713
              >>> lon
              19.0633
              >>> msg2 =int(str(lat*100000)[1:-2]+str(lon*100000)[1:-2])
              >>> msg2
              749713906330
              >>> msg = ustruct.pack("i", msg2)
              >>> msg
              b'\x9aZn\x8e'
              >>> ret = ustruct.unpack("i", msg)
              >>> ret
              (-1905370470,)
              
              robert-hhR J 3 Replies Last reply Reply Quote 0
              • robert-hhR Offline
                robert-hh @tttadam
                last edited by robert-hh

                @tttadam The numer is too long for the i format, then you have to use the "q" format (long long). But that results in 8 bytes, and then you can also directly pack the two floats and have no further need for reformatting or scaling (see my post below).
                Using the "q" format, you could eventually drop the last three bytes, they are zero, and add them before unpacking. But that does not seem to be worth the effort.

                T 1 Reply Last reply Reply Quote 1
                • robert-hhR Offline
                  robert-hh @tttadam
                  last edited by robert-hh

                  @tttadam Or you could split the number:

                  >>> msg2
                  749713906330
                  >>> msg = ustruct.pack("IB", msg2 // 256, msg2 % 256)
                  >>> msg
                  b'Zn\x8e\xae\x9a'
                  >>> msb,lsb = struct.unpack("IB", msg)
                  >>> ret=msb * 256 + lsb
                  >>> ret
                  749713906330
                  

                  But still that is overkill compared to the float packing, unless you fight for every single byte.

                  1 Reply Last reply Reply Quote 1
                  • T Offline
                    tttadam @robert-hh
                    last edited by

                    @robert-hh So basicly your implamentation is the best. :)
                    Thank you.

                    1 Reply Last reply Reply Quote 0
                    • J Offline
                      jcaron @tttadam
                      last edited by

                      @tttadam why do you keep doing the same stuff you have already been told twice is not correct?

                      You have been told twice that the solution is very simply ustruct.pack(“ff”,lat,long). What’s wrong with that? Stop with the str and the concatenation and all that. Just pack the two values, and you’re done.

                      robert-hhR 1 Reply Last reply Reply Quote 0
                      • robert-hhR Offline
                        robert-hh @jcaron
                        last edited by

                        @jcaron I think that this was @tttadam's conclusion.

                        1 Reply Last reply Reply Quote 0

                        Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                        Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                        With your input, this post could be even better 💗

                        Register Login
                        • 1
                        • 2
                        • 2 / 2
                        • First post
                          Last post

                        Pycom on Twitter

                        Pycom