amurison718
Published © GPL3+

Furby - Hacked, Hot Wired and Channeling Cartman

Possessed Furby

BeginnerFull instructions provided2,072
Furby - Hacked, Hot Wired and Channeling Cartman

Things used in this project

Hardware components

Arduino Pro Mini 328 - 5V/16MHz
SparkFun Arduino Pro Mini 328 - 5V/16MHz
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free

Story

Read more

Code

Furby code

C/C++
#include "DFRobotDFPlayerMini.h"
#include <avr/io.h>
#include <avr/interrupt.h>

#define mForPin 3
#define mBakPin 4
#define led 13
#define camPin 14
#define lightPin 15
#define gearPin 16
#define mouthPin 17
#define backPin 18 
#define bellyPin 19
#define tiltPin 20 



DFRobotDFPlayerMini myDFPlayer;


 int aveLight;
 int annoy;
 int touchBack;
unsigned long timethen;
unsigned long timethen1;


 volatile int camPos;
 volatile int mDir;

// debounce flags
boolean tiltFlag;
boolean mouthFlag;
boolean bellyFlag;
boolean backFlag;
boolean lightFlag;

void openMouth()
{
// cam position between 0 and 50
  Serial.println("Open mouth ");
  goToCamPos(50);  
}

void closeMouth()
{
// cam position between 50 and 100  
  Serial.println("Close mouth "); 
  goToCamPos(100); 
}

void openEyes()
{
  Serial.println("Open eyes "); 
  goToCamPos(100); 
}

void closeEyes()
{
  Serial.println("Close eyes "); 
  goToCamPos(190); 
}


void rock()
{
  Serial.println("Rock");
  goToCamPos(240); 
  delay(100);
  goToCamPos(190);     
  delay(100);
}


void findCamStart()
{
// find start position
  digitalWrite(mForPin, HIGH);
  digitalWrite(led, HIGH);
  
while (digitalRead(camPin) == LOW)
 {
 }

 digitalWrite(mForPin, LOW);
 digitalWrite(led, LOW);
 camPos =0;
}


void goToCamPos(int targetPos)
{
  while (camPos <targetPos -2 || camPos >targetPos +2)
  {
   if (camPos >targetPos +2)
   {
    digitalWrite(mForPin, LOW);
    digitalWrite(mBakPin, HIGH);
    mDir =-1;
   }
   else if (camPos < targetPos -2)
   {
    digitalWrite(mForPin, HIGH);
    digitalWrite(mBakPin, LOW);   
    mDir =1;
   }
  }
    digitalWrite(mForPin, LOW);
    digitalWrite(mBakPin, LOW);   
    Serial.print("Cam pos ");
    Serial.println(camPos);
    mDir =0;  
}

//Interrupt routines
void gearPinChange()
{
// Interrupt to increase or decrease cam position depending on motor direction
  camPos += mDir;
}

void camHome()
{
  camPos =0;
}


void cross()
{
 int track; 
 String folder;
 String trackNumber;

 myDFPlayer.volume(20);  //Set volume value (0~30)
 track = random(8)+1;
 trackNumber = "00" + (String)track;
 folder = "0" + (String)annoy;

 Serial.print(folder);
 Serial.print("/");
 Serial.println(trackNumber);
 myDFPlayer.playFolder(folder.toInt(), trackNumber.toInt());

 annoy ++;

 if (annoy >3)
 {
  annoy = 3;
 }
}



void happy()
{
 int track; 
 String trackNumber;

 myDFPlayer.volume(20);  //Set volume value (0~30)

  track = random(5)+1;
  trackNumber = "00" + (String)track;
  Serial.println(trackNumber);
  myDFPlayer.playFolder(04, trackNumber.toInt());
 
 annoy =1;
}

void actions()
{
 int track; 
 String trackNumber;

 myDFPlayer.volume(20);  //Set volume value (0~30)

 track = random(10)+1;
 trackNumber = "00" + (String)track;

 Serial.println(trackNumber);
 myDFPlayer.playFolder(05, trackNumber.toInt());

 annoy =1;
}

void backTouch()
{
 int track; 
 String folder; 
 String trackNumber;

 myDFPlayer.volume(20);  //Set volume value (0~30)

  track = random(3)+1;
  trackNumber = "00" + (String)track;
  Serial.println(trackNumber);
 folder = "0" + (String)(touchBack+7);

 Serial.print(folder);
 Serial.print("/");
 Serial.println(trackNumber);
 myDFPlayer.playFolder(folder.toInt(), trackNumber.toInt());
 
 touchBack ++;

 if (touchBack >2)
 {
  touchBack = 2;
 }
 
}

 void moveMouth()
 {
    do
    {
     openMouth();
     delay(300);
     closeMouth();
    }
    while (myDFPlayer.readState() !=0);  
 }


void resetFlags()
{
   tiltFlag = false;
   mouthFlag = false;
   bellyFlag = false;
   backFlag = false;
   lightFlag = false;  
}

void getLightLevel()
{
// get average light level
  for (int i =0; i<100; i++)
   {
    aveLight +=  analogRead(lightPin);
   }
  aveLight = aveLight /100;  
  aveLight -=100;
}

void setup() 
{

// Set up pins 
 pinMode(mouthPin, INPUT_PULLDOWN);
 pinMode(bellyPin, INPUT_PULLDOWN);
 pinMode(backPin, INPUT_PULLDOWN);
 pinMode(lightPin, INPUT_PULLDOWN); 
 pinMode(tiltPin, INPUT_PULLDOWN); 
 pinMode(gearPin, INPUT_PULLDOWN);
 pinMode(camPin, INPUT_PULLDOWN);
 pinMode(led, OUTPUT);
 
 pinMode(mForPin, OUTPUT);
 pinMode(mBakPin, OUTPUT);

 digitalWrite(mForPin, LOW);
 digitalWrite(mBakPin, LOW); 
 

// Other set up   
 Serial.begin(9600);

// Sound card set up

  Serial3.begin(9600);
   if (!myDFPlayer.begin(Serial3)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
  }
  else
  {
  Serial.println(F("DFPlayer Mini online."));
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);  
  }

 myDFPlayer.playFolder(06, 001); // start up sound

// get average light level
  getLightLevel();
  
// initialise misc variables
  annoy =1;
  touchBack =1;
  timethen = millis();

  resetFlags();

 findCamStart();
 attachInterrupt(digitalPinToInterrupt(gearPin), gearPinChange, CHANGE);
 attachInterrupt(digitalPinToInterrupt(camPin), camHome, RISING);
 goToCamPos(100);  // start position

}

void loop() {

 
 if (digitalRead(mouthPin) && !mouthFlag)
{
  Serial.println("Mouth");
  happy();
  moveMouth();
  timethen = millis();
  timethen1 = millis();
  mouthFlag = true;
}

 if (digitalRead(backPin) && !backFlag)
 {
  Serial.println("Back");
  backTouch();
  moveMouth();
  timethen = millis();
  timethen1 = millis();
  backFlag = true; 
 }


 if (digitalRead(bellyPin) && !bellyFlag)
  {
    Serial.println("Belly");
  myDFPlayer.playFolder(07,001); //Laugh  
  for (int i =0; i<5; i++)
   {
    rock(); 
   }
  goToCamPos(100);  // start position  
  bellyFlag = true;
  timethen1 = millis();  
  timethen = millis();
  }

// Check tilt sensor
  if (digitalRead(tiltPin) && !tiltFlag)
  {
     cross();
     moveMouth();
     timethen = millis();  
     timethen1 = millis();
     tiltFlag = true;
  }

// check light sensor
 if ((analogRead(lightPin) <aveLight) && !lightFlag)
  {
   Serial.print("Dark ");
   cross();
   openMouth();
   delay(1500);
   closeMouth();
   timethen1 = millis();  
   timethen = millis();
   lightFlag = true;
  }

// Reset flags
  if ( millis() > timethen1 + 2000)
  {
    resetFlags();
  }


// Has Furby been left alone for 60 seconds?
  if ( millis() > timethen + 60000)
  {
    actions();
    moveMouth();
    timethen = millis();
// get average light level
   getLightLevel();    
  }



 
}

Credits

amurison718
4 projects • 2 followers

Comments