Project

General

Profile

Revision 11

Added ColonetServer and colonet libs.

View differences:

trunk/code/projects/colonet/lib/colonet_wireless/colonet_wireless_test.cpp
1
/* Eugene Marinelli
2
 * 11/2/06
3
 *
4
 * colonet_wireless_test - tests the colonet_wireless library
5
 */
6

  
7
#include <iostream>
8
#include <signal.h>
9

  
10
#include "colonet_wireless.h"
11

  
12
int msg_handler(ColonetPacket* pkt)
13
{
14
  printf("Handler!\n");
15

  
16
  fprintf(stderr, 
17
          "token_src:%d\n"
18
          "token_dest:%d\n"
19
          "msg_dest:%d\n"
20
          "msg_type:%d\n"
21
          "msg_code:%d\n"
22
          "num_robots:%d\n",
23
          pkt->token_src, pkt->token_dest, pkt->msg_dest, pkt->msg_type,
24
          pkt->msg_code, pkt->num_robots);
25
  
26
  printf("data: ");
27

  
28
  for(int i = 0; i < PACKET_DATA_LEN; i++){
29
    printf("%d ", pkt->data[i]);
30
  }
31
  
32
  printf("\n\n");
33

  
34
  return 0;
35
}
36

  
37
int main()
38
{
39
  ColonetWireless* cw = new ColonetWireless(SERIAL_PORT, msg_handler, NULL, 
40
                                            true, false);
41

  
42
  /*
43
  unsigned char orbdata[3] = {0xFF, 0xFF, 0xFF};
44
  unsigned char motordata[4] = {0, 1, 0, 0xFF};
45
  unsigned char motordata2[4] = {0, 0, 0, 0xFF};
46
  unsigned char buzzerdata[5] = {0x01};
47
  */
48

  
49
  unsigned char data[10];
50
  unsigned char msgcode;
51

  
52
  //cw->send(GLOBAL_DEST, 0, 0, "eugene");
53

  
54
  //cw->send(GLOBAL_DEST, COLONET_COMMAND, ORB_SET, orbdata);
55
  //cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTOR1_SET, motordata);
56

  
57
  //cw->send(GLOBAL_DEST, COLONET_COMMAND, BUZZER_INIT, (unsigned char*)"");
58
  //cw->send(GLOBAL_DEST, COLONET_COMMAND, BUZZER_SET_VAL, buzzerdata);
59

  
60
  cw->run_listener_thread();
61

  
62
  printf("spawned thread\n");
63

  
64
  while(1){
65
    printf("Code: ");
66
    scanf("%x", (int*)&msgcode);
67

  
68
    for (int i = 0; i < 5; i++) {
69
      printf("Byte %d: ", i);
70
      scanf("%x", (int*)&(data[i]));
71
    }
72

  
73
    cw->send(GLOBAL_DEST, COLONET_COMMAND, msgcode, data);
74

  
75
    /*
76
    cw->send(GLOBAL_DEST, COLONET_COMMAND, ORB_SET, orbdata);
77
    cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTOR1_SET, motordata);
78
    cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTOR2_SET, motordata2);
79

  
80
    sleep(3);
81
    */
82
  }
83

  
84
  return 0;
85
}
trunk/code/projects/colonet/lib/colonet_wireless/colonet_wireless.cpp
1
/** @file colonet_wireless.cpp 
2
 *
3
 * @brief Implementation of server-side colonet wireless library
4
 *
5
 * @author Eugene Marinelli
6
 *
7
 * @bug Only reads when gtkterm is open
8
 * @bug Fails to tokenize
9
 * @bug Deconstructor not implemented
10
 * @bug Nonsense initializations in constructor
11
 */
12

  
13
/********************************* Includes **********************************/
14
#include <string>
15
#include <pthread.h>
16
#include <iostream>
17
#include <fstream>
18
#include <unistd.h>
19
#include <fcntl.h>
20
#include "colonet_wireless.h"
21

  
22
/******************************* Definitions *********************************/
23
#define TIMEOUT_MAX 100
24
#define WL_SEND_DELAY 5 //microseconds
25

  
26
//for debug printouts
27
#define DEBUG 1
28

  
29
#ifdef DEBUG
30
#define dbg_printf(...) printf(__VA_ARGS__)
31
#define dbg_fprintf(...) fprintf(__VA_ARGS__)
32
#else
33
#define dbg_printf(...)
34
#define dbg_fprintf(...)
35
#endif
36

  
37
typedef struct {
38
  MsgHandlerFunction handler;
39
  ColonetWireless* cw;
40
} ListenerArgs;
41

  
42
/************************* Internal prototypes *******************************/
43
static void* listen(void* args);
44

  
45
/**************************** Public functions *******************************/
46
ColonetWireless::ColonetWireless(char* wl_port, 
47
                                 MsgHandlerFunction message_handler_, 
48
                                 char* log_filename_, bool join_token_ring_,
49
                                 bool ignore_token_)
50
{
51
  have_token = false;
52
  first_packet_sent = false;
53

  
54
  //FIX THESE INITIALIZATIONS
55
  token_src = 255;
56
  token_dest = 255;
57
  num_robots = 0;
58
  connected = false;
59
  ignore_token = ignore_token_;
60

  
61
  sprintf(wireless_port, wl_port);
62

  
63
  if (log_filename) {
64
    logging_enabled = true;
65
    sprintf(log_filename, log_filename_);
66
  }
67

  
68
  join_token_ring = join_token_ring_;
69

  
70
  message_handler = message_handler_;
71
}
72

  
73
ColonetWireless::~ColonetWireless()
74
{
75
  //kill listener thread
76
  
77

  
78
  //free packets in queues
79
  
80
}
81

  
82
int ColonetWireless::handle_packet(ColonetPacket* pkt)
83
{
84
  if (logging_enabled) {
85
    /* Log the packet */
86
    log_packet(pkt);
87
  }
88

  
89
  /* Update what we know about the network based on the packet */
90
  update_network_props(pkt);
91

  
92
  /* Received a message */
93
  if (message_handler(pkt) < 0) {
94
    fprintf(stderr, "%s: message_handler failed\n", __FUNCTION__);
95
    return -1;
96
  }
97
  
98
  if ((unsigned char) pkt->token_dest == WL_ERROR_DEST) {
99
    /* token_dest is an error - handle it */
100
    if (handle_error(pkt) < 0) {
101
      fprintf(stderr, "%s: handle_error failed\n", __FUNCTION__);
102
      return -1;
103
    }
104
  } else if(join_token_ring && !connected) {
105
    /* We want to join the token ring but we are not connected - join robot 
106
     * network */
107
    dbg_printf("%s: Trying to join robot network...\n", __FUNCTION__);
108

  
109
    if (join_network(pkt) < 0) {
110
      dbg_fprintf(stderr, "%s: join_network failed\n", __FUNCTION__);
111
      return -1;
112
    }
113
  } else {
114

  
115
    if (pkt->token_dest == token_src && join_token_ring && !ignore_token) {
116
      /* Received the token - send queued message(s) */
117
      dbg_printf("%s: token received\n", __FUNCTION__);
118

  
119
      have_token = true;
120
    
121
      if (transmit_queued_message() < 0) {
122
        fprintf(stderr, "%s: transmit_queued_message failed\n", __FUNCTION__);
123
        return -1;
124
      } else {
125
        if (!first_packet_sent) {
126
          dbg_printf("First packet sent.\n");
127
          first_packet_sent = true;
128
        }
129
      }
130
    }
131
  }
132

  
133
  return 0;
134
}
135

  
136
pthread_t* ColonetWireless::run_listener_thread()
137
{
138
  // pthread_t listener_thread;
139

  
140
  pthread_t* listener_thread = (pthread_t*)malloc(sizeof(pthread_t));
141

  
142
  dbg_printf("Spawning listener thread...\n");
143

  
144
  ListenerArgs* args = new ListenerArgs;
145
  args->cw = this;
146

  
147
  if (pthread_create(listener_thread, NULL, listen, args) != 0) {
148
    perror("pthread_create");
149
    return NULL;
150
  }
151

  
152
  return listener_thread;
153
}
154

  
155
int ColonetWireless::send(unsigned char msg_dest, unsigned char msg_type, 
156
                          unsigned char msg_code, unsigned char* data)
157
{
158
  /* Create a new packet it and queue it to be sent */
159
  ColonetPacket* newpkt = create_packet(token_src, token_dest, msg_dest, 
160
                                        msg_type, msg_code, data, num_robots);
161

  
162
  if(newpkt == NULL){
163
    fprintf(stderr, "Error: %s - create_packet failed\n", __FUNCTION__);
164
    return -1;
165
  }
166

  
167
  if (ignore_token) {
168
    send_packet(newpkt);
169
  } else {
170
    outbox.push(newpkt);                
171
  }
172

  
173
  return 0;
174
}
175

  
176
void ColonetWireless::clear_message_queue(void)
177
{
178
  while (!outbox.empty()) {
179
    outbox.pop();
180
  }
181
}
182

  
183
/**************************** Private functions ******************************/
184

  
185
/** @brief Analogous to the "SIGNAL" or "ISR" function on the robots.
186
 * Listens for bytes on the wireless port and constructs packets based on them.
187
 * Not part of the ColonetWireless class since a function pointer must be
188
 * passed in starting the thread that runs it (tricky or impossible if it's 
189
 * a class function).
190
 *
191
 * @param args Pointer to arguments.  Can be safely casted to ListenerArgs type
192
 * @return NULL
193
 */
194
static void* listen(void* args)
195
{
196
  int read_len;
197
  int portfd;
198
  unsigned char inbuf[128];
199
  int no_packet_timeout_count = 0;
200
  ColonetPacket* in_pkt;
201

  
202
  /* Extract arguments from args */
203

  
204
  ColonetWireless* cw = ((ListenerArgs*)args)->cw;
205

  
206
  /* Open connection to wireless port */
207
  if((portfd = open(cw->wireless_port, O_RDWR)) < 0){
208
    perror("open");
209
    pthread_exit(NULL);
210
  }
211

  
212
  /* loop waiting for messages */
213
  while(1){
214
    /* Read in some bytes (blocks until bytes are read) */
215
    read_len = read(portfd, inbuf, 3);
216

  
217
    if(read_len > 0){
218
      /* Read in some bytes - this will always be true if portfd is blocking */
219
      /* parse the packet or part of packet */
220
      in_pkt = cw->build_packet(inbuf, read_len);
221
      
222
      if(in_pkt == NULL){
223
        /* Packet is not ready yet - go back and read some more bytes */
224
        continue;
225
      }else{
226
        /* Packet is complete */
227
        /* close fd so that we can safely write to it in the handler */
228
        close(portfd);
229

  
230
        if (cw->handle_packet(in_pkt)) {
231
          fprintf(stderr, "%s: Error - handle_packet failed\n", __FUNCTION__);
232
        }
233

  
234
        /* reopen wireless port */
235
        if(!(portfd = open(cw->wireless_port, O_RDWR))){
236
          perror("open");
237
          pthread_exit(NULL);
238
        }
239
      }
240
    }else if(read_len == 0){
241
      // Note - this won't actually happen if read blocks
242
      if(no_packet_timeout_count++ > TIMEOUT_MAX){
243
        //Nothing received for a while - try to start a new token ring
244
        dbg_printf("Attempting to start a token ring...\n");
245

  
246
        cw->token_src = 0;
247
        cw->token_dest = 1;
248
        cw->num_robots = 0;
249
  
250
        ColonetPacket* tmp_pkt = cw->create_packet(cw->token_src, 
251
                                                   cw->token_dest, 0, 0, 0, 
252
                                                   (unsigned char*) "",
253
                                                   cw->num_robots);
254
        cw->send_packet(tmp_pkt);
255
        free(tmp_pkt);
256
      }
257
    }else{ //(read_len < 0)
258
      //Error
259
      perror("read");
260
    }
261
  }
262

  
263
  pthread_exit(NULL);
264

  
265
  return NULL;
266
}
267

  
268
/** @brief Takes some number of bytes and tries to build a packet with them
269
 * State of the function is saved between callings, so parts of packets 
270
 * can be provided as available
271
 *
272
 * @param buf Data buffer 
273
 * @param len Number of bytes to build with
274
 */
