Project

General

Profile

Statistics
| Revision:

root / branches / encoders / code / projects / colonet / testing / wl_network_colonet / wl_adhoc.c @ 1390

History | View | Annotate | Download (20 KB)

1
/**
2
   \file wl_adhoc.c
3
   Wireless ad hoc networking.
4
   NOW WITH SENSORS
5
   Robots can come in and out of the ring.
6
*/
7
 
8
/*
9
  Wireless ad hoc networking + sensors
10

11
  If a robot is the first to turn on, it will set itself as the leader
12

13
  The next robot will receive that packet and tokenize with it.
14
  Each other robot turned on will receive packets, and join the ring.
15
  All the robots will also change their network topology (num_bots)
16
  
17
  
18
  2006-11-21: Felix
19
              Fixed buzzer.c code (copied from a different dir).
20
              Code still works on robots at this time 
21
              
22
              Felix used this code to figure out the robot resetting problem.  BOM sensor 10
23
              needs to be taped up.
24
              You may put this event in the history books.
25
              
26
  
27
  2006-10-31 Kevin
28
  Changed the boards to the 115200 Baud rate. Changed the pound define to reflect this.
29
  The boards have been hardcoded to do this. They are labelled in case you do not know
30
  which ones do this. It works.
31
  
32
  2006-10-13: Kevin
33
  Made improvements to make the module more modular and general
34
  so that you can just drag and drop it into any behavior.
35
  Began the integration of autonomous charging. We're using the
36
  error system that is built into wl_adhoc originally to ping the
37
  charge stations. Do not know if it works, can't test it yet. But
38
  wireless normally still works.
39

40
  2006-08-07: Felix
41
  Added the use of the sensor row that was being transmitted
42
  Robots now share a common table of sensor 'positions'
43
  Just add light sensing and you're good to go
44
            
45
  WARNING: Robots seem to reset randomly due to batteries, especially
46
  when moving around.  Could be brownout detector kicking in.
47
  Added a beep at startup to detect reset.
48

49
  2006-08-03: Felix
50
  Now added follow-the-leader code
51
  Battery problem -- testing only really worked on power supply
52
            
53
  Robots follow the leader (theoretically).
54
  They fill their own row of the sensors matrix, but do not get
55
  the other robots' row -- not in the code.
56

57
  2006-07-27: Felix
58
  Created new directory for sensors use
59

60
  2006-07-24: Felix
61
  Added BOM.c/BOM.h
62
  bom_test works -- gets max bom
63
            
64
  Added the get_maxbom each time you get a wireless packet
65
  ---NEEDS TESTING
66
            
67
  Also, packet sent should contain your 'row'
68
  Also, received packet should be stored in matrix
69

70
  2006-07-13: Felix
71
  Works for the most part
72
  W00t
73
                        
74
  Still a few kinds I imagine, but robot death & birth work
75
*/
76

    
77
#include "firefly+_lib.h"
78
#include "wl_adhoc.h"
79
#include <avr/interrupt.h>
80
#include <colonet.h>
81

    
82
#define MAX(a, b) ((a) > (b) ? (a) : (b))
83
#define MIN(a, b)  ((a) < (b) ? (a) : (b))
84

    
85
unsigned char set_orb_wireless = 0;
86
//unsigned char set_orb_wireless = 1;
87

    
88
/*
89
  int main( void ) 
90
  {
91
  wl_adhoc();
92
  bom_test();
93

94
  return 0;
95
  }
96
*/
97

    
98
void bom_test (void)
99
{
100
  int maxb;
101

    
102
  lcd_init();
103
  analog_init();
104

    
105
  while(1) {
106
    if(button1_read()){
107
      lcd_clear_screen();
108
      bom_on();
109
      delay_ms(100);
110
    }
111
    
112
    if(button2_read()) {
113
      lcd_clear_screen();
114
      bom_off();
115
      delay_ms(100);
116
    }
117
        
118
    maxb = getMaxBom();
119
        
120
    lcd_putint(maxb);
121

    
122
    delay_ms(50); 
123
  }
124
}
125

    
126
void wl_adhoc()
127
{
128
  //initialize the serial modules
129
  serial_init(WL_BAUD);       //XBee
130
  serial1_init(BAUD115200);   //Serial port
131
  
132
  //lcd, orb, all that good stuff
133
  lcd_init();
134
  analog_init();
135
  led_init();
136
  orb_init();
137
  motors_init();
138
  buzzer_init();
139
        
140
  //init the wireless
141
  wl_init();
142
        
143
  //int max_bom_to_follow;
144

    
145
  while(1){
146
    //this needs to happen continuously -- it handles the packet
147
    parse_buffer();
148
        
149
    /*
150
      if(SRC ==  0) {
151
      //leader -- just drive
152
      drive_forward();
153
      }
154
      else {
155
      max_bom_to_follow = getSelfSensor(SRC, PREV, NUM_BOTS);
156
      //lcd_putchar('f');
157
      //lcd_putchar(max_bom_to_follow + 48);
158
      //lcd_putchar(' ');
159
      seek(max_bom_to_follow);
160
      }
161
    */
162
                
163
    //button1 prints debug information
164
    if(button1_read()) {
165
      //lcd_clear_screen();
166
      display_debug();
167
      delay_ms(10);
168
    }
169
                
170
    /*
171
    //button2 does nothing
172
    if(button2_read()) {
173
      //wl_create_packet();
174
      //wl_send();
175
      //delay_ms(10);
176
    }
177
    */
178
  }
179

    
180
  return;        
181
}
182

    
183
/**
184
   \fn display_debug
185
   \brief displays debug information
186

187
   Prints out 4 numbers, in the following order
188
   ( PREV | SRC | DEST | NUM_BOTS | wl_to_death_count )
189
   where PREV is the previous robot before you
190
   SRC is you
191
   DEST is your destination
192
   NUM_BOTS is the total number of robots in the ring
193
   wl_do_death_count is the number of timeouts that will result in a death
194
*/
195
void display_debug()
196
{
197
  lcd_clear_screen();
198
  lcd_putchar('(');
199
  lcd_putchar(PREV+48);
200
  lcd_putchar('|');
201
  lcd_putchar(SRC+48);
202
  lcd_putchar('|');
203
  lcd_putchar(DEST+48);
204
  lcd_putchar('|');
205
  lcd_putchar(NUM_BOTS+48);        
206
  lcd_putchar('|');
207
  lcd_putint(wl_to_death_count);
208
  lcd_putchar(')');
209
    
210
  //print table
211
  int y = 1;
212
  lcd_gotoxy(0, y);
213
  int i, j;
214

    
215
  for(i = 0; i < NUM_BOTS; i++) {
216
    for(j = 0; j < NUM_BOTS; j++) {
217
      lcd_putchar( getSelfSensor(i, j, NUM_BOTS) + 48);
218
      lcd_putchar(' ');
219
    }
220
    y++;
221
    lcd_gotoxy(0, y);
222
  }
223
}
224

    
225
/*
226
  \fn wl_timeout_handler
227
  Handles the timeout case.
228

229
  A time out occurs about every 1/4 second.  This function is called each time 
230
  one occurs.  In the case where a robot first turns on, it will wait for a 
231
  long time before declaring itself the leader.  Otherwise, if enough 
232
  time-outs occur in a row, wl_to_flag will be set to 1.  This will cause a 
233
  timeout packet to be sent next time around
234

235
*/
236
void wl_timeout_handler( void ) {
237
  //increment the total number of wireless time-outs
238
  wl_to_count++;
239
  //lcd_putchar('w');
240
        
241
  static int wl_first_to_count =  0;
242
        
243
  //first time time out routine - listen for a long time
244
  if(first_time) {
245
    if(wl_to_count > WL_TO_INITIAL){
246
      //increment the counter for first timeouts
247
      wl_first_to_count++;
248
                                
249
      //lcd_putchar('Z');
250
                                
251
      //you don't actually want to send out a packet -- you would confuse 
252
      //other robots
253
      wl_to_flag = 0;
254
      wl_to_count = 0;
255
    }
256
  }else{
257
    //not the first time - regular time out routine
258

    
259
    //if you have enough timeouts
260
    if(wl_to_count > WL_TIMEOUT){
261
      //lcd_putchar('z');
262
                        
263
      //change the time-out flag to 1
264
      wl_to_flag = 1;
265
      wl_to_count = 0;
266
                        
267
      //increment the count for robot death
268
      if(NUM_BOTS > 1) {
269
        //only increase death count if there are robots that can die
270
        //if numbots = 1, you are the only robot (no suicidal robots... yet)
271
        wl_to_death_count++;
272
      }
273
      
274
      //check for a robot death
275
      if(wl_to_death_count > WL_TO_DEATH) {
276
        //a robot has died :(
277
        wl_to_death_flag = 1;
278
        wl_death_handler();
279
      }
280
    }
281
  }
282
        
283
  //take care of the case where you time out so much that you become the leader
284
  if(wl_first_to_count > WL_TO_LEADER) {
285
    //you are now the leader
286
    //lcd_putchar('L');
287
                
288
    first_time = 0;
289
                                
290
    NUM_BOTS = 1;                        //there are (1) robot in the ring
291
    SRC = 0;                                //you are robot # 1
292
    DEST = 1;                                //you are 'speaking' to (nonexistent) robot #1
293
                
294
    lcd_putchar('[');
295
    lcd_putchar(SRC+48);
296
    lcd_putchar('|');
297
    lcd_putchar(DEST+48);
298
    lcd_putchar('|');
299
    lcd_putchar(NUM_BOTS+48);        
300
    lcd_putchar('|');
301
    lcd_putint(wl_to_death_count);
302
    lcd_putchar(']');
303
                
304
    //create a a packet and send it
305
    wl_create_packet();
306
    wl_send();
307
                
308
    //change the timeout count to 0
309
    wl_to_count = 0;
310
    wl_first_to_count = 0;
311
  }
312
}
313

    
314
/**
315
   \fn wl_error_handler(int errcode)
316
   Handles error codes.
317
   \param errcode The error code.
318
   At the time, the only real error that happens is robot death.
319

320
   Robot death requires that wl_buf have been set (either by receiving a
321
   error packet or by calling wl_death_handler.
322

323
   Robot death:
324
   Number of robots will decrement.
325
   Robots above the dead robot will decrement their ID and their source.
326
   The loop remains closed.
327

328
*/
329
void wl_error_handler(unsigned char errcode)
330
{
331
  //which robot is dead
332
  int dead_robot;
333

    
334
  //print debug information
335
  lcd_clear_screen();
336
  lcd_gotoxy(0,0);
337
  lcd_putstr("error handler    ");
338
  lcd_putint(errcode);
339
  lcd_gotoxy(0,1);
340

    
341
  switch(errcode) {
342
  case WL_ERRCODE_ROBOTDEATH:
343
    lcd_putstr("  dead_robot: ");
344
    lcd_putint(wl_buf[WL_ERR_DEAD_LOC]);
345
    break;
346
  case WL_ERRCODE_NEEDTOCHARGE:
347
    lcd_putstr("   charge_robot: ");
348
    lcd_putint(wl_buf[WL_SRC_LOC]);
349
    break;
350
  default:
351
    break;
352
  }
353

    
354
  lcd_gotoxy(0,2);
355
        
356
  //set all the time-out counts and flags to 0
357
  wl_to_count = 0;
358
  wl_to_flag = 0;
359
  wl_to_death_flag = 0;
360
  wl_to_death_count = 0;
361
                
362
  //acknowledge receipt of the error packet by setting the errorcode in the 
363
  //packet to 0
364
  wl_buf[WL_ERROR_LOC] = 0;
365
  //also set checksum to !0
366
  wl_chksum = 1;
367
        
368
  //switch the error code
369
  switch(errcode) {
370
    //ROBOT DEATH
371
  case WL_ERRCODE_ROBOTDEATH:
372
    //get which robot has died
373
    dead_robot = wl_buf[WL_ERR_DEAD_LOC];
374
                        
375
    //decrement the total number of robots
376
    NUM_BOTS--;
377
                        
378
    //see if you are above the dead robot
379
    if( SRC > dead_robot ) {
380
      //if you are the last robot (since NUM_ROBOTS was decremented, 
381
      //you can check that way) then decrement your number
382
      //and set your destination to 0
383
      if( SRC == NUM_BOTS) {
384
        lcd_putchar('+');
385
        lcd_putchar('1');
386
        lcd_putchar('+');
387
        SRC--;
388
        DEST = 0;
389
      } else {
390
        //otherwise decrement both your ID and the destination by 1
391
        lcd_putchar('+');
392
        lcd_putchar('2');
393
        lcd_putchar('+');
394
        //decrement src and dest
395
        SRC--;
396
        DEST--;
397
      }
398
    }
399
                        
400
    //ensure that the last robot talks to the 0th one
401
    //this won't be set if the LAST robot dies (all robots are < dead)
402
    if(SRC == (NUM_BOTS - 1) ) {
403
      DEST = 0;
404
    }
405
    
406
    //now your SRC and DEST have been set properly
407
    //if you are the robot before the dead robot - send a message
408
    if(SRC == dead_robot) {
409
      lcd_putstr(" send packet ");
410
      //you took the place of the dead robot
411
      //you start the token ring again
412
      wl_create_packet();
413
      wl_send();
414
    }
415
    break;
416
      
417
  case WL_ERRCODE_NEEDTOCHARGE:
418
    if (CHARGESTATION == 1) {
419
      /*Turn on BOM for the length of time robots normally would have their 
420
        BOM on. This is effectively telling everyone where the charging 
421
        station is.  Assuming only one charging station at the moment.
422
      */
423
      bom_on();
424
      delay_ms(WL_DELAY_BOM_PRE);
425
      wl_create_error_packet(WL_ERRCODE_CHARGESTATION);
426
      wl_send();
427
      delay_ms(WL_DELAY_BOM_POST);
428
      bom_off();
429
    }
430
    break;      //Do nothing about this, yet
431
        
432
  case WL_ERRCODE_CHARGESTATION:
433
    // If the Charging Station responds, look for where it's comming from and 
434
    //store that value for later
435
    //wl_csloc = getMaxBOM();
436
    break;
437
      
438
  default:
439
    //do other stuff;
440
    break;
441
  }        
442
}
443

    
444
/**
445
   \fn wl_death_handler
446

447
   Handles robot death (for the one robot that detects death).
448

449
   The robot that currently 'senses' robot death is the robot AFTER the dead
450
   robot in the ring.  It knows that PREV (the robot right before it) is dead.
451
   Robot creates a error packet and sends it. 
452

453
   This will also call wl_error_handler since wl_buf was set with the current
454
   dead robot
455
*/
456
void wl_death_handler( void ) 
457
{
458
  //set time out and death count/flags to 0
459
  wl_to_count = 0;
460
  wl_to_flag = 0;
461
  wl_to_death_flag = 0;
462
  wl_to_death_count = 0;
463

    
464
  //create a packet with the error
465
  wl_create_error_packet(WL_ERRCODE_ROBOTDEATH);
466
  wl_buf[WL_ERR_DEAD_LOC] = PREV;   //PREV is the robot that is dead
467
  wl_make_checksum();   //Recompute checksum after adding data
468
        
469
  //send the packet
470
  wl_send();
471
        
472
  //handle the error yourself
473
  wl_error_handler(wl_buf[WL_ERROR_LOC]);
474
        
475
  return;
476
}
477

    
478
/**
479
   \fun parse_buffer
480
   Parses the buffer in wl_buf.
481

482
   Does nothing if the buffer isn't full.
483
*/
484
void parse_buffer(void) 
485
{
486
  //deal with timeout case
487
  if( wl_to_flag ) {
488
    wl_to_flag = 0;
489
    wl_create_packet();
490
    wl_send();
491
    return;
492
  }
493

    
494
  //do nothing is packet is not complete
495
  if( (wl_chksum != 0) || (wl_index != 0) ) {
496
    return;
497
  }
498
  
499
  //acknowledge you take the packet by changing the chksum to nonzero
500
  wl_chksum = 1;
501

    
502
  if(wl_buf[WL_DATA_DATA1] == COLONET_REQUEST || 
503
     wl_buf[WL_DATA_DATA1] == COLONET_COMMAND){
504
    printf("colonet message received: code %d\n", wl_buf[WL_DATA_DATA2]);
505
    colonet_handle_message(SRC, wl_buf);
506
  }else{
507
    printf("\ndata1:%d\n", wl_buf[WL_DATA_DATA1]);
508
  }
509
        
510
  if(first_time == 1) {
511
    //you received a first packet from someone
512
    first_time = 0;
513
                
514
    //get the current number of robots
515
    NUM_BOTS = wl_buf[NUM_BOTS_LOC];
516
                
517
    //you are now the last robot in the line
518
    SRC = NUM_BOTS;
519
    //you are sending back to the first robot
520
    DEST = 0;
521
                
522
    //since you've just added yourself, increase numbots
523
    NUM_BOTS++;
524
                
525
    //figure out a way to send out a packet TODO
526
    //wl_wait_for_turn = 1;
527
                
528
    //create and send a packet
529
    wl_create_packet();
530
    wl_send();
531
  }
532
  
533
  //IS NOT CALLED FOR NOW
534
  if(wl_wait_for_turn) {
535
    if( wl_buf[WL_DEST_LOC] == (NUM_BOTS - 1) ) {
536
      //you just got a packet from the 'old' last robot send yours
537
      //lcd_putchar('S');
538
      wl_create_packet();
539
      wl_send();
540
    }else{
541
      //otherwise just exit out of parse
542
      return;
543
    }
544
  }
545
  
546
  //check for error packet first
547
  if(wl_buf[WL_DEST_LOC] == WL_PKT_ERROR){
548
    //handle error packet
549
    wl_error_handler( wl_buf[WL_ERROR_LOC] );
550
    return;
551
  }
552
  
553
  //see if there are more robots this turn around -- NUM_ROBOTS would have 
554
  //increased
555
  if(wl_buf[NUM_BOTS_LOC] > NUM_BOTS){
556
    //if you are the last robot
557
    if(DEST == 0){
558
      //if you are the last robot in the ring
559
      //change your dest to the new number (the last bot)
560
      DEST = NUM_BOTS;
561
      //lcd_putchar('j');
562
    }
563

    
564
    //increase the number of robots to what it is in the incoming packet
565
    NUM_BOTS = wl_buf[NUM_BOTS_LOC];
566
  }
567
                
568
  //make sure packet isn't your own (shouldn't really happen)
569
  if(wl_buf[WL_SRC_LOC] == SRC) {
570
    //lcd_putchar('d');
571
    return;
572
  }
573
  
574
  //get the data out of the sensor row
575
  int i = 0;
576
  int self = wl_buf[WL_SRC_LOC];
577
  //13-4 = 9
578
  int end = MIN(WL_DATA_ROW_END, NUM_BOTS+WL_DATA_ROW_START);
579
  //lcd_putchar('s');
580
  //lcd_putchar(self+48);
581
  //lcd_putchar(':');
582
  //lcd_putchar(end+48);
583
  for(i = WL_DATA_ROW_START; i < end; i++){
584
    addSensor(wl_buf[i], self, (i-WL_DATA_ROW_START), NUM_BOTS);
585
  }
586
  
587
  //if you are the destination - respond
588
  if(wl_buf[WL_DEST_LOC] == SRC) {
589
    //you know that you got a message addressed to you -- previous robot must 
590
    //not be dead
591
    wl_to_death_count = 0;
592
    //the robot previous to you is in wl_buf[WL_SRC_LOC]
593
    PREV = wl_buf[WL_SRC_LOC];
594
    
595
    //create a packet
596
    //lcd_putchar('s');
597
    wl_create_packet();
598
    wl_send();
599
  }
600

    
601
  return;
602
}
603

    
604
/**
605
   \fun wl_init
606
*/
607
void wl_init(void)
608
{
609
  lcd_putchar('~');
610
  lcd_putchar(SRC+48);
611
  lcd_putchar('~');
612
  lcd_putchar(DEST+48);
613
  lcd_putchar('~');
614
  lcd_putchar(NUM_BOTS+48);
615
  lcd_putchar('~');
616
    
617
  buzzer_init();
618
  buzzer_set_freq(C5);
619
  delay_ms(800);
620
  buzzer_off();
621
        
622
  wl_index = 0;
623
  wl_chksum = 1;
624
  wl_buf[0] = 'R';
625
  wl_buf[1] = 'C';
626
        
627
  /* executes the function about every 1/4 sec */
628
  rtc_init(PRESCALE_DIV_128, 64, &wl_timeout_handler); 
629

    
630
  wl_to_flag = 0;
631
  wl_to_count = 0; 
632
  wl_to_death_count = 0;
633
  wl_to_death_flag = 0;
634
        
635
  wl_to_max = WL_TO_INITIAL;
636
  first_time = 1;
637
  wl_wait_for_turn = 0;
638
        
639
  UCSR0B |= _BV(RXCIE) | _BV(RXEN);
640
        
641
  sei();
642
}
643

    
644
void wl_send ( void ) {
645
  int i = 0;
646
  
647
  if(set_orb_wireless) {
648
    orb_set_color(BLUE);
649
  }
650
  
651
  led_user(1);
652
  
653
  if(SRC == (NUM_BOTS - 1) ) {
654
    //if you are the last robot
655
    //delay for some time
656
    if(set_orb_wireless) {
657
      orb_set_color(RED);
658
    }
659
    delay_ms(LAST_ROBOT_DELAY);
660
    
661
    //warning: delay is actually 0 -- adding the delay back causes issues.
662
  }
663
  
664
  //this is where you would turn on the BOM
665
  bom_on();
666
  delay_ms(WL_DELAY_BOM_PRE);
667
  for(i = 0; i < WL_PKT_LEN; i++) {
668
    serial_putchar(wl_buf[i]);
669
    serial1_putchar(wl_buf[i]);
670
  }
671
  
672
  delay_ms(WL_DELAY_BOM_POST);
673
  //this is where you would turn the BOM off
674
  bom_off();
675
  
676
  led_user(0);
677
  //sprintf(buf, "%d\n\r", wl_buf[WL_CHK_LOC]);
678
  //put_string(buf);
679
}
680

    
681
void wl_create_packet() {
682
  //Header for Colony Project
683
  wl_buf[0] = 'R';
684
  wl_buf[1] = 'C';
685
  
686
  wl_buf[WL_SRC_LOC] = SRC;     //Where the packet came from
687
  wl_buf[WL_DEST_LOC] = DEST;   //Who the packet is for
688
  
689
  //Behavior Specific Data goes here
690
  wl_buf[WL_DATA_DATA0] = 0;
691
  wl_buf[WL_DATA_DATA1] = 0;
692
  wl_buf[WL_DATA_DATA2] = 0;
693
  
694
  //fill packet with data -- sensor row
695
  for(int i = WL_DATA_ROW_START; i <= WL_DATA_ROW_END; i++) {
696
    wl_buf[i] = sensors[SRC][i - WL_DATA_ROW_START];
697
  }
698
  
699
  //add the number of robots in there
700
  wl_buf[NUM_BOTS_LOC] = NUM_BOTS;
701
  
702
  //create the checksum
703
  wl_make_checksum();
704
}
705

    
706
//Add custom data to the packets
707
void wl_create_data_packet(unsigned char d0, unsigned char d1, 
708
                           unsigned char d2)
