Build Log: Part 15
This update is going to be about some of the electronics that I’m designing and working with to control special effects on the model – the lighting of the torp launcher and the sounds that go along with the lighting effects.
First off, let’s spell out my requirements – there are three basic sound effects I want to establish:
First: an ambient noise that will operate at all times that will provide a low-level of background effects. I’ve mixed a 13-minute MP3 of various clips from ST:TMP of scenes from the engineering deck and the shuttle bay.
Second: a music track “Enterprise Clears Moorings” from ST:WOK that will accompany a power-up lighting procedure that I have on a separate board purchased from Tenacontrols (given what I know now about programming the Arduino, I didn’t really need to buy this, but I’ve got it so I’ll use it).
Third: a torpedo sound effect that will accompany the firing sequence of lights.
(I might decide to add a fourth for going to Warp, but I haven’t decided yet.)
These sounds fit into the actions I want the little computer to do:
- Start-up. When the power comes on, it should power basic lights and take us directly into…
- Idle State. Start the ambient background noise on a cycle, which will loop endlessly when nothing else is going on.
- Power-Up. This will halt whatever else is going on, then begin a process that will match the lighting sequence as seen on ST:WOK when the Enterprise leaves drydock, and will also play the theme tune “Enterprise Clears Moorings.” After the tune is done the computer will return to (2), the idle state.
- Torpedo launch. Whatever else is going on, it should stop that and kick off the lighting sequence for launch while synchronizing the torpedo sound with the lighting. Afterwards, return to (2), idle state.
So how are we going to do this?
I’m going to assume you aren’t big on electronics, so if you know this stuff already, skip this part.
The Arduino is a small computer, with a series of input and output pins. You can program it to trigger the outputs based on what it might receive from inputs.
Certain electronic components produce current as a result of conditions around it – like changes in light, temperature, buttons being pressed, rheostats being turned, etc. These are considered “sensors” – you have several natural sensors of your own: eyes, skin, smell, etc.
Other electronic components do things when they receive current – like spin gears, light up, etc. These are called “actuators,” but more often they’re referred to by their specific function. LEDs, servomotors, transistors, etc. are all actuators.
So the Arduino, as a microcontroller, receives inputs from sensors and issues on/off to actuators. There are about a jillion other add-ons that are built specifically for the Arduino, in many cases that snap onto the Arduino itself. These are called “shields”, and they are pin-compatible with the Arduino’s rows of pins so they easily slide onto and off of the little computer.
The Arduino’s controlling circuits have “on” and “off” functions, “on” being represented by the board sending 5 Volts of current out the particular pin of the circuit. “Off” receives no current. All the outputs can operate in “digital” on/off style, and some of them can operate in “analog” mode – they’re still on/off, but they can emulate analog output by cycling a percent of the time by switching much faster than a human can perceive. So to be completely “on” they turn on 100% of the time, and to be “half” on they cycle on/off 50% of the time, etc.
Remember the lighting from the Neck section that I made for the torpedo launcher? Five lights – one for the background, then a red and white for each torpedo. The background will light up, then to simulate a torpedo launch, the red on each side will cycle up, and at the point of launch the white behind it will flash. See this video for an example:
In the video above, you see the torpedo red LEDs fade in and then go off – the fade-on is accomplished by using the analog outputs this way.
So I want to make sounds, and the easy way would normally be to pick up an MP3 player shield, but I’m a bit of a masochist, and the form factor of a full sized Arduino plus a shield is a bit tall for what I want to build as a base. Plus, it’ll be cooler this way.
What I did instead, is I bought some el-cheapo MP3 players from Amazon – they were about $2-$3 each, self-contained little units that were meant for thumb-control. I ended up with two different kinds (the first one shipped from Hong Kong and took longer than expected, so I ended up ordering a different set and when all was said and done I had both kinds). One was a bare-bones model with just controls, the second had a similar layout for its controls, and had a tiny little LCD display in it.
Internally they are both very similar, small circuit boards with a set of five button pads. Each button pad has an internal and an external connection pad, and there’s a connector disc held in place by some tape that makes it into a momentary switch (momentaries are on for a “moment,” only on so long as they’re held connected). When the buttons on the unit are pressed, the connector disc bends in and makes a connection between the inner and outer sections which results in an “on” result for as long as the button is held down.
Each one also has a 16-pin controller chip, a tiny flat battery pack, an earphone jack, an on-off dip switch, and a micro-SD card slot.
A lot of these connector pads are hooked up to the same circuit inside the MP3 player, some of them being ground, and others connecting to pins on the 16-pin chip. The connector disc shorts the pads when the button is pushed. We’re going to use this principle to make the Arduino pretend to be fingers pressing buttons. There’s only so many outputs from the Arduino though, and fortunately we only need a few functions of the MP3 player.
Those functions are:
- Navigation (forward or back)
We might also have need of:
- Volume +/-
There are a few sites on the net that describe how to hack an MP3 player like these, and they show some of the connector pin-outs and which pins they connect to on the MP3 chip. These may or may not be correct – I found a few errors when testing.
I picked up a pair cheap 2GB micro-SD cards (important to get the kind with adapters, or you may not be able to use them) for $5 on eBay, and these will serve just fine for my purpose here. Also important is to note the capacity of your MP3 player, some can handle large SDs and some can’t. You don’t need an expensive high-cap model for this purpose, and don’t blow money on SDs that are too big for your player.
As you saw in the video I’ve got the Arduino set up to trigger those lights in the right sequence for the firing, which I used transistors to control (I got five of them in a starter kit, but you can buy them really cheap on eBay or at an electronics store – they are unit “BC 547 K7 E”).
A transistor is a special actuator that basically operates as a switch. It has three legs, called collector, base, and emitter. When a little bit of current is applied to the base, the collector and the base are connected to one another. These little gems enable you to control something considerably more power-hungry than your controller board can supply. So if you were going to run a big motor and wanted to control it with the Arduino, you wouldn’t be able to get it powered up with the Arduino itself – but you’d power it from another source and run that power through the transistor. You supply the positive through the collector arm, and connect the emitter to the positive of the motor, then connect the ground for the motor to the ground for the whole system.
The base on the transistor isn’t built to take a lot of current, it only needs a little tiny trickle to trigger it. Easiest way to do that for these models of transistor is to put a 1k Ohm resistor in the path of the current from your Arduino’s pin.
Let’s go into the details of which pads do what for each of the MP3 players. We’ll start with the simpler one, which doesn’t have a display (the number represents the pin on the chip):
I think it’s important to note that you might end up with a different board or circuit layout – these things might be mass-produced in China, but they have a lot of different variations. Seriously I’d recommend creating a table as I’ve done in the next example, and finding the right wiring solution from studying that.
Each time a button is pressed, it shorts the connection between the inner and outer pad, which connects two pins on the chip to one another – and the chip responds with the function given. So, when you press “Play” on this model, it connects pins 7 and 8, so for this chip 7 + 8 = Play.
I snipped the battery off and connected leads to its wires – when the time came I’d link these to the Arduino’s 3.3V output. I also soldered new leads to the inner and outer pads of the Vol +, and the inner and outer pads of the Next button. This gives me leads attached to pins 6,7,8 and 16 of the chip. Notice that using a combination of two of any of these, I can generate any of the commands available on the control board of the player.
Using a transistor on each wire, I could wire all the emitter arms of the four transistors to a common line (which would be a “bus”), and by turning on two transistors at a time I could pretend I was pressing buttons.
Here’s the problem – this model player has a convenience feature programmed into it that turns out to be really inconvenient for me: it remembers where it left off when you last turned it off. If it’s in the middle of playing a track, it’ll remember and when you turn it back on, and it’ll resume playing in the track where it left off. My Arduino has no such memory unless I program one into it, which requires a persistent storage that would just be a huge pain in the ass to wire up and write to.
So if I had only one track that needed playing, this unit would be fine. But I need several, and that memory feature is a real bugger.
That’s where the next model came in much more handy.
The one with the LCD display happens to reset itself to “zero” when it’s powered down and then up. Whew! That makes life a lot easier for me. An added benefit, the volume control is set at a reasonable level by default, which is great (extra great since it has a weird volume control – you have to hold down the Vol while pressing >> or << to adjust the volume). Slightly less convenient, the “zero” state powers up to a menu, but this is only a minor problem because once you tap the menu button once it begins to play at the first track.
Since I have the option of starting from a zeroed state, I basically only need three functions here:
- Tap the menu button
- Move (forward or back doesn’t matter)
I wasn’t able to trace which pad went to which pin on the chip this time, so instead I used a jumper wire to map out what happens when I short any of the various pads against each other. In my map, the pads are represented by a number – 1 for the 12 O’clock button and going clockwise, 5 being for the center button, plus “i” for inner and “o” for outer, see the image here:
Using that jumper wire (holding one end to one pad, and touching the other pad to the other), here are the functions:
Pl/Pa = Play / Pause
>> = Next
<< = Back
Vol = Volume toggle (this plus >> or << adjusts volume)
Menu = Menu button
X = no function
Other things I noticed while I was making this map that I’ll need to keep in mind while programming controls for this unit:
- Back does a jump to the prior track – it does not return to zero on the current track.
- Pause only holds within a track – advancing or backing up a track takes it off pause.
- Volume, as mentioned, is a toggle that changes the << and >> circuits to change volume.
- Boot of the MP3 player takes about 2s, and lands in a menu that takes one Menu tap to exit and start playing track 1.
- Left Idle, after 30-40 seconds the LCD display turns off and requires a single button press (any button) to “wake up” and be receptive to further commands. The wake up tap elicits no response.
Based on this map, I really only need transistor-enabled connections to 1o, 2o, and 3i to produce the actions I require – I will connect the emitters of all three to 5o, which will give me Menu, Back, and Play/Pause function.
I’ll also put a transistor switch on the power for this player. I’ll snip the battery off and connect it to the Arduino’s 3.3V output and stick a transistor control on that. This gives me the ability to turn off the MP3 player and Reset it to “zero” state when I need to.
Additionally, the Tenacontrols board uses a momentary switch to trigger its power-up sequence. I’ll slap a transistor there instead of a momentary switch, and control that through the Arduino too. That enables me to control the Power-Up through software.
So now my functions are starting to shape up. I’ll need two reference points: what track I’m on, and whether I’m currently playing something. (This second one is not really necessary since I’ll be playing something all the time, but there’s a slight chance that something might go askew and since I have no ability to handle exception cases post-facto in this code, I need to establish solid control up-front.) I will have to have assumed knowledge in this little application that there are three tracks, and the order in which they appear on the storage card, because I have no real means by which to figure that out (technically I could hack further into the device to find where the LCD display gets length-of-track information and track # info, and use that, but I’m not that much of a masochist).
I’ll need to code the Arduino to do the actions described earlier in the following ways:
- Start-up. Always-on lights will be wired to the power directly so no action required there, the Arduino will Reset the MP3 player, tap Menu once, then Pause (tapping the menu automatically starts playing, so I’m establishing known control here and Pausing it). Record the play-state as paused, and record what track we’re on (the first one), then enter Idle state.
- Idle State. Check the reference sites to find what track we’re on and whether we’re currently playing or paused. Navigate to the ambient background noise by pressing the Back button an appropriate number of times, and then every 13 minutes use the Back button to re-navigate to the ambient track.
- Power-Up. Figure out where we are and whether we’re playing or paused. If playing, Pause, then navigate to the “Enterprise Clears Moorings” track. Pause Trigger the Power-Up sequence on the Tenacontrols board. Delay the right amount of time and Play the track when it will synch up properly with the lighting as seen on ST:WOK when the Enterprise leaves drydock. 1 second before the tune is done, Pause and enter (2) the idle state.
- I may amend this depending on whether I decide to “power down”, too. Not sure yet.
- Torpedo launch. Figure out where we are and whether we’re playing or paused. If playing, Pause, then navigate to the Torpedo track. Pause Trigger the code for the torpedo cycle (which will include synching the sound effects with the lights). If we’re in the middle of Powering Up, all that matters is that we disable the sound – let the lighting finish on its own, the torp will launch normally independent of all that. Afterwards, return to (2), idle state.
Some of the timing above will require manually observing and hard-coding times to get things right (particularly where buttons have to be pressed in rapid succession – I don’t know how sensitive that MP3 chip is). Once I’m satisfied that the whole thing works on my breadboard and proof-of-concept harness, I’ll move the circuitry onto a permanent board and solder it up.
I’ve also bought some inexpensive computer speakers that run on their own wall-socket plug, and a headphone extension cable. Inside the base of the model, I’ll secure the headphone cable so that it shows a port on the outside of the base. The computer speakers will plug into that, and they’ll have their own volume control, so I can adjust according to the needs of the room.
I’ll also probably try to move the code onto a different Arduino platform – the standard “Mega” version is about the size of a credit card, and although this is perfectly acceptable, I’d like to see if I can get all this working with a “Nano” size board. The “Nano” is about 2cm x 8cm, so from a form-factor perspective I could potentially move all my circuitry outside of main power directly into the secondary hull. That’s not my intention, but it’d be neat if I could manage it. The Nano also consumes less amperage than the Mega, which might be advantageous. I haven’t added up the total Amps this whole affair will draw – lights, computer boards, MP3 player – and I’m pretty sure it’ll be <2.0, but I’d still like to conserve what energy I can.
Now this is all well and good, you’re probably thinking – but I’m missing a very, very important piece to this whole puzzle. In the IT industry it’s called “HMI,” or “Human-Machine Interface.” That amounts to the method by which I or other persons will tell this system to do the stuff it knows how to do, for us. When I want it to do a power-up sequence, how do I tell it? When I want it to fire torpedoes, how do I tell it? I haven’t said anything at all about that stuff here.
I’ll settle one thing first off – there will be a main on/off switch to control the power for the entire operation. But these other items?
That’s going to be a hell of a lot cooler, and I’ll cover that in the next installment, because I haven’t got all the parts yet.