275
ColonetPacket* ColonetWireless::build_packet(unsigned char* buf, int len)
276
{
277
  static unsigned char packet_buf[PACKET_SIZE];
278
  static int buf_pos = 0;
279

  
280
  /* If this is pointer is returned - will either point to NULL or a complete
281
   * packet */
282
  ColonetPacket* complete_packet = NULL;
283

  
284
  if (buf_pos >= PACKET_SIZE) {
285
    buf_pos = 0;
286
  }
287

  
288
  for (int i = 0; i < len; i++) {
289
    dbg_printf("%d ", buf[i]);
290

  
291
    switch(buf_pos){
292
    case 0: //prefix0
293
      if(buf[i] == 'R'){
294
        memset(packet_buf, 0, PACKET_SIZE);
295
        packet_buf[0] = 'R';
296
        buf_pos = 1;
297
      }
298
      break;
299
    case 1: //prefix1
300
      if(buf[i] == 'C'){
301
        packet_buf[1] = 'C';
302
        buf_pos = 2;
303
      }else{
304
        buf_pos = 0;
305
      }
306
      break;
307
    default: 
308
      /* anything except prefix0, prefix1, or checksum */
309
      
310
      /* Check for R,C - in this case, very likely that we missed a byte */
311
      if (i > 0 && buf[i] == 'C' && buf[i-1] == 'R') {
312
        packet_buf[0] = 'R';
313
        packet_buf[1] = 'C';
314
        
315
        buf_pos = 2;
316
      } else {
317
        packet_buf[buf_pos] = buf[i];
318
        buf_pos++;
319
      }
320
      break;
321
    case (PACKET_SIZE-1):
322
      /* At checksum location */
323
      buf_pos = 0;
324
      packet_buf[15] = buf[i];
325

  
326
      /* Compute desired checksum */
327
      unsigned char sum = 0;
328
      for(int j = 2; j < PACKET_SIZE; j++){
329
        sum += packet_buf[j];
330
      }
331
      
332
      if(!sum){
333
        //Checksum passed
334
        dbg_printf("%s: checksum passed\n", __FUNCTION__);
335

  
336
        complete_packet = create_packet(packet_buf[2], packet_buf[3], 
337
                                        packet_buf[4], packet_buf[5], 
338
                                        packet_buf[6], (packet_buf+7), 
339
                                        packet_buf[PACKET_SIZE-2]);
340
      }else{
341
        dbg_printf("%s: checksum failed\n", __FUNCTION__);
342
      }
343

  
344
      break;
345
    }
346
  }
347

  
348
  return complete_packet;
349
}
350

  
351
void ColonetWireless::update_network_props(ColonetPacket* pkt)
352
{
353
  if(first_packet_sent && pkt->token_dest == token_dest){
354
    /* Another robot is sending to our dest - therefore the network
355
     * doesn't know about us yet.  Try to register again. */
356
    dbg_printf("Disconnected from network\n");
357
    dbg_printf("%s: failed to register in network; trying again...\n", 
358
               __FUNCTION__);
359
    connected = false;
360

  
361
  }
362

  
363
  if(num_robots < pkt->num_robots){    
364
    if(token_dest == 0){
365
      /* If we were the last robot, we now point to newly added robot */
366
      token_dest = num_robots;
367
      dbg_printf("%s: token_dest updated to %d\n", __FUNCTION__, token_dest);
368
    }
369

  
370
    num_robots = pkt->num_robots;
371

  
372
    dbg_printf("%s: num_robots updated to %d\n", __FUNCTION__, num_robots);
373
  }else if(num_robots > pkt->num_robots && first_packet_sent){
374
    /* A robot has left the network... hopefully not us */
375
    dbg_printf("%s: number of robots decreased to %d\n", __FUNCTION__, 
376
               pkt->num_robots);
377

  
378
    num_robots = pkt->num_robots;
379
  }
380
}
381

  
382
int ColonetWireless::join_network(ColonetPacket* pkt)
383
{
384
  dbg_printf("Attempting to join network...\n");
385

  
386
  token_src = pkt->num_robots;
387
  token_dest = 0;
388
  num_robots = pkt->num_robots+1;
389

  
390
  ColonetPacket* newpkt = create_packet(token_src, token_dest, 0, 0, 0, 
391
                                        (unsigned char*)"", num_robots);
392
  if(newpkt == NULL){
393
    fprintf(stderr, "Error: %s - create_packet failed\n", __FUNCTION__);
394
    return -1;
395
  }
396

  
397
  dbg_printf("JOIN PACKET:\n"
398
             "token_src:%d\n"
399
             "token_dest:%d\n"
400
             "msg_dest:%d\n"
401
             "msg_type:%d\n"
402
             "msg_code:%d\n"
403
             "num_robots:%d\n",
404
             newpkt->token_src, newpkt->token_dest, newpkt->msg_dest, 
405
             newpkt->msg_type, newpkt->msg_code, newpkt->num_robots);
406
  
407
  dbg_printf("data: ");
408

  
409
  for(int i = 0; i < PACKET_DATA_LEN; i++){
410
    dbg_printf("%d ", newpkt->data[i]);
411
  }
412
  dbg_printf("\n");
413

  
414
  send_packet(newpkt);
415

  
416
  connected = true;
417
  dbg_printf("Connected to network.\n");
418

  
419
  free(newpkt);
420

  
421
  return 0;
422
}
423

  
424
int ColonetWireless::transmit_queued_message()
425
{
426
  ColonetPacket* top_pkt;
427
  int ret;
428

  
429
  if(have_token){
430
    top_pkt = outbox.front();
431
    if(top_pkt == NULL){
432
      dbg_printf("%s: no messages to send -- Passing the token.\n", 
433
                 __FUNCTION__);
434
      /* If no packets need to be sent, just send a blank packet */
435
      top_pkt = create_packet(token_src, token_dest, 0, 0, 0, 
436
                              (unsigned char*)"", num_robots);
437
    }else{
438
      outbox.pop();
439
    }
440

  
441
    ret = send_packet(top_pkt);
442
    free(top_pkt);
443
    if(ret < 0){
444
      dbg_fprintf(stderr, "%s: send_packet failed\n", __FUNCTION__);
445
      return -1;
446
    }
447

  
448
    dbg_printf("%s: packet sent\n", __FUNCTION__);
449

  
450
    have_token = false;
451
  }
452

  
453
  return 0;
454
}
455

  
456
int ColonetWireless::send_packet(ColonetPacket* pkt)
457
{
458
  int portfd = open(wireless_port, O_RDWR);
459

  
460
  dbg_printf("\nsend packet: \n");
461

  
462
  if (portfd == 0) {
463
    return -1;
464
  }
465

  
466
  //write(portfd, (unsigned char*)pkt, 16);
467

  
468
  for (int i = 0; i < PACKET_SIZE; i++) {
469
    write(portfd, (unsigned char*)pkt+i, 1);
470
    usleep(50); //delay here - robot wireless can't handle full data rate...
471
    dbg_fprintf(stderr, "%x ", ((unsigned char*)pkt)[i]);
472
  }
473
  dbg_printf("\n");
474

  
475
  close(portfd);
476

  
477
  return 0;
478
}
479

  
480
unsigned char ColonetWireless::compute_checksum(ColonetPacket* pkt)
481
{
482
  char checksum = 0;
483

  
484
  checksum -= pkt->token_src;
485
  checksum -= pkt->token_dest;
486
  checksum -= pkt->msg_dest;
487
  checksum -= pkt->msg_type;
488
  checksum -= pkt->msg_code;
489

  
490
  for(int i = 0; i < PACKET_DATA_LEN; i++){
491
    checksum -= pkt->data[i];
492
  }
493

  
494
  checksum -= pkt->num_robots;
495

  
496
  return checksum;
497
}
498

  
499
ColonetPacket* ColonetWireless::create_packet(unsigned char token_src_, 
500
                                              unsigned char token_dest_,
501
                                              unsigned char msg_dest, 
502
                                              unsigned char msg_type, 
503
                                              unsigned char msg_code, 
504
                                              unsigned char* data,
505
                                              unsigned char num_robots_)
506
{
507
  ColonetPacket* dest_packet = new ColonetPacket;
508

  
509
  dest_packet->prefix[0] = 'R';
510
  dest_packet->prefix[1] = 'C';
511

  
512
  dest_packet->token_src = token_src_;
513
  dest_packet->token_dest = token_dest_;
514
    
515
  dest_packet->msg_dest = msg_dest;
516
  dest_packet->msg_type = msg_type;
517
  dest_packet->msg_code = msg_code;
518

  
519
  memset(dest_packet->data, 0, PACKET_DATA_LEN);
520
  memcpy(dest_packet->data, (char*)data, PACKET_DATA_LEN);
521

  
522
  dest_packet->num_robots = num_robots_;
523
  dest_packet->checksum = compute_checksum(dest_packet);
524

  
525
  //printf("Made this packet: \n");
526
  //print_packet(dest_packet);
527

  
528
  return dest_packet;
529
}
530

  
531
void ColonetWireless::print_packet(ColonetPacket* pkt)
532
{
533
  int i;
534

  
535
  printf("Prefix: %c%c\n", pkt->prefix[0], pkt->prefix[1]);
536
  printf("Token src: %d\n", pkt->token_src);
537
  printf("Token dest: %d\n", pkt->token_dest);
538
  printf("Msg dest: %d\n", pkt->msg_dest);
539
  printf("Msg type: %d\n", pkt->msg_type);
540
  printf("Msg code: %d\n", pkt->msg_code);
541

  
542
  printf("Data: ");
543
  for(i = 0; i < PACKET_DATA_LEN; i++){
544
    printf("%d ", pkt->data[i]);
545
  }
546
  printf("\n");
547
  
548
  printf("Num robots: %d\n", pkt->num_robots);
549
  printf("Checksum: %d\n", pkt->checksum);
550
}
551

  
552
int ColonetWireless::handle_error(ColonetPacket* pkt)
553
{
554
  int dead_robot;
555
  int errcode = ((char*)pkt)[WL_ERROR_LOC];
556

  
557
  dbg_printf("%s: Handling error %d\n", __FUNCTION__, pkt->token_dest);
558

  
559
  switch(errcode){ //token_dest 
560
  case WL_ERRCODE_ROBOTDEATH:
561
    dead_robot = ((char*)pkt)[WL_ERR_DEAD_LOC];
562

  
563
    fprintf(stderr, "Dead robot: %d\n", dead_robot);
564
    num_robots--;
565
    
566
    if(token_src > dead_robot){
567
      if(token_src == num_robots){
568
        token_src--;
569
        token_dest = 0;
570
      }else{
571
        token_src--;
572
        token_dest--;
573
      }
574
    }
575

  
576
    //ensure that the last robot talks to the 0th one
577
    //this won't be set if the LAST robot dies (all robots are < dead)
578
    if(token_src == num_robots - 1){
579
      token_dest = 0;
580
    }
581

  
582
    if(token_src == dead_robot){
583
      //you took the place of the dead robot
584
      //you start the token ring again
585
      ColonetPacket* tmp_pkt = create_packet(token_src, token_dest, 0, 0, 0,
586
                                             (unsigned char*)"", num_robots);
587
      send_packet(tmp_pkt);
588
      free(tmp_pkt);
589
    }
590
    break;
591
  case WL_ERRCODE_NEEDTOCHARGE:
592
    fprintf(stderr, "Need to charge error received\n");
593
    break;
594
  case WL_ERRCODE_CHARGESTATION:
595
    fprintf(stderr, "Charge station error received\n");
596
    break;
597
  }
598
    
599
  return 0;
600
}
601

  
602
/** @brief 
603
 *
604
 * @param pkt Packet to be logged
605
 *
606
 * @return 0 on success, -1 on failure
607
 */
608
int ColonetWireless::log_packet(ColonetPacket* pkt)
609
{
610
  FILE* logfile = fopen(log_filename, "a");
611

  
612
  if (logfile == NULL) {
613
    dbg_printf("%s: Error - fopen %s failed.\n", log_filename, __FUNCTION__);
614
    return -1;
615
  }
616

  
617
  for (int i = 0; i < PACKET_SIZE; i++) {
618
    fprintf(logfile, "%d ", *((unsigned char*)pkt+i));
619
  }
620

  
621
  fprintf(logfile, "\n");
622

  
623
  fclose(logfile);
624

  
625
  return 0;
626
}
trunk/code/projects/colonet/lib/colonet_wireless/colonet_wireless_test2.cpp
1
/** @file colonet_wireless_test2.cpp
2
 * @brief colonet_wireless_test2 - tests the colonet_wireless library with
3
 * manual control.
4
 *
5
 * @author Eugene Marinelli
6
 * @date 2/5/06
7
 */
8

  
9
#include <iostream>
10
#include <signal.h>
11
#include <fcntl.h>
12
#include <signal.h>
13

  
14
#include "colonet_wireless.h"
15
#include "colonet_defs.h"
16

  
17
ColonetWireless* cw;
18

  
19
int msg_handler(ColonetPacket* pkt)
20
{
21
  printf("Handler!\n");
22
  return 0;
23
}
24

  
25
char get_mouse()
26
{
27
  int fd;
28
  char buf[10];
29

  
30
  fd = open("/dev/input/mouse0", O_RDONLY);
31

  
32
  read(fd, buf, 1);
33

  
34
  close(fd);
35

  
36
  return buf[0];
37
}
38

  
39
void exit_handler(int sig)
40
{
41
  unsigned char data[10];
42

  
43
  printf("Sending kill packet...\n");
44
  cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTORS_OFF, data);
45

  
46
  printf("Exiting...\n");
47

  
48
  sleep(2);
49
  exit(0);
50
}
51

  
52
int main()
53
{
54
  unsigned char data[10];
55
  char dir;
56
  int paused = 0;
57

  
58
  unsigned char motor_back_args[6] = {0, 0, 0, 0xFF, 0};
59
  unsigned char motor_forward_args[6] = {0, 1, 0, 0xFF, 0};
60

  
61
  cw = new ColonetWireless(SERIAL_PORT, msg_handler, NULL, true, true);
62

  
63
  signal(SIGINT, exit_handler);
64

  
65
  cw->run_listener_thread();
66

  
67
  while(1){
68
    dir = get_mouse();
69

  
70
    usleep(300000);
71

  
72
    printf("%d\n", dir);
73

  
74
    switch (dir) {
75
    case 40:
76
      /* Forward */
77
      cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTOR1_SET, motor_forward_args);
78
      cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTOR2_SET, motor_forward_args);
79
      break;
80
    case 8:
81
      /* Back */
82
      cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTOR1_SET, motor_back_args);
83
      cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTOR2_SET, motor_back_args);
84
      break;
85
    case 24:
86
      /* Left */
87
      //cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTORS_OFF, data);
88
      cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTOR1_SET, motor_forward_args);
89
      break;
90
    case 56:
91
      /* Right */
92
      //cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTORS_OFF, data);
93
      cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTOR2_SET, motor_forward_args);
94
      break;
95
    case 9:
96
      /* Left click */
97
      /* Stop */
98
      cw->clear_message_queue();
99
      cw->send(GLOBAL_DEST, COLONET_COMMAND, MOTORS_OFF, data);
100
      break;
101
    case 10:
102
      /* Right click */
103
      /* Execute first user-defined function */
104
      cw->send(GLOBAL_DEST, COLONET_COMMAND, 0xF0, data);
105
      break;
106
    }
107
  }
108

  
109
  return 0;
110
}
trunk/code/projects/colonet/lib/colonet_wireless/colonet_wireless.h
1
/** @file colonet_wireless.h
2
 *
3
 * @brief Wireless library for communicating with colony robots
4
 * 
5
 * @author Eugene Marinelli
6
 * @date 10/26/06
7
 *
8
 * @bug gtkterm must be running for the library to work...
9
 */
10

  
11
/* 
12
   NOTES
13
   Things colonet server must be able to do with wireless:
14
   - Send a commmand/request packet to a specific robot
15
   - Accept packets from robots - need a "SIGNAL"-like function and a 
16
   message queue
17
   - Only send stuff when we have the token
18
   - Pass token along to the next robot
19
   - Join ad-hoc network automatically
20
*/
21

  
22
#ifndef COLONET_WIRELESS_H_
23
#define COLONET_WIRELESS_H_
24

  
25
#include <queue>
26
#include <colonet_defs.h>
27

  
28
using namespace std;
29

  
30
typedef int(*MsgHandlerFunction)(ColonetPacket*);
31
/* takes src, msg_type, req_code, data */
32

  
33
class ColonetWireless {
34
 public:
35
  /** @brief Constructor - creates a new instance of ColonetWireless 
36
   * and initializes values
37
   * 
38
   * @param wl_port Either SERIAL_PORT or USB_PORT (as defined in COLONET_DEFS)
39
   * @param log_filename Path to log file - outputs all raw data on the network
40
   * If set to NULL, logging is disabled.
41
   * @param msg_handler Function to be called when a packet is received.
42
   * Must take a ColonetPacket as an argument (see defn of MsgHandlerFunction)
43
   * @param join_token_ring true if server should join the token ring,
44
   * false if it should just observe the network
45
   * 
46
   * @return new ColonetWireless object
47
   */
48
  ColonetWireless(char* wl_port, MsgHandlerFunction message_handler_, 
49
                  char* log_filename_, bool join_token_ring_, 
50
									bool ignore_token_);
51

  
52
  /**
53
   * @brief Deconstructor - frees queue and other stuff
54
   */
55
  ~ColonetWireless(void);
56

  
57
  /** @brief Spawns a thread which reads data from the hardware interface 
58
   * with the colony (either a dongle or a robot programmed to relay data)
59
   * and runs msg_handler when a full packet is received
60
   *
61
   * @return pointer to the thread
62
   */
63
  pthread_t* run_listener_thread(void);
64

  
65
  /** @brief Adds a message to the message sending queue.  One message in the
66
   * queue is sent each time the server receives the token.  Therefore
67
   * there might be a delay on the order of seconds before the packet is 
68
   * actually sent.
69
   *
70
   * @param msg_dest ID of the robot message is being sent to.  To send to 
71
   * all robots, use GLOBAL_DEST
72
   * @param msg_type Type of message being sent.  Should be either 
73
   * COLONET_COMMAND or COLONET_REQUEST
74
   * @param msg_code The message code/id telling the robot what to do or 
75
   * return.  For example this might be ORB_SET
76
   * @param data Pointer to a buffer of data to be sent.  Assumed to 
77
   * point to valid data.  An invalid pointer will cause a segfault.
78
   *
79
   * @return -1 on failure, 0 on success
80
   */
81
  int send(unsigned char msg_dest, unsigned char msg_type, 
82
           unsigned char msg_code, unsigned char* data);
83

  
84
  /** @brief Clears the message queue
85
   * @return void
86
   */
87
  void clear_message_queue(void);
88

  
89
  /** @brief Handles a complete packet.
90
   *
91
   * @param pkt A complete packet to which we should react
92
   *
93
   * @return 0 on success, -1 on failure
94
   */
95
  int handle_packet(ColonetPacket* pkt);
96

  
97
  //the rest of these would ideally be private, but must be accessed by 
98
  //the listen function
99
  ColonetPacket* create_packet(unsigned char token_src_, 
100
                               unsigned char token_dest_, 
101
                               unsigned char msg_dest, 
102
                               unsigned char msg_type, 
103
                               unsigned char msg_code, 
104
                               unsigned char* data, unsigned char num_robots_);
105
  ColonetPacket* build_packet(unsigned char* buf, int len);
106
  int send_packet(ColonetPacket* pkt);
107

  
108
  char wireless_port[80];
109
  unsigned char token_src; //id of server in token ring
110
  unsigned char token_dest; //id of "dest" robot in token ring
111
  unsigned char num_robots;
112

  
113
 private:
114
  queue<ColonetPacket*> outbox;
115
  bool join_token_ring;
116
  MsgHandlerFunction message_handler;
117
  bool have_token;
118
  bool connected; //whether we are connected to the robot
119
  bool first_packet_sent;
120
  bool logging_enabled;
121
	bool ignore_token;
122
  char log_filename[80];
123

  
124
  int transmit_queued_message(void);
125
  int join_network(ColonetPacket* pkt);
126
  void update_network_props(ColonetPacket* pkt);
127
  unsigned char compute_checksum(ColonetPacket* pkt);
128
  void print_packet(ColonetPacket* pkt);
129

  
130
  int handle_error(ColonetPacket* pkt);
131
  int log_packet(ColonetPacket* pkt);
132
};
133

  
134
#endif
trunk/code/projects/colonet/lib/colonet_wireless/Makefile
1
# colonet_wireless_test makefile
2

  
3
CC = g++
4
CFLAGS = -Wall -Wshadow -Wextra -g
5
INCLUDES = ../
6

  
7
all: colonet_wireless_test colonet_wireless_test2
8

  
9
colonet_wireless_test: colonet_wireless_test.o colonet_wireless.o Makefile
10
	$(CC) $(CFLAGS) -I ../ -pthread -o colonet_wireless_test colonet_wireless_test.o colonet_wireless.o 
