Advertisement
Guest User

Untitled

a guest
Jan 24th, 2012
440
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.90 KB | None | 0 0
  1. /** RoombaPhotovore: Turns your Roomba into a light follower by controlling it via IR.
  2.  *  Uses a 38 KHz carrier generated by directly setting timer 2's registers.
  3.  *  Author: Tom Lauwers, tlauwers@birdbraintechnologies.com
  4.  *  Date: 1/3/2011
  5.  *
  6.  *  Modified: 01/24/2012 by Max Eliaser of O'Reilly Media, Inc.
  7.  *  Capitalize preprocessor macro names.
  8.  *  Add LEFT_LIGHT_PIN, RIGHT_LIGHT_PIN, LIGHT_THRESHOLD, LIGHT_DIFF_THRESHOLD, and IR_OUTPUT_PIN
  9.  *  macros where previously there had been hardcoded numbers.
  10.  */
  11.  
  12. // The length of the raw IR signals
  13. #define SIGNAL_LENGTH 15
  14. // The pins for the LED and photoresistors
  15. #define IR_OUTPUT_PIN 11
  16. #define LEFT_LIGHT_PIN 0
  17. #define RIGHT_LIGHT_PIN 1
  18. // Twiddle this to adjust for the peculiarities of your photoresistors and the ambient light levels
  19. #define LIGHT_THRESHOLD 800 // was originally 100; I changed it to 800 to compensate for a bright room
  20. // Twiddle this to adjust how different the photoresistors should be to trigger a turn
  21. #define LIGHT_DIFF_THRESHOLD 100
  22.  
  23. // Arrays that contain the raw IR signal times in microseconds
  24. // Captured directly from IRAnalyzer
  25. unsigned int goForward[SIGNAL_LENGTH] = {3028,956,996,2948,956,2948,960,2948,960,2940,964,2948,2896,984,996};
  26. unsigned int turnLeft[SIGNAL_LENGTH] = {2992,1008,968,2964,944,2964,944,2964,940,2972,936,2976,932,2976,2872};
  27. unsigned int turnRight[SIGNAL_LENGTH] = {2988,1012,968,2964,936,2976,940,2968,932,2976,932,2976,2872,1012,2904};
  28.  
  29. // For storing the left and right light sensor values
  30. int leftLight;
  31. int rightLight;
  32.  
  33. void setup()
  34. {  
  35.   // start serial port at 57600 bps:
  36.   Serial.begin(57600);
  37.   // PWM Magic - we directly set atmega registers to 50% duty cycle,
  38.   // variable frequency mode. Currently set to 38 KHz.
  39.   // Thanks http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM
  40.   TCCR2A = _BV(WGM21) | _BV(WGM20);
  41.   //set prescalar to 16MHz clock for now
  42.   TCCR2B = _BV(WGM22) | _BV(CS20);
  43.   // To get a 38KHz wave, we need OCR2A = (16000000/76000)-1 = 209
  44.   OCR2A = 209;
  45.   // Set the pin the IR LED is on to output
  46.   pinMode(IR_OUTPUT_PIN, OUTPUT);
  47. }
  48.  
  49. void loop()
  50. {
  51.   // Read in light sensors - left on pin 0, right on pin 1
  52.   leftLight = analogRead(LEFT_LIGHT_PIN);
  53.   rightLight = analogRead(RIGHT_LIGHT_PIN);
  54.  
  55.   // Print the values for debugging purposes
  56.   Serial.print("Left: ");
  57.   Serial.print(leftLight);
  58.   Serial.print(" Right: ");
  59.   Serial.print(rightLight);
  60.   Serial.print("\n");
  61.  
  62.   // If both sensors see very little light, stop!
  63.   if((leftLight < LIGHT_THRESHOLD) && (rightLight < LIGHT_THRESHOLD)) {
  64.     // do nothing, effectively stops Roomba
  65.   }
  66.   // If left is a lot less than right, turn right to balance it out
  67.   else if(leftLight < (rightLight - LIGHT_DIFF_THRESHOLD)) {
  68.     playSignal(turnRight);
  69.   }  
  70.   // If right is less than left, turn left
  71.   else if(rightLight < (leftLight - LIGHT_DIFF_THRESHOLD)) {
  72.     playSignal(turnLeft);
  73.   }
  74.   // else, go straight towards the light
  75.   else {
  76.     playSignal(goForward);
  77.   }
  78.   // Roomba needs a call to playSignal to repeat every 20 milliseconds
  79.   delay(20);
  80. }
  81.  
  82. // Plays raw signal
  83. void playSignal(unsigned int signal[])
  84. {
  85.   // Traverse the raw IR signal array, turning the LED on or off by the amount of time
  86.   // specified by the array
  87.   for(int i = 0; i < SIGNAL_LENGTH; i++)
  88.   {
  89.     // even elements of the array = IR LED is on
  90.     if(i%2 == 0) {
  91.       TCCR2A |=  _BV(COM2A0); // turns on the IR LED to 50% duty cycle
  92.       delayMicroseconds(signal[i]);
  93.     }
  94.     // IR LED is off for odd elements of the array
  95.     else {
  96.       TCCR2A &= (0xFF - _BV(COM2A0)); // disconnect pin from signal
  97.       digitalWrite(IR_OUTPUT_PIN,LOW); // turn pin low in case it's high    
  98.       delayMicroseconds(signal[i]);
  99.     }
  100.   }
  101.   // Turn off signal one last time
  102.   TCCR2A &= (0xFF - _BV(COM2A0)); // disconnect pin from signal
  103.   digitalWrite(IR_OUTPUT_PIN,LOW); // turn pin low in case it's high      
  104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement