Roomba Tank
CSC 460 Project 3
remote.c
Go to the documentation of this file.
1 #define F_CPU 16000000
2 
3 #include <avr/io.h>
4 #include <avr/interrupt.h>
5 #include <util/delay.h>
6 #include "../roomba/roomba.h"
7 #include "../rtos/os.h"
8 #include "../uart/uart.h"
9 
10 uint8_t LASER = 0;
11 uint8_t SERVO = 1;
12 uint8_t PHOTO = 2;
13 uint8_t SCREEN = 3;
14 uint8_t ROOMBA = 4;
15 uint8_t MODE = 5;
16 
17 uint8_t IdlePID;
18 uint8_t RoombaTestPID;
19 uint8_t RoombaTaskPID;
22 uint8_t LaserTaskPID;
23 uint8_t ServoTaskPID;
26 
33 
35 uint16_t photoThreshold;
36 
37 int AUTO;
38 
39 // An idle task that runs when there is nothing else to do
40 // Could be changed later to put CPU into low power state
41 
42 typedef enum laser_states {
43  OFF = 0,
45 } LASER_STATES;
46 
47 typedef enum servo_states {
48  FULL_BACK = 0,
53 } SERVO_STATES;
54 
58 #define QSize 10
59 
63 
67 
71 
72 // Mutexes
76 
80 int buffer_isFull(int *front, int *rear) {
81  return (*rear == (*front - 1) % QSize);
82 }
83 
87 int buffer_isEmpty(int *front, int *rear) {
88  return (*rear == *front);
89 }
90 
94 void buffer_enqueue(int val, int *queue, int *front, int *rear) {
95  if (buffer_isFull(front, rear)) {
96  return;
97  }
98  queue[*rear] = val;
99  *rear = (*rear + 1) % QSize;
100 }
101 
105 int buffer_dequeue(int *queue, int *front, int *rear){
106  if (buffer_isEmpty(front, rear)) {
107  return -1;
108  }
109  int result = queue[*front];
110  *front = (*front + 1) % QSize;
111  return result;
112 }
113 
117 void enablePORTL6() {
118  PORTL |= _BV(PORTL6);
119 }
124  PORTL &= ~_BV(PORTL6);
125 }
126 
130 void enablePORTL2() {
131  PORTL |= _BV(PORTL2);
132 }
137  PORTL &= ~_BV(PORTL2);
138 }
139 
143 void enablePORTL5() {
144  PORTL |= _BV(PORTL5);
145 }
150  PORTL &= ~_BV(PORTL5);
151 }
152 
156 void enablePORTH3() {
157  PORTL |= _BV(PORTH3);
158 }
163  PORTL &= ~_BV(PORTH3);
164 }
165 
166 // ******************************************************************* //
167 // ****************************** TASKS ****************************** //
168 // ******************************************************************* //
169 
173 void ADC_init() {
174  ADMUX |= (1<<REFS0);
175  ADCSRA |= (1<<ADEN) | (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2);
176 }
177 
181 void Servo_Init() {
182  // Setup ports and timers
183  DDRA = 0xFF; // All output
184  PORTA = 0;
185 
186  // Configure timer/counter4 as phase and frequency PWM mode
187  TCNT4 = 0;
188  TCCR4A = (1<<COM4A1) | (1<<COM4B1) | (1<<WGM41); //NON Inverted PWM
189  TCCR4B |= (1<<WGM43) | (1<<WGM42) | (1<<CS41) | (1<<CS40); //PRESCALER=64 MODE 14 (FAST PWM)
190  ICR4 = 4999;
191 
192  OCR4A = 375; // 90 Degrees
193 }
194 
198 void Idle() {
199  for(;;) {
200  continue;
201  }
202 }
203 
207 void Laser_Task() {
208  for(;;) {
210 
213  if (laserState == ON) {
214  enablePORTL5();
215  }
216  else {
217  disablePORTL5();
218  }
219  }
220 
222  Task_Sleep(10);
223  }
224 }
225 
229 void Servo_Task() {
230  for(;;) {
232 
235  }
236 
237  if (servoState > 380 && (lastServoState <= 610)) {
238  if (servoState > 550) {
239  lastServoState += 3;
240  }
241  lastServoState += 1;
242  OCR4A = lastServoState;
243  }
244  else if (servoState < 370) {
245  if (servoState < 1) {
246  lastServoState -= 3;
247  }
248  lastServoState -= 1;
249  OCR4A = lastServoState;
250  }
251 
253  Task_Sleep(3);
254  }
255 }
256 
261  uint16_t photo1;
262  uint16_t photo2;
263  uint16_t photo3;
264 
265  ADMUX = (ADMUX & 0xE0);
266 
267  ADMUX = (ADMUX | 0x07); // Channel 7
268 
269  ADCSRB |= (0<<MUX5);
270 
271  ADCSRA |= (1<<ADSC); // Start conversion
272 
273  while((ADCSRA)&(1<<ADSC)); //WAIT UNTIL CONVERSION IS COMPLETE
274 
275  photo1 = ADC;
276 
277  ADCSRA |= (1<<ADSC); // Start conversion
278 
279  while((ADCSRA)&(1<<ADSC)); //WAIT UNTIL CONVERSION IS COMPLETE
280 
281  photo2 = ADC;
282 
283  ADCSRA |= (1<<ADSC); // Start conversion
284 
285  while((ADCSRA)&(1<<ADSC)); //WAIT UNTIL CONVERSION IS COMPLETE
286 
287  photo3 = ADC;
288 
289  photoThreshold = (photo1 + photo2 + photo3) / 3;
290 }
291 
296  int i = 0;
297 
298  for(;;) {
299  // Read photocell
300  ADMUX = (ADMUX & 0xE0);
301 
302  ADMUX = (ADMUX | 0x07); // Channel 7
303 
304  ADCSRB |= (0<<MUX5);
305 
306  ADCSRA |= (1<<ADSC); // Start conversion
307 
308  while((ADCSRA)&(1<<ADSC)); //WAIT UNTIL CONVERSION IS COMPLETE
309 
310  photocellReading = ADC;
311 
312  if (photocellReading >= (photoThreshold + 50)) {
313  enablePORTL2();
314  Roomba_Play(0);
315  disablePORTL5();
316  Roomba_Drive(0,0);
317  OS_Abort();
318  }
319 
320  if(i % 5 == 0) {
322  i = 0;
323  }
324  else {
325  i++;
326  }
327 
328  Task_Sleep(10);
329  }
330 }
331 
336  for(;;) {
337  Roomba_QueryList(7, 13);
338 
339  // while(!(UCSR3A & (1<<RXC3)));
340  Task_Sleep(2);
342  // while(!(UCSR3A & (1<<RXC3)));
343  Task_Sleep(2);
345 
346  Task_Sleep(20);
347  }
348 }
349 
353 void Reverse() {
354  if(roombaState == 'F') {
355  Roomba_Drive(ROOMBA_SPEED,TURN_RADIUS); // Forward-Left
356  }
357  else if(roombaState == 'G') {
359  }
360  else if(roombaState == 'H') {
361  Roomba_Drive(ROOMBA_SPEED,-TURN_RADIUS); // Forward-Right
362  }
363  else if(roombaState == 'E') {
365  }
366  else if(roombaState == 'D') {
368  }
369  else if(roombaState == 'A') {
370  Roomba_Drive(-ROOMBA_SPEED,TURN_RADIUS); // Backward-left
371  }
372  else if(roombaState == 'B') {
374  }
375  else if(roombaState == 'C') {
376  Roomba_Drive(-ROOMBA_SPEED,-TURN_RADIUS); // Backward-right
377  }
378  else if(roombaState == 'X') {
380  }
381 }
382 
386 void Bump_Back() {
388 }
389 
393 void Manual_Drive() {
394  if(roombaState == 'A') {
395  Roomba_Drive(ROOMBA_SPEED,TURN_RADIUS); // Forward-Left
396  }
397  else if(roombaState == 'B') {
399  }
400  else if(roombaState == 'C') {
401  Roomba_Drive(ROOMBA_SPEED,-TURN_RADIUS); // Forward-Right
402  }
403  else if(roombaState == 'D') {
405  }
406  else if(roombaState == 'E') {
408  }
409  else if(roombaState == 'F') {
410  Roomba_Drive(-ROOMBA_SPEED,TURN_RADIUS); // Backward-left
411  }
412  else if(roombaState == 'G') {
414  }
415  else if(roombaState == 'H') {
416  Roomba_Drive(-ROOMBA_SPEED,-TURN_RADIUS); // Backward-right
417  }
418  else if(roombaState == 'X') {
419  Roomba_Drive(0,0); // Stop
420  }
421 }
422 
426 void Auto_Drive() {
428 }
429 
433 void Roomba_Task() {
434  for(;;) {
435  if(wallState) {
437  Reverse();
438 
439  if(AUTO==1) {
440  Task_Sleep(20);
443  }
444  }
445  else if(bumpState >= 1 && bumpState <= 3) {
447  Bump_Back();
448 
449  if(AUTO==1) {
450  Task_Sleep(20);
453  }
454  }
455  else {
456  if(AUTO==1) {
457  Auto_Drive();
458  }
459  else {
461  Manual_Drive();
462  }
463  }
464 
465  Task_Sleep(20);
466  }
467 }
468 
473  for(;;) {
474  // SEND LIGHT SENSOR DATA
478 
479  Task_Sleep(10);
480  }
481 }
482 
487  uint8_t flag;
488  uint8_t laser_data;
489  uint16_t servo_data;
490  uint8_t servo_data1;
491  uint8_t servo_data2;
492 
493  char roomba_data;
494 
495  for(;;){
496  if(( UCSR1A & (1<<RXC1))) {
497  flag = Bluetooth_Receive_Byte();
498 
499  if (flag == LASER){
501 
502  laser_data = Bluetooth_Receive_Byte();
504 
506  }
507 
508  // else if (flag == SERVO){
509  // Mutex_Lock(servoMutex);
510 
511  // servo_data1 = Bluetooth_Receive_Byte();
512  // servo_data2 = Bluetooth_Receive_Byte();
513  // servo_data = ( ((servo_data1)<<8) | (servo_data2) );
514 
515  // buffer_enqueue(servo_data, servoQueue, &servoFront, &servoRear);
516 
517  // Mutex_Unlock(servoMutex);
518  // }
519 
520  else if (flag == ROOMBA) {
521  roomba_data = Bluetooth_Receive_Byte();
523  }
524 
525  else if (flag == MODE) {
526  if(AUTO == 1){
527  AUTO = 0;
530  }
531  }
532  else {
533  AUTO = 1;
534  }
535  }
536 
537  else {
538  continue;
539  }
540  }
541  Task_Sleep(5);
542  }
543 }
544 
548 void a_main() {
549 
550  // Initialize Ports
551  DDRL |= _BV(DDL6);
552  DDRL |= _BV(DDL2);
553  DDRL |= _BV(DDL5);
554  DDRH |= _BV(DDH3);
555 
556  // Initialize Queues
557  laserFront = 0;
558  laserRear = 0;
559  servoFront = 0;
560  servoRear = 0;
561  roombaFront = 0;
562  roombaRear = 0;
563 
564  // Initialize Mutexes
568 
569  // Initialize Bluetooth and Roomba UART
572  ADC_init();
573  // Servo_Init();
574  Roomba_Init();
575 
576  // Evaluate light
578 
579  // Initialize Values
580  photocellReading = 0;
581  servoState = 375;
582  lastServoState = 375;
583  wallState = 0;
584  bumpState = 0;
585  roombaState = 'X';
586  AUTO = 0;
587 
588  // Create Tasks
594  // ServoTaskPID = Task_Create(Servo_Task, 2, 3);
597 
598  Task_Terminate();
599 }
#define MINPRIORITY
Definition: os.h:9
uint8_t LaserTaskPID
Definition: remote.c:22
void ADC_init()
Definition: remote.c:173
uint8_t LASER
Definition: remote.c:10
#define QSize
Definition: remote.c:58
void disablePORTL6()
Definition: remote.c:123
void Servo_Init()
Definition: remote.c:181
void Laser_Task()
Definition: remote.c:207
void Reverse()
Definition: remote.c:353
int buffer_isEmpty(int *front, int *rear)
Definition: remote.c:87
char roombaState
Definition: remote.c:30
int laserQueue[QSize]
Definition: remote.c:64
int buffer_dequeue(int *queue, int *front, int *rear)
Definition: remote.c:105
uint8_t BluetoothReceivePID
Definition: remote.c:21
void enablePORTH3()
Definition: remote.c:156
uint8_t MODE
Definition: remote.c:15
uint8_t SERVO
Definition: remote.c:11
#define DRIVE_STRAIGHT
Definition: roomba.h:40
uint8_t LightSensorTaskPID
Definition: remote.c:24
MUTEX sensorMutex
Definition: remote.c:75
int roombaFront
Definition: remote.c:69
void Bump_Back()
Definition: remote.c:386
MUTEX servoMutex
Definition: remote.c:74
int laserRear
Definition: remote.c:66
MUTEX Mutex_Init()
Definition: os.c:674
void Roomba_UART_Init()
Definition: uart.c:10
void Bluetooth_Send_Byte(uint8_t data_out)
Definition: uart.c:73
void Roomba_Init()
Definition: roomba.c:13
void Manual_Drive()
Definition: remote.c:393
uint8_t SCREEN
Definition: remote.c:13
uint8_t ServoTaskPID
Definition: remote.c:23
uint8_t PHOTO
Definition: remote.c:12
Definition: remote.c:44
int servoFront
Definition: remote.c:61
void disablePORTL5()
Definition: remote.c:149
int servoState
Definition: remote.c:28
void Auto_Drive()
Definition: remote.c:426
void Set_Photocell_Threshold()
Definition: remote.c:260
int wallState
Definition: remote.c:31
void buffer_enqueue(int val, int *queue, int *front, int *rear)
Definition: remote.c:94
int lastServoState
Definition: remote.c:29
enum laser_states LASER_STATES
int AUTO
Definition: remote.c:37
void Task_Terminate(void)
Definition: os.c:817
void disablePORTL2()
Definition: remote.c:136
servo_states
Definition: remote.c:47
unsigned char Bluetooth_Receive_Byte()
Definition: uart.c:83
int bumpState
Definition: remote.c:32
int servoQueue[QSize]
Definition: remote.c:60
uint8_t RoombaTaskPID
Definition: remote.c:19
void disablePORTH3()
Definition: remote.c:162
void a_main()
Definition: remote.c:548
#define IN_PLACE_CW
Definition: roomba.h:41
void Servo_Task()
Definition: remote.c:229
void OS_Abort()
Definition: os.c:667
unsigned int MUTEX
Definition: os.h:22
void Task_Sleep(TICK t)
Definition: os.c:779
int roombaQueue[QSize]
Definition: remote.c:68
laser_states
Definition: remote.c:42
int roombaRear
Definition: remote.c:70
enum servo_states SERVO_STATES
void enablePORTL2()
Definition: remote.c:130
uint8_t GetSensorDataTaskPID
Definition: remote.c:25
#define ROOMBA_SPEED
Definition: roomba.h:36
PID Task_Create(voidfuncptr f, PRIORITY py, int arg)
Definition: os.c:747
void Bluetooth_Receive()
Definition: remote.c:486
int buffer_isFull(int *front, int *rear)
Definition: remote.c:80
void Roomba_Play(uint8_t song)
Definition: roomba.c:61
uint16_t photoThreshold
Definition: remote.c:35
MUTEX laserMutex
Definition: remote.c:73
void LightSensor_Task()
Definition: remote.c:295
uint8_t IdlePID
Definition: remote.c:17
unsigned char Roomba_Receive_Byte()
Definition: uart.c:37
uint16_t photocellReading
Definition: remote.c:34
#define ROOMBA_TURN
Definition: roomba.h:37
void Bluetooth_UART_Init()
Definition: uart.c:56
uint8_t ROOMBA
Definition: remote.c:14
uint8_t RoombaTestPID
Definition: remote.c:18
void Roomba_Drive(int16_t velocity, int16_t radius)
Definition: roomba.c:50
void Mutex_Lock(MUTEX m)
Definition: os.c:686
void Mutex_Unlock(MUTEX m)
Definition: os.c:699
void Bluetooth_Send()
Definition: remote.c:472
uint8_t BluetoothSendPID
Definition: remote.c:20
void Idle()
Definition: remote.c:198
#define IN_PLACE_CCW
Definition: roomba.h:42
int laserFront
Definition: remote.c:65
int laserState
Definition: remote.c:27
int servoRear
Definition: remote.c:62
void Get_Sensor_Data()
Definition: remote.c:335
void enablePORTL6()
Definition: remote.c:117
Definition: remote.c:43
void Roomba_Task()
Definition: remote.c:433
void enablePORTL5()
Definition: remote.c:143
#define TURN_RADIUS
Definition: roomba.h:38
void Roomba_QueryList(uint8_t packet1, uint8_t packet2)
Definition: roomba.c:77