Error sending composing message to Sigfox

  • Hi,

    I'm using this way of compose the message to send to Sigfox

    s.send(struct.pack("<f", sbatt)+struct.pack("<f", stemp)+struct.pack("<B", shum)+struct.pack("<B", spress)+struct.pack("<f", captemp21)+struct.pack("<B", caphum21))

    but I recieved this error:

    OSError: [Errno 122] EMSGSIZ

    What I'm doing wrong???
    Thank's for your help guys

  • Hi @robert-hh

    PErfect, now is sending the info and now I'm decoding the info in my server...all works perfect!! thanks for your help

  • @ecabanas See

    It depends on the range and the precision you need.

    For instance for the battery level, if you only need one decimal:

    • Multiply by 10. You now have a number between 33 and 47
    • Subtract 33. You now have a number between 0 and 14.
    • Convert to integer to truncate any additional digits
    • You now have a number than fits in 4 bits!

    If you need two decimals:

    • Multiply by 100. You now have a number between 330 and 470
    • Subtract 330. You now have a number between 0 and 140.
    • Convert to integer to truncate any additional digits
    • You now have a number than fits in 8 bits (one byte).

    Same for the temperature, depending on how many significant digits you need, you could store it as:

    • 0 to 70 (add 20) -> fits in 7 bits,
    • or 0 to 700 (multiply by 10, add 200) -> fits in 10 bits

    And so on.

    Even numbers that are already integers can use less space. shum only need 7 bits. spress only needs 8 bits.

    Multiples of 8 bits are easy to manipulate and store with ustruct.pack. If you want to optimise every single bit (which when you can only send 96 bits at a time can be really useful), you'll either have to do some bit-shifting and ORing, or you can use something like the micropython-bitstring package.

  • @ecabanas For instance instead of
    struct.pack("<f", sbatt)
    you could write:
    struct.pack("<h", int(sbatt * 100))
    Obviously you would receive a value 100 times larger than the initial value, so you have to scale that back (divide by 100)
    You would have to do than anyhow for pressure, which has initially the range of 900-1100. Since a byte has the range of 0-255, you would need something like:
    struct.pack("<B", spress - 900)
    Note, that you can put that all into a single struct instruction like:
    struct.pack("<hhBhhB", int(sbatt * 100), int(stemp * 100), shum, spress, int(captemp21 * 100), caphum21)

  • @robert-hh said in Error sending composing message to Sigfox:

    If you scale all of them by a factor

    Hi @robert-hh

    How do I do this? I'm sorry but I'm very new at this and I don't have the slightest idea about this subject
    Thank you very much

  • @ecabanas Depending on the required resolution you can scale the floats to int, saving 2 bytes or 3 bytes depending on the resolution. If you scale all of them by a factor of 100, they would still fit into a 16 bit int, with a resolution of 10mV or 0.01 degree, which may be sufficient.

  • Hi @jcaron

    Thank's for your reply, this is the worst part of my code, and allways is a nightmare.

    Any idea how to reduce them? I have no idea.

    here it is the data perimeter:

    sbatt: from 3,3 to 4,7 (float)
    stemp: from -20 to 50 (float)
    shum: from 0 to 100 (int)
    spress: from 900 to 1100 (int)
    captemp21: from -20 to 50 (float)
    caphum21: from 0 to 100 (int)

  • @ecabanas SigFox messages are limited to 12 bytes. I believe yours is 15 bytes long.

Log in to reply

Pycom on Twitter