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

    How build sigfox message?

    Scheduled Pinned Locked Moved SiPy
    9 Posts 4 Posters 70 Views 4 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.
    • E Offline
      ecabanas
      last edited by ecabanas

      Hi all
      I'm coming from c++ and python is not my best ability right now. Finally, I read the sensors and now I have the values to be sent to Sigfox.
      s.send(bytes([1.89, 2.90, 3.67, 4.87, 5.77, 6.44,0,0,0,12.7]))
      I have some values with float or decimal format, but I have to convert. In C I use c function to convert to Uint, how do you do in python? and how do you decode them in Sigfox?

      Thank's

      1 Reply Last reply Reply Quote 0
      • G Offline
        Gijs
        last edited by

        I had some issues with this in the beginning as well (so much easier working with actual datatypes than this guessing of what it actually is :) )
        What you need to do is convert a float to a bytearray (with for example the bytes(...) function, apparently, in Python you would use a struct for that:

        https://docs.python.org/3/library/struct.html

        Have a look at this, we have it in micropython as well and it works the same!
        Let me know if that helps you
        Gijs

        1 Reply Last reply Reply Quote 0
        • E Offline
          ecabanas
          last edited by ecabanas

          Hi @Gijs

          First of all, thank's for your comments and help.

          I did the following but it doen's work:

          import struct
          
          def binary(num):
              return ''.join(bin(ord(c)).replace('0b', '').rjust(8, '0') for c in struct.pack('!f', num))
          
          Test = 0.25
              binTest = binary(Test)
              print(binTest)
          
          

          But I received the following error:

            File "main.py", line 23, in binary
            File "main.py", line 23, in <genexpr>
          TypeError: can't convert 'int' object to str implicitly
          

          and another question, how could I do with negative values? this is a temp sensor that send info to sigfox.
          Could you help to me with this? thank you very very much,

          Eduard

          C 1 Reply Last reply Reply Quote 0
          • C Offline
            claus @ecabanas
            last edited by

            @ecabanas You just need to convert the data to a known (little or big endian) binary representation. I use bytearrays more or less like this

            >>> import struct
            >>> num1=1.23
            >>> num2=2.34
            >>> little_en1=struct.pack('<f', num1)
            >>> little_en2=struct.pack('<f', num2)
            >>> ba=bytearray(little_en1+little_en2)
            >>> print(ba)
            bytearray(b'\xa4p\x9d?\x8f\xc2\x15@')
            >>> len(ba)
            8
            >>> struct.unpack('<ff',ba)
            (1.23, 2.34)
            

            You see however that one sigfox message only permits for 3 floats (4 bytes each). If your data does not require high precision, you could think about a 16bit float representation, as shown here https://davidejones.com/blog/python-precision-floating-point/ for example.

            E 1 Reply Last reply Reply Quote 1
            • E Offline
              ecabanas @claus
              last edited by

              @claus said in How build sigfox message?:

              num1=1.23

              num2=2.34
              little_en1=struct.pack('<f', num1)
              little_en2=struct.pack('<f', num2)
              ba=bytearray(little_en1+little_en2)
              print(ba)
              bytearray(b'\xa4p\x9d?\x8f\xc2\x15@')
              len(ba)
              8
              struct.unpack('<ff',ba)

              Hi @claus

              Thank's for your help, it is very very usufull.

              My message is like this:

                  # unicode string
                  sbatt=voltage
                  stemp=bme280temp
                  shum=bme280hum
                  spress=0
                  captemp21=temp_moist
                  caphum21=0
                  caphum22=0
                  caphum23=0
                  rain=0
                  vane=0
                  wind=0
                  gust=0
              
                  little_en1=struct.pack('<f', sbatt)
                  little_en2=struct.pack('<f', stemp)
                  little_en3=struct.pack('<f', shum)
                  little_en4=struct.pack('<f', spress)
                  little_en5=struct.pack('<f', caphum21)
                  little_en6=struct.pack('<f', caphum22)
                  little_en7=struct.pack('<f', caphum23)
                  little_en8=struct.pack('<f', rain)
                  little_en9=struct.pack('<f', vane)
                  little_en10=struct.pack('<f', wind)
                  little_en11=struct.pack('<f', gust)
              
                  ba=bytearray(little_en1+little_en2+little_en3+little_en4+little_en5+little_en6+little_en7+little_en8+little_en9+little_en10+little_en11)
                  print(ba)
                 print(len(ba))
              

              And the array is like this:

              bytearray(b'\x00P\x12ER\xb8\xaeA\x9a\x99kB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
              

              but the len is 44 and if I'm not wrong, the limit is 12, how could I reduce it?

              Thanks in advance
              ...and sorry but this part of the code is always a nightmare for me
              Eduard

              C 1 Reply Last reply Reply Quote 0
              • C Offline
                claus @ecabanas
                last edited by

                @ecabanas You can pack at most 3 "normal" floats in one sigfox message. "normal" meaning 4 bytes, or float32. If you do the trick with the float16 which I linked you can pack 6 floats into one message, but you loose precision with respect to float32. You have to carefully check if this is ok with your data. It might be ok for battery voltage (only the first few digits are of interest) but it might not be for high precision gps position. I would say you'll get around 3-4 valid digits with float16 for a number around 1.

                E 1 Reply Last reply Reply Quote 0
                • E Offline
                  ecabanas @claus
                  last edited by ecabanas

                  @claus said in How build sigfox message?:

                  which I linked yo

                  Hi @claus

                  If I reduce "aulity" of data from list below, could we reach it? In C I convert all data to Uint8 and was the solution correct, is it possible to do the same in python?

                  little_en1=struct.pack('<f', sbatt) int
                  little_en2=struct.pack('<f', stemp) float one decimal
                  little_en3=struct.pack('<f', shum) float one decimal
                  little_en4=struct.pack('<f', spress) int
                  little_en5=struct.pack('<f', caphum21) int
                  little_en6=struct.pack('<f', caphum22) 0
                  little_en7=struct.pack('<f', caphum23) 0
                  little_en8=struct.pack('<f', rain) 0
                  little_en9=struct.pack('<f', vane) 0
                  little_en10=struct.pack('<f', wind) 0
                  little_en11=struct.pack('<f', gust) 0
                  

                  What is your opinion? thanks again

                  Eduard

                  C 1 Reply Last reply Reply Quote 0
                  • C Offline
                    claus @ecabanas
                    last edited by

                    @ecabanas I do not know a lot about python, and I dont know the syntaxis you use here. But you will not be able to compress 11 floats into 12 bytes, it is just too much information loss. Remember 1 byte is just able to store 0..255. Using float16 or a similar representation you might be able to include 6 floats at reduced precision, but I'd guess that that's about as far as you can go.

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

                      @ecabanas In many cases, it's actually not necessary to send floats. Either just convert to integers (if the decimal part is not useful), or multiply by a power of 10 before doing so. Adding an offset may also help

                      For instance, if you have values between 0.00 and 2.00 and need 2 decimals, then multiply by 100, you'll get an integer between 0 and 200 which you can encode as a single byte.

                      If you have values between 20.0 and 40.0 and only need one decimal, subtract 20 and multiply by 10, you'll again be able to send that as a single byte.

                      Given the limitations of Sigfox packet sizes, every byte (and even every bit) counts! Don't waste bits on precision or exponents you don't need. Try to find out for each value the possible range and how much precision you need, and use the smallest number of bits which can accommodate that.

                      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 / 1
                      • First post
                        Last post

                      Pycom on Twitter

                      Pycom