Image
Nate Craddock Headshot

Nate Craddock

Media Creator, Electronics Hobbyist, Developer, Leader, and Speaker

I'm going to be doing some updates to the animatronic skeleton I built last year for Halloween.  One issue I ran into at the last minute last year was that I didn't have enough memory to initially load all the animation sequences for both songs and patter.  I did a Band-Aid and just loaded the patter, but this year, we want to make our animatronic sing, so I will be doing some updates to load in the animation files on demand to accomplish this.  Additionally, we'll be doing less hands-on running of the animation sequences,. There will be a jukebox mode so the skeleton can run without intervention.

Here's the status of last year's code.  I'll rework this repo to clean up and remove unused options.

https://github.com/darthmario/halloween23-skelleton

Image
skeleton

I'm going to do a whole post / video on this at some point, but for now, just going to place this here. Along with this link for a vintage article describing exactly the same thing

From some amiga bbs:

> How did you do it?  I mean, connect your Amiga 1200 to your Sony
> KV25-XBR?  Nobody I've spoken with at any computer store or Sony dealer has
> any idea where to get a cable to connect a computer to the 34-pin RGB port
> on my Sony.  I even called Sony customer service, and those folks are real
> polite but even THEY don't have a clue.

I went to a Sony Service Center back in 1985 and purchased the
"KV-25XBR/RM-724/APM-X3U Service Manual".  It has schematics and lists
two options for the RGB MULTI INPUT:

  1) The PX-34 RGB multi connector plugs into the back of the TV.
     It has to be soldered on to the end of a cable that brings RGB
     data to the TV.

  2) The SMK-0001 cable has a PX-34 at one end and a "microcomputer
     connector" at the other.  (From the drawing, it is not obvious
     whether this is a DB-9 or some other style of connector.  The
     microcomputer in the diagram looks more like a TI-99 than an IBM-PC.)

The PX-34 was listed for more than $30, and there was no guarentee that the
SMK-0001 had the connectors I needed.  So I built my own.

I purchased a standard 34-pin connector with flat ribbon cable from a
computer store, and wired up a box that has an Amiga-compatible 9-pin
video connector, 6 RCA phono jacks (red green blue sync left right), and
2 switches.  One switch selects sync-on-green versus separate sync, the
other enables TV audio while in RGB mode.  The Amiga has a 23-pin video
connector, so I had to use either a DB-23 to DB-9 cable, or use a
genlock (which uses a 9-pin output connector).

9-pin Video connector (used by A2002 and A1084 monitors, AmiGen genlock):
  01 = Sync ground	06 = no connection
  02 = RGB ground	07 = combined Sync
  03 = Red		08 = no connection
  04 = Green		09 = no connection
  05 = Blue
	07+01 go to a black RCA jack labeled "Sync"
	03+02 go to a red   RCA jack labeled "Red"
	04+02 go to a green RCA jack labeled "Green"
	05+02 go to a blue  RCA jack labeled "Blue"

On a 23-pin Video connector, 03=Red, 04=Green, 05=Blue, 10=Csync, and
16-20 are all ground.  Do not use 11=Hsync or 12=Vsync in this case.
(On the 9-pin male to 9-pin female cable I was using, I took some wire
cutters to pins 06, 08 and 09, since their signals confused my A2002
monitor.)

I planned on adding a second DB-9 for CGA (TTL) monitor, but never got
around to it.  The original IBM PC used 1=GND, 2=unused, 3=RED, 4=GREEN,
5=BLUE, 6=INTENSITY, 7=unused, 8=H-SYNC, 9=V-SYNC.

34-pin RGB connector:
  01 = +5V		18 = no connection
  02 = +5V		19 = no connection
  03 = ground		20 = Audio, Right
  04 = ground		21 = Mode Switch (digital RGB vs analog RGB)
  05 = Remote Ctl gnd	22 = no connection
  06 = Composite gnd	23 = Video (composite)
  07 = Audio ground	24 = Audio, Left
  08 = Red ground	25 = Red
  09 = Green ground	26 = Green
  10 = Blue ground	27 = Blue
  11 = Ground		28 = no connection
  12 = Blank ground	29 = Blanking
  13 = Hsync ground	30 = H-sync
  14 = no connection	31 = V-sync
  15 = Vsync ground	32 = no connection
  16 = Ground		33 = RGB vs Normal
  17 = no connection	34 = Audio Select (+5v enables audio)

01+34 go to a SPST switch (to enable audio while in RGB mode)
20+03 go to a red RCA jack labeled "Right"
24+07 go to a white RCA jack labeled "Left"
25+08, 26+09, 27+10 go to the Red, Green, Blue jacks (and Amiga connector)
13 goes to the Sync jack ground, 30 goes to a SPDT switch, which connects
it to either the Sync jack (separate) or the Green jack (sync-on-green)

The phono jacks are useable by a "GIGI" (DEC VK100 terminal with BASIC).
The 9-pin connector is useable by an Amiga 23-pin to 9-pin cable, or
by the 9-pin output of an AmiGen genlock.

See also the "Sci.Electronics.Repair FAQ on Pinouts" 
http://www.repairfaq.org/REPAIR/F_Pinouts3.html#PINOUTS_015
for "Sony RGB Multi Input (found on KV-25XBR TV's).

Links to other documents:

 *) http://www.hut.fi/Misc/Electronics/circuits/vga2tv/ for details
	on converting VGA video (15 pin) to NTSC (CGA, 9 pin).

 *) http://home.att.net/~billhudson/rybyrgb.pdf has a component (YPrPb)
	to RGB converter.

 *) http://elm-chan.org/works/yuv2rgb/report.html - look for "Circuit Diagram
	3 (Simplified Lv.2) BG part is omitted (Sync on RGB)".

-- 
Joe Smith  <js-cgi@inwap.com>  CA license plate: "POPJ P,"  36-bits forever!
Humorous disclaimer: "My Amiga 3000 speaks for me."    http://www.inwap.com/

 

I've meant to fix this Amiga 500 for a few years now.  I had originally stopped working on it when we moved into the house and it's only been lately that I've been able to return to it.

I originally tried to update kickstart 3.1 with a board to make this version of the motherboard work correctly with this kickstart ROM.I originally tried to update Kickstart 3.1 with a board to make this motherboard version work correctly with this Kickstart ROM.  This caused a black screen during boot.  I removed the 3.1 Rom and returned to the 1.2 Rom, which still didn't work/stopped on a yellow screen.  Somehow I zapped the machine and now it all is working correctly.  It's very strange, but it's all good. I tested the floppy drive and it's working fine.  The last hurdle is getting the keyboard working correctly & building out a cable for analog RGB.

Image

I have the case of a Mac Cube I've been meaning to turn into a Linux box and I'm tempted to buy one of the trash can 2013 Power Macs since the prices are pretty damn low on eBay nowadays. There are a ton of fun weirdo machines out there!

Each machine listed below was manufactured and sold to the public—no prototypes here. These computers highlight not only Apple's innovative spirit but also its willingness to take risks and experiment with design and functionality. It's worth noting that what is "weird" in this case is a matter of opinion, so you might have your own personal picks that we missed. If that's the case, let us know in the comments. And we'd love to hear what the Macintosh means to you on this 40th anniversary.

Image

It’s coming up on October 31st again which means it’s time for our household to start building out our Halloween decorations. We enjoy Halloween in our neighborhood. There’s quite a few kids on our street and we get into the spirit.

Now when I say get into the spirit, I mean that through the lens of a child. There are plenty of houses that go for the scary theme. For us, it’s more a matter of spooky. The other houses can be Universal Horror Nights, we want to be Disney’s spooky time and aim for the feel of the Haunted Mansion at Disney… spooky and not scary. It should be a little scary for the little tots, but not so scary that they can’t come and get their candy.

Last year we did a pretty great theme based around toxic waste and mutant candy corns.

We love the fact that you can pretty much make all of this stuff yourselves with UV paint, plaster of Paris, Home Depot runs, as well as some simple motors to drive the animatronics.

Image

We also do a custom window animations that we love to make and is something that requires the design and skills of both my wife and myself.

Image

This year we’re going to do something a little different, still the same kind of goody atmostphere, but something that’s a little more involved from the animatronics and staging.

I've been waiting to take delivery of my 2023 Bronco for a while now.  It started in July of 2021 when I put my original order in and then waited patiently (like a year and a half).  I had to change my color to eruption green (which I love) and dropped the tow package, but I'm in love.

One cool thing Ford did was send all us order holders a photo of our Bronco coming off the line.

Image

And here's the goodbye to my trusty old Honda CRZ that lasted me almost a decade.  This car had almost 100,000 miles on it and still was pretty damn solid.

Image