709
{
710
  //Header for Colony Project
711
  wl_buf[0] = 'R';
712
  wl_buf[1] = 'C';
713
        
714
  wl_buf[WL_SRC_LOC] = SRC;     //Where the packet came from
715
  wl_buf[WL_DEST_LOC] = DEST;   //Who the packet is for
716
    
717
  //Behavior Specific Data goes here
718
  wl_buf[WL_DATA_DATA0] = d0;
719
  wl_buf[WL_DATA_DATA1] = d1;
720
  wl_buf[WL_DATA_DATA2] = d2;
721
        
722
  //fill packet with data -- sensor row
723
  for(int i = WL_DATA_ROW_START; i <= WL_DATA_ROW_END; i++) {
724
    wl_buf[i] = sensors[SRC][i - WL_DATA_ROW_START];
725
  }
726
        
727
  //add the number of robots in there
728
  wl_buf[NUM_BOTS_LOC] = NUM_BOTS;
729
  
730
  //create the checksum
731
  wl_make_checksum();
732
}
733

    
734
//Send an error packet
735
void wl_create_error_packet(unsigned char errcode)
736
{
737
  //Header for Colony Project
738
  wl_buf[0] = 'R';
739
  wl_buf[1] = 'C';
740
  
741
  //DEST is all robots
742
  wl_buf[WL_SRC_LOC] = SRC;
743
  wl_buf[WL_DEST_LOC] = WL_PKT_ERROR;
744
  wl_buf[WL_ERROR_LOC] = errcode;
745
        
746
  //rest of the packet is just a bunch of 0s
747
  for(int i = WL_ERR_DEAD_LOC + 1; i <= WL_DATA_END; i++) {
748
    wl_buf[i] = 0;
749
  }
750
        
751
  //add the number of robots in there
752
  wl_buf[NUM_BOTS_LOC] = NUM_BOTS;
753
        
754
  //create the checksum
755
  wl_make_checksum();
756
}
757

    
758
//Computes the checksum
759
void wl_make_checksum() 
760
{
761
  char checksum = 0;
762

    
763
  for(int i = WL_SRC_LOC; i < WL_CHK_LOC; i++) {
764
    checksum -= wl_buf[i];
765
  }
766

    
767
  wl_buf[WL_CHK_LOC] = checksum;
768
}
769

    
770
//use on new avr-libc
771
//ISR(USART0_RX_vect)
772
SIGNAL(SIG_USART0_RECV)
773
{
774
  int max_bom;
775
  
776
  wl_input = UDR0;
777
  
778
  //printf("%d ", wl_input);
779
        
780
  if((wl_index == 0) && (wl_chksum != 0)){
781
    //first packet? - check chksum to make sure we're not beginning
782
    if( wl_input == 'R' ) {
783
      //got the first code
784
      wl_index++;
785
      
786
      //if(set_orb_wireless) {
787
      //  orb_set_color(GREEN);
788
      //}
789
      //lcd_putchar('R');
790
      //serial1_putchar('R');
791
                        
792
      wl_to_count = 0;                   //at this point we're not timing out, reset counter
793
    }
794
    return;
795
  }else if( wl_index == 1 ){
796
    if(wl_input == 'C') {
797
      wl_index++;
798
      wl_chksum = 0;
799
      //lcd_putchar('C');
800
      //serial1_putchar('C');
801
    }else{
802
      //incomplete packet header
803
      wl_index = 0;
804
    }
805
    return;
806
  }
807
        
808
  if( wl_index >= WL_SRC_LOC ) {
809
    if( wl_index < WL_CHK_LOC ) {
810
      //getting the rest of the packet
811
      wl_buf[wl_index] = wl_input;
812
      wl_chksum += wl_input;
813
      wl_index++;
814
    }else{
815
      //we are at checksum location
816
      wl_buf[wl_index] = 0;
817
      wl_chksum += wl_input;
818
      wl_index = 0;
819
      if(!wl_chksum) {
820
        //checksum is correct - equal to zero
821
        //if(set_orb_wireless) {
822
        //  orb_set_color(ORB_OFF);
823
        //}
824
        //lcd_putchar('p');
825
                
826
        //get the maximum BOM from the person who sent you the packet
827
        max_bom = getMaxBom();
828
        //lcd_putint(max_bom);
829
        //lcd_putchar(' ');
830
        //add to your own sensor the other robot's direction
831
                
832
        //        max_bom  you  them
833
        addSensor(max_bom, SRC, wl_buf[WL_SRC_LOC], NUM_BOTS);
834
                
835
        //also set whether that robot can see the light or not
836
        //set_light_status(wl_buf[WL_SRC_LOC], wl_buf[WL_DATA_LIGHT_LOC]);
837
      }else{  
838
        //chksum failed
839
        //serial1_putchar('F');
840
        //lcd_putchar('F');
841
      }
842
    }
843
  }
844
}