/********************************************************
* Main intelligence algorithm. Includes IR reception.
* By: Liliane Barbour and Jonathan Mash
* Date: Apr. 2009
*********************************************************/
#include <Wire.h>
#include <Servo.h>
#define DEBUG 0
#define LOWERLIMIT 400
#define UPPERLIMIT 650
#define COUNTLIMIT 2
#define OUTPIN 12 //Pulse out to Motor Controller
#define SETUPPIN 13 //Pin to hold Motor at 90
#define srfAddress 0x70 // Address of the SRF08
#define lightByte 0x01 // Byte to read light sensor
#define rangeByte 0x02 // Byte for start of ranging data
#define cmdByte 0x00 // Command byte
#define TIMER_RESET TCNT1 = 0
#define SAMPLE_SIZE 38
#define DEBUG 1
#define led_pin 4
#define IRpin 2
unsigned int TimerValue[SAMPLE_SIZE];
char direction[SAMPLE_SIZE];
byte change_count;
long time;
bool checkIR;
Servo turret;
byte sensor_address = 0xd0;
int PIRREAD[4][5];
int PIR[4];
byte index = 0;
byte currentState = 4;
byte currentServo = 90;
void setup()
{
turret.attach(9); // attaches the servo on pin 9 to the servo object
turret.write(90);
Wire.begin();
Serial.begin(9600);
pinMode(OUTPIN, OUTPUT);
pinMode(SETUPPIN, OUTPUT);
//TCCR1A = 0x00; // COM1A1=0, COM1A0=0 => Disconnect Pin OC1 from Timer/Counter 1 -- PWM11=0,PWM10=0 => PWM Operation disabled
// ICNC1=0 => Capture Noise Canceler disabled -- ICES1=0 => Input Capture Edge Select (not used) -- CTC1=0 => Clear Timer/Counter 1 on Compare/Match
// CS12=0 CS11=1 CS10=1 => Set prescaler to clock/64
//TCCR1B = 0x03; // 16MHz clock with prescaler means TCNT1 increments every 4uS
// ICIE1=0 => Timer/Counter 1, Input Capture Interrupt Enable -- OCIE1A=0 => Output Compare A Match Interrupt Enable -- OCIE1B=0 => Output Compare B Match Interrupt Enable
// TOIE1=0 => Timer 1 Overflow Interrupt Enable
//TIMSK1 = 0x00;
pinMode(IRpin, INPUT);
pinMode(led_pin, OUTPUT);
checkIR = false;
//attachInterrupt(0, isrIR, FALLING);
digitalWrite(SETUPPIN, HIGH);
delay(10000);
digitalWrite(SETUPPIN, LOW);
for(int i=0; i<6; i++) {
PIRREAD[0][i] = analogRead(0);
PIRREAD[1][i] = analogRead(1);
PIRREAD[2][i] = analogRead(2);
PIRREAD[3][i] = analogRead(3);
}
delay(1000);
}
void loop()
{
byte decision;
int retVal =0;
int initVal = 90;
int pingVal = 0;
//START IR CODE
if(checkIR == true)
{
int retVal = getIR();
checkIR = false;
switch(retVal)
{
case 384: //Volume up
Serial.println("Volume Up");
break;
case 64: //Volume down
Serial.println("Volume Down");
break;
case 224: //Power
Serial.println("Power");
break;
case 48: //Left
Serial.println("Left");
break;
case 50: //Right
Serial.println("Right");
break;
}
}
//END IR CODE
recordPIR();
decision = 4;
if(PIR[0] > UPPERLIMIT || PIR[0] < LOWERLIMIT) {
if(DEBUG) Serial.println("main loop 0");
decision = stateZeroHit(0,currentState);
}
else if(PIR[1] > UPPERLIMIT || PIR[1] < LOWERLIMIT) {
if(DEBUG) Serial.println("main loop 1");
decision = stateOneHit(1,currentState);
}
else if(PIR[2] > UPPERLIMIT || PIR[2] < LOWERLIMIT) {
if(DEBUG) Serial.println("main loop 2");
decision = stateTwoHit(2,currentState);
}
else if(PIR[3] > UPPERLIMIT || PIR[3] < LOWERLIMIT) {
if(DEBUG) Serial.println("main loop 3");
decision = stateThreeHit(3,currentState);
}
if(decision < 4) {
if(DEBUG) Serial.println(PIR[decision]);
retVal = recordThermo(decision);
pingVal = getRange();
if(retVal < 200)
{
//c = (int)floor(sqrt(11600-8000*(cos((90+retVal)*2*PI/180))));
//beta = (int)floor((90 - acos((-8400+c*c)/80*c)));
//outServo.write(retVal);
float c1, alpha;
float final;
if(retVal >90) {
c1 = sqrt(10900.0 - (6000.0*(cos((270.0 - retVal)*PI/180.0))));
alpha = (-9100.0+(c1*c1))/(60.0*c1);
final = ((acos(alpha)*180/PI)+ 90);
}
else if (retVal <90) {
c1 = sqrt(10900.0 - (6000.0*(cos((90 + retVal)*PI/180.0))));
alpha = (-9100.0+(c1*c1))/(60.0*c1);
final =(90.0-(acos(alpha)*180.0/PI));
}
else {
final = 90.0;
}
// float final = retVal;
if(final < 0)
final = 0.0;
if(final > 180)
final = 180.0;
Serial.print("Final: ");
Serial.println((int)floor(final*100));
moveTV((int)floor(final));
}
currentState = decision;
}
delay(50);
}
void isrIR()
{
checkIR = true;
}
int recordThermo(byte sector)
{
byte pos;
byte heat[9];
switch(sector){
case 0:
pos = 10;
break;
case 1:
pos = 60;
break;
case 2:
pos = 120;
break;
case 3:
pos = 170;
break;
}
turret.write((int)pos);
if(DEBUG) Serial.print("scanning sector ");
if(DEBUG) Serial.println((int)sector);
delay(500);
int i=0;
int wsum = 0;
int sum = 0;
for(i=1; i<=9; i++)
{
Wire.beginTransmission(sensor_address>>1);
Wire.send(i);
Wire.endTransmission();
Wire.requestFrom(sensor_address>>1, (int) 1);
while(Wire.available() < 1)
{ ; }
heat[i-1] = Wire.receive(); // receive a byte as character
}
for(i = 1; i<9; i++)
{
heat[i]-=heat[0];
if(heat[i] > 100)
heat[i] = 0;
else if(heat[i] < 3)
heat[i] = 0;
sum+=heat[i];
wsum+=heat[i]*i;
if(DEBUG) Serial.print(heat[i], DEC);
if(DEBUG) Serial.print(" ");
}
float div = wsum/sum;
int val = (int) round(div);
if(DEBUG) Serial.println("");
if(DEBUG) Serial.println(val);
if(div > 0)
{
int newval = pos - (int)floor(5*(div-4));
Serial.print("TPA Val: ");
Serial.println(newval);
return newval;
}
return 200;
}
byte stateZeroHit(byte detected, byte lastState) {
if(DEBUG) Serial.println("hit state 0");
byte count = 0;
if(lastState != 1) {
while(count < COUNTLIMIT && detected == 0) {
recordPIR();
if(PIR[1] > UPPERLIMIT || PIR[1] < LOWERLIMIT) {
detected = 1;
detected = stateOneHit(detected, 0);
}
count++;
}
}
return detected;
}
byte stateOneHit(byte detected, byte lastState) {
if(DEBUG) Serial.println("hit state 1");
byte count = 0;
if(lastState == 0) {
while(count < COUNTLIMIT && detected == 1) {
recordPIR();
if(PIR[2] > UPPERLIMIT || PIR[2] < LOWERLIMIT) {
detected = 2;
detected = stateTwoHit(detected, 1);
}
count++;
}
}
else if(lastState == 2) {
while(count < COUNTLIMIT && detected == 1) {
if(PIR[0] > UPPERLIMIT || PIR[0] < LOWERLIMIT) {
detected = 0;
detected = stateZeroHit(detected, 1);
}
else
recordPIR();
count++;
}
}
return detected;
}
byte stateTwoHit(byte detected, byte lastState) {
if(DEBUG) Serial.println("hit state 2");
byte count = 0;
if(lastState == 1) {
while(count <COUNTLIMIT && detected == 2) {
recordPIR();
if(PIR[3] > UPPERLIMIT || PIR[3] < LOWERLIMIT) {
detected = 3;
detected = stateThreeHit(detected, 2);
}
count++;
}
}
else if(lastState == 3) {
while(count < COUNTLIMIT && detected == 2) {
recordPIR();
if(PIR[1] > UPPERLIMIT || PIR[1] < LOWERLIMIT) {
detected = 1;
detected = stateTwoHit(detected, 2);
}
count++;
}
}
return detected;
}
byte stateThreeHit(byte detected, byte lastState) {
if(DEBUG) Serial.println("hit state 3");
byte count = 0;
if(lastState != 2) {
while(count < COUNTLIMIT && detected == 3) {
recordPIR();
if(PIR[2] > UPPERLIMIT || PIR[2] < LOWERLIMIT) {
detected = 2;
detected = stateTwoHit(detected, 3);
}
count++;
}
}
return detected;
}
void moveTV(int pos) {
float newPos = pos;
int inDelays = (int)floor(1300.0 + (400.0*newPos/180.0));
// Serial.println(inDelays);
digitalWrite(OUTPIN, HIGH);
delayMicroseconds(inDelays);
digitalWrite(OUTPIN, LOW);
}
void recordPIR()
{
int count, currentval;
PIRREAD[0][index] = analogRead(0);
delay(5);
PIRREAD[1][index] = analogRead(1);
delay(5);
PIRREAD[2][index] = analogRead(2);
delay(5);
PIRREAD[3][index] = analogRead(3);
//for each sensor
for (int i = 0; i<4; i++) {
//for each index in the sensor
for(int m = 0; m<5; m++) {
currentval = PIRREAD[i][m];
count = 0;
for(int q = 0; q<5; q++) {
if(currentval >= PIRREAD[i][q])
count++;
}
if (count == 3) {
PIR[i]=PIRREAD[i][m];
m=20;
}
}
}
index++;
if(index >=5)
index = 0;
}
int getRange()
{ // This function gets a ranging from the SRF08
int range = 0;
byte highByte = 0x00; // Stores high byte from ranging
byte lowByte = 0x00; // Stored low byte from ranging
Wire.beginTransmission(srfAddress); // Start communticating with SRF08
Wire.send(cmdByte); // Send Command Byte
Wire.send(0x51); // Send 0x51 to start a ranging
Wire.endTransmission();
delay(100); // Wait for ranging to be complete
Wire.beginTransmission(srfAddress); // start communicating with SRFmodule
Wire.send(rangeByte); // Call the register for start of ranging data
Wire.endTransmission();
Wire.requestFrom(srfAddress, 2); // Request 2 bytes from SRF module
while(Wire.available() < 2); // Wait for data to arrive
highByte = Wire.receive(); // Get high byte
lowByte = Wire.receive(); // Get low byte
range = (highByte << 8) + lowByte; // Put them together
return(range); // Returns Range
}
int getIR()
{
int value = 0;
//Capture Signal
change_count = 0;
while(digitalRead(IRpin) == HIGH) {}
TIMER_RESET;
TimerValue[change_count] = TCNT1;
direction[change_count++] = '0';
while (change_count < SAMPLE_SIZE) {
if (direction[change_count-1] == '0') {
while(digitalRead(IRpin) == LOW) {}
TimerValue[change_count] = TCNT1;
direction[change_count++] = '1';
} else {
while(digitalRead(IRpin) == HIGH) {}
TimerValue[change_count] = TCNT1;
direction[change_count++] = '0';
}
}
//Analyze Signal
change_count = 0;
time = (long) TimerValue[change_count] * 4;
change_count++;
while (change_count < SAMPLE_SIZE) {
time = (long) TimerValue[change_count] * 4;
if(direction[change_count-1] == '0' && direction[change_count] == '1')
{
//Do nothing
}
else if(direction[change_count-1] == '1' && direction[change_count] == '0')
{
if(time - (long)TimerValue[change_count-1] * 4 > 2000)
{
if(DEBUG) Serial.print("-");
value = 0;
}
else if(time - (long)TimerValue[change_count-1] * 4 > 1000)
{
value+=1;
value = value*2;
if(DEBUG) Serial.print((int)1);
}
else if(time - (long)TimerValue[change_count-1] * 4 < 1000)
{
value = value*2;
if(DEBUG) Serial.print((int)0);
}
}
change_count++;
}
if(DEBUG) Serial.print(" (");
if(DEBUG) Serial.print(value);
if(DEBUG) Serial.println(") end");
delay(200);
return value;
}
Back to top