从光电压传感器读取正确的值

时间:2013-09-12 18:23:00

标签: c embedded microcontroller sensor contiki

我正试图从TSL261 TI的传感器以正确的格式打印出正确的光强度值。 CC2530和contiki都用于此目的。 smartrf05EB和BB也被使用。

客户:

#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#include "contiki-conf.h"
#include "dev/leds.h"

#include <string.h>
#include "dev/leds.h"
#include "dev/button-sensor.h"
#include "debug.h"
#include "adc-sensor.h"
#include "port.h"
#include "cc253x.h"
#include "sfr-bits.h"
#include "lib/sensors.h"

#define DEBUG DEBUG_PRINT
#include "net/uip-debug.h"

#define SEND_INTERVAL       3 * CLOCK_SECOND
#define MAX_PAYLOAD_LEN     40

static uint16_t buf[MAX_PAYLOAD_LEN];
static uint16_t temp_buf[MAX_PAYLOAD_LEN];

static int rv;
uint16_t lv, tv;
static struct sensors_sensor *sensor;
static float sane = 0;
static int dec;
static int frac;


#define LOCAL_CONN_PORT 3001
static struct uip_udp_conn *l_conn;
#if UIP_CONF_ROUTER
#define GLOBAL_CONN_PORT 3002
static struct uip_udp_conn *g_conn;
#endif

/*---------------------------------------------------------------------------*/
//PROCESS(sensors_test_process, "Sensor Test Process");
PROCESS(udp_client_process, "UDP client process");

#if BUTTON_SENSOR_ON
PROCESS_NAME(ping6_process);
AUTOSTART_PROCESSES(&udp_client_process, &ping6_process);

#else
AUTOSTART_PROCESSES(&udp_client_process);
#endif
/*---------------------------------------------------------------------------*/
static void
tcpip_handler(void)
{
  leds_on(LEDS_GREEN);
  if(uip_newdata()) {
    putstring("0x");
    puthex(uip_datalen());
    putstring(" bytes response=0x");
    puthex((*(uint16_t *) uip_appdata) >> 8);
    puthex((*(uint16_t *) uip_appdata) & 0xFF);
    putchar('\n');
  }
  leds_off(LEDS_GREEN);
  return;
}
/*---------------------------------------------------------------------------*/

static void ReadLightSensor(void)
{
            P0SEL &= ~0x10; /* Set pin as GPIO */
            P0DIR &= ~0x10; /* Set pin as input*/
            P0INP |= 0x10;  /* Set as tri-state*/
            APCFG |= 0x10;  /* configure ADC on pin*/

            ADCCON3 = 0x34; /*This represents the paramters passed into ADCCON3*/

            while (!ADCIF);
            ADCIF = 0;

            tv = ADCL;
            lv = ADCH;
//          tv |= (((unsigned short) ADCH) << 8);
//          tv >>= 4 ;
//          lv = tv;
            //PRINTF("Port 0 Pin 4 reading = 0x%04x\n\r", lv);
            PRINTF("ADCL = 0x%04x\n\r", tv);
            PRINTF(" ADCH = 0x%04x\n\r",lv);

            return;
}
/*---------------------------------------------------------------------------*/
static void
timeout_handler(void)
{
  static int seq_id;

  struct uip_udp_conn *this_conn;

  leds_on(LEDS_RED);
  memset(buf, 0, MAX_PAYLOAD_LEN);
  seq_id++;

    this_conn = g_conn;
    if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) // Only use one port to send
    {
      return;
    }


  PRINTF("Client to: ");
  PRINT6ADDR(&this_conn->ripaddr);

   temp_buf[0] = dec;
   temp_buf[1] = frac;
   temp_buf[2] = lv;
   temp_buf[3] = tv;

   //add light values and barometer values

  memcpy(buf, temp_buf, sizeof(temp_buf)); //copy data in temp_buf into buf



  PRINTF(" Remote Port %u,", UIP_HTONS(this_conn->rport));

  PRINTF("\n\r (msg=0x%04x), %u bytes\n", *(uint16_t *) buf, sizeof(buf));


  uip_udp_packet_send(this_conn, buf, sizeof(buf));

  PRINTF("Decimal = %d   ", buf[0]);
  PRINTF("Fraction = %d   ", buf[1]);


  leds_off(LEDS_RED);
}

/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udp_client_process, ev, data)
{
  static struct etimer et;
  uip_ipaddr_t ipaddr;

  PROCESS_BEGIN();
  PRINTF("UDP client process started\n");
  uip_ip6addr(&ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x4B00, 0x0205, 0xF37A); //local ipv6 addr
  //uip_ip6addr(&ipaddr, 0xfe80, 0, 0, 0, 0x0215, 0x2000, 0x0002, 0x2145);
  /* new connection with remote host */
  l_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL);
  if(!l_conn) {
    PRINTF("udp_new l_conn error.\n");
  }
  udp_bind(l_conn, UIP_HTONS(LOCAL_CONN_PORT));

  PRINTF("Link-Local connection with ");
  PRINT6ADDR(&l_conn->ripaddr);
  PRINTF(" local/remote port %u/%u\n",
         UIP_HTONS(l_conn->lport), UIP_HTONS(l_conn->rport));
  uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0x0212, 0x4B00, 0x0205, 0xF37A); //global ipv6 addr
  //uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0x0215, 0x2000, 0x0002, 0x2145);
  g_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL);
  if(!g_conn) {
    PRINTF("udp_new g_conn error.\n");

  }
  udp_bind(g_conn, UIP_HTONS(GLOBAL_CONN_PORT));

  PRINTF("Global connection with ");
  PRINT6ADDR(&g_conn->ripaddr);
  PRINTF(" local/remote port %u/%u\n",
         UIP_HTONS(g_conn->lport), UIP_HTONS(g_conn->rport));

  etimer_set(&et, SEND_INTERVAL);

  while(1) {


        PROCESS_YIELD();
        if(etimer_expired(&et))
        {
            ReadLightSensor(); // fire function to read from light sensor



            sensor = sensors_find(ADC_SENSOR);
                             if(sensor) {
                               PRINTF("------------------\n");
                               leds_on(LEDS_RED);
                               rv = sensor->value(ADC_SENSOR_TYPE_TEMP);
                                                   if(rv != -1) {
                                                     sane = 25 + ((rv - 1480) / 4.5);
                                                     dec = sane;
                                                     frac = (int)(100*(sane - dec));
                                                    PRINTF("  Temperature = %d.%02u C (%d)\n", dec, (unsigned int)(frac*100), rv);
                                                   }
          timeout_handler();
          etimer_restart(&et);
        } else if(ev == tcpip_event) {
          tcpip_handler();
        }
      }
  }
  PROCESS_END();
  }

服务器:

  #include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"

#include <string.h>

#define DEBUG DEBUG_PRINT
#include "net/uip-debug.h"
#include "dev/watchdog.h"
#include "dev/leds.h"
#include "net/rpl/rpl.h"
#include "dev/button-sensor.h"
#include "debug.h"

#define UIP_IP_BUF   ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define UIP_UDP_BUF  ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])

#define MAX_PAYLOAD_LEN 120
#define TABLE_LEN 5

void update_table(float tmpr, uint16_t lv);
void display_vtable();
static struct uip_udp_conn *server_conn;
static uint16_t buf[MAX_PAYLOAD_LEN];
static uint16_t len, lv,tv;
static numofcl = 0;
static float recvtemp;


// structure to hold ip and state
typedef struct {
    uip_ipaddr_t IP;
    uint8_t      nstatus;
    uint8_t      is_default;
    float        temp;
    uint16_t     light;
}verify;

static verify vtable[TABLE_LEN];

#define SERVER_REPLY          1

/* Should we act as RPL root? */
#define SERVER_RPL_ROOT       1

#if SERVER_RPL_ROOT
static uip_ipaddr_t ipaddr;
#endif
/*---------------------------------------------------------------------------*/
PROCESS(udp_server_process, "UDP server process");
AUTOSTART_PROCESSES(&udp_server_process);
/*---------------------------------------------------------------------------*/
static void
tcpip_handler(void)
{
  int i,x ;
  float g, sumtemp, avgtemp ; //For handling temperature float value
  memset(buf, 0, MAX_PAYLOAD_LEN); // set buffer
  if(uip_newdata()) {
     leds_on(LEDS_RED);
     len = uip_datalen();
     PRINTF("Incoming packet of length %d\r\n", len);
     memcpy(buf, uip_appdata, len);

     for (i=0; i<4; i++)
     {
         PRINTF("0x%04x ",buf[i]);
     }
     PRINTF("\n\r");
     g = (float)buf[1] / 100;
     recvtemp = buf[0] + g;
     lv = buf[2];
     tv = buf[3];



      printf("upper light value  = 0x%04x\n\r",  lv); //print light value in correct format
      printf("lower light value= 0x%04x\n\r", tv);
      printf("temperature value = %02f\n\r", recvtemp);

//    PRINTF("%u\n\r bytes from [", len);
//    PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
//    PRINTF("]:%u\n", UIP_HTONS(UIP_UDP_BUF->srcport));

    update_table(recvtemp,lv);

    PRINTF("\n\rnumofcl = %d\n\r", numofcl);

// Table Full condition

    if ( numofcl == TABLE_LEN )
    {
        PRINTF("\n\rTable Full\n");

        //Calculate average
        sumtemp = 0;
        for(i = 0; i < TABLE_LEN; i++)
        {
            sumtemp += vtable[i].temp;
        }

        avgtemp = sumtemp / TABLE_LEN;
        PRINTF("\n\rAverage Temperature = %d\n", avgtemp);

        //clear sensor data ..temp,light,etc
        for (x=0; x<TABLE_LEN; x++)
            {
                //vtable[x].nstatus = 0;
                vtable[x].temp = 0;
                vtable[x].light = 0;
            }
    }

#if SERVER_REPLY
    uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr);
    server_conn->rport = UIP_UDP_BUF->srcport;

    uip_udp_packet_send(server_conn, buf, len);
    /* Restore server connection to allow data from any node */
    uip_create_unspecified(&server_conn->ripaddr);
    server_conn->rport = 0;
#endif
  }
  leds_off(LEDS_RED);
  display_vtable();
  return;
}
/*---------------------------------------------------------------------------*/
#if (BUTTON_SENSOR_ON && (DEBUG==DEBUG_PRINT))
static void
print_stats()
{
  PRINTF("tl=%lu, ts=%lu, bs=%lu, bc=%lu\n",
         rimestats.toolong, rimestats.tooshort, rimestats.badsynch,
         rimestats.badcrc);
  PRINTF("llrx=%lu, lltx=%lu, rx=%lu, tx=%lu\n", rimestats.llrx,
         rimestats.lltx, rimestats.rx, rimestats.tx);
}
#endif
/*---------------------------------------------------------------------------*/
static void
print_local_addresses(void)
{
  int i;
  uint8_t state;

  PRINTF("Server IPv6 addresses:\n");
  for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
    state = uip_ds6_if.addr_list[i].state;
    if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state
        == ADDR_PREFERRED)) {
      PRINTF("  ");
      PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
      PRINTF("\n");
      if(state == ADDR_TENTATIVE) {
        uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;
      }
    }
  }
}
/*---------------------------------------uip_newdata------------------------------------*/
#if SERVER_RPL_ROOT
void
create_dag()
{
  rpl_dag_t *dag;

  uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
  uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
  uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);


  print_local_addresses();

  dag = rpl_set_root(RPL_DEFAULT_INSTANCE,
                     &uip_ds6_get_global(ADDR_PREFERRED)->ipaddr);
  if(dag != NULL) {
    uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
    rpl_set_prefix(dag, &ipaddr, 64);
    PRINTF("Created a new RPL dag with ID: ");
    PRINT6ADDR(&dag->dag_id);
    PRINTF("\n");
  }
}
#endif /* SERVER_RPL_ROOT */

