Step 4: Wire Up Motion Sensor and Servo

Here's how the motion sensor and servo are connected up.  these diagrams are done this way because I hooked all the wires in the skull up to a small project circuit board and then used CAT-5 Network Cable to run it down to the arduino.  The network cable allowed me to have more than enough wires to run everything I needed in one convenient package.
<p>151107 Naomi the Witch </p><p>(<a>http://azatheist.com/2015/11/07/fun-stuff-from-thi...</a></p><p>I made it! Sorta. This<br>year I decided to take my Halloween adventures into the world of Arduino. I saw<br>the &ldquo;Talking Arduino Halloween Skeleton&rdquo; on the Instructables.com website.<br>Halloween is the best time of year for a retired engineer and tinkerer like me.</p><p>The young men in the Intructables article were quite<br>energetic and their tutorial was wonderful. Instead of another skeleton I<br>wanted to build up a talking witch. It would be a bit of a challenge and I was<br>fortunate to have the &ldquo;Talking Arduino Halloween Skeleton&rdquo; to work from. </p><p>Naomi the talking witch<br>started out as a standard Halloween hanging prop from the Spirit Store and made in China. The original<br>prop had a voice box and glowing eyes but the voice was hard to understand. I<br>keep everything so perhaps the voice box will be used in a future project. I really wanted her<br>face and hands but I ended up using everything except for the voicebox. </p><p>The project involved<br>building an audio circuit board for the Arduino and making some special WAV<br>files for her voice. The board went together rather quickly and worked well. My<br>wife Nancy recorded the witch&rsquo;s voice clips and did a great job. There were<br>challenges. The witch&rsquo;s face was a solid chunk of plastic and I wanted her jaw<br>to move when she spoke. So I had to perform plastic surgery, for real! I used a<br>hot knife which is a #ll Exacto blade mounted on the end of a soldering iron.<br>This made the job easy. The hot blade works its way slowly through the plastic but doesn&rsquo;t<br>take a lot of force. <a href="https://www.youtube.com/watch?v=NLWPd2cLeZo&spfreload=10">Here is a<br>video of the modified face with the servo to move the jaw.</a> Building the<br>frame came next along with a foundation. She came out very close to way I had imagined<br>and was the first active prop in the <a href="https://www.youtube.com/watch?v=xi8AZpRJ-18&spfreload=10">graveyard<br>this year</a>. </p>
<p>WaveHC update for talking skeleton. </p><p>New Debugging features.</p><p>Shows voltage reading for servo tweaking. </p><p>I have not finished tweaking this yet but it does work. You may have to tweak a few things to make it work for you.</p><p>Have a happy Halloween!</p><p>#include &lt;FatReader.h&gt;</p><p>#include &lt;avr/pgmspace.h&gt;</p><p>#include &lt;SdReader.h&gt;</p><p>#include &quot;WaveHC.h&quot;</p><p>#include &quot;WaveUtil.h&quot;</p><p>#define DEBOUNCE 100</p><p>#define swPin 14</p><p>#define eyeleds 18</p><p>SdReader card; // This object holds the information for the card</p><p>FatVolume vol; // This holds the information for the partition on the card</p><p>FatReader root; // This holds the information for the volumes root directory</p><p>FatReader f;</p><p>WaveHC wave;</p><p>uint8_t dirLevel; // indent level for file/dir names (for prettyprinting)</p><p>dir_t dirBuf; </p><p>#define error(msg) error_P(PSTR(msg))</p><p>// Function definitions (we define them here, but the code is below)</p><p>int inputPin = 8; // choose the input pin (for PIR sensor)</p><p>int servoPin = 16; // choose the input pin (for Servo)</p><p>int pirState = LOW; // we start, assuming no motion detected</p><p>int val = 0; // variable for reading the pin status for motion sensor</p><p>int minPulse = 100; // minimum servo position</p><p>int maxPulse = 8200; // maximum servo position</p><p>int turnRate = 50000; // servo turn rate increment (larger value, faster rate)</p><p>int refreshTime = 3000; // time (ms) between pulses (50Hz)</p><p>int mouthchange = 6; //checks to see if mouth position needs to be changed</p><p>int randNumber; //random number variable to allow the choosing of which wav will be played</p><p>/** The Arduino will calculate these values for you **/</p><p>int centerServo; // center servo position</p><p>int pulseWidth; // servo pulse width</p><p>long lastPulse = 0; // recorded time (ms) of the last pulse</p><p>void setup() {</p><p> // set up serial port</p><p> Serial.begin(9600);</p><p> putstring(&quot;Free RAM: &quot;); // This can help with debugging, running out of RAM is bad</p><p> Serial.println(FreeRam());</p><p> pinMode(inputPin, INPUT); // declare sensor as input for PIR</p><p> pinMode(eyeleds, OUTPUT); // declare sensor as output for eyes</p><p> // set up servo pin</p><p> pinMode(servoPin, OUTPUT); // Set servo pin 18 (analog 4) as an output pin</p><p> centerServo = maxPulse - ((maxPulse - minPulse)/2);</p><p> pulseWidth = centerServo; // Give the servo a starting point (or it floats)</p><p> // set up waveshield pins</p><p> pinMode(2, OUTPUT);</p><p> pinMode(3, OUTPUT);</p><p> pinMode(4, OUTPUT);</p><p> pinMode(5, OUTPUT);</p><p> // if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you</p><p> if (!card.init()) { //play with 8 MHz spi (default faster!) </p><p> error(&quot;Card init. failed!&quot;); // Something went wrong, lets print out why</p><p> }</p><p> // enable optimize read - some cards may timeout. Disable if you're having problems</p><p> //card.partialBlockRead(true);</p><p>// Now we will look for a FAT partition!</p><p> uint8_t part;</p><p> for (part = 0; part &lt; 5; part++) { // we have up to 5 slots to look in</p><p> if (vol.init(card, part)) </p><p> break; // we found one, lets bail</p><p> }</p><p> if (part == 5) { // if we ended up not finding one :(</p><p> putstring_nl(&quot;No valid FAT partition!&quot;);</p><p> sdErrorCheck(); // Something went wrong, lets print out why</p><p> while(1); // then 'halt' - do nothing!</p><p> }</p><p>putstring(&quot;Using partition &quot;);</p><p> Serial.print(part, DEC);</p><p> putstring(&quot;, type is FAT&quot;);</p><p> Serial.println(vol.fatType(),DEC); // FAT16 or FAT32?</p><p> // Try to open the root directory</p><p> if (!root.openRoot(vol)) {</p><p> putstring_nl(&quot;Can't open root dir!&quot;); // Something went wrong,</p><p> while(1); // then 'halt' - do nothing!</p><p> }</p><p> // Whew! We got past the tough parts.</p><p> putstring_nl(&quot;Ready!&quot;);</p><p>}</p><p>void loop() </p><p>{ </p><p> val = digitalRead(inputPin);</p><p> if (val == HIGH) </p><p> { </p><p> if (pirState == LOW) </p><p> {</p><p> // we have just turned on</p><p> Serial.println(&quot;Motion!&quot;);</p><p> //Turn eyes on</p><p> digitalWrite(eyeleds, HIGH);</p><p> // Play a sound: </p><p> randNumber = 0;</p><p> randNumber = random(3);</p><p>if (randNumber &gt;= 1)</p><p>{</p><p> randNumber = random(3);</p><p> randNumber = randNumber + 1;</p><p> Serial.println(randNumber);</p><p> if (randNumber == 1)</p><p> {</p><p> playcomplete(&quot;11.WAV&quot;);</p><p> }</p><p> else if (randNumber == 2)</p><p> {</p><p> playcomplete(&quot;2.WAV&quot;);</p><p> }</p><p> else if (randNumber == 3)</p><p> {</p><p> playcomplete(&quot;13.WAV&quot;);</p><p> }</p><p> else if (randNumber == 4)</p><p> {</p><p> playcomplete(&quot;1.WAV&quot;);</p><p> }</p><p>}</p><p> pirState = HIGH;</p><p> }</p><p> }</p><p> else </p><p> {</p><p> if (pirState == HIGH)</p><p> {</p><p> digitalWrite(eyeleds, LOW);</p><p> // we have just turned off</p><p> Serial.println(&quot;Motion ended!&quot;);</p><p> // We only want to print on the output change, not state</p><p> pirState = LOW;</p><p> }</p><p> }</p><p>}</p><p>void playcomplete(char *name) </p><p>{</p><p> char i;</p><p> uint8_t volume;</p><p> int v2;</p><p> playfile(name);</p><p> while (wave.isplaying) </p><p> {</p><p> volume = 0;</p><p> for (i=0; i&lt;8; i++) </p><p> {</p><p> v2 = analogRead(1);</p><p> delay(5);</p><p> }</p><p> if (v2 &lt;= 270) </p><p> {</p><p> pulseWidth = 1600;</p><p> mouthchange = 1;</p><p> Serial.println(v2);</p><p> } </p><p> else if (v2 &lt;= 250)</p><p> {</p><p> pulseWidth = 700;</p><p> mouthchange = 1;</p><p> Serial.println(v2);</p><p> }</p><p> else</p><p> {</p><p> pulseWidth = 300;</p><p> mouthchange = 1;</p><p> Serial.println(v2);</p><p> }</p><p> digitalWrite(servoPin, HIGH); // start the pulse</p><p> delayMicroseconds(pulseWidth); // pulse width</p><p> digitalWrite(servoPin, LOW); // stop the pulse</p><p> }</p><p> digitalWrite(eyeleds, HIGH);</p><p> // we have just turned off </p><p>}</p><p>void playfile(char *name) {</p><p> // see if the wave object is currently doing something</p><p> if (wave.isplaying) {// already playing something, so stop it!</p><p> wave.stop(); // stop it</p><p> }</p><p> // look in the root directory and open the file</p><p> if (!f.open(root, name)) {</p><p> putstring(&quot;Couldn't open file &quot;); Serial.print(name); return;</p><p> }</p><p> // OK read the file and turn it into a wave object</p><p> if (!wave.create(f)) {</p><p> putstring_nl(&quot;Not a valid WAV&quot;); return;</p><p> }</p><p> // ok time to play! start playback</p><p> wave.play();</p><p>}</p><p>void error_P(const char *str) {</p><p> PgmPrint(&quot;Error: &quot;);</p><p> SerialPrint_P(str);</p><p> sdErrorCheck();</p><p> while(1);</p><p>}</p><p>void sdErrorCheck(void) {</p><p> if (!card.errorCode()) return;</p><p> PgmPrint(&quot;\r\nSD I/O error: &quot;);</p><p> Serial.print(card.errorCode(), HEX);</p><p> PgmPrint(&quot;, &quot;);</p><p> Serial.println(card.errorData(), HEX);</p><p> while(1);</p><p>}</p>
<p>Thanks for the update! I built this and have it mostly working, except I used a digital servo. I can't include the Servo library because of a conflict with WaveHC. It's pretty still works somehow, but the mouth opens way too much on the initial pulse. Any ideas how to adjust that?</p>
I need hints on communicqtion wiyh getti freq<br>
<p>Oh and thank you so much! This tutorial is awesome! I really hope you make more videos and tutorials in the future!</p>
Ivogt I just got the WaveHC code working last night. I'll post the update after I get finish updating the servo code if I can. Probably a day or two.
<p>Has any one modified this code to work with the latest version of WaveHC library?<br>Newbie needs help. Thanks.</p>
<p>Very spooky! Love it.</p>
<p>Spooky! Nice work.</p>
<p>I've met the creator of arduino and he signed my shirt</p>
getting to be that time again. planning Halloween stuff for this year. <br> <br>how hard would it be to combine the mouth movement of this project with LED backpacks like here? <br>http://learn.adafruit.com/animating-multiple-led-backpacks <br> <br>I'd love to have the mouth move and also have the creepy moving LED eyes in RED.
Since you'd be using Adafruit products for both the sound playback and the LED eyes, why not ask on their forum?
Nice Instructable, and the project looks good. But....For less money than what you spent for the 2 Arduno boards and the aggrivation of putting them together you could have bought a Scary Terry Audio servo driver board From Cowalicious for $42.95 which is pretty much plug and play....Your Arduino kit comes to about $56.94. Just Curious as to why you did it that way.
Hey!<br>Very nice instructable! I am searching a while, could please tell me somebody where to buy a skull like the one in the instructable. Best will be when i can buy it in germany or austria.<br>Thanks!
Have you tried: http://www.skeleton-factory.com/ ?
Has anyone converted this for use with the WaveHC library, by any chance? I'm a total newbie to Arduino and stumbling through it at the moment.
is there a way to make the servo quiet it seems a litlle loud
i get 9 error #include expects filename <br> <br>sorry my key boards broke so some keys dont work, but yeah i compile this and get that error message is there anything i have to add, i need this by halloween.
Make sure you include Ladyada's AF_Wave library from her site for the Wave Shield <br>Also missing in the code here, there are 2 Include statements that are blank right at the top of the code. &quot;Instructables doesnt like the &quot;&lt;&gt;&quot; symbols posted in the code and it dropped the information after the #include statement. I typed out the names of the symbols here before and after the information that is required. <br> <br>The first one should be #include (less than symbol) AF_Wave.h (greater than symbol) <br>The second one should be &quot;#include (less than symbol)avr/pgmspace.h <br>(greater than symbol) <br>It took me a bit to figure out (i'm new to arduino and not a programmer) looking at other examples of code lead me to change those two include statements <br>I loaded the code last night (without a servo hooked up yet) and the wav portion works no problem. <br> <br>Cheers
Great Instructable.&nbsp;Anxious to re-task Mr. Skull!&nbsp; When I try to verify the code on my Arduino, I get an error (looking for a particular filename). Any Ideas?
could be a library you are missing.&nbsp; Take that error that you are getting and type it into google.&nbsp; Whenever I&nbsp;had an error happen like that I was missing an arduino library I&nbsp;just had to download and throw into a folder.&nbsp; Good luck!&nbsp; Hope this helps!<br />
I love it, this is totally awesome!&nbsp; Someone else mentioned the waveshield recently, and after seeing what you've done with it, I'm totally considering buying one.&nbsp; <br /> <br /> I'm pretty new at all this arduino stuff, and I'd like to see the code you used. &nbsp;Can you post it?<br /> <br /> Thanks!<br />
see my reply to bill2009.&nbsp; I don't know why it isn't showing up for some people, but it's there in step 8!&nbsp; I'll attach it as a text file in that step too I guess!&nbsp; I'll also message you a copy of it.<br />
for some rason I can't see the code.&nbsp; Is it posted directly somewhere?
it's posted in step 8 and is visible on my laptop here in firefox.&nbsp; I had the same problem you were having when I tried to pull it up at my work.&nbsp;&nbsp; I don't know why that is.&nbsp; I'll send you a message with the code in it.<br />
Might also be cool to use the voltage from the wav shield to set how wide the mouth opens. Open the mouth wider as the sound gets louder. I'd have to try it out, but in my head at least it seems like this would make the mouth movement a little more natural.<br />
I totally get what you're saying.&nbsp; It may look better.&nbsp; Try it and let me know!&nbsp; haha.<br />
A trim pot might have been better, taken off the other lead of the resistor.&nbsp; This way you could adjust the sensitivity to the audio.<br />
you can still adjust the sensitivity using the code by just telling it at what audio level the mouth should open.&nbsp; So you could do it as a hardware or a software solution.<br />
HAHA:&nbsp; &quot;Hey kids, come here, let me tickle your funny bone.&quot;<br />
This is really cool.&nbsp; Wish I saw it sooner.<br />
get an early jump on next year!&nbsp; haha<br />
video has now been embedded!&nbsp; Take a look!<br />
Awesome, but needs video!<br />
a great friend of mine, and a great youtuber, is putting up a video documenting the build as well as showing it running.&nbsp; Should be done sometime after 8pm CST&nbsp;10-29-09.&nbsp; Check back then as I'll put a link to it in the first step!<br />
You can even embed the video. Just click the &quot;Video&quot; button in the editor.<br />

About This Instructable


147 favorites


More by samseide: Mini Arcade Machines! Halloween Time Machine Morris the Hunchback Costume
Add instructable to: