FEZ Spider and the SP03

Hi,

Been digging through devices I’ve bought in the past and never got round to using. How easy would it be to get this device connected to the FEZ Spider.

http://www.robot-electronics.co.uk/htm/Sp03doc.shtml

Jas

Very easy, this is FEZ :slight_smile:

The only point is that this device have rs332 levels. You need rs232 module (coming soon) or see if they expose TTL pins. I also see I2C so maybe you can use that.

I’ll have a go with the I2C. Just checked and the spider seems to power it ok:

I’ll solder something like this http://www.maplin.co.uk/0.1inch-series-straight-plug-pcb-header-1487 to the extender and have a play.

Jas

Awesome! a gadgeteer that can talk :slight_smile: Looking forward to seeing it working.

While I’m working on this, I came across this on the Gadgeteer site:

Text to Speech English, French, German - YouTube!

Looks interesting.

Jas

Love it!

I’m verry happy you are interested in my Text-To-Speech library!

If you try it, it would be great if you tell me what you think about.

Right, Parts arrived and I now have everything wired together. (First good thing was no magic blue smoke)

I used a previous post to work out pin layouts.

Extender plugged into Socket 3
SDA of device connected to Pin 8 of Extender
SCL of device connected to Pin 9 of Extender
Ground & +5v connected as required.

On power up SP03 speaks it’s default sentence.

Now onto the bit I am unsure about I2C. (Please excuse my lack of knowledge)

This is the I2C quote from the devices website:

[quote]I2C Bus Communications
Along with the 5Volt power supply, the I2C bus just requires the SDA and SCL lines. The I2C interface does not have any pull-up resistors on the board, these should be provided elsewhere, most probably with the bus master. They are required on both the SCL and SDA lines, but only once for the whole bus, not on each module. I suggest a values of 4k7 for 100KHz and 1k8 if you are going to be working up to 400KHz or higher. If your going for higher speeds than 400KHz then you must separate all bytes transmitted over the I2C bus to the SP03 with a 40uS delay. This is to give the processor time to transfer the incoming data to the buffer. By doing this we have tested the SP03 with SCL up to 1MHz.

I2C communication protocol with the speech module is the same as popular eeprom’s such as the 24C04. The SP03 only has two registers, the command register and the software revision number. To read the software revision number, first send a start bit, the module address (0XC4) with the read/write bit low, then the register number you wish to read (0x01). This is followed by a repeated start and the module address again with the read/write bit high (0XC5). You now read one byte which is the PIC software revision number and follow this with the stop bit.[/quote]

Pull up resisters? Do I need to put them in myself or are they handled by the Spider end?

I had a look at the I2C - EEPROM wiki page and duplicated that example with the address of the device (0xC4):


            //create I2C object
            //note that the netmf i2cdevice configuration requires a 7-bit address! It set the 8th R/W bit automatically.
            I2CDevice.Configuration con =
               new I2CDevice.Configuration(0xC4,400);
            I2CDevice MyI2C = new I2CDevice(con);

            // Create transactions
            // We need 2 in this example, we are reading from the device
            // First transaxrtion is writing teh "read command"
            // Second transaction is reading the data
            I2CDevice.I2CTransaction[] xActions =
               new I2CDevice.I2CTransaction[2];

            // create write buffer (we need one byte)
            byte[] RegisterNum = new byte[1] { 2 };
            xActions[0] = I2CDevice.CreateWriteTransaction(RegisterNum);
            // create read buffer to read the register
            byte[] RegisterValue = new byte[1];
            xActions[1] = I2CDevice.CreateReadTransaction(RegisterValue);

            // Now we access the I2C bus using a timeout of one second 
            // if the execute command returns zero, the transaction failed (this 
            // is a good check to make sure that you are communicating with the device correctly
            // and dont have a wiring issue or other problem with the I2C device)
            if (MyI2C.Execute(xActions, 1000) == 0)
            {
                Debug.Print("Failed to perform I2C transaction");
            }
            else
            {
                Debug.Print("Register value: " + RegisterValue[0].ToString());
            }

This gives me:

An unhandled exception of type ‘System.ArgumentException’ occurred in Microsoft.SPOT.Hardware.dll

Any help is appreciated. This is completely new territory to me :wink:

Cheers,

Jas

The fact that the documentation talks about 0xc4 and 0xc5 as addresses shows they are the 8-bit addresses not the 7-bit address for the device, so you need to change that.

That might give you the argument exception (overflow when it does the 8th bit?) but I can’t be sure.

Thisbis from the gadgeteer module builders guide:

Hi,

Thanks for the responses. I’ve put the pull up resistors in place (2.2k). I checked another piece of source code that uses I2C and this device and the address they used was 0x62.

This all worked and I managed to get the revision number back from the device. Fingers crossed while I work out how to send the speech commands :wink:

Cheers,

Jas

Got it all working bar tiny one problem.

The working bit first:

Here is the code for the class I created to control the SP03

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace FEZ_Speak
{
    class SP03
    {
        // initialse the device object
        private I2CDevice _sp03;

        // setup constants
        private const byte SP03ADDRESS = 0x62;
        private const int SP03CLOCKRATE = 100;

        // setup default speaking paramaters
        private byte _volume = 0x00;
        private byte _speed = 0x03;
        private byte _pitch = 0x05;

        // Initialise the hardware
        public SP03()
        {
            I2CDevice.Configuration config = new I2CDevice.Configuration(SP03ADDRESS, SP03CLOCKRATE);
            _sp03 = new I2CDevice(config);
        }

        // Speech properties
        public byte Volume
        {
            get { return _volume; }
            set { _volume = value; }
        }

        public byte Speed
        {
            get { return _speed; }
            set { _speed = value; }
        }

        public byte Pitch
        {
            get { return _pitch; }
            set { _pitch = value; }
        }

        // Methods
        // Say something
        public void Say(string speech)
        {
            WaitForSpeechFinish();
            I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[3];
            xActions[0] = I2CDevice.CreateWriteTransaction(GetSettings());
            xActions[1] = I2CDevice.CreateWriteTransaction(ConvertText(speech));
            xActions[2] = I2CDevice.CreateWriteTransaction(SayIt());
            if (_sp03.Execute(xActions, 1000) == 0)
            {
                Debug.Print("Failed to perform I2C transaction");
            }
        }

        private byte[] ConvertText(string text)
        {
            System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
            byte[] buffer = encoding.GetBytes(text);
            byte[] result = new byte[buffer.Length + 2];
            result[0] = 0;
            result[1] = 0;
            buffer.CopyTo(result, 2);
            return result;
        }

        private byte[] GetSettings()
        {
            byte[] speechConfig = new byte[] { 0, 0, _volume, _pitch, _speed };
            return speechConfig;
        }

        private byte[] SayIt()
        {
            return new byte[] { 0, 0x40 };
        }

        private void WaitForSpeechFinish()
        {
            bool speaking = true;

            byte[] request = new byte[1] { 0 };

            while (speaking)
            {
                byte[] response = new byte[1];
                I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[2];
                xActions[0] = I2CDevice.CreateWriteTransaction(request);
                xActions[1] = I2CDevice.CreateReadTransaction(response);
                if (response[0] == 0)
                    speaking = false;
            }
        }
    }
}

And the bit that uses it:

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;
using Microsoft.SPOT.Hardware;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace FEZ_Speak
{
    public partial class Program
    {
        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            SP03 speechUnit = new SP03();

            speechUnit.Say("Hello Tiny C L R.");
        }
    }
}

It has said the words a few times but I keep getting both the SP03 and the Spider rebooting which probably means I need a better power supply. I plugged it into my keyboard (Which has powered USB ports) and it works fine.

Here’s the proof :wink:

Better demo coming soon…

Jas

There is a small error in this piece of code:

// Speech properties
public byte Volume
{
    get { return _volume; }
    set { Volume = value; }
}

It should read:

// Speech properties
public byte Volume
{
    get { return _volume; }
    set { _volume = value; }
}

Someone is having fun :slight_smile:
You only need to plug a power connector to the DP module.

Doh! (About the Volume)

And Gus I would If I had one. (On the to buy list :wink: )

Jas

Very nice, I will try your code on FEZ Panda II. will post the results soon.