using floating point in CC2538 based RE-Mote board for CoAP Server with Contiki OS

172 views Asked by At

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?

1

There are 1 answers

1
eugene-nikolaev On BEST ANSWER

@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?