0

I'm working in upd-sink.c and udp-sender.c examples of contiki/examples/ipv6/rpl-collect path in Cooja. I want the sender mote to send their sensor data to sink. In udp-sender.c code, there is a struct called msg and this struct has a data field called msg that is of type struct collect_view_data_msg type. I want to put my reading sensor in msg and send to sink.How do i do this? I have a program for sensing temperature. I want to send s variable as massage to sink. I want to just simulate this network in Cooja.

The sensor program:

PROCESS(sensor_acq_process,"Sensor Acquisition");
AUTOSTART_PROCESSES(&sensor_acq_process);
PROCESS_THREAD(sensor_acq_process,ev,data)
{ 
  static struct etimer et;
  static int val;
  static float s = 0;
  static int dec;
  static float frac;

  PROCESS_BEGIN();

  printf("Starting Sensor Example.\n");

  while(1)
  {
   etimer_set(&et, CLOCK_SECOND * 2);
   SENSORS_ACTIVATE(sht11_sensor);

   PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));

   val = sht11_sensor.value(SHT11_SENSOR_TEMP);
   if(val != -1) 
   {
     s = ((0.01*val) - 39.60);
     dec = s;
     frac = s - dec;
     printf("\nTemperature=%d.%02u C (%d)\n", dec, (unsigned int)(frac * 100),val);               
    }       

    etimer_reset(&et);
    SENSORS_DEACTIVATE(light_sensor);
    SENSORS_DEACTIVATE(sht11_sensor);
  } //end of while

  PROCESS_END();
}

Function collect-common-send of udp-sender.c program:

 void collect_common_send(void)
{
  static uint8_t seqno;
  struct {
    uint8_t seqno;
    uint8_t for_alignment;
    struct collect_view_data_msg msg;
  } msg;
  /* struct collect_neighbor *n; */
  uint16_t parent_etx;
  uint16_t rtmetric;
  uint16_t num_neighbors;
  uint16_t beacon_interval;
  rpl_parent_t *preferred_parent;
  linkaddr_t parent;
  rpl_dag_t *dag;
  if(client_conn == NULL) {
    /* Not setup yet */
    return;
  }
  memset(&msg, 0, sizeof(msg));
  seqno++;
  if(seqno == 0) {
    /* Wrap to 128 to identify restarts */
    seqno = 128;
  }
  msg.seqno = seqno;

  linkaddr_copy(&parent, &linkaddr_null);
  parent_etx = 0;

  /* Let's suppose we have only one instance */
  dag = rpl_get_any_dag();
  if(dag != NULL) {
    preferred_parent = dag->preferred_parent;
    if(preferred_parent != NULL) {
      uip_ds6_nbr_t *nbr;
      nbr = uip_ds6_nbr_lookup(rpl_get_parent_ipaddr(preferred_parent));
      if(nbr != NULL) {
        /* Use parts of the IPv6 address as the parent address, in reversed byte order. */
        parent.u8[LINKADDR_SIZE - 1] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) - 2];
        parent.u8[LINKADDR_SIZE - 2] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) - 1];
        parent_etx = rpl_get_parent_rank((uip_lladdr_t *) uip_ds6_nbr_get_ll(nbr)) / 2;
      }
    }
    rtmetric = dag->rank;
    beacon_interval = (uint16_t) ((2L << dag->instance->dio_intcurrent) / 1000);
    num_neighbors = uip_ds6_nbr_num();
  } 
  else {
    rtmetric = 0;
    beacon_interval = 0;
    num_neighbors = 0;
  }

  /* num_neighbors = collect_neighbor_list_num(&tc.neighbor_list); */
  collect_view_construct_message(&msg.msg, &parent,
      parent_etx, rtmetric,
      num_neighbors, beacon_interval);
  //i add this code but it led to an error:invalid type argument
  //of'->'(have 'struct collect_view_data_msg')

  SENSORS_ACTIVATE(sht11_sensor);
  msg.msg->sensors[TEMP_SENSOR] = sht11_sensor.value(SHT11_SENSOR_TEMP);
  //end added

  uip_udp_packet_sendto(client_conn, &msg, sizeof(msg),
      &server_ipaddr, UIP_HTONS(UDP_SERVER_PORT));

  SENSORS_DEACTIVATE(sht11_sensor);
}
kfx
  • 8,136
  • 3
  • 28
  • 52
maryam
  • 1,437
  • 2
  • 18
  • 40

1 Answers1

0

Which platform for you use in Cooja? (Most likely sky.)

  1. The sensor readings are already included in the collect view message if the platform is sky. If it's not, the collect view code under apps/collect-view/ can be easily extended do do that using collect-view-template.c as the base.
  2. Don't use floating point numbers on embedded systems.
  3. If you really really know what you are doing, want to use floating point, and want to have data in ASCII format, create new field in the struct collect_view_data_msg that is a char array, and snprintf the value of the sensor in that field.

As a minor comment, this code is not needed:

SENSORS_ACTIVATE(sht11_sensor);
msg.msg->sensors[TEMP_SENSOR] = sht11_sensor.value(SHT11_SENSOR_TEMP);
...
SENSORS_DEACTIVATE(sht11_sensor);

As mentioned, the sht11_sensor is already read and included in the message in the collect view app.

kfx
  • 8,136
  • 3
  • 28
  • 52
  • I use sky platform.You mean i add a char array field in `struct collect-view-data-msg` for example `char buf[100]` and put value of sensor in it this way: msg.`mag->buf=sht11_sensor.value(SHT11_SENSOR_TEMP);` ? – maryam Jul 30 '17 at 14:16
  • And if that piece code is not needed, where i activate and deactivate sensor? – maryam Jul 30 '17 at 14:18
  • See the function `collect_view_arch_read_sensors` in `collect-view/collect-view-sky.c` - the sensor is already activated there. – kfx Jul 30 '17 at 17:30
  • `msg->buf=sht11_sensor.value(SHT11_SENSOR_TEMP);` is not even going to compile. In C, to change the value of an array, a loop, `memcpy()` or `str[n]cpy()` must be used`. Please read an intro to C. – kfx Jul 30 '17 at 17:32