11

  
12
colonet_wireless_test2: colonet_wireless_test2.o colonet_wireless.o Makefile
13
	$(CC) $(CFLAGS) -I ../ -pthread -o colonet_wireless_test2 colonet_wireless_test2.o colonet_wireless.o 
14

  
15
colonet_wireless.o: colonet_wireless.cpp colonet_wireless.h
16
	$(CC) $(CFLAGS) -I $(INCLUDES) -pthread -c colonet_wireless.cpp
17
	ar rc ../libcolonet_wireless.a colonet_wireless.o 
18
	ranlib ../libcolonet_wireless.a
19

  
20
colonet_wireless_test.o: colonet_wireless_test.cpp
21
	$(CC) $(CFLAGS) -I $(INCLUDES) -pthread -c colonet_wireless_test.cpp
22

  
23
colonet_wireless_test2.o: colonet_wireless_test2.cpp
24
	$(CC) $(CFLAGS) -I $(INCLUDES) -pthread -c colonet_wireless_test2.cpp
25

  
26
clean: 
27
	rm -rf *o colonet_wireless_test
trunk/code/projects/colonet/lib/colonet_dragonfly/colonet_dragonfly.c
1
/** @file colonet.c
2
 * @brief Colonet library for DRAGONFLY colony robots
3
 *
4
 * @author Eugene Marinelli
5
 * @date 4/17/07
6
 * 
7
 * @bug Handler registration not tested
8
 * @bug Request reponding not implemented - only accepts commands.
9
 */
