Robotic F.A.C.E.: PIC C code
for the face iRX board.
//////////////////////////////////////////////////////////////////
// //
// This code written by Mark Newman (newman@media.mit.edu), //
// with a little help from Stefan Marti (stefanm@media.mit.edu) //
// for the Robotic F.A.C.E. project //
// //
// Copyright (C) 2003 MIT Media Laboratory //
// //
//////////////////////////////////////////////////////////////////
#include <16F84.H>
#include "Math32.c"
// Configure PIC to use: HS clock, no Watchdog Timer,
// no code protection, enable Power Up Timer
//
#fuses HS,NOWDT,NOPROTECT,PUT
// Tell compiler clock is 10MHz. This is required for delay_ms()
// and for all serial I/O (such as printf(...). These functions
// use software delay loops, so the compiler needs to know the
// processor speed.
//
#use DELAY(clock=10000000)
// Declare that we'll manually establish the data direction of
// each I/O pin on port B.
//
#use fast_io(B)
#use fast_io(A)
// Standard definitions for the irx2_1 board
//
#define RS232_XMT PIN_B1 // (output) RS232 serial transmit
#define RED_LED PIN_B2 // (output) Red LED (low true)
#define IR_LED PIN_B3 // (output) Infrared LED (low true)
#define IR_SENSOR PIN_B4 // (input) IR sensor (Sharp IS1U30)
#define RS232_RCV PIN_B5 // (input) RS232 serial receive
// Macros to simplify I/O operations
//
#define RED_LED_ON output_low(RED_LED)
#define RED_LED_OFF output_high(RED_LED)
#define IR_LED_ON output_low(IR_LED)
#define IR_LED_OFF output_high(IR_LED)
#define IR_RECEIVED (!input(IR_SENSOR))
// Inform printf() and friends of the desired baud rate
// and which pins to use for serial I/O.
//
#use rs232(baud=9600, xmit=RS232_XMT, rcv=RS232_RCV)
int motor, pwm, speed;
#int_rtcc clock_isr() {
pwm++;
if (pwm == speed)
pwm = 0;
if (motor && pwm < 8)
output_high(PIN_A2);
else
output_low(PIN_A2);
}
void Move(int dir) {
// output_high(PIN_A2);
motor = 1;
if (dir)
output_low(PIN_A1);
else
output_high(PIN_A1);
}
void Stop() {
// output_low(PIN_A2);
motor = 0;
}
int Trigger(int dir) {
if (dir)
return input(PIN_A3);
return input(PIN_A4);
}
int Next(int curr, int dir) {
if (dir) {
return ((curr + 1) % 26);
}
return ((curr + 25) % 26);
}
void main() {
char c;
int first, comm, curr, dest, dir;
// since we've declared #use fast_io(B) (above), we MUST
// include a call to set_tris_b() at startup.
//
set_tris_b(0b00110000);
set_tris_a(0b00011000);
output_high(PIN_B7);
speed = 8;
pwm = 0;
motor = 0;
set_rtcc(0);
setup_counters(RTCC_INTERNAL, RTCC_DIV_32);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
RED_LED_ON; // reality check at startup
delay_ms(200);
RED_LED_OFF;
Stop();
delay_ms(200);
c = getc(); // Serial check at startup
RED_LED_ON;
delay_ms(200);
RED_LED_OFF;
while (Trigger(1))
Move(0);
Stop();
first = 1;
comm = 0;
curr = 0;
dest = 0;
while (1) {
if (kbhit()) {
c = getc();
if (comm) {
if (c & 1) {
dir = c & 2;
dest = c >> 2;
}
output_low(PIN_B7);
if (curr == dest)
putchar(curr << 2 | 3);
else
putchar(curr << 2 | 2);
output_high(PIN_B7);
comm = 0;
} else {
if ((c & 15) == 8) {
comm = 1;
speed = (c >> 5) + 8;
}
}
}
if (!Trigger(0) && first) {
curr = Next(curr, dir);
first = 0;
} else if (Trigger(0))
first = 1;
if (!Trigger(1) && !Trigger(0))
curr = 0;
if (curr == dest) {
RED_LED_OFF;
Stop();
} else {
RED_LED_ON;
Move(dir);
}
}
}