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!

11 comments:

  1. is it possible to switch between low and high voice, like it had work with currah speech 64 cartridge?

    ReplyDelete
  2. Unfortunately no; I surmise that was accomplished via an external ROM in the cartridge based on brief web searching, though I'm not positive.

    ReplyDelete
  3. But there must be a way to use it in this way. Is there any information how they managed the low speechout. It there a way to use the other ICs or a way to pitch down or up the voice? Thanks for any information.

    ReplyDelete
  4. I have found a documentation about SP0256 instructions, where I am able to pitch the voice through a 2-Bit Mode register, which should inside of the speech chip:

    http://spatula-city.org/~im14u2c/intv/tech/sp0256_instr_set.html

    so, I am not sure, could that mode set only via serial in connection?

    greets

    ReplyDelete
    Replies
    1. My guess from a brief scan is that your ROM contents would have pitch associated with each phoneme. So the cartridge probably switches between ROMs somehow. (Or switches ROM MSB address line), one set of phonemes with low, one set with high voice. You could conceivably have a massive enough ROM to store phonemes at, say 8 or 16 or 32 pitches and control the most significant address lines to the ROM by the MCU to control pitch... at least for an entire word. If you're tricky you might be able to find a way to do it per phoneme.

      Delete
  5. Thanks very much Michael, for this circuit and code! I pulled out my 30 year old SP0256-AL2 also that was sitting in my parts bin, and created this Hello World build from your blog.
    Glenn

    ReplyDelete
    Replies
    1. Fantastic! I just got a correct xtal from a guy on Parallax forums and also got a tip to search for the TTS chip on ebay, so I found one, bought it, and hoping to give it a go one of these days soon. :)

      Delete
  6. I, too built that project on the C-64. My memory of the pitch was that it was dependent on the crystal used (3.579 in your case).

    Since I am just getting back into electronics after 30 years, I don't understand how this might be changed by a microcontroller. I remember the article explaining that the original datasheet that came with the chip called for a 3.12 MHz crystal, which gave it a lower pitch than the 3.57 indicated in the article. The article explained that the 3.12 MHz crystal was rare (at least back then), so they suggested the 3.57 since you could just pick it off the shelf at Radio Shack.

    I have this chip on a breadboard packed away in a box somewhere, but I haven't seen it since I moved last (I have moved three times since I packed it away).

    I just found the SP0256-AL2 chip paired with a 3.12 MHz crystal on eBay and bought it without delay.

    I know that I can use a software solution these days, but I want that retro feel.

    ReplyDelete
  7. I just found a possible answer to the voice pitch issue: http://www.linear.com/product/LTC6900

    It's a resistor-controlled variable oscillator. It ranges from 1kHz to 20MHz (that should get you a REAL low bass voice). They say that it can be a direct replacement for a fixed crystal oscillator, so I thought you could build in a small circuit to replace X2.

    I also found a SPI programmable variable resistor IC MCP4131 (https://www.youtube.com/watch?v=_dUQOTemSJQ) that could be used to drive this variable oscillator so you can program the Arduino to change the pitch whenever you want (even while it is speaking).

    ReplyDelete
    Replies
    1. Woah that is great! Would be super sweet to get pitch control at long last!!

      Delete
  8. I finally hooked my chip up after 30+ years and broke the 3.12MHz crystal. I used a pic12f683's PWM output running @ 3.0 MHz and ran it into a resistive voltage divider through a cap in to the SPO256 xtal in. It works fine. It also runs from a 4MHz crystal I have. Pitch is raised a bit. Just so people know it's not that critical.

    ReplyDelete

Note: Only a member of this blog may post a comment.