Heidi



The final version of the robot is the same as the earlier design of squarish-looking robot. But the colors are much brighter now. The robot has the following characteristics:

1. Range-finder detects if someone has come within 30 cm of the robot and if so, the robot abruptly wakes up, moving its head up and eyes lighting up. The robot's neck pulls up using a servo motor and its eyes have LED's which light up to show it's awake and ready to play.


2. Force Sensitive Resistors in the ears detect the slightest rub and if someone scratches one of its ears, the robot giggles (bobs its head and blinks eyes).




3. Capacitive Sensor in the nose detects if anyone touches the nose. If so, the robot pulls its head back down.

 

4. Wheels activate if a person messes with the robot's nose too much. The robot moves it's head down and then suddenly rolls away to a side (moves to left or right alternately).




The final breadboard looked somewhat like this: (there are still a few connections missing - which I can't take a picture of since the breadboard is inserted into the robot-body to connect to those).





              





==========================================

Arduino Code:

#include [servo.h]

#define EYES_OPEN  255
#define EYES_SHUT  0
#define EYES_DIM   30

#define HEAD_HI    10
#define HEAD_LO    100

#define RANGE_NEAR 35
#define RANGE_NEARER 20
#define RANGE_FAR  100
#define R_SAMPLES  20
#define INTERVAL   10000
#define WHEEL_INTERVAL   1000

#define TOUCH_HI   60
#define FSR_HI     30

int HEAD = HEAD_LO;
int EYES = EYES_SHUT;

unsigned long currMillis;
long prevMillis = 0;
long prevWheelMillis = 0;
boolean dir = true;
boolean running = false;

// ##################
// ## Analog Pins: ##
// ##################

// RANGEFINDER VARs
int rangeSum=0;         //Create sum variable
int rangeCount = 0;
int rangePrev = RANGE_NEAR;
int rangeCurr = RANGE_FAR;

// FSR VARs
int FSRval1;
int FSRval2;

// ###################
// ## Digital Pins: ##
// ###################

// CAPACITATIVE SENSOR VARs
unsigned int touchX, touchY;
float touchSum, touchOut, touchVal = .07;    // these are variables for a simple low-pass (smoothing) filter - touchVal of 1 = no filter - .001 = max filter

// SERVO VARs
Servo myservo;  // create servo object to control a servo

int pinTest = 3;
int pinFSR1 = 0;
int pinFSR2 = 1;
int pinRange = 2;    // select the input pin for the ultrasonic sensor

const int pinTouchOut  = 2;
const int pinTouchIn   = 3;
const int pinTouchGrd  = 4;
const int pinServo     = 5;
const int pinEyes      = 6;

const int motor1Pin = 9;    // H-bridge leg 1 (pin 2, 1A)
const int motor2Pin = 8;    // H-bridge leg 2 (pin 7, 2A)
const int motor3Pin = 11;    // H-bridge leg 1 (pin 2, 1A)
const int motor4Pin = 12;    // H-bridge leg 2 (pin 7, 2A)
const int enablePin = 10;    // H-bridge enable

int runRangeFinder();
int runTouchSensor();
int runFSR();

int noseCount = 0;

void setup()
{
  Serial.begin(9600);

  pinMode(pinTest, OUTPUT);        // TEST LED
  pinMode(pinRange, INPUT);        // RANGEFINDER
  pinMode(pinFSR1, INPUT);          // FSR
  pinMode(pinFSR2, INPUT);          // FSR
 
  pinMode(pinEyes, OUTPUT);        // EYES' LEDs
  pinMode(pinTouchOut, OUTPUT);    // output pin
  pinMode(pinTouchIn,   INPUT);    // input pin
  pinMode(pinTouchGrd, OUTPUT);    // guard pin
  digitalWrite(pinTouchGrd, LOW);  // could also be HIGH - don't use this pin for changing output though
  myservo.attach(pinServo);        // SERVO:

  // set all the other pins you're using as outputs:
  pinMode(motor1Pin, OUTPUT);
  pinMode(motor2Pin, OUTPUT);
  pinMode(motor3Pin, OUTPUT);
  pinMode(motor4Pin, OUTPUT);
  pinMode(enablePin, OUTPUT);
}

void loop()
{
  currMillis = millis();
 
  randomSeed(analogRead(pinTouchGrd));  // setting the seed to data from unconnected pin
  runRangeFinder();
  runTouchSensor(); 
  runFSR();
  runWheels();

  // when normal --> return to Normal Position
  myservo.write(HEAD);                 
  analogWrite (pinEyes, EYES);
/*
  Serial.print("\t Touch: ");
  Serial.print( (long)touchOut, DEC); // Smoothed Low to High
  Serial.print("\t FSR: ");
  Serial.print( FSRval);
  Serial.println();
*/
  delay(10); 
}


//==================
//  RANGE FINDER
//==================
int runRangeFinder()
{
  unsigned long currRangeMillis = millis();
  // sampleCount starts life at 0, then loops through sampleSize
  rangeSum += analogRead(pinRange);
  rangeCount++;
  if (rangeCount == R_SAMPLES)
  {
    rangeCurr= rangeSum/R_SAMPLES;
  
    Serial.print("Range: ");
    Serial.print(rangeCurr);
    Serial.println();
    rangeCount = 0;  rangeSum = 0;
    if (rangeCurr <= RANGE_NEAR)
      rangePrev = RANGE_NEAR;
    if (currRangeMillis - prevMillis > INTERVAL )
    {
      prevMillis = currRangeMillis;
      if (rangeCurr >= RANGE_FAR)
        rangePrev = rangeCurr;
      Serial.print(" Interval - Curr: ");
      Serial.print(rangeCurr);
      Serial.print(" Prev: ");
      Serial.print(rangePrev);
      Serial.println();
    }
  }
 
  if (rangeCurr < RANGE_NEAR)
  {
    Serial.println("Hi there!");
//    talk();
    HEAD = ( HEAD > HEAD_HI ? HEAD-=10 : HEAD_HI);
    EYES = ( EYES < EYES_OPEN ? EYES+=10 : EYES_OPEN);
  }
  else if(rangePrev >= RANGE_FAR && rangeCurr >= RANGE_FAR)
  {
    HEAD = HEAD_LO;
    EYES = EYES_SHUT;
  }
 
  return 0;
}

//==================
//  TOUCH SENSOR:
//==================
int runTouchSensor()

  touchX = 0;        // clear out variables
  touchY = 0;

  for (int i=0; i < 4 ; i++ )
  { // do it four times to build up an average - not really neccessary but takes out some jitter

    digitalWrite(pinTouchOut, HIGH);     // LOW-to-HIGH transition
    while (digitalRead(pinTouchIn) != 1) touchX++;// while the sense pin is not high
    delay(1);
    digitalWrite(pinTouchOut, LOW);      //  HIGH-to-LOW transition
    while(digitalRead(pinTouchIn) != 0 ) touchY++; 
    delay(1);
  }

  touchOut =  (touchVal * (float)touchX) + ((1-touchVal) * touchSum);  // Easy smoothing filter "touchVal" determines amount of new data in touchOut
  touchSum = touchOut;

//  Serial.print(touchOut);
//  Serial.println(touchOut);
 
  // when nose touched --> hide
  if (touchOut >= TOUCH_HI)
  {
    Serial.println ("You touched my Nose! :(");
//    EYES = EYES_DIM;
//    HEAD = HEAD_LO;   

    myservo.write(HEAD_LO);                 
    analogWrite (pinEyes, EYES_DIM);
    noseCount += 1;
    Serial.print(" NoseCount: ");
    Serial.println(noseCount);
    delay (1000);
    }
  return 0;
}