Big thanks to Lief Johnson Truck City for being a great dealer to work with.

Image
Tags:

For my Halloween costume this year (2022), My wife and I decided to do a whole house theme. Early on, we decided to do something with Mystery Science Theater 3000. Not only do we love the show, but it (along with Futurama) was a show we both loved and had contributed to both of us staying sane during COVID lockdowns.

I'll cover some of our house decorations in a separate post, but Disney's Haunted Mansion highly influences our idea of a house decorated for Halloween. We don't want it to be that, but we want it to feel spooky and fun rather than scary. Creepy and fun are partially our sensibilities, but also because we have a lot of young children.

Yes, I'm A Nerd & An MST3K Fan

Let's talk about the costume with all that out of the way!

Image

The central part of my costume was pretty easy to put together. I just purchased the items from this list (they're all readily available on Amazon, except for the Gizmonics patch found here)

The best part of this costume was that it was an excuse to assemble a Tom Servo kit. There are two robots I've always wanted to build: replicas of Tom Servo and K9. K9 will happen someday, but I was able to do Tom Servo for this costume. Now, I've got a robotic buddy to serve as my rubber duck for debugging.

Image

You may notice that his red color is not the original color. I ordered the matching color, but it took three months to arrive, so I used what I had. This color represents the colors I saw on my old tube television while watching MST3K when it aired.

Building a Servo, Tom Servo

I got the kit for Tom Servo here. It's a great kit and produces a screen-accurate version you can puppeteer. The instructions are unambiguous, but I got a little help from this excellent instructional video. It frames the instructional video part like an episode of MST3K. Genius!

Remote video URL

Now, I didn't just want a puppet I could carry around. That would be awesome, but I wanted to take it to the next level. I wanted a puppet that I could also set up self-contained to play a selection of prerecorded Tom Servo clips!

The Animatronic Concept

So, I sat down and determined some objectives and specs for the project.

  1. I should still be able to use Tom Servo as a puppet in addition to some amount of animation.
  2. Tom Servo should be self-contained and powered by a battery pack.
  3. Use one of the multitude of Arduino Pro Minis I ended up with.
  4. The project should use one button to play a Tom Servo clip randomly.
  5. The project should have built-in speakers to play the sound files.

Some of the work around this, particularly the servos and Arduino code I would start with, were based on the eyeball pumpkins I made for the previous year - Halloween Fun 2021 - The Tiki-themed Mahalloween.

Additionally, I knew that I'd need some type of external mp3 player & simple amplifier setup since there was going to be no way to play mp3 files directly from the Arduino. That and there's only so much onboard storage on the Arduino Itself.

After a bit of research, I ran across this fantastic little board that also happened to have an Arduino Library, the DFPlayer Mini:

Image

This little board seemed extraordinary. Additionally, I knew if I got in a pinch, it could be controlled by the Arduino via serial, so I could program something myself if needed. Here's an excellent little video on it.

Putting the Board Together

I could quickly source the rest of the parts I needed beyond the Arduino and DFPlayer Mini:

  1. Perf / Vero board - I had a bunch of these. I like to use these as they're simpler to work with than plain through-hole boards. With a little layout, you can use minimal wires and soldering to put these together. The main drawback is that your board may need to be more compact.
  2. Male and Female headers - already had.
  3. Capacitors - always have a bunch of these on hand.
  4. Resistors - yup, same as #3.
  5. Wires - I got too many.
  6. Tactile button - yeah, I got lots in lots of sizes.
  7. Battery holder - I ordered this from Amazon.
  8. Speakers - I ordered this from Amazon.

I had a general idea of what I was building and how I would go about it. I also had the information on what pins I would connect and how to power them. So, I created an initial version with all connections and boards on a breadboard to run some initial tests, like just triggering one track to play from the DFPlayer Mini on the board.

Image

While most of the functionality worked as expected, I ran into a few issues with this layout that took some research online. While the DFPlayer Mini worked fine after a short period, around 5 minutes, it would start to have a pretty bad popping sound from the speakers. What was wrong? I did a bunch of research and found others with the same problem. Some recommendations included adding capacitors and resistors to help smooth the current. I tried these with varying success.

After further digging, I found a couple of reports that while the DFPlayer Mini is rated for between 3.3V to 5V, it likes a steady 3.3V. However, using 3.3V presented a little problem. I had a 5V Adruino and planned to have a common 5V rail and ground plane for everything. I did a minor redesign and added a little 3.3 voltage regulator. Adding the voltage regulator worked like a charm and proved that I'm still learning; I don't know what I'm doing! That's how I learn: by trying things and breaking or being willing to understand why something isn't working. I do know my limits, though, and I never would try to wing it with things that could blow up or cause serious harm.

Anyway, now I have my working prototype and can assemble the board.

Image
Programming the Tom Servo

With the hardware at least partially resolved, it was time to start programming the Tom Servo. I used the Arduino IDE to program this as the programming would be relatively simple, and I would rely on Arduino libraries a lot: for the DFPlayer, for the Servo control, for the button and debounce.

I've put the code up into a public GitHub repository here. To approach the programming of the microcontroller, I broke the tasks down into a few different blocks as it's easier to work each part of the problem before gluing it all together into the overall main program.

So this program broke down into three main parts:

  1. Respond to the button click and select a random number from within the count of audio clips.
  2. Take the random number and select that number to play from the SD card of the DFPlayer Mini.
  3. Use that random number to pull up the array representing the keyframes (mouth open and mouth closed) that sync to the playing track.

It's important to remember that the DFPlayer will play its audio on its hardware while the Arduino handles the timing of the keyframes. While this doesn't mean anything in practice with this project, there could be a drift between the audio playing and the keyframes.

#1 Responding to the button click

This part was pretty straightforward:

void handleEvent(AceButton* /*button*/, uint8_t eventType, uint8_t /*buttonState*/) {
  // get a random number to play
  switch (eventType) {
    case AceButton::kEventPressed:
      randNumber = random(21);
      // cancel all servo timers
      timer.cancel();
      playQuote(randNumber);
      break;
  }
}

I chose to use AceButton as its API was easy to use and offered the button states and functionality I wanted, particularly debounce. Also, I didn't need to custom-code this.

This function handles the button click when pressed and selects a random number in the range of sound clips I have defined. The range is static. 

Next up, we'll cancel all timers related to the servos. In the next block, we'll get into more detail on the animation function.

Finally, we'll call the playQuote function with the random number we generated earlier.

#2 Setting up the animation

// play audio and sync servos
void playQuote(byte clip) {
  //grab the array related to the item on display
  for (int i = 0; i < rows; i++) {
    animationCol1 = pgm_read_word_near(animations[clip][i]+0);
    animationCol2 = pgm_read_word_near(animations[clip][i]+1);   
    if(animationCol1 != 0){
      timer.in(animationCol1, moveServo, animationCol2);
    }
  }
  myDFPlayer.play(clip+1);  //Play the selected mp3
}

Now, we get to the real meat of this. This function loads up the keyframes for the specific clip, sets up a bunch of timers for each animation keyframe, and then triggers the DFPlayer to play the audio clip. Let's walk through this!

First, you'll notice that we're going to loop through something called rows. What is this? We've predefined our clips and animations in a multidimensional array in the file audiosync.h. Here's a sample of that file to get an idea.

#ifndef AUDIOSYNC_h
#define AUDIOSYNC_hs
#include <Arduino.h>
const PROGMEM int clips = 21;
const PROGMEM int rows = 71;
const PROGMEM int columns = 2;
const PROGMEM int animations[clips][ rows ][ columns ] = {
  {
    {20, 0},
    {60, 1},
    {120, 0},
    {160, 1},
    {200, 0},
    {400, 1},
    {460, 0},
    {500, 1},
    {560, 0},
    {600, 1},
    {920, 0},
    {960, 1},
    {1280, 0},
    {2260, 1},
    {2380, 0},
    {2460, 1},
    {2560, 0},
    {2640, 1},
    {2700, 0},
    {2740, 1},
    {2820, 0},
    {2860, 1},
    {2960, 0},
    {3020, 1},
    {3160, 0},
    {3220, 1},
    {3440, 0}
  }
}

This 3D array contains:

  1. The first level contains an array where the index correlates to a specific audio clip.
  2. The next level contains an array of each keyframe for that clip.
  3. Finally, we have an array that reflects the time and state of the servo at that time (0 for closed and 1 for open). The second entry reads that at 60 milliseconds, the servo that controls the mouth should be in the open state.

At the top of this file, we declare the array max sizes we'll need to store all these attributes, where we get the clip, row, and column counts. For our purposes, we don't care if some of the arrays are smaller than what we define.

Now, back to the function that is using these:

// play audio and sync servos
void playQuote(byte clip) {
  //grab the array related to the item on display
  for (int i = 0; i < rows; i++) {
    animationCol1 = pgm_read_word_near(animations[clip][i]+0);
    animationCol2 = pgm_read_word_near(animations[clip][i]+1);   
    if(animationCol1 != 0){
      timer.in(animationCol1, moveServo, animationCol2);
    }
  }
  myDFPlayer.play(clip+1);  //Play the selected mp3
}

So, we will loop through the array referenced by the clip number we chose previously to set up our animation.

The first thing to notice is that we will extract two variables from the clip keyframes. First, we want to get the millisecond timing (animationCol1), and second, we get the servo state (AnimationCol2, which represents the open or closed mouth state). You may have noticed that we're using a method called pgm_read_word_near(). We use this because we're not reading this variable from the Arduino RAM but from the Arduino flash memory. I had to go this route because the animation keyframe array was too large for the Arduino's limited onboard RAM. Apparently, on newer Arduino boards, you can also set a variable as a const, and it will use this method. I have yet to try that with this code. For more information, see here.

The second thing to note here is what we're doing in this loop with the milliseconds, and the servo mouth state is setting some timers to run the moveServo function later. The function uses the arduino-timer library to set up some non-blocking timers for later. Using a timer is a concept familiar to anyone who's done this in JavaScript. It's pretty straightforward to use; essentially, we set up the timer with the time it should run, the callback to use, and the data to send the callback. In our use case, we set it in this line:

timer.in(animationCol1, moveServo, animationCol2);

When the Adruino hits the timer, it calls this function to determine what to send the servo:

bool moveServo(int argument) {
  if (argument == 0) {
    myServo.write(openDeg);
  } else {
    myServo.write(closedDeg);
  }
  return false; // to repeat the action - false to stop
}

The argument sent here is whether the mouth should be open or closed. We set the openDeg and closedDeg at the top of the Arduino sketch:

// Variables will change:
byte fileCount;
byte openDeg = 100;
byte closedDeg = 0;
byte randNumber;
int animationCol1;
int animationCol2;

One additional note on all variables within an Arduino sketch and for microcontrollers in general: they are resource-limited devices. While we may not worry about using extra bytes when we're building something for the web or our home computers, we have to be very aware of that in this context. Choosing appropriate variable types is very important, as a few bytes could be the difference between doing what we want or not being able to build and deploy to the microcontroller.

 #3 Playing the MP3

The last thing we must do is trigger the DFPlayer Mini to play the file we want. Triggering the DFPlayer Mini is handled by a straightforward call using the DFPlayer library:

myDFPlayer.play(clip+1);  //Play the selected mp3

Every time I set up one of these DFPlayer minis, there are little quirks with the file layout on the device. I only have a few tips for these quirks other than trying different ways of setting up the file layout and how you call the files. Additionally, I always buy in multiples. Depending on the source, you may get some that don't work.

And now we're done!

I ended up putting all the electronics in the hover skirt of the Tom Servo replica. I want to rework the button placement so it's a little easier to get to and rethink how I'm attaching the battery pack. It had fallen out multiple times and is not in this photo.

Image

I'll be adding a video of the actual robot in action here at a later date.

Now that we're new to the neighborhood we wanted to something fun for Halloween.  We decided to take a two pronged approach, create some eyeball animatronic pumpkins and do a custom window animation.

The eyeball pumpkins camout out pretty great.  I made these with some cheap servos and arduinos.

Remote video URL
Remote video URL

I followed a lot of the tutorials on how to build these from here. I did find that all of these tutorials had the arduino powering the servos, which can work for a few, but when you have 8 or so you're not going to be able to draw enough power right from the arduino.  I ended up setting up an external supply for the arduino which also had a separate power rail to drive all the eyeball servos.  Someday I'll post the fritzing and code for these.  Nothing that intersting though.

Image

More fun was a collab my wife and I did on our custom window animation.  She handled the design and all the skilled drawing.  I took it into after effects and did the animation loop.  I love the way this looked.

Remote video URL

Let's check out some new hardware I've purchased over the past couple months.  A new power supply, monitor, some memory upgrades.  All rad.

I also give a visit to Funspot in New Hampshire, home to a huge collection of arcade games

Remote video URL

If you like the channel, please consider supporting me on Patreon

Special Thanks to:

  • Casey Craddock
  • Alan Narup

Products in this video:

Music Referral

Music used in this video: