CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Basic I2C problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Bill Legge



Joined: 07 Sep 2010
Posts: 24
Location: West Australia

View user's profile Send private message

Basic I2C problem
PostPosted: Mon Jan 31, 2011 9:52 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jan 31, 2011 11:44 pm     Reply with quote

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

View user's profile Send private message

I2C
PostPosted: Tue Feb 01, 2011 3:05 am     Reply with quote

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

View user's profile Send private message

Basic I2C
PostPosted: Tue Feb 01, 2011 8:42 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Feb 01, 2011 10:55 pm     Reply with quote

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

View user's profile Send private message

Basic I2C
PostPosted: Wed Feb 02, 2011 2:07 am     Reply with quote

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: 19549

View user's profile Send private message

PostPosted: Wed Feb 02, 2011 3:42 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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