Sunday, December 26, 2010

Renaming an Applescript Xcode Project

To rename an Xcode AppleScript project, follow the steps below, based on my experience using Aleksandar Vacić's article. I needed to rename my serial communications AppleScript project. I simplified and clarified some of the steps in Aleksandar's article and made them specific to an AppleScript project.
  • Close the project in Xcode. 
  • Copy/rename the folder into new name
  • Open the new folder and rename the .applescript* and .xcodeproj files to the new name
  • Delete the build folder
  • Right click .xcodeproj and select Show package contents, which will reveal several files
  • Edit each of these files with a text editor (TextEdit, vi, Vim, Aquamacs, etc.) and replace all instances of the old name with the new name. In vi (or vim), type :.,$s/oldname/newname/g
  • Load the project file in Xcode, select  Clean all targets
  • Now build the project
_______
* You'll need to rename whatever your source code file is, like .sch as in Aleksandar's article.

Friday, December 17, 2010

SP0256-AL2 Speech With Arduino

Here's the Arduino version of a project to use the General Instruments (GI) SP0256-AL2 vintage speech synthesis chip to say "hello world". I'd previously shown how to do this with a Basic Stamp 2.


Here's what it sounds like saying, "hello world" 20101215_164333.mp3

How it works, in short, is that the GI chip must be given an 8-bit address corresponding to a vocalization.  It sends an audio signal on its digital out pin which is filtered and presented to an LM386 audio amplifier with a speaker connected.

The 8-bit address is presented to the SP0256 on pins A1-A8. The address is latched into the chip with the !ALD (Address LoaD) pin. The address represents a speech sound in the chip's internal ROM which corresponds to an English allophone (like CH, SS, LL, EH, EE, AH, ...).  The SBY (standby) pin goes low until the chip is done speaking the allophone just presented.

I used a breadboard Arduino with ATmega328P and wired the address lines to PORTC (Arduino digital pins 0..5) so that in software I could simply assign the allophone address all at once ala PORTC = address rather than a pin at a time.  I arbitrarily hooked up !ALD to PD6 (digital pin 10) and SBY to PB1 (digital pin 9).  Here's a schematic that shows the hookup.


There are many more details to hooking up the SP0256. Here's a link to the datasheet I scanned in.

SP0256-AL2.zip (5.2 MB download)

Astute readers may have noticed the IR ranger in the schematic. My current plan is to create a device that speaks random phrases whenever a Sharp infrared ranger detects the presence of an object (like a person walking by).

As for the code, it was a simple matter of porting the BS2 code to C for Arduino.  Here it is:

/* SP0256-AL2 Speech Chip
 * Control Code

 * Text: HELLO WORLD.
 * Phoneme: HH EH LL AX OW (PAUSE) WW ER1 LL PA2 DD1 (PAUSE)
 * Octal: 033 007 055 017 065 003 056 063 055 001 025 004
 * Dec: 27 7 45 15 53 3 46 51 45 1 21 4
 */

char data[64];

// PINOUT
//  SBY -> PB1 / Pin 9
// !ALD -> PD6 / Pin 10
// A6..A1 -> PD5..0 / Pin 0..5
#define SBY 9
#define ALD 10
#define LED 13

void setup()
{
  int i;
  
  // DON'T USE Serial Ports!!!

  // LOAD data  
  i = 0;
  data[i++]  = 27; //HH1
  data[i++]  = 7;  //EH
  data[i++]  = 45; //LL
  data[i++]  = 15; //AX
  data[i++]  = 53; //OW
  data[i++]  = 3;  //PA4
  data[i++]  = 46; //WW
  data[i++]  = 51; //ER1
  data[i++]  = 45; //LL
  data[i++]  = 1;  //PA2
  data[i++]  = 21; //DD1
  data[i++]  = 4;  //PA5  
  data[i++]  = 0;  //end

  // Could do: DDRD = 0b00011111;
  for (int p=0; p < 6; p++) {
    pinMode(p, OUTPUT);
  }
  pinMode(ALD, OUTPUT);
  pinMode(SBY, INPUT);
  pinMode(LED, OUTPUT); // LED
}

void loop() 
{
  int i;
  
  i = 0;
  digitalWrite(ALD, HIGH);    
  while (data[i] != 0) {
    // Set address
    PORTD = data[i];
    // Set !ADL=0 for 2usec to tell the chip to read
    digitalWrite(ALD, LOW);
    delayMicroseconds(2);
    digitalWrite(ALD, HIGH);
    i++;
    // Wait for SBY=1 (standby) to indicate chip is done speaking
    while (digitalRead(SBY) == 0);
  }
  delay(2000); // delay 2 sec between phrases
}

A little trivia / history: When I first became interested in building a robot, way back in the late 80's in the days of big hair, record players, stone knives and bear skins, Radio Shack stocked these chips on their parts shelves. I got one of the last before they sold out. I connected it to my Commodore 64 cartridge port and got the chip to say stuff. This was my first real robotics project. Whee!

Friday, December 10, 2010

Fan Motor Driver Circuit

At long last, let's revisit Pokey's fan motor driver circuit, redesign it, and get it working in real life. Previously, we modeled the original, flawed motor driver circuit in a series on SPICE.

The fan is used on Pokey, my firefighting robot, to blow out the candle flame in a Trinity Robotic Firefighting competition. The motor and blade come from an entry level RC plane. I was running it off a common, everyday, 9V alkaline battery.

Since the fan only runs in one direction, a single transistor suffices to drive the fan, rather than an H-bridge. A simple circuit can interface the driver transistor to Pokey's ATmega MCU.

What not to do. 

