Advertisement
Guest User

LInelightfollower

a guest
Apr 1st, 2015
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.28 KB | None | 0 0
  1. #include <Pololu3pi.h>
  2. #include <PololuQTRSensors.h>
  3. #include <OrangutanMotors.h>
  4. #include <OrangutanAnalog.h>
  5. #include <OrangutanLEDs.h>
  6. #include <OrangutanLCD.h>
  7. #include <OrangutanPushbuttons.h>
  8. #include <OrangutanBuzzer.h>
  9.  
  10. int pin_number6=6;
  11. int pin_number7=7;
  12. int counter=0;
  13. int light=1;
  14. int prevlight=0;
  15. int i=0;
  16. int j=1;
  17. int maxs=500;
  18.  
  19.  
  20. void lightfollower()
  21. {
  22. pinMode(pin_number6, INPUT);
  23. pinMode(pin_number7, INPUT);
  24. while(counter<3)
  25. {
  26. while(i<1)
  27. {
  28. set_motors(50,-50);
  29. delay(700);
  30. set_motors(50,50);
  31. delay(500);
  32. i=1;
  33. }
  34.  
  35. long LDR_1;
  36. long LDR_2;
  37.  
  38. LDR_1=analogRead(pin_number6); // Left LDR Read //
  39. LDR_2=analogRead(pin_number7); // Right LDR Read //
  40.  
  41. // Displaying LDR Values //
  42. lcd_goto_xy(0,0);
  43. print_long(LDR_1);
  44. lcd_goto_xy(0,1);
  45. print_long(LDR_2);
  46.  
  47. // Setting Motors based on LDR's //
  48. int m1;
  49. int m2;
  50.  
  51. if (LDR_1 <= ((LDR_2)+20) && LDR_1 >= ((LDR_2)-20) && (LDR_1 < maxs && LDR_2 < maxs))
  52. {
  53. set_motors(50,50);
  54. light=1;
  55. prevlight=1;
  56. }
  57.  
  58. // id (LDR1 < 30 && LDR1>50)
  59. // or ||
  60. // and &&
  61.  
  62. if ( LDR_1 < ((LDR_2)-20)&& (LDR_1 < maxs && LDR_2 < maxs) )
  63. {
  64. set_motors(35,50);
  65. light=1;
  66. prevlight=1;
  67. }
  68.  
  69. if ( LDR_1 > ((LDR_2)+20)&& (LDR_1 < maxs && LDR_2 < maxs) )
  70. {
  71. set_motors(50,35);
  72. light=1;
  73. prevlight=1;
  74. }
  75.  
  76. if ( LDR_1 < ((LDR_2)-50)&& (LDR_1 < maxs && LDR_2 < maxs) )
  77. {
  78. set_motors(20,50);
  79. light=1;
  80. prevlight=1;
  81. }
  82.  
  83. if ( LDR_1 > ((LDR_2)+50)&& (LDR_1 < maxs && LDR_2 < maxs) )
  84. {
  85. set_motors(50,20);
  86. light=1;
  87. prevlight=1;
  88. }
  89.  
  90. if (LDR_1 > maxs && LDR_2 > maxs)
  91. {
  92. set_motors(0,0);
  93. delay (1);
  94. if(j<3)
  95. {
  96. set_motors(0,0);
  97. delay(500);
  98. set_motors(-30,-30);
  99. delay(500);
  100. set_motors(40,-40);
  101. delay(450);
  102. set_motors(50,50);
  103. delay(1000);
  104. set_motors(0,0);
  105. delay(1);
  106. j++;
  107. }
  108.  
  109. light=0;
  110. if (light != prevlight);
  111. {
  112. counter++;
  113. prevlight=0;
  114. }
  115. }
  116.  
  117.  
  118. }
  119.  
  120.  
  121. }
  122.  
  123. Pololu3pi robot;
  124. unsigned int sensors[5]; // an array to hold sensor values
  125. unsigned int last_proportional = 0;
  126. long integral = 0;
  127. #include <avr/pgmspace.h>
  128. const char welcome_line1[] PROGMEM = " Pololu";
  129. const char welcome_line2[] PROGMEM = "3\xf7 Robot";
  130. const char demo_name_line1[] PROGMEM = "PID Line";
  131. const char demo_name_line2[] PROGMEM = "follower";
  132.  
  133.  
  134. // Data for generating the characters used in load_custom_characters
  135. // and display_readings. By reading levels[] starting at various
  136. // offsets, we can generate all of the 7 extra characters needed for a
  137. // bargraph. This is also stored in program space.
  138. const char levels[] PROGMEM = {
  139. 0b00000,
  140. 0b00000,
  141. 0b00000,
  142. 0b00000,
  143. 0b00000,
  144. 0b00000,
  145. 0b00000,
  146. 0b11111,
  147. 0b11111,
  148. 0b11111,
  149. 0b11111,
  150. 0b11111,
  151. 0b11111,
  152. 0b11111
  153. };
  154.  
  155. // This function loads custom characters into the LCD. Up to 8
  156. // characters can be loaded; we use them for 7 levels of a bar graph.
  157. void load_custom_characters()
  158. {
  159. OrangutanLCD::loadCustomCharacter(levels + 0, 0); // no offset, e.g. one bar
  160. OrangutanLCD::loadCustomCharacter(levels + 1, 1); // two bars
  161. OrangutanLCD::loadCustomCharacter(levels + 2, 2); // etc...
  162. OrangutanLCD::loadCustomCharacter(levels + 3, 3);
  163. OrangutanLCD::loadCustomCharacter(levels + 4, 4);
  164. OrangutanLCD::loadCustomCharacter(levels + 5, 5);
  165. OrangutanLCD::loadCustomCharacter(levels + 6, 6);
  166. OrangutanLCD::clear(); // the LCD must be cleared for the characters to take effect
  167. }
  168.  
  169. // This function displays the sensor readings using a bar graph.
  170. void display_readings(const unsigned int *calibrated_values)
  171. {
  172. unsigned char i;
  173.  
  174. for (i=0;i<5;i++) {
  175. // Initialize the array of characters that we will use for the
  176. // graph. Using the space, an extra copy of the one-bar
  177. // character, and character 255 (a full black box), we get 10
  178. // characters in the array.
  179. const char display_characters[10] = { ' ', 0, 0, 1, 2, 3, 4, 5, 6, 255 };
  180.  
  181. // The variable c will have values from 0 to 9, since
  182. // calibrated values are in the range of 0 to 1000, and
  183. // 1000/101 is 9 with integer math.
  184. char c = display_characters[calibrated_values[i] / 101];
  185.  
  186. // Display the bar graph character.
  187. OrangutanLCD::print(c);
  188. }
  189. }
  190.  
  191. // Initializes the 3pi, displays a welcome message, calibrates, and
  192. // plays the initial music. This function is automatically called
  193. // by the Arduino framework at the start of program execution.
  194. ///////////////////////////////////////////////////////////////////////////////////////
  195.  
  196.  
  197. void linefollowsetup()
  198. {
  199. unsigned int counter; // used as a simple timer
  200.  
  201. // This must be called at the beginning of 3pi code, to set up the
  202. // sensors. We use a value of 2000 for the timeout, which
  203. // corresponds to 2000*0.4 us = 0.8 ms on our 20 MHz processor.
  204. robot.init(2000);
  205.  
  206. load_custom_characters(); // load the custom characters
  207.  
  208. OrangutanLCD::clear();
  209. OrangutanLCD::printFromProgramSpace(demo_name_line1);
  210. OrangutanLCD::gotoXY(0, 1);
  211. OrangutanLCD::printFromProgramSpace(demo_name_line2);
  212.  
  213.  
  214. // Auto-calibration: turn right and left while calibrating the
  215. // sensors.
  216. for (counter=0; counter<80; counter++)
  217. {
  218. if (counter < 20 || counter >= 60)
  219. OrangutanMotors::setSpeeds(40, -40);
  220. else
  221. OrangutanMotors::setSpeeds(-40, 40);
  222.  
  223. // This function records a set of sensor readings and keeps
  224. // track of the minimum and maximum values encountered. The
  225. // IR_EMITTERS_ON argument means that the IR LEDs will be
  226. // turned on during the reading, which is usually what you
  227. // want.
  228. robot.calibrateLineSensors(IR_EMITTERS_ON);
  229.  
  230. // Since our counter runs to 80, the total delay will be
  231. //80*20 = 1600 ms.
  232. delay(20);
  233. }
  234. OrangutanMotors::setSpeeds(0, 0);
  235.  
  236. // Display calibrated values as a bar graph.
  237. // Read the sensor values and get the position measurement.
  238. unsigned int position = robot.readLine(sensors, IR_EMITTERS_ON);
  239.  
  240. // Display the position measurement, which will go from 0
  241. // (when the leftmost sensor is over the line) to 4000 (when
  242. // the rightmost sensor is over the line) on the 3pi, along
  243. // with a bar graph of the sensor readings. This allows you
  244. // to make sure the robot is ready to go.
  245. OrangutanLCD::clear();
  246. OrangutanLCD::print(position);
  247. OrangutanLCD::gotoXY(0, 1);
  248. display_readings(sensors);
  249.  
  250. delay(100);
  251.  
  252. }
  253. ////////////////////////////////////////////////////////////////////////
  254.  
  255. int x=0;
  256. void linefollower()
  257. {
  258. while (x<1)
  259. {
  260. linefollowsetup();
  261. x++;
  262. }
  263. // Get the position of the line. Note that we *must* provide
  264. // the "sensors" argument to read_line() here, even though we
  265. // are not interested in the individual sensor readings.
  266. unsigned int position = robot.readLine(sensors, IR_EMITTERS_ON);
  267.  
  268. // The "proportional" term should be 0 when we are on the line.
  269. int proportional = (int)position - 2000;
  270.  
  271. // Compute the derivative (change) and integral (sum) of the
  272. // position.
  273. int derivative = proportional - last_proportional;
  274. integral += proportional;
  275.  
  276. // Remember the last position.
  277. last_proportional = proportional;
  278.  
  279. // Compute the difference between the two motor power settings,
  280. // m1 - m2. If this is a positive number the robot will turn
  281. // to the right. If it is a negative number, the robot will
  282. // turn to the left, and the magnitude of the number determines
  283. // the sharpness of the turn. You can adjust the constants by which
  284. // the proportional, integral, and derivative terms are multiplied to
  285. // improve performance.
  286. int power_difference = proportional/20 + integral/10000 + derivative*3/2;
  287.  
  288. // Compute the actual motor settings. We never set either motor
  289. // to a negative value.
  290. const int maximum = 70;
  291. if (power_difference > maximum)
  292. power_difference = maximum;
  293. if (power_difference < -maximum)
  294. power_difference = -maximum;
  295.  
  296. if (power_difference < 0)
  297. OrangutanMotors::setSpeeds(maximum + power_difference, maximum);
  298. else
  299. OrangutanMotors::setSpeeds(maximum, maximum - power_difference);
  300. }
  301.  
  302. void setup()
  303. {
  304. }
  305. void loop()
  306. {
  307. lightfollower();
  308. set_motors(50,-50);
  309. delay(700);
  310. set_motors(0,0);
  311. linefollower();
  312. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement