0

I am using RE-Mote Development Board along with Contiki-OS. I am interfacing it with Adafruit BNO055 Absolute Orientation Sensor.

I want particularly:

  1. the Accelerometer Data in floating point precision.
  2. the Euler Angles in floating point precision.

I did some digging in and found out that the printf in Contiki is Board dependent and not many boards have floating point printing implementation. source

However this might become critical for creating a CoAP Resource because when returning data the code uses snprintf.

The snippet:

/*GET Method*/

RESOURCE(res_bno055,
    "title=\"BNO055 Euler\";rt=\"bno055\"",
    res_get_handler,
    NULL,
    NULL,
    NULL);

static void res_get_handler(void *request, void *response, uint8_t *buffer,
uint16_t preferred_size, int32_t *offset) {

   adafruit_bno055_vector_t euler_data = getVector(VECTOR_EULER);
   double eu_x = euler_data.x;
   double eu_y = euler_data.y;
   double eu_z = euler_data.z;

   unsigned int accept = -1;

   REST.get_header_accept(request, &accept);

   if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
        /*PLAIN TEXT Response*/
        REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
        // >>>>>>>>>>will snprintf create a problem? <<<<<<<<<<<<<<<<<
        snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%lf, %lf, %lf",eu_x,eu_y, eu_z,);
        REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
   } else if (accept == REST.type.APPLICATION_JSON) {
        /*Return JSON REPONSE*/
        REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
        // >>>>>>>>>>>>>>>same question here.. <<<<<<<<<<<<<<<<<<<<<<<<<<<<
        snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'bno055_eu':{ 'X':%f, 'Y':%f, 'Z':%f}}",
        eu_x,  eu_y, eu_z);
        REST.set_response_payload(response, buffer, strlen((char *)buffer));
   } else {
        REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
        const char *msg = "Only text/plain and application/json";
        REST.set_response_payload(response, msg, strlen(msg));
   }
}

I have tried the above mentioned Resource Code and setup a CoAP Server but I get

plain-text response:

, , ,

json response:

{'bno055_eu: { 'X': , 'Y': , 'Z': }}

the struct:

typedef struct {
    double x;
    double y;
    double z;
}adafruit_bno055_vector_t

What would be an optimal way to create a GET CoAP Resource with floating point response?

Shan-Desai
  • 3,101
  • 3
  • 46
  • 89
  • 1
    _Why_ do you need floating point? It is far from obvious with the given code. Do you need to do trigonometry calculations or similar? I don't believe the MCU on the specified board has a FPU, so floating point will result in horrible performance. – Lundin Sep 06 '17 at 08:27
  • One reason being the sub GHz availability. Other being the Application will be used in a boat where higher precision of Accelerometer is of utmost importance. – Shan-Desai Sep 06 '17 at 08:48
  • 1
    What does sub GHz radio have to do with floating point? And how exactly does floating point calculations give _higher_ precision? Because they are rather known to reduce precision. And you don't have 64 bit resolution on your accelerometer anyway, more likely it is 12 bits or so. So you won't get any better resolution than that no matter what you do in your software. – Lundin Sep 06 '17 at 08:57
  • I understand. Thanks. The Sub GHz point was faulty. Apologies. I meant the board is the only one that provides Sub GHz and 2.4 GHz wireless devices on the same board. – Shan-Desai Sep 06 '17 at 09:07
  • Sorry if I got it all wrong, but why do you need sprintf at all? Why just not send float value as bytes as they are? – eugene-nikolaev Sep 06 '17 at 11:09
  • @eugene-nikolaev I am just playing by the examples available. I am not sure what you mean but I think `set_payload_response()` function might not take the values of `double`. If you can give me a hint as to how to proceed I can try it out. – Shan-Desai Sep 06 '17 at 11:16

1 Answers1

1

@eugene-nikolaev I am just playing by the examples available. I am not sure what you mean but I think set_payload_response() function might not take the values of double. If you can give me a hint as to how to proceed I can try it out.

I am not very experienced in C so I cannot' show you a good snippet. But you're casting your buffer to (uint8_t) and for sure set_payload_response acquires binary payload.

It would be like (I note again - it could be not too correct):

REST.set_response_payload(response, (uint8_t *) &euler_data, sizeof(adafruit_bno055_vector_t));

But it will work only for your else branch.

In a classical meaning of CoAP I am used to send a binary payload or CBOR-encoded payload, and parse it on the other side in the similar cases. It all depends on what are your CoAP peers and what do you want to achieve.

UPD: Regarding the plaintext/json branches - I'd advise you to check which range/precision of values your module provides. Maybe there is no big point to use double as @Lundin said.

Also, do you really need plain-text and json format?

eugene-nikolaev
  • 1,290
  • 1
  • 13
  • 21
  • +1 for CBOR. I think JSON is a good data representation format for the sensor values so I can poll the server using a CoAP Client and collect information at the client for some analyses. Apart from that I am open to any way of data format. – Shan-Desai Sep 06 '17 at 12:04