|
|
View previous topic :: View next topic |
Author |
Message |
Bill Legge
Joined: 07 Sep 2010 Posts: 24 Location: West Australia
|
Basic I2C problem |
Posted: Mon Jan 31, 2011 9:52 pm |
|
|
I'm trying to drive the SP03 text-to-speech module from robotparts.com.au using the I2C method - and having no luck.
I do have 4.7k to Vcc on both SDA and SCL lines.
1. The module works OK with the RS232 comms.
2. I've pre-recorded 30 messages, they re-play OK with RS232.
3. The example code (in BASIC) is:' a single line command is all that is required to speak any of the 30 pre-loaded phrases. The example below shows how to speak phrase number 21.
gosub wait4shutup ' wait for last phrase to finish speaking
i2cout SDA, $c4, 0, [21] ' speak phrase number 21 and flush internal buffer
wait4shutup:
i2cin SDA, $c4, 0, [status]
if status>0 then wait4shutup
return
My attempt:
Code: | /////////////////////////////////////////////////////////////////////////////
// Project: 8722 SPO3_01\main.c //
// Author: WVL //
// Date: February 2011 //
// Outline: Test of TTS SPO3 board: //
// BIGPIC5 board with PIC18F8722 //
// Heartbeat LED onportH.0 //
// 10Mhz Xtal run at 40Mhz using PLL //
/////////////////////////////////////////////////////////////////////////////
#include <main.h>
// using second hardware i2c: SDA=PIN_D5, SCL=PIN_D6
// with 4.7k pullups on both pins
#use I2C(master,I2C2,FORCE_HW)
#define HEARTBEAT PIN_H0
void main()
{
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_4(T4_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
i2c_start();
i2c_write(0xC4); // Device address
i2c_write(0x01); // Play pre-stored message number 1
i2c_stop();
while(1){ // Just to show that we have arrived here
output_toggle(HEARTBEAT);
delay_ms(100);
}
} |
Any advice or help please. Incidentally - if you have this module, get rid of the small speaker on the module, replace with some better 8ohm speaker and the volume/quality is much better.
Regards Bill Legge _________________ Denmark in West Australia
'Where the forest meets the sea' |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 31, 2011 11:44 pm |
|
|
How do we know that hardware i2c works on the 2nd i2c channel
of the 18F8722 in your version of the compiler ? Post your version.
Try using this program to see if it can find the SP03 device on the i2c bus.
http://www.ccsinfo.com/forum/viewtopic.php?t=42368&start=4
If it can't find it, then re-write the #use i2c line in your program to use
software i2c. (Don't use the 'FAST' parameter). See if it can find the
device.
Also, sample drivers on the internet show that the Command Register
byte must be sent after the Device address byte. Then you send the
pre-stored message number. Example:
Code: |
i2c_start();
i2c_write(0xC4); // Device address
i2c_write(0x00); // Command Register
i2c_write(0x01); // Play pre-stored message number 1
i2c_stop();
|
|
|
|
Bill Legge
Joined: 07 Sep 2010 Posts: 24 Location: West Australia
|
I2C |
Posted: Tue Feb 01, 2011 3:05 am |
|
|
Thanks PCM
I have tried it with the first hardware I2C and the '12c_write(0x00)' to select the command register but no joy.
I will try the software on your link.
Thanks for your advice
regards Bill Legge _________________ Denmark in West Australia
'Where the forest meets the sea' |
|
|
Bill Legge
Joined: 07 Sep 2010 Posts: 24 Location: West Australia
|
Basic I2C |
Posted: Tue Feb 01, 2011 8:42 pm |
|
|
Thanks, I have got it working. The following code gets the SP03 to play a test message and a pre-recorded message. A fixed delay is used to wait till the first is done:
Code: |
/////////////////////////////////////////////////////////////////////////////
// Project: 8722 SP03_01\main.c //
// Author: WVL //
// Date: February 2011 //
// Outline: Test of TTS SP03 board using I2C: //
// BIGPIC5 board with PIC18F8722 //
// Heartbeat LED onportH.0 //
// 10Mhz Xtal run at 40Mhz using PLL //
/////////////////////////////////////////////////////////////////////////////
#include <main.h>
// using first hardware i2c: SDA=PIN_C4 ,SCL=PIN_C3
// using second hardware i2c: SDA=PIN_D5, SCL=PIN_D6
// with 4.7k pullups on both pins
#use I2C(MASTER,I2C1,FORCE_HW)
#define HEARTBEAT PIN_H0
void main()
{
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_4(T4_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
unsigned int8 status;
// load the text
i2c_start();
i2c_write(0xC4); // device address
i2c_write(0x00); // command register
i2c_write(0x00); // NOP
i2c_write(0x00); // volume - max, 5 is min
i2c_write(0x05); // speed - max
i2c_write(0x03); // pitch - lowest
i2c_write(0x48); // h
i2c_write(0x65); // e
i2c_write(0x6C); // l
i2c_write(0x6C); // l
i2c_write(0x6F); // o
i2c_write(0x00); // NOP
i2c_stop();
// play loaded message
i2c_start();
i2c_write(0xC4); // device address
i2c_write(0x00); // command register
i2c_write(0x40); // speak previously recorded msg "hello"
i2c_stop();
delay_ms(2000); // let previous messsage complete
// play pre-recorded message
i2c_start();
i2c_write(0xC4); // device address
i2c_write(0x00); // command register
i2c_write(10); // play pre-recorded message 10
i2c_stop();
}
|
However, I should be able to check the contents on the register and detect when the current message is finished. The device notes say:
To check to see when the SP03 has finished speaking, you can read back the command register. Whilst speaking, it will be the command that initiated the speaking, either 1-30 (0x01-0x1E) or 64 (0x40). It will be cleared to zero (0x00) when speaking is complete and the module is ready for the next phrase.
The example code in BASIC is:
wait4shutup:
i2cin SDA, $c4, 0, [status]
if status>0 then wait4shutup
return
My attempt uses:
Code: |
// wait for previous message to finish
i2c_start();
i2c_write(0xC4); // device address
i2c_write(0x00); // command register
Loop:
status = i2c_read(); // read command register, should=zero when done
if(status>0) goto Loop;
i2c_stop();
|
And does not work - any idea why?
Regards Bill Legge _________________ Denmark in West Australia
'Where the forest meets the sea' |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 01, 2011 10:55 pm |
|
|
This is more likely to work. It really should be modified to return a
result code. If it returns True, then it successfully waited for a short
time until the device "shut up". If it returns False, then a timeout period
expired without a non-zero read of the status. As it is shown below,
the device could lock-up and the program would stay in this function forever.
Code: |
void WaitForShutUp(void)
{
int8 status;
do{
i2c_start();
i2c_write(0xC4); // Device address - Write
i2c_write(0x00); // Command register
i2c_start(); // Restart
i2c_write(0xC5); // Device address - Read
status = i2c_read(0); // Read - Nack
i2c_stop();
}while(status != 0);
} |
|
|
|
Bill Legge
Joined: 07 Sep 2010 Posts: 24 Location: West Australia
|
Basic I2C |
Posted: Wed Feb 02, 2011 2:07 am |
|
|
PCM
Thank you - that worked a treat.
Code: |
void WaitForShutUp(void)
{
int8 status;
do{
i2c_start();
i2c_write(0xC4); // Device address - Write
i2c_write(0x00); // Command register
i2c_start(); // Restart
i2c_write(0xC5); // Device address - Read
status = i2c_read(0); // Read - Nack
i2c_stop();
}while(status != 0);
}
|
Will you explain why one has to do a 'restart' please? I do understand your advice about improvements: with TRUE/FALSE and timeout.
Regards Bill Legge _________________ Denmark in West Australia
'Where the forest meets the sea' |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Wed Feb 02, 2011 3:42 am |
|
|
Restart, is the standard way of turning round the I2C bus.
Since the physical address includes the direction bit, if you want to select a part, and specify a register address, then read from this register, you specify the physical address, with 'write' set (since you need to write a register address to it), write the register address, then do a restart, and specify 'read' (to turn the bus round), and can then read from the device (in this case to get the status).
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|