One
The circuit's original incarnation featured a giant NPN transistor (15A!) with the motor between emitter and ground. That limits the current through the transistor, prevents it from saturating and, as a result, reduces the voltage and current available to the motor. It also heats up the transistor something terrible.

Don't do this.

The Fix. Instead, we want to place the load between Vcc and the collector, and tie the emitter to ground. If we're using an NPN, that is...

In this common emitter configuration, we can dump as much base current into the transistor as required to keep it in saturation, minimizing Vce so the motor receives maximum voltage and power, while the transistor stays cool.

Two
Next problem is in driving the 9V circuit with a 5V microcontroller. The ATmega MCU is limited to about 40mA output current. The circuit had to step up from 40mA to 1.8A.

In the second iteration, I swapped in a more appropriate ZTX649 NPN transistor (2A, continuous) as the driver. I decided to drive the power transistor with a small signal PNP, a 2N3906.

My "thinking" was that with the base of the PNP grounded through the MCU, the circuit would turn on fully (it did) and the MCU set high would be enough to turn off the transistor (it wasn't). The circuit never shut off.

This is why prototyping before etching a circuit board is a good idea. I would've saved myself some time and hassle. I have a beautiful little circuit board... for a circuit that is totally bogus.

Don't do this either.

The Fix. The PNP needed a pull-up resistor to force it off by default, using the MCU to ground the base and turn it on. Problem is, the MCU has to turn "on" the circuit by setting output low, and turn the circuit "off" by setting the output... not high, but to high impedance. That's messier than it needs to be.

Three
I discovered that 9V batteries are not very good at delivering high current. In fact they suck. But at least they have low energy capacity. Sheesh.

These limitations are undoubtedly because 9V batteries are comprised of many small battery cells. Each cell probably has some series resistance so when you draw a lot of current, the voltage drop in the battery gets very high (on the order of 2V in this particular application).

The Fix. As soon as I strapped an 1800mAH, 6-cell, NiMH RC car battery to the fan, I knew I was done with the little 9V.  The fan is plenty strong now. Just watch the vid below.

Also, with the high current battery, I discovered that the motor draws closer to 4A steady state, not 1.8A!

What to do.

Use a PNP to drive the motor.  This seems to me like the simplest way for a lower voltage input to control a higher voltage motor.

I did some more research in my old EE books, and on the web and came across an example circuit that uses a PNP power transistor driven by an NPN transistor to interface with the MCU for a simple, clean interface: set the motor pin high to turn on the motor, low to turn it off.

That combined with some experimentation and SPICE modeling and I put together a circuit that can drive 4A without any problem, using only a few mA of current from the MCU.

I selected a TIP42 PNP transistor from Radio Shack as the driver. It's capable of driving 10A, which is overkill here, but I had the transistor on hand and I was too impatient to search for and order anything else.

The PNP emitter connects to 9V, the collector to one side of the motor. Ground the other motor pin.



Tie the PNP base to the 9V source through a pull-up resistor to force the transistor off by default, Also connect the base to the collector of the interfacing NPN, using a resistor in series to limit base current in the PNP.

The interfacing NPN base is tied to the MCU through a current limiting resistor, but is also tied to ground through a pull-down resistor to ensure the circuit is off whether connected or not.

Now, about resistor values. Pull up and pull down resistors can be 10K.  Or probably more but that's high enough that they are effectively open when the motor is on and draw very little current with the motor off.

We start with the TIP42, Q1, which has hfe=20, minimum. To calculate Ibsat, the saturation current into the base, I've seen suggestions to divide Ic by 10. So, 400mA.

You can also calculate Ib right at the edge of saturation using Ic = hfe(Ib) and then multiply by an overdrive factor of 2-10.  Ib = 4.0A / 20 = 200mA. With overdrive factor, we get 400mA-2000mA drive current.

Even 400mA is too much for many small signal TO92 transistors and 2A certainly is too much! Remember the ZTX649 NPN from above? With a 2A continuous rating and a huge hfe=200, it was perfect to drive the TIP42. So we'll use that.

Calculate the ZTX649's saturation Ibsat = Icsat / hfe * 2  = 4mA.

Now, analyze the circuit using values for Vce (per datasheet) and/or Vbe (0.6V) and find the resistances.



Model!

I used LTSpice to model the circuit to make sure I was in the ballpark. The modeled values for saturation current seemed on par with the resistances selected. I tweaked the motor resistance until Ic = 4.0A.

Prototype, Prototype, Prototype

No more etching boards until I prototype first. I built the circuit on a Sparkfun mini breadboard, and tested Vcesat, Ib for the two transistors and also tested temperature on the transistors (with my finger) and all seems reasonably ok. I haven't yet prototyped the new values I calculated above, but I will before I etch the board.

Prototype, TIP42 top right, ZTX649, lower left.
Transistors are in saturation (cool, low Vce), motor spins with about as much speed as directly connected to the battery.  Which is to say, the motor spins really fast...


Only problem, the fan sometimes comes on partially when connecting motor power with the MCU off. Good thing I didn't etch the circuit yet...

Circuit and PCB Design

Despite this glitch, I wanted to fiddle with PCB design. I used Eagle once again to draft the circuit and build the board.

With some trial and error and some tweaking I was able to get everything to fit on a 1.000" x 0.875" board. Pretty tiny for through-hole!

I added power and motor on LED indicators to the circuit as well as a 100uF capacitor to handle the initial high current draw when the motor kicks on.

Circuit diagram (without power indicator LED)
PCB layout, power indicator added
All I needed was a small battery pack with enough current capacity.  So I borrowed a 6-cell, 2/3 A NiMH pack that a friend of mine used in his RC rock crawler.  It works quite well.

Here are the LTSpice and Eagle files for the circuit:

FanMotorDriverFiles.zip