10

  
11
#include <dragonfly_lib.h>
12
#include "colonet_dragonfly.h"
13

  
14
typedef struct {
15
  unsigned char msgId; //is this necessary?
16
  void (*handler)(void);
17
} UserHandler;
18

  
19
/* Globals (internal) */
20
static UserHandler user_handlers[USER_DEFINED_MSG_TOTAL];
21

  
22
/* Internal function prototypes */
23
static void packet_string_to_struct(ColonetPacket* dest_pkt, char* pkt_buf);
24
static unsigned int two_bytes_to_int(char high, char low);
25

  
26
/* Public functions */
27
int colonet_handle_message(unsigned char robot_id, char* pkt_buf)
28
{
29
  ColonetPacket pkt;
30
  unsigned char* args; //up to 7 char args
31
  unsigned int int_args[3]; //up to 3 int (2-byte) args
32

  
33
  packet_string_to_struct(&pkt, pkt_buf);
34

  
35
  if(pkt.msg_dest != GLOBAL_DEST && pkt.msg_dest != robot_id){ 
36
    //message not intended for us
37
    return 1;
38
  }
39

  
40
  args = pkt.data;
41
  
42
  int_args[0] = two_bytes_to_int(args[0], args[1]);
43
  int_args[1] = two_bytes_to_int(args[2], args[3]);
44
  int_args[2] = two_bytes_to_int(args[4], args[5]);
45

  
46
  if(pkt.msg_type == COLONET_REQUEST){
47
    /* TODO - send back data! */
48

  
49
    switch(pkt.msg_code){
50
      //Sharp
51
    case READ_DISTANCE:
52
      break;
53
    case LINEARIZE_DISTANCE:
54
      break;
55
    case LOG_DISTANCE:
56
      break;
57

  
58

  
59
      //Analog
60
    case CALL_ANALOG8:
61
      break;
62
    case CALL_ANALOG10:
63
      break;
64
    case WHEEL:
65
      break;
66
    case BATTERY:
67
      break;
68

  
69
      //BOM
70
    case GETMAXBOM:
71
      break;
72

  
73
      //Dio
74
    case DIGITAL_INPUT:
75
      break;
76
    case BUTTON1_READ:
77
      break;
78
    case BUTTON2_READ:
79
      break;
80

  
81
      //Bumper
82
    case DETECT_BUMP:
83
      break;
84
    }
85
  }else if(pkt.msg_type == COLONET_COMMAND){
86
    if(pkt.msg_code >= USER_DEFINED_MSG_ID_START && 
87
       pkt.msg_code <= USER_DEFINED_MSG_ID_END){
88
      if (user_handlers[pkt.msg_code - USER_DEFINED_MSG_ID_START].handler) {
89
        /* Call the user's handler function if it the function's address
90
         * is non-zero (has been set) */
91
        user_handlers[pkt.msg_code - USER_DEFINED_MSG_ID_START].handler();
92
      }
93

  
94
      return 0;
95
    }
96

  
97
    switch(pkt.msg_code){
98
    default:
99
      printf("%s: Error - message code %d not implemented\n", __FUNCTION__,
100
             pkt.msg_code);
101
      return -1;
102
      break;
103

  
104
      //Buzzer
105
    case BUZZER_INIT:
106
      buzzer_init();
107
      break;
108
    case BUZZER_SET_VAL:
109
      buzzer_set_val(args[0]);
110
      break;
111
    case BUZZER_SET_FREQ:
112
      buzzer_set_freq(args[0]);
113
      break;
114
    case BUZZER_CHIRP:
115
      buzzer_chirp(int_args[0], int_args[1]);
116
      break;
117
    case BUZZER_OFF:
118
      buzzer_off();
119
      break;
120
      
121
      //LCD
122
    case LCD_INIT:
123
      lcd_init();
124
      break;
125
    case LCD_CLEAR_SCREEN:
126
      lcd_clear_screen();
127
      break;
128
    case LCD_PUTBYTE:
129
      lcd_putbyte(args[0]);
130
      break;
131
    case LCD_PUTCHAR:
132
      lcd_putchar((char)args[0]);
133
      break;
134
    case LCD_PUTSTR:
135
      lcd_putstr((char*)args);
136
      break;
137
    case LCD_GOTOXY: 
138
      lcd_gotoxy(int_args[0], int_args[1]);
139
      break;
140
    case LCD_PUTINT: 
141
      lcd_putint(int_args[0]);
142
      break;
143
    case ORB_INIT:
144
      orb_init();
145
      break;
146
      //Orb
147
    case ORB_SET:
148
      orb_set(args[0], args[1], args[2]);
149
      break;
150
    case ORB_SET_COLOR:
151
      orb_set_color(int_args[0]);
152
      break;
153
    case ORB_DISABLE:
154
      orb_disable();
155
      break;
156
    case ORB_ENABLE:
157
      orb_enable();
158
      break;
159
    case LED_INIT:
160
      break;
161
    case LED_USER:
162
      break;
163
    case ORB_SEND:
164
      //orb_send();
165
      break;
166
      //Motors
167
    case MOTORS_INIT:
168
      motors_init();
169
      break;
170
    case MOTOR1_SET:
171
      motor1_set(int_args[0], int_args[1]);
172
      break;
173
    case MOTOR2_SET:
174
      motor2_set(int_args[0], int_args[1]);
175
      break;
176
    case MOTORS_OFF:
177
      motors_off();
178
      break;
179

  
180
      /*
181
    case MOVE:
182
      
183
      break;
184
      */
185

  
186
    case XBEE_INIT:
187
      xbee_init();
188
      break;
189

  
190
    case XBEE_PUTC:
191
      xbee_putc((char)args[0]);
192
      break;
193

  
194
    case USB_INIT:
195
      usb_init();
196
      break;
197

  
198
    case USB_PUTC:
199
      usb_putc((char)args[0]);
200
      break;
201

  
202
    case PRINTF:
203
      printf("%s", pkt.data);
204
      break;
205
    case KILL_ROBOT:
206
      motors_off();
207
      buzzer_off();
208
      exit(0); //kill the robot
209
      break;
210
      //Time
211
    case DELAY_MS:
212
      delay_ms(int_args[0]);
213
      break;
214

  
215
      //Analog
216
    case ANALOG_INIT:
217
      analog_init();
218
      break;
219

  
220
      //BOM
221
    case BOM_ON:
222
      bom_on();
223
      break;
224
    case BOM_OFF:
225
      bom_off();
226
      break;
227
    case OUTPUT_HIGH:
228
      output_high(int_args[0]);
229
      break;
230
    case OUTPUT_LOW:
231
      output_low(int_args[0]);
232
      break;
233

  
234
      //Dio
235
    case DIGITAL_OUTPUT:
236
      digital_output(int_args[0], int_args[1]);
237
      break;
238
    }
239
  }else{
240
    printf("%s: Error: Invalid colonet message type", __FUNCTION__);
241
    return -1;
242
  }
243

  
244
  return 0;
245
}
246

  
247
/* colonet_add_message
248
 * Adds a user-defined message
249
 */
250
int colonet_add_message(unsigned char msgId, void (*handler)(void))
251
{
252
  if(msgId < USER_DEFINED_MSG_ID_START || msgId > USER_DEFINED_MSG_ID_END){
253
    return -1;
254
  }
255

  
256
  /* Register this function in the array */
257
  user_handlers[msgId-USER_DEFINED_MSG_ID_START].msgId = msgId;
258
  user_handlers[msgId-USER_DEFINED_MSG_ID_START].handler = handler;
259

  
260
  return 0;
261
}
262

  
263
/* Private functions */
264
static void packet_string_to_struct(ColonetPacket* dest_pkt, char* pkt_buf)
265
{
266
  int i;
267
  
268
  printf("\npacket:");
269
  for(i = 0; i < 16; i++){
270
    printf("%d ", pkt_buf[i]);
271
  }
272

  
273
  printf("\n");
274

  
275
  dest_pkt->prefix[0] = pkt_buf[0];
276
  dest_pkt->prefix[1] = pkt_buf[1];
277
  dest_pkt->token_src = pkt_buf[2];
278
  dest_pkt->token_dest = pkt_buf[3];
279
  dest_pkt->msg_dest = pkt_buf[4];
280
  dest_pkt->msg_type = pkt_buf[5];
281
  dest_pkt->msg_code = pkt_buf[6];
282
  
283
  for(i = 0; i < PACKET_DATA_LEN; i++){
284
    dest_pkt->data[i] = pkt_buf[7+i];
285
  }
286

  
287
  dest_pkt->num_robots = pkt_buf[PACKET_SIZE-2];
288
  dest_pkt->checksum = pkt_buf[PACKET_SIZE-1];
289
}
290

  
291
/* two_bytes_to_int(char a, char b)
292
 * Returns int of form [high][low]
293
 */
294
static unsigned int two_bytes_to_int(char high, char low)
295
{
296
  return (((unsigned int)high)<<8) + (unsigned int)low;
297
}
trunk/code/projects/colonet/lib/colonet_dragonfly/Makefile
1
# colonet_wireless_test makefile
2
MCU = atmega128
3
F_CPU = 8000000
4
CDEFS = -DF_CPU=$(F_CPU)UL
5

  
6
CC = avr-gcc
7
CFLAGS = -Wall -Wshadow -Wextra -g -mmcu=$(MCU)
8
INCLUDES = -I../../../xfly_lib -I../
9

  
10
all: colonet_dragonfly.o
11

  
12
#colonet_dragonfly: colonet_dragonfly.o Makefile
13
#	$(CC) $(CFLAGS) $(INCLUDES) -o colonet_wireless_test colonet_wireless.o
14

  
15
colonet_dragonfly.o: colonet_dragonfly.c colonet_dragonfly.h
16
	$(CC) $(CDEFS) $(CFLAGS) $(INCLUDES) -c colonet_dragonfly.c
17
	ar rc ../libcolonet_dragonfly.a colonet_dragonfly.o
18
	ranlib ../libcolonet_dragonfly.a
19

  
20
clean: 
21
	rm -rf *.o
trunk/code/projects/colonet/lib/colonet_dragonfly/colonet_dragonfly.h
1
/** @file colonet.h
2
 * @brief Colonet library for colony robots
3
 * @author Eugene Marinelli
4
 * @date 10/26/06
5
 */
6

  
7
#ifndef COLONET_DRAGONFLY_H_
8
#define COLONET_DRAGONFLYH_
9

  
10
#include <colonet_defs.h>
11

  
12
/** @brief Handles colonet packets.  Should be called by parse_buffer 
13
 * when it is determined that a colonet message has been received.
14
 *
15
 * @param robot_id The robot id
16
 * @param pkt_buf The packet buffer (e.g. wl_buf)
17
 * 
18
 * @return -1 on error (invalid msgId), 0 on success
19
 */
20
int colonet_handle_message(unsigned char robot_id, char* packet);
21

  
22
/** @brief Registers a new colonet message handler function.  If a message
23
 * with msgId is received, then handler will be called.
24
 * 
25
 * @param msgId The message id of the handler to be registered.  Must be
26
 * between USER_DEFINED_MSG_ID_START and USER_DEFINED_MSG_ID_END
27
 * @param handler The function to be called if a colonet packet with message
28
 * id msgId is received
29
 * 
30
 * @return -1 on error (invalid msgId), 0 on success
31
 */
32
int colonet_add_message(unsigned char msgId, void (*handler)(void));
33

  
34
#endif
trunk/code/projects/colonet/lib/colonet_defs.h
1
/* Eugene Marinelli, Fan
2
 * 10/27/06
3
 *
4
 * Colonet Definitions - common definitions and structs used in all colonet 
5
 * applications
6
 */
7

  
8
#ifndef COLONET_DEFS_H_
9
#define COLONET_DEFS_H_
10

  
11
//Message types
12
#define COLONET_COMMAND 0x0D
13
#define COLONET_REQUEST 0x0E
14
#define COLONET_RESPONSE 0x0F
15

  
16
//Packet properties
17
#define PACKET_DATA_LEN 7
18
#define PACKET_SIZE 16
19

  
20
//Packet error codes
21
#define WL_ERRCODE_ROBOTDEATH 123     //For timeouts
22
#define WL_ERRCODE_NEEDTOCHARGE 250   //For pinging charging station
23
#define WL_ERRCODE_CHARGESTATION 251  //Charging station response to ping
24
#define WL_ERR_DEAD_LOC 5
25
#define WL_ERROR_DEST 255
26
#define WL_ERROR_LOC 4
27

  
28
#define WL_DEFAULT_PAN 3332
29

  
30
typedef struct {
31
  unsigned char prefix[2];
32
  unsigned char token_src;
33
  unsigned char token_dest;
34
  unsigned char msg_dest;
35
  unsigned char msg_type;
36
  unsigned char msg_code;
37
  unsigned char data[PACKET_DATA_LEN];
38
  unsigned char num_robots;
39
  unsigned char checksum;
40
} ColonetPacket;
41

  
42
#define SERIAL_PORT "/dev/ttyS0"
43
#define USB_PORT "/dev/ttyUSB0"
44

  
45
// Message dests
46
#define GLOBAL_DEST 200
47
#define MAX_NUM_ROBOTS 7
48
#define COLONET_SERVER_RESPONSE_ADDR 201
49

  
50
#define USER_DEFINED_MSG_ID_START 0xF0
51
#define USER_DEFINED_MSG_ID_END 0xFF
52
#define USER_DEFINED_MSG_TOTAL 0x0F
53

  
54
/* Low level robot commands */
55
//BUZZER
56
#define BUZZER_INIT 0x00
57
#define BUZZER_SET_VAL 0x01
58
#define BUZZER_SET_FREQ 0x02
59
#define BUZZER_CHIRP 0x03
60
#define BUZZER_OFF 0x04
61

  
62
//LCD
63
#define LCD_INIT 0x05
64
#define LCD_CLEAR_SCREEN 0x06
65
#define LCD_PUTBYTE 0x07
66
#define LCD_PUTCHAR 0x08
67
#define LCD_PUTSTR 0x09
68
#define LCD_GOTOXY 0x0A
69
#define LCD_PUTINT 0x0B
70

  
71
//ORB
72
#define ORB_INIT 0x0C
73
#define ORB_SET 0x0D
74
#define ORB_SET_COLOR 0x0E
75
#define ORB_DISABLE 0x0F
76
#define ORB_ENABLE 0x10
77
#define ORB_SET_DIO 0x11
78
#define LED_INIT 0x12
79
#define LED_USER 0x13
80
#define ORB_SET_NUM_NS 0x14
81
#define ORB_SET_NUM 0x15
82
#define ORB_SEND 0x16
83

  
84
//MOTORS
85
#define MOTORS_INIT 0x17
86
#define MOTOR1_SET 0x18
87
#define MOTOR2_SET 0x19
88
#define MOTORS_OFF 0x1A
89
#define MOVE 0x1B
90
#define MOVE_AVOID 0x1C
91

  
92
//SHARP
93
#define READ_DISTANCE 0x24
94
#define LINEARIZE_DISTANCE 0x25
95
#define LOG_DISTANCE 0x26
96
#define ENABLE_IR 0x27
97
#define DISABLE_IR 0x28
98

  
99
//SERIAL
100
#define XBEE_INIT 0x29
101
#define XBEE_PUTC 0x2A
102
#define XBEE_GETC 0x2B
103

  
104
#define USB_INIT 0x2D
105
#define USB_PUTC 0x2E
106
#define USB_GETC 0x2F
107

  
108

  
109

  
110
//DELAY_MS
111
#define DELAY_MS 0x31
112

  
113
//ANALOG
114
#define ANALOG_INIT 0x32
115
#define SET_ADC_MUX 0x33
116
#define ENABLE_ANALOG 0x34
117
#define CALL_ANALOG8 0x35
118
#define CALL_ANALOG10 0x36
119
#define WHEEL 0x37
120
#define BATTERY 0x38
121

  
122
//BOM
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff