#include #include #include #include "WaveUtil.h" #include "WaveHC.h" //files that will be played: //POWERON.wav //LFT (x).wav //TLT (x).wav //SEE (x).wav //where x = 1 thru 99 SdReader card; // This object holds the information for the card FatVolume vol; // This holds the information for the partition on the card FatReader root; // This holds the information for the filesystem on the card FatReader f; // This holds the information for the file we're play WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time const int PIR_PIN = A0;//used to sense motion const int TILT_PIN = A3;//used to sense the turret falling over const int LIFT_PIN = A2;//used to sense the turret being lifted up const long debounceTime = 50;//wait at least 50ms for switch bounce const long speachTime = 3000;//wait 1 second after finishing talking //before saying the next thing int previousTilt = HIGH;//sensor is high when the turret is upright int previousLift = LOW;//sensor is low when the turret is not lifted int lifted = 0;//0 when on the ground; 1 when lifted up int tilted = 0;//0 when upright; 1 when fallen over long seen = 0;//0 when no one is seen; 1 when a target is acquired int powerOn = 1;//make the turret say hello when turned on long tiltTimer; long liftTimer; long speachTimer; int tltNumber=1; int lftNumber=1; int seeNumber=1; void setup() { //start up the serial connection for debug Serial.begin(9600); Serial.println("setup"); //set the pins connected to the pir, lift sensor, and tilt //sensor to be inputs. use the internal pullup resistors for //the lift and tilt sensors, but not for the pir sensor. digitalWrite(PIR_PIN,LOW); pinMode(PIR_PIN,INPUT); digitalWrite(TILT_PIN,HIGH); pinMode(TILT_PIN,INPUT); digitalWrite(LIFT_PIN,HIGH); pinMode(LIFT_PIN,INPUT); // Set the output pins for the DAC control. This pins are defined in the library pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); //reset the timers to prevent false positives at startup tiltTimer = millis(); liftTimer = millis(); speachTimer = millis(); // if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you if (!card.init()) { //play with 8 MHz spi (default faster!) putstring_nl("Card init. failed!"); // Something went wrong, lets print out why while(1); // then 'halt' - do nothing! } // enable optimize read - some cards may timeout. Disable if you're having problems card.partialBlockRead(true); // Now we will look for a FAT partition! uint8_t part; for (part = 0; part < 5; part++) { // we have up to 5 slots to look in if (vol.init(card, part)) break; // we found one, lets bail } if (part == 5) { // if we ended up not finding one :( putstring_nl("No valid FAT partition!"); while(1); // then 'halt' - do nothing! } // Lets tell the user about what we found putstring("Using partition "); Serial.print(part, DEC); putstring(", type is FAT"); Serial.println(vol.fatType(),DEC); // FAT16 or FAT32? // Try to open the root directory if (!root.openRoot(vol)) { putstring_nl("Can't open root dir!"); // Something went wrong, while(1); // then 'halt' - do nothing! } // Whew! We got past the tough parts. putstring_nl("Ready!"); } void loop() { //check sensors checkSensors(); //speak, if necessary speak(); } // Plays a full file from beginning to end with no pause. void playcomplete(char *name) { // call our helper to find and play this name playfile(name); while (wave.isplaying) { // do nothing while its playing } speachTimer = millis(); // now its done playing } void playfile(char *name) { // see if the wave object is currently doing something if (wave.isplaying) {// already playing something, so stop it! wave.stop(); // stop it } // look in the root directory and open the file if (!f.open(root, name)) { putstring("Couldn't open file "); Serial.println(name); return; } // OK read the file and turn it into a wave object if (!wave.create(f)) { putstring_nl("Not a valid WAV"); return; } // ok time to play! start playback wave.play(); } void speak() { //check if the turret was just turned on if (powerOn == 1) { //say "hello, friend!" Serial.println("poweron"); playcomplete("POWERON.wav"); //reset the speach timer speachTimer = millis(); //clear powerOn bit powerOn = 0; //dont say anything else. return to calling function return; } //if the turret has finished talking if ((millis() - speachTimer) > speachTime) { //priority of speach strings: //1) tilted //2) seen //3) lifted //explanation: the turret doesnt target people when tiled, so tilted //must be above seen. the turret does target people when lifted, so //seen must be above tilted. tilted must be above lifted because //the tilt sensor is only activated when the lifted sensor is also //activated. the robot will never be sideways and also have its feet //on the ground. char filename[13]; int result; //if the turret has fallen over if (tilted == 1) { //reset the speach timer speachTimer = millis(); //say "I've fallen over!" tltNumber++; if (tltNumber > 12 ) { tltNumber = 1;}//set n equal to the number of files result = sprintf(filename, "TLT%d.wav", tltNumber); Serial.println("tilted"); playcomplete(filename); } //if the turret is lifted up else if (lifted == 1) { //reset the speach timer speachTimer = millis(); //say "Put me down!" lftNumber++; if (lftNumber > 9 ) { lftNumber = 1;}//set n equal to the number of files result = sprintf(filename, "LFT%d.wav", lftNumber); Serial.println("lifted"); playcomplete(filename); } //if the turret sees someone else if ((-seen + millis() > 200) && (-seen + millis() < 500)) {//put in a slight delay so that the turret doesnt say "i see you" when he is tipped over //reset the speach timer speachTimer = millis(); //say "I see you!" seeNumber++; if (seeNumber > 9 ) { seeNumber = 1;}//set n equal to the number of files result = sprintf(filename, "SEE%d.wav", seeNumber); Serial.println("seen"); playcomplete(filename); } } } void checkSensors() { //record the values of the sensors int PIRReading = analogRead(PIR_PIN); int tiltReading = digitalRead(TILT_PIN); int liftReading = digitalRead(LIFT_PIN); /* unneccessary now that it uses millis() // PIR sensor is high when there is no motion // if the PIR sensor is high if (PIRReading > 900) { // then nobody is seen seen = 0; } */ //if the PIR sensor is low if (PIRReading < 100) { if (millis() - seen > 500) { //only update it if someone hasnt been seen for a while //then somebody is seen seen = millis(); } } Serial.print(PIRReading, DEC); Serial.print("\t"); int loopValue = 0; for (loopValue = 0; loopValue < PIRReading; loopValue +=64) { Serial.print('='); } Serial.println("|"); //if the sensor state changes if (tiltReading != previousTilt) { //reset the tilt timer tiltTimer = millis(); } //if the switch has settled for a long time if ((millis() - tiltTimer) > debounceTime) { //update the turret's state tilted = !tiltReading; } //if the sensor state changes if (liftReading != previousLift) { //reset the lift timer liftTimer = millis(); } //if the switch has settled for a long time if ((millis() - liftTimer) > debounceTime) { //update the turret's state lifted = liftReading; } //keep track of the last reading previousTilt = tiltReading; previousLift = liftReading; }