void update_table(float tmpr, uint16_t lv)
{
    int x;
    uint8_t intbl = 0;
    uip_ipaddr_t defaultIP;
    uip_ipaddr(&defaultIP,0,0,0,0);
    for (x=0; x<TABLE_LEN; x++)
    {

        if(uip_ipaddr_cmp(&vtable[x].IP, &UIP_IP_BUF->srcipaddr)) //compare ip's / updating an existing client
        {
            //if (vtable[x].nstatus == 0)
            //{
                //vtable[x].nstatus = 1;
                vtable[x].temp = tmpr;
                vtable[x].light = lv;
            //}


            PRINTF("Existing field updated");
            break;
        }


        else if(vtable[x].is_default == 0)  // updating a null field/ adding new client
        {
            uip_ipaddr_copy(&vtable[x].IP, &UIP_IP_BUF->srcipaddr); //
            //vtable[x].nstatus = 1;
            vtable[x].is_default = 1;
            vtable[x].temp = tmpr;
            vtable[x].light = lv;
            PRINTF("new field updated");
            numofcl++;
            break;
        }
    }

}

void
display_vtable()
{
    int j;
     for(j = 0; j < TABLE_LEN; j++)
      {
         PRINTF("\n\rvtable[%d] --> uip_addr =",j);
         uip_debug_ipaddr_print(&vtable[j].IP);
         PRINTF( "status = %d\r\n", vtable[j].nstatus);
         PRINTF( "temperature = %02f\n", vtable[j].temp );
         PRINTF(" Light = 0x%04x\n\r", vtable[j].light);
         PRINTF( "is_default = %d\n\r", vtable[j].is_default);
      }

    }
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udp_server_process, ev, data)
{

  uint8_t i;

  PROCESS_BEGIN();
  for(i = 0; i < TABLE_LEN; i++) //Initialize table by setting values to zero
  {
      uip_ipaddr(&vtable[i].IP,0,0,0,0);
      vtable[i].nstatus = 0;
      vtable[i].is_default = 0;
  }

  putstring("Starting UDP server\n");

#if BUTTON_SENSOR_ON
  putstring("Button 1: Print RIME stats\n");
#endif

#if SERVER_RPL_ROOT
  create_dag();
#endif

  server_conn = udp_new(NULL, UIP_HTONS(0), NULL);
  udp_bind(server_conn, UIP_HTONS(3000));

  PRINTF("Listen port: 3000, TTL=%u\n", server_conn->ttl);

  while(1) {
    PROCESS_YIELD();
    if(ev == tcpip_event) {

      tcpip_handler();
#if (BUTTON_SENSOR_ON && (DEBUG==DEBUG_PRINT))
    } else if(ev == sensors_event && data == &button_sensor) {
      print_stats();
#endif /* BUTTON_SENSOR_ON */
    }
  }

  PROCESS_END();
}
/*---------------------------------------------------------------------------*/

服务器收到的值看起来不正确。 记录的最高值(最亮)是0x07FF,而记录的最低值(最亮)是0x0FFE。我不知道我的代码或微控制器是否有问题,我期待数字接近于零(以十六进制形式)表示最暗,而值接近“0xFFFF”表示最亮的值。有什么帮助吗?

0 个答案:

没有答案