//==================
//  FORCE SENSOR:
//==================
int runFSR()
{
  FSRval1 =  analogRead(pinFSR1);
  FSRval2 =  analogRead(pinFSR2);
 
  //  when ear rubbed --> laugh
  if (FSRval1 >= FSR_HI || FSRval2 >= FSR_HI)
  {
    Serial.println("Hehehe :D");
    for (int i = 0; i < random(2,5); i++)
    {
      myservo.write(HEAD_HI);                 
      analogWrite (pinEyes, EYES_OPEN);
      delay(100);

      myservo.write(HEAD_LO);                 
      analogWrite (pinEyes, EYES_DIM);
      delay(130); 
    }
  } 
//  Serial.print(", FSR1: ");
//  Serial.print( FSRval1);
//  Serial.print(", FSR2: ");
//  Serial.println( FSRval2);
 
//  delay (500);
  return 0;
}

int runWheels()
{
    if (noseCount == 3 || running)
    {       
      if (currMillis - prevWheelMillis > WHEEL_INTERVAL )
      {
        prevWheelMillis = millis();
        if (!running)
        {
          digitalWrite(enablePin, HIGH);
          Serial.println("go!");
          running = !running;
        }
        else
        {
          Serial.println("stop!");
          digitalWrite(enablePin, LOW);
          noseCount = 0;
          running = !running;
          return 1;
         }
       
        if (dir)
        {
          Serial.println("dir1!");
          digitalWrite(motor1Pin, LOW);   // set leg 1 of the H-bridge low
          digitalWrite(motor2Pin, HIGH);  // set leg 2 of the H-bridge high
         
          digitalWrite(motor3Pin, LOW);   // set leg 1 of the H-bridge low
          digitalWrite(motor4Pin, HIGH);  // set leg 2 of the H-bridge high
         
          dir = !dir;
        }
        else
        {
          Serial.println("dir2!");
          digitalWrite(motor1Pin, HIGH);   // set leg 1 of the H-bridge low
          digitalWrite(motor2Pin, LOW);  // set leg 2 of the H-bridge high
         
          digitalWrite(motor3Pin, HIGH);   // set leg 1 of the H-bridge low
          digitalWrite(motor4Pin, LOW);  // set leg 2 of the H-bridge high
         
          dir = !dir;
        }
      }
    }
    return 0;
}