August 30, 2012
Academics week

Today I met with Yaoqi regarding transfer of my credits from my masters. Also met with Jeff to talk about applying to grants, unfortunately I am ineligible for the NSF grant I was hoping for since I already have a graduate degree. Listened to several talks regarding network analysis and predictions for drug toxicity. Helped […]

May 2, 2012
Food Adventures

So this past week my girlfriend and I decided to do our on BBQ Chicago-style pizza, here is the link to here post about it, it was amazing: http://andrealynchlens.com/wp/?p=23 .

April 30, 2012
On the internet learnings

So, a big trend now are webinars or web lectures.  The Khan Academy is a great example.  I’ve been using to recently to hone up on some of my know atrophied math skills, as well as generally re-familiarizing myself with different concepts.  Additionally a conglomeration of universities have begun providing lecture series online for anyone […]

April 27, 2012
On the gaming apocalypse

So it has been quite awhile, I wasn’t kidding when I said fall gaming was going to wreck me.  So a bit on that.  Deus Ex:  Human Revolution was fantastic, it was just the sort of game I was looking for.  Sure it seemed to reward players for being slightly more stealthy, or slightly less […]

August 24, 2011
Cry havoc! And let slip the games of Fall!

So, like I mentioned before, this summer had a wealth of super hero and generally great flicks. Nothing that’ll win any Oscars, mind you. But the sort that leaving you chewing popcorn until you fossilize kernels into your enamel. What was nice about the Summer movie rush, was that they seemed to be fairly evenly […]

Click here for a copy.

I627 Seminar Papers

Project page for seminar

This link leads to a page containing infromation about articles read for the I627 Seminar in Bioinformatics class offered in the Fall of 2012 at IUPUI.

Masters Thesis: Boutique Functional Gene Networks

Work has been done to emphasize the importances of combining heterogenous data sources to build gene networks to infer function and interactions between these elements. Such work was completed for Drosophila melanogaster, and created the Indigene global functional gene network. The next step was to investigate whether or not the currently constructed global network could be modified or "retooled" to focus on specific biological processes, in our case protein secretion. By implementing a rule set that excluded data that had low information contribution with respect to protein secretion function predictions, we determined that this is infact possible. The global gene network can be retooled towards creating "boutique" networks.

Boutique Functional Gene Networks in Drosophila melanogaster from Binaebi Akah on Vimeo.

Presentations

Me

I'm Bobak Kechavarzi, originally born in Columbia, Tennessee. I spent most of my inquisitive life in Louisville, Kentucky where I attended Louisville Male Highschool, and my pursuit of sciences began.

It was absolutley amazing learning all the small nuances that contributed to the intricate mechanism that is our lives. What I began feeling particularly drawn to was the subject of genetics. Ecology, comparitive biology, all of these "classical" practices were beginning to incorporate genetics and molecular biology.

I graduated from Louisville Male Highschool in 2003 and began the next phase of my academic life at Hanover College. There I focused my studies on biology, and also began honing a personal hobby: computers and computer technology. I delved into programming and computer architecture to better understand these fascinating machines we interact with on a daily basis.

It was at Hanover that I began learning about Bioinformatics. The idea of melding computer programming and technology with biological research seemed incredibly intuitive. Furthermore, my work at the Pritzker Laboratory in the Field Museum and at the U of L department of Nephrology emphasized the need to meld disciplines.

In 2010 I received my Masters in Bioinformatics from School of Informatics and Computing from Indiana University in Bloomington. Since then I have been working with the department in developing, programming, and constructing robots for Human Robot Interaction (HRI) studies. I continue to enjoy odd and novel programming tasks, video games, pop culture, and life in general.

>gi|311701369|gb|GU205080.1| Ascaris suum enolase (enol-1) mRNA, complete cds
GGTTTAATTACCCAAGTTTGAGCAAATCGCCACTCTTTGGGAGTATCGCCGGACTATCGACAACAATGCC
GATCACTCGTATTCACGCTCGTCAAATCTATGACTCTCGTGGTAACCCAACAGTTGAGGTTGATCTCACC
ACCGAGAAAGGTATCTTCCGCGCGGCAGTACCTAGCGGTGCGTCGACGGGTGTGCACGAAGCTTTGGAAC
TACGCGACAAGGACAAAGCCGTCCATCATGGCAAGGGAGTACTGAATGCGGTTGCAAACATCAACGAGAA
AATTGGCCCAGCTATAGTTGCTAAGAACTTCTGCCCCACTCAACAAGTGGAAATCGACAAATTCATGCTT
GCGCTTGATGGCACCGAAAATAAATCGAACCTCGGTGCGAACGCAATCTTGGGTGTTTCGCTTGCGGTCG
CGAAGGCAGGTGCCGTTCACAAGGGTTTGCCACTTTACAAATATATCGCTGAGCTGGCAGGAATCTCGCA
AGTTGTGCTGCCTGTACCCGCATTCAACGTTATCAATGGTGGATCACACGCTGGCAATAAGCTTGCCATG
CAGGAATTCATGATTTTACCTGTGGGAGCGAAATCGTTCGCTGAGGCAATGCGTATGGGTTCTGAAATCT
ACCATCATCTGAAGGCTGAAATCAAGAAGCGTTATGGTCTTGATGCGACGGCCGTAGGAGATGAAGGTGG
ATTTGCACCTAACATTCAGGATAACAAGGAAGGTCTCGATCTGCTCAACACTGCCATCGCACTTGCTGGT
TACACTGGCCGAGTGTCGATCGGAATGGATGTGGCCGCATCTGAGTTCTACAAGGCTGAGGAAAAGAAAT
ATGACCTCGACTTCAAGAATCCCAACTCTGACAAGAGCCTGTGGAAGACTGGTGATGAGATGGCCGAACT
CTATCAGACTTTCATCAAGGAATATCCGGTGGTATCAATCGAGGACGCATTCGACCAGGATGATTGGGGC
AATTGGGAGAAACTGATGAATAATACGCACATCCAGTTGGTCGGAGATGACCTTACTGTCACCAACCCTA
AGCGTATTCAGATGGCCATCGAGAAGAAGGCGTGCAACTGTCTACTGCTTAAGGTGAACCAGATCGGATC
GGTTACTGAGTCGATCGAGGCAGCCAAACTATCGCGCTCACATGGATGGGGAGTAATGGTTTCGCATCGT
TCAGGTGAAACCGAAGATACGTTCATCGCTGATCTCGTTGTGGGTCTCGCTACTGGACAGATCAAAACCG
GTGCACCATGCCGTTCGGAACGTTTGGCGAAGTACAATCAACTGCTGCGTATCGAGGAGGAATTGGGTCC
ACATGCGGTTTATGCTGGCGAGAAGTTCCGAAACCCGCAAGCTTAAAGAGTCGGCAACGTCAAGAAACAA
TATGCTTATTTCATCATTGCAAGAACCTTTGCTAATGTCGCATATTGCTCGTTTTGTGCTGTTCGGCGTT
CTTTTGTTTTTCTCACGTTATAGGTTTAGAWTTTTTAAATAGGAAATGCCGGTTGTGTTGAATTTATGAA
TCGTTTTTAAAGGGCGTTGCAAACAGACTTTGAATTTCTTTTTTTGGATTTTATCTTAACTTATGAGTGA
AATATTTTTTGCTATTGAAATTGGTGAATTTTTTGCATTTCATATGGGAAGCAGAGTTTTTATAGATGGG
TTTTTGATGAAAGAATATAAGCGAATTGGGAATAATTGCATCATTCGTTTAATTATTGCTCGTTTTATCG
GTAATAAATAAAAATCTGAAAAAAAAAAAA
>gi|308035479|dbj|AB591805.1| Ascaris suum mitochondrial cox1 gene for cytochrome oxidase subunit 1, partial cds, isolate: AscP13
TCTATTTCTTTGGAACATATGAGTTTGTTTGTTTGGACCGTTTTTGTTACTGTTTTTTTGTTGGTTTTGT
CTTTACCTGTTTTGGCTGGGGCTATTACTATGTTGTTAACTGATCGTAATCTTAATACTTCTTTTTTTGA
TCCTAGGACTGGTGGTAACCCTTTGATTTATCAACATTTATTTTGGTTTTTTGGTCATCCTGAGGTTTAT
ATTTTGATTTTACCAGCTTTTGGTATTATTAGTCAGAGTAGTTTGTATTTGACTGGTAAAAAGGAGGTTT
TTGGGTCTTTGGGTATGGTTTATGCTATTTTAAGTATTGGTTTGATTGGTTGTGTTGTTTGAGCTCATCA
TATGTATACTGTTGGTATGGATCTTGATTCTCGGGCTTATTTTACTGCTGCAACTATGGTTATTGCTGTT
CCTACTGGTGTTAAGGTTTTTAGTTGGTTGGCTACCTTGTTTGGTATAAAAATGGTTTTTCAGCCTTTAC
TTTTATGAGTTATGGGTTTTATTTTTTTGTTTACTATTGGTGGGTTAACCGGGGTTATACTTTCTAATTC
TAGTTTGGATATTATCTTGCATGATACTTATTATGTTGTTAGTCATTTTCATTATGTTCTTAGTTTGGGG
GCTGTTTTTGGTATTTTTACGGGTGTGACTTTGTGGTGAAGTTTTATTACTGGTTTTGTTTATGATAAGA
TGATGATGAGAAGTGTTTTTTTTTTAATGTTTGTTGGGGTTAATTTAACTTTTTTTCCTTTACATTTTGC
TGGTATTCATGGC
>gi|308035477|dbj|AB591804.1| Ascaris suum mitochondrial cox1 gene for cytochrome oxidase subunit 1, partial cds, isolate: AscP12
TCTATTTCTTTGGAACATATGAGTTTGTTTGTTTGGACCGTTTTTGTTACTGTTTTTTTGTTGGTTTTGT
CTTTACCTGTTTTGGCTGGGGCTATTACTATGTTGTTAACTGATCGTAATCTTAATACTTCTTTTTTTGA
TCCTAGGACTGGTGGTAACCCTTTGATTTATCAACATTTATTTTGGTTTTTTGGTCATCCTGAGGTTTAT
ATTTTGATTTTACCAGCTTTTGGTATTATTAGTCAGAGTAGTTTGTATTTGACTGGTAAAAAGGAGGTTT
TTGGGTCTTTGGGTATGGTTTATGCTATTTTAAGTATTGGTTTGATTGGTTGTGTTGTTTGAGCTCATCA
TATGTATACTGTTGGTATGGATCTTGATTCTCGGGCTTATTTTACTGCTGCAACTATGGTTATTGCTGTT
CCTACTGGTGTTAAGGTTTTTAGTTGGTTGGCTACCTTGTTTGGTATAAAAATGGTTTTTCAGCCTTTAC
TTTTATGAGTTATGGGTTTTATTTTTTTGTTTACTATTGGTGGGTTAACCGGGGTTATACTTTCTAATTC
TAGTTTGGATATTATCTTGCATGATACTTATTATGTTGTTAGTCATTTTCATTATGTTCTTAGTTTGGGG
GCTGTTTTTGGTATTTTTACGGGTGTGACTTTGTGGTGAAGTTTTATTACTGGTTTTGTTTATGATAAGA
TGATGATGAGAAGTGTTTTTTTTTTAATGTTTGTTGGGGTTAATTTAACTTTTTTTCCTTTACATTTTGC
TGGTATTCATGGC
>gi|308035475|dbj|AB591803.1| Ascaris suum mitochondrial cox1 gene for cytochrome oxidase subunit 1, partial cds, isolate: AscP11
TCTATTTCTTTGGAACATATGAGTTTGTTTGTTTGAACTGTTTTTGTTACTGTTTTTTTGTTGGTTTTGT
CTTTACCTGTTTTGGCTGGGGCTATTACTATGTTGTTAACTGATCGTAATCTTAATACTTCTTTTTTTGA
TCCTAGGACTGGTGGTAACCCTTTGATTTATCAACATTTATTTTGGTTTTTTGGTCATCCTGAGGTTTAT
ATTTTGATTTTACCAGCTTTTGGTATTATTAGTCAAAGTAGTTTGTATTTGACTGGTAAAAAGGAGGTTT
TTGGGTCTTTGGGTATGGTTTATGCTATTTTAAGTATTGGTTTGATTGGTTGTGTTGTTTGAGCTCATCA
TATGTATACTGTTGGTATGGATCTTGATTCTCGGGCTTATTTTACTGCTGCAACTATGGTTATTGCTGTT
CCTACTGGTGTTAAGGTTTTTAGTTGGTTGGCTACCTTGTTTGGTATAAAAATGGTTTTTCAACCTTTAC
TTTTATGAGTTATGGGTTTTATTTTTTTGTTTACTATTGGTGGGTTAACTGGGGTTATGCTTTCTAATTC
TAGTTTGGATATTATCTTGCATGATACTTATTATGTTGTTAGTCATTTTCATTATGTTCTTAGTTTGGGG
GCTGTTTTTGGTATTTTTACGGGTGTGACTTTGTGGTGAAGTTTTATTACTGGTTTTGTTTATGATAAGA
TGATGATGAGAAGTGTTTTTTTTTTAATGTTTGTTGGGGTTAATTTGACTTTTTTTCCTTTACATTTTGC
TGGTATTCATGGT
>gi|308035473|dbj|AB591802.1| Ascaris suum mitochondrial cox1 gene for cytochrome oxidase subunit 1, partial cds, isolate: AscP8
TCTATTTCTTTGGAACATATGAGTTTGTTTGTTTGAACTGTTTTTGTTACTGTTTTTTTGTTGGTTTTAT
CTTTGCCTGTTTTGGCTGGGGCTATTACTATGTTGTTAACTGATCGTAATCTTAATACTTCTTTTTTTGA
TCCTAGGACTGGTGGTAACCCTTTGATTTATCAACATTTGTTTTGGTTTTTTGGTCATCCTGAAGTTTAT
ATTTTGATTTTACCGGCTTTTGGTATTATTAGTCAGAGTAGTTTGTATCTGACTGGTAAAAAGGAGGTTT
TTGGGTCTTTGGGTATGGTTTATGCTATTTTGAGTATTGGTTTAATTGGTTGTGTTGTTTGAGCTCATCA
TATGTATACTGTTGGTATGGATCTTGACTCTCGGGCTTATTTTACTGCTGCAACTATGGTTATTGCTGTT
CCTACTGGTGTTAAGGTTTTTAGTTGGTTGGCTACCTTGTTTGGTATAAAGATGGTTTTTCAACCTTTAC
TTTTATGAGTTATGGGTTTTATTTTTTTGTTTACTATTGGTGGGTTAACCGGGGTTATGCTTTCTAATTC
TAGTTTGGATATTATCTTACATGATACTTATTATGTTGTTAGTCATTTTCATTATGTTCTTAGTTTGGGG
GCTGTTTTTGGTATTTTTACGGGTGTGACTTTGTGGTGAAGTTTTATTACTGGTTTTGTTTATGATAAGA
TGATAATGAGAAGTGTTTTTGTTTTAATGTTTGTTGGGGTTAATTTAACTTTTTTTCCTTTACATTTTGC
TGGTATTCATGGT
>gi|303304931|dbj|AB576594.1| Ascaris suum genes for ITS1, 5.8S rRNA, partial sequence, isolate: AscP18
AAAAAAAAAAAAGTTTCCGAACGTGCACATAAGTACTATTTGGGGGTATACGTGAGCCACATAGTAAATT
GCACACAAATGTGGTGATGTAATAGCCGTTGGCGGTTTTTTTTTTTTTTGGCCGACAATTGCATGCGATT
TGCTATGTGTTGAGGGAGAATAGGTGGCATGTTGGGCTTGTTAGAAAGGCATGCCGCTAGCGCTTATTTT
CCCGCTATTTCGTAACAACGGTGTCCAATTTGGCGTCTACGCTTCACCGAGCTATCGCCTGGACCGTCGG
TAGCGATGAAAGGTGGAGAGAAAGCTCCTCGTTTCGAGTCGAGTAGACTCAATGAGCCTCAGCTTGGAGG
CCGCCAAAACTCAAAAAACACAATCACTTTTGAAAATCTATTCTAATGAAAGATGCTAAATTTTGTTTAG
TATCTTCGAATTGTAAGATGAACAAATCTTAGCGGTGGATCACTCGGTTCGTGGATCGATGAAGAACGCA
GC
///===================================
///
///  OBJECT DEFS
///
///===================================


///===================================
/// Servo defs
///===================================
#include 
Servo myServRot;  // create servo object to control a servo, rotational 
Servo myServOther;//create servo object to control a servo, forward/backward 


///===================================
/// Signal defs
///===================================
const int ledPin1 = 13;      // led connected to digital pin 13
const int ledPin2 = 12;
int ledState1 = LOW;         // variable used to store the last LED status, to toggle the light
int ledState2 = LOW;


///===================================
/// RFID defs
///===================================
#include 
#define rxPin 7
#define txPin 2
#define TAG_LEN 12
#define ARR_LEN 14
NewSoftSerial RFID =  NewSoftSerial(rxPin, txPin); //connection to RFID reader
byte code[TAG_LEN];		 // var that will hold the bytes-in read from the serialBuffer
int bytes_read = 0;
int currentSelection = 99;
int previousSelection = 99;
int hasItemInMind = 0;
char target_tag[ARR_LEN][TAG_LEN] =
  {
    {0x02, 0x32, 0x35, 0x30, 0x30, 0x41, 0x42, 0x43, 0x36, 0xe45, 0x31, 0x41 },
    {0x02, 0x32, 0x39, 0x30, 0x30, 0x39, 0x34, 0x32, 0x38, 0xe42, 0x36, 0x32 },
    {0x02, 0x32, 0x39, 0x30, 0x30, 0x39, 0x33, 0x45, 0x31, 0xe44, 0x37, 0x38 },
    {0x02, 0x32, 0x39, 0x30, 0x30, 0x39, 0x33, 0x46, 0x46, 0xe41, 0x44, 0x45 },
    {0x02, 0x32, 0x39, 0x30, 0x30, 0x39, 0x33, 0x46, 0x45, 0xe31, 0x33, 0x35 },
    {0x02, 0x32, 0x35, 0x30, 0x30, 0x41, 0x42, 0x44, 0x37, 0xe33, 0x35, 0x36 },
    {0x02, 0x32, 0x35, 0x30, 0x30, 0x41, 0x42, 0x44, 0x36, 0xe37, 0x30, 0x32 },
    {0x02, 0x32, 0x35, 0x30, 0x30, 0x41, 0x42, 0x43, 0x37, 0xe36, 0x32, 0x32 },
    {0x02, 0x32, 0x35, 0x30, 0x30, 0x41, 0x42, 0x46, 0x44, 0xe34, 0x45, 0x33 },
    {0x02, 0x32, 0x39, 0x30, 0x30, 0x39, 0x33, 0x45, 0x45, 0xe34, 0x35, 0x31 },   
    {0x02, 0x32, 0x35, 0x30, 0x30, 0x41, 0x43, 0x32, 0x34, 0xe32, 0x35, 0x38 },
    {0x02, 0x32, 0x35, 0x30, 0x30, 0x41, 0x42, 0x46, 0x34, 0xe46, 0x33, 0x38 },
    {0x02, 0x32, 0x35, 0x30, 0x30, 0x41, 0x42, 0x44, 0x41, 0xe31, 0x46, 0x34 },    
    {0x02, 0x32, 0x35, 0x30, 0x30, 0x41, 0x43, 0x32, 0x45, 0xe30, 0x36, 0x41 },
  };



///===================================
//Timing definition
///===================================
#include   
#include   
#include   // a basic DS1307 library that returns time as a time_t

long timeNow;
/// Etc
#define RECV_BUFFER 200
///==================================
///Tri-color LED pins
///==================================
int redPin = 4;
int greenPin = 5;
int bluePin = 6;
///===================================
/// Major state variables
///===================================
int state = 0;
int alertLevel = 0;
int timer = 0;
int lastTime = 0;

///==*==*==*====*===*==*==============
///
/// Behavior parameters
///
///==*==*====**==*===*=====*==========

int workInterval = 5; // The minutes dewey will wait until break recommendation
int responseWaitInterval = 1; // The minutes dewey will wait  until repeating a request
int breakInterval = 1; // The minutes dewey will waitn until it will stop waiting for requested item
int copeInterval =  1; // minutes that dewey will wait to go to sleep after no response


///===================================
/// Piezo defs
///===================================
const int knockSensor = 0;  // the piezo is connected to analog pin 0
const int threshold = 7;  // threshold value to decide when the detected sound is a knock or not
int pauseMaxTime = 500; // .2 sec
int maxSequenceTime = 5000; // 10 sec
int sequenceTime2 = 3000;
int sequenceTime3 = 1000;
int currentSequenceTime = 0;
int knocksInSession = 0;
// Tuning constants.  Could be made vars and hoooked to potentiometers for soft configuration, etc.
// const int threshold = 7;           // Minimum signal from the piezo to register as a knock
const int rejectValue = 50;    //15    // If an individual knock is off by this percentage of a knock we don't unlock..
const int averageRejectValue = 50; //15// If the average timing of the knocks is off by this percent we don't unlock.
const int knockFadeTime = 125;     // milliseconds we allow a knock to fade before we listen for another one. (Debounce timer.)
const int maximumKnocks = 20;       // Maximum number of knocks to listen for.
const int knockComplete = 1100;     // Longest time to wait for a knock before we assume that it's finished.
// codes 
int patternCode1[maximumKnocks] = {50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};  //two knocks
//int patternCode2[maximumKnocks] = {50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //three knocks
//int patternCode3[maximumKnocks] = {50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //four knocks 
//int patternCode4[maximumKnocks] = {50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //five knocks 
int knockReadings[maximumKnocks];   // When someone knocks this array fills with delays between knocks.
int knockSensorValue = 0;           // Last reading of the knock sensor.



///===================================
///
///  SETUP
///
///===================================
void setup() {
  pinMode(ledPin1, OUTPUT); // declare the ledPin as as OUTPUT
  pinMode(ledPin2, OUTPUT);
  Serial.begin(9600);       // use the serial port
  RFID.begin(9600);
  randomSeed(analogRead(1));
}


///===================================
///
///  MAIN BEHAVIOR LOOP
///
///===================================
void loop() { 
 beDewey(); 
  //signalTest();
}

void beDewey(){
  //=========
  // Always reading RFID
  readRFID();
  
  //=========
  // If Dewey is asleep listen for two knocks to wake up
  if(state == 0){
    listenForKnocks();
    lightsOff();
    resetTimer();
  }
  //=========
  // If Dewey is with user who is at desk working
  if(state == 1){
    petPlay();
    lights();
    if(checkTime() == workInterval){
      lightsOff();
      lightBlue();
      // Switch to break
      state = 2; //if your minutes count equals the time for first alert, change state
     // chooseItemToRequest();
      alertLevel = 0;
      resetTimer();
      bodySignal(alertLevel);
    }
  }
  //=========
  // If Dewey is trying to get the user to get an RFID
  if(state == 2){

    listenForUserResponse(); // might need to set bytes to 0 on state switch

    if(checkTime() == responseWaitInterval){
      alertLevel++;
      if(alertLevel >= 2){
        // switch to state 4 - coping with no food
        resetTimer();
        state = 4;
      }
      resetTimer();
      bodySignal(alertLevel);
    }
  }
  //=========
  // If waiting for food for too long
  if(state == 3){
    
    listenForRequestRFID();
    
    alertLevel = 0;
    if(checkTime() == breakInterval){
      // switch to state 4 - coping with no food
      bodySignal(4);
      hasItemInMind = 0;
      state = 4;
      printState();
    }
  }
  //=========
  // If 
  if(state == 4){
    alertLevel = 0;
    if(checkTime() == copeInterval ){
      // switch to sleep mode
      bodySignal(4); 
      hasItemInMind = 0;  
      state = 0;   
    }
  }
  
  
  RFID.flush();
  bytes_read = 0;
  delay(50);
  
  printTimer();
}

void printState(){
  Serial.print("State is: ");
  Serial.println(state);
}
void printTimer(){
  Serial.print("... and the timer is: ");
  Serial.println(checkTime());
}

void updateTimer(){
  // timer = millis() - lastTime; // not needed with time.h implementation
}

int checkTime(){
  long minutes = 60000;
  
  return ((millis()-timeNow)/minutes);
  
}
void resetTimer(){
  timeNow = millis();
}



//=============================================================================================
//
// RFID Interface Functions
//
//=============================================================================================


//Allows selection based on whether or not an item is already chosen, or if it is the first selection
void chooseItemToRequest(){
  if(hasItemInMind == 0){
    if(currentSelection == 99){
      currentSelection = makeSelection();
      hasItemInMind = 1;
    }else{
      previousSelection = currentSelection;
      while(currentSelection == previousSelection){
        currentSelection = makeSelection();
      }
      hasItemInMind = 1;
    }  
  }
}

//Performs random selection
int makeSelection(){
  int choice;
  choice = random(5);
  Serial.print("I am choosing card ");
  Serial.print(choice);
  Serial.println();
  return choice;
}




void readRFID(){
  if(RFID.available()){
    //keep reading from serial untill there are bytes in the serial buffer
    while (RFID.available() && bytes_read < TAG_LEN){		    //read Serial
      code[bytes_read] = RFID.read();
      bytes_read++;  // ready to read next digit
    }
 /*    Print tag...
    for(int i=0; i= TAG_LEN){
    if(memcmp(code, target_tag[previousSelection], TAG_LEN) == 0 ){
      
      Serial.println("Thanks!");
      
      resetTimer();
      bodySignal(3);
      state = 3;
      printState();
    }else if((previousSelection == 99) && (RFID.available())){ // if first break
      
      //Check to see the index of the card that was just read 
      for(int index = 0; index < 14; index++){ 
        if(memcmp(code, target_tag[index], TAG_LEN) == 0){
           previousSelection = index;
        } 
      }
      delay(15);
      Serial.println("Thanks! Have a fun break");
      
      resetTimer();
      bodySignal(3);
      state = 3;
      printState();
    }
    bytes_read = 0;
  }
}

// Await user bringing back requested RFID
void listenForRequestRFID(){
  if( bytes_read >= TAG_LEN){
    if(memcmp(code, target_tag[previousSelection], TAG_LEN) != 0 ){
        Serial.println("Thanks. Time, to get back to work!");
        
        //Check to see the index of the card that was just read 
        for(int i = 0; i < 14; i++){ 
          if(memcmp(code, target_tag[i], TAG_LEN) == 0){
             previousSelection = i;
             Serial.print("Index:  ");
             Serial.println(i);
           
          } 
        }
        
        Serial.println(previousSelection);
        
        bodySignal(3);
        // setSyncProvider(RTC.get); //resets clock
        resetTimer();
        //previousSelection = currentSelection;
        hasItemInMind = 0;
        state = 1;
        printState();
      } else {
        Serial.println("@$??");
        bodySignal(1);
      }
    bytes_read = 0;
  }
}


//=============================================================================================
//
// Piezo Interface Functions
//
//=============================================================================================

void petPlay(){
  int currentPauseTime = 0;
  int sequenceStartTime = millis();
  int startTime = millis();

  digitalWrite(ledPin1, LOW);      			
  delay(knockFadeTime);                       
  digitalWrite(ledPin1, HIGH); 
  
  do {
    knockSensorValue = analogRead(knockSensor);
    if (knockSensorValue >= threshold){
      currentPauseTime = 0;
      startTime = millis();
  
       digitalWrite(ledPin2, HIGH);      	      
       delay(knockFadeTime/2);                       
       digitalWrite(ledPin2, LOW);     
       delay(knockFadeTime/2);
       
      knocksInSession++;
    }
    currentSequenceTime = millis() - sequenceStartTime;
    currentPauseTime = millis() - startTime;
  } while ((currentPauseTime < pauseMaxTime) && (currentSequenceTime < maxSequenceTime));
   
  if (currentSequenceTime >= sequenceTime3){
    bodySignal(5);
  }
}

// Records the timing of knocks.
void listenForKnocks(){
  int i = 0;
  // First lets reset the listening array.
  for (i = 0; i < maximumKnocks; i++){ knockReadings[i]=0; }
  int currentKnockNumber=0;         			// Incrementer for the array.
  int startTime=millis();           			// Reference for when this knock started.
  int now=millis();
  digitalWrite(ledPin1, LOW);      			
  delay(knockFadeTime);                       
  digitalWrite(ledPin1, HIGH); ;
  do {
    //listen for the next knock or wait for it to timeout. 
    knockSensorValue = analogRead(knockSensor);
    if (knockSensorValue >=threshold){                   //got another knock...
      now=millis();
      knockReadings[currentKnockNumber] = now-startTime;
      currentKnockNumber ++;                             //increment the counter
      startTime=now;          
      digitalWrite(ledPin2, HIGH);      	      
      delay(knockFadeTime/2);                       
      digitalWrite(ledPin2, LOW);     
      delay(knockFadeTime/2);
    }
    now=millis();
    //did we timeout or run out of knocks?
  } while ((now-startTime < knockComplete) && (currentKnockNumber < maximumKnocks));
  if (validateKnock() == true){ } else { }
}

//Knock validation
boolean validateKnock(){
  int i=0;
 
  // simplest check first: Did we get the right number of knocks?
  int currentKnockCount = 0;
  int PatternKnock1Count = 0;
  int maxKnockInterval = 0; // We use this later to normalize the times.
  
  for (i=0;i 0){ currentKnockCount++; }
    if (patternCode1[i] > 0){ PatternKnock1Count++; }
		
    // collect normalization data while we're looping.
    if (knockReadings[i] > maxKnockInterval){ maxKnockInterval = knockReadings[i];}
  }
  
  if ((currentKnockCount != PatternKnock1Count)){//&&(currentKnockCount != PatternKnock2Count)&&(currentKnockCount != PatternKnock3Count)){
    return false; 
  }
   /*  Now we compare the relative intervals of our knocks, not the absolute time between them.
      (ie: if you do the same pattern slow or fast it should still open the door.)
      This makes it less picky, which while making it less secure can also make it
      less of a pain to use if you're tempo is a little slow or fast. 
  */
  
  boolean code1found=true;
  int totaltimeDifferences1=0;
  int timeDiff=0;
  
  for (i = 0; i < maximumKnocks; i++){ // Normalize the times
    knockReadings[i]= map(knockReadings[i],0, maxKnockInterval, 0, 100);      
    timeDiff = abs(knockReadings[i]-patternCode1[i]);
   
    if (timeDiff > rejectValue){ // Individual value too far out of whack
      code1found=false;
    }
    totaltimeDifferences1 += timeDiff;
  }
  // It can also fail if the whole thing is too inaccurate.
  if (totaltimeDifferences1/PatternKnock1Count > averageRejectValue){
    code1found = false;
  }
  
  if ((code1found == false)){ 
    return false;
  } else {
    if (code1found==true){
      // Serial.println(" (knock 1)"); 
      validSignal();
      bodySignal(4);
      state = 1;
      printState();
    } 
    return true;
  }
  
}

// Use led to signal that the knock recieved is valid
void validSignal(){
  int t=40;
  for(int i = 0; i < 3; i++){
    digitalWrite(ledPin1, LOW); 
    delay(t);
    digitalWrite(ledPin1, HIGH);      			// light the knock LED.
  }
}







//=============================================================================================
//
// Signaling 
//
//=============================================================================================
// body signal codes
/*Function that animates based on switch state
 0 = shaking head slowly, LEVEL 1 ALARM
 1 = shakes head fast LEVEL 2 AGITATION
 2 = complete spaz: fast rocking and shaking head, LEVEL 3 angry
 3 = rock side-side, HAPPY/GREETING
 4 = Login/logout animation
 5 = Playful animation
*/
void bodySignal(int behavior)
{
   
    int pos1 = 0;    // variable to store the servo position 
    int pos2 = 0;
  
    switch(behavior){
    ///===================================
    /// SHAKE HEAD SLOWLY
    ///===================================
    case 0:          
      myServOther.attach(9);  // attaches the servo on pin 9 to the servo object 
      myServRot.attach(10); //attaches the servo on pin 10 to the servo object
      myServOther.write(90);
      for(int i = 0; i <= 2; i += 1)
      { 
        for(pos1 = 0; pos1 < 60; pos1 += 1)  // goes from 0 degrees to 180 degrees 
        {                                  // in steps of 4 degrees 
          myServRot.write(pos1);              // tell servo to go to position in variable 'pos' 
          delay(15);                       // waits 15ms for the servo to reach the position 
        } 
        for(pos1 = 60; pos1 >= 1; pos1 -= 1)     // goes from 180 degrees to 0 degrees 
        {                                  
          myServRot.write(pos1);              // tell servo to go to position in variable 'pos' 
          delay(15);                       // waits 15ms for the servo to reach the position 
        }
      }
      myServOther.detach();  // attaches the servo on pin 9 to the servo object 
      myServRot.detach(); //attaches the servo on pin 10 to the servo object
    break;
    
    ///===================================
    /// ROCK SIDE-SIDE
    ///===================================
    case 3: //rock side-side, HAPPY/GREETING
      myServOther.attach(9);  // attaches the servo on pin 9 to the servo object 
      myServRot.attach(10); //attaches the servo on pin 10 to the servo object
      for(int i = 0; i < 2; i++){
        for(pos2 = 60; pos2 < 130; pos2 += 2)  
          {                                 
            myServOther.write(pos2);               
            delay(15);                        
          } 
          for(pos2 = 130; pos2 >= 60; pos2 -= 2)     
          {                                  
            myServOther.write(pos2);               
            delay(15);                       
          }
        }        
      myServOther.detach();  // attaches the servo on pin 9 to the servo object 
      myServRot.detach(); //attaches the servo on pin 10 to the servo object  
    break;
    
    ///===================================
    /// 
    ///===================================  
    case 1 : //shakes head fast LEVEL 2 AGITATION
      myServOther.attach(9);  // attaches the servo on pin 9 to the servo object 
      myServRot.attach(10); //attaches the servo on pin 10 to the servo object
    
      for(int i = 0; i < 4; i++){
        for(pos1 = 0; pos1 < 180; pos1 += 5)  
        {                                  
          myServRot.write(pos1);              
          delay(15);                     
        } 
        for(pos1 = 180; pos1 >= 1; pos1 -= 5)     
        {                                  
          myServRot.write(pos1);               
          delay(15);                    
        }
      }
      
      myServOther.detach();  // attaches the servo on pin 9 to the servo object 
      myServRot.detach(); //attaches the servo on pin 10 to the servo object
    break;
    
    ///===================================
    /// 
    ///===================================   
    case 2: //complete spaz: fast rocking and shaking head, LEVEL 3 angry     
    //  Serial.println("DEBUG:  Performing behavior 4:  complete spaz: fast rocking and shaking head, LEVEL 3 angry");
  
      myServOther.attach(9);  // attaches the servo on pin 9 to the servo object 
      myServRot.attach(10); //attaches the servo on pin 10 to the servo object
      
      for(int i = 0; i < 7; i++){
        for(pos1 = 60; pos1 < 130; pos1 += 5)  
        {                                  
          myServRot.write(pos1);  //both servos change to the same position at the same rate
          myServOther.write(pos1);          
          delay(15);                       
        } 
        for(pos1 = 130; pos1 >= 60; pos1 -= 5)     
        {                                  
          myServRot.write(pos1);
          myServOther.write(pos1);          
          delay(15);                      
        }
      } 
      myServOther.detach();  // attaches the servo on pin 9 to the servo object 
      myServRot.detach(); //attaches the servo on pin 10 to the servo object
    break;
    
    ///===================================
    /// 
    ///=================================== 
    case 4: //login robot stands up
      myServOther.attach(9);  // attaches the servo on pin 9 to the servo object 
      myServRot.attach(10); //attaches the servo on pin 10 to the servo object
      if(state == 0){
        for(pos1 = 0; pos1 < 90; pos1+=3){
          myServOther.write(pos1);
          delay(15);
        }
        state = 1; //should not be changing state here...
        printState();
      }else{
        for(pos1 = 90; pos1 > 0; pos1--){
          myServOther.write(pos1);
          delay(15);
        }
        state = 0;
        printState();
      }  
      myServOther.detach();
      myServRot.detach();
    break;

    ///===================================
    /// 
    ///=================================== 
    case 5:  //Robot playful
      myServOther.attach(9);  // attaches the servo on pin 9 to the servo object 
      myServRot.attach(10); //attaches the servo on pin 10 to the servo object 
      int repeats;
      repeats = currentSequenceTime/1000; //calculate how many times to repeat 
      if(repeats == 0){
        repeats = 1;
      }else if(repeats > 5){
        repeats = 5;
      } 
      for(int i = 0; i <= repeats; i++){
        for(pos2 = 70; pos2 < 100; pos2 += 2)  
        {                                 
          myServOther.write(pos2);               
          delay(15);                        
        } 
        for(pos2 = 100; pos2 >= 70; pos2 -= 2)     
        {                                  
          myServOther.write(pos2);               
          delay(15);                       
        }
      }      
      myServOther.detach();
      myServRot.detach(); 
    break;
 
    default:  //blank case, robot sitting still, waiting for input from sensor
    break;
  
  } 
}

void lights(){
  
  if(checkTime() == (floor(workInterval*(5.0/6.0)))){
    Serial.println("red");
    lightRed();
  }else if((checkTime() >= (floor(workInterval*(2.0/3.0)))) && (checkTime() <= (floor(workInterval*(5.0/6.0))))){
    Serial.println((floor(workInterval*(5.0/6.0))));
    Serial.println("Yellow");
    lightYellow(); 
  }else{
    lightGreen();
  } 
}

void lightsOff(){
  analogWrite(redPin,0);
  analogWrite(greenPin,0);
  analogWrite(bluePin,0);
}

void lightGreen(){
  analogWrite(redPin, 0);
  analogWrite(bluePin, 0);
  analogWrite(greenPin, 255);
}

void lightRed(){
  analogWrite(redPin, 255);
  analogWrite(bluePin, 0);
  analogWrite(greenPin, 0);
}

void lightBlue(){
  analogWrite(redPin, 0);
  analogWrite(bluePin, 255);
  analogWrite(greenPin, 0);
}

void lightYellow(){
  analogWrite(redPin, 255);
  analogWrite(bluePin, 0);
  analogWrite(greenPin, 255);
}

void signalTest(){

  // Always reading RFID
  readRFID();
  
  if( bytes_read >= TAG_LEN){
    if(memcmp(code, target_tag[0], TAG_LEN) == 0 ){
        bodySignal(0);
        Serial.println("bodySignal(0);");
    }
    if(memcmp(code, target_tag[1], TAG_LEN) == 0 ){
        bodySignal(1);
        Serial.println("bodySignal(1);");
    }
    if(memcmp(code, target_tag[2], TAG_LEN) == 0 ){
        bodySignal(2);
        Serial.println("bodySignal(2);");
    }
    if(memcmp(code, target_tag[3], TAG_LEN) == 0 ){
        bodySignal(3);
        Serial.println("bodySignal(3);");
    }
    if(memcmp(code, target_tag[4], TAG_LEN) == 0 ){
        bodySignal(4);
        Serial.println("bodySignal(4);");
    }
    // To test signal 5 using card #4
//    if(memcmp(code, target_tag[4], TAG_LEN) == 0 ){
//        bodySignal(5);
//        Serial.println("bodySignal(5);");
//    }

    bytes_read = 0;
  }
  
 
  RFID.flush();
  bytes_read = 0;
  delay(50);

}