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

I2C master and 2 slaves, getting wrong ADC values !!!
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

I2C master and 2 slaves, getting wrong ADC values !!!
PostPosted: Fri Jul 13, 2012 3:41 pm     Reply with quote

Hi guys, I'm just using the same code written by pcmprogrammer, but with two slaves and getting wrong values, when the microcontroller starts it gives the correct value but then immediately changes to 255 for ever !!!.

However, when I request data from slave_1 only it works, and the same when I only request data form slave_2 it gives the correct values.

So why can't I use both of them at the same time to get correct values?

This the master code:
Code:

#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#include "lcd.c"
   
#define SLAVE1_WRT_ADDR   0x12
#define SLAVE1_READ_ADDR  0x13

#define SLAVE2_WRT_ADDR   0x14
#define SLAVE2_READ_ADDR  0x15

//====================================
void main()
{
int8 data; //stores data sent by slave_1
int8 data_2; //stores data sent by slave_2

lcd_init();

while(1)
  {
   //requesting data form slave_1
   i2c_start();
   i2c_write(SLAVE1_READ_ADDR);
   data = i2c_read(0);
   i2c_stop(); 

   printf("Slave_1 ADC: %u \n\r", data); //displaying data sent by slave_1 on RS232

   delay_ms(500);
   
   //requesting data form slave_2
   i2c_start();
   i2c_write(SLAVE2_READ_ADDR);
   data_2 = i2c_read(0);
   i2c_stop();

   lcd_putc("\f"); //clear lcd
   printf(lcd_putc,"Slave_2 ADC: %u \n\r", data_2); //displaying data sent by slave_2 on LCD

   delay_ms(500);
  }

}

and this is slave_1 code:
Code:

#include <16F877.h>
#device adc=8
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x12)

int8 adc_result;


#INT_SSP
void ssp_interrupt()
{
int8 incoming, state;

state = i2c_isr_state();
   
if(state < 0x80)     // Master is sending data
  {
   incoming = i2c_read(); 
  }

if(state == 0x80)   // Master is requesting data from slave
  {
   i2c_write(adc_result);
  }

}

//======================================
void main ()
{
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
delay_us(20);
adc_result = read_adc();

enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
   
while(1)
  {
   adc_result = read_adc();
   delay_ms(500);
  }

}

Lastly this is the slave_2 code:
Code:

#include <16F877.h>
#device adc=8
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x14)

int8 adc_result;


#INT_SSP
void ssp_interrupt()
{
int8 incoming, state;

state = i2c_isr_state();
   
if(state < 0x80)     // Master is sending data
  {
   incoming = i2c_read(); 
  }

if(state == 0x80)   // Master is requesting data from slave
  {
   i2c_write(adc_result);
  }

}

//======================================
void main ()
{
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
delay_us(20);
adc_result = read_adc();

enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
   
while(1)
  {
   adc_result = read_adc();
   delay_ms(500);
  }

}


Last edited by semmoor on Fri Jul 13, 2012 5:38 pm; edited 1 time in total
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jul 13, 2012 3:46 pm     Reply with quote

Do you have the correct I2C bus resistors installed for speed-distance-VCC ?
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Fri Jul 13, 2012 4:13 pm     Reply with quote

temtronic wrote:
Do you have the correct I2C bus resistors installed for speed-distance-VCC ?


yup, I'm using 2.2k for scl and sda.

I tried with different resistor values like 1.7k and 4.7k, but still doesn't work.
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jul 13, 2012 7:54 pm     Reply with quote

hmmmm...
I'd run PCM pgmr's I2C test program to see if it sees both slaves...
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Sat Jul 14, 2012 12:44 am     Reply with quote

One 'classic' possible problem.
State 0x80 needs you to first _read_ the byte from the slave, then write.
So he slave code need:
Code:

#INT_SSP
void ssp_interrupt(void) {
   int8 incoming, state;

   state = i2c_isr_state();   
   if(state <= 0x80)     // Master is sending data - note the =
   {
       incoming = i2c_read();
   }
   if(state == 0x80)   // Master is requesting data from slave
   {
      i2c_write(adc_result);
   }
}


This is a very common 'miss' on I2C, with state 0x80, being 'unique' in requiring this 'double' transaction.

Best Wishes
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

!!
PostPosted: Sat Jul 14, 2012 7:13 am     Reply with quote

Ttelmah wrote:
One 'classic' possible problem.
State 0x80 needs you to first _read_ the byte from the slave, then write.
So he slave code need:
Code:

#INT_SSP
void ssp_interrupt(void) {
   int8 incoming, state;

   state = i2c_isr_state();   
   if(state <= 0x80)     // Master is sending data - note the =
   {
       incoming = i2c_read();
   }
   if(state == 0x80)   // Master is requesting data from slave
   {
      i2c_write(adc_result);
   }
}


This is avery common 'miss' on I2C, with state 0x80, beng 'unique' in requiring this 'double' transaction.

Best Wishes



I did exactly what you said but still didn't work, it didn't even show any result i saw just blank on lcd and RS232, so nothing is displayed.
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sat Jul 14, 2012 12:28 pm     Reply with quote

No solutions ??

it's the second day and still didn't solve this issue!!
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jul 14, 2012 1:10 pm     Reply with quote

What's your report on using PCM pgmr's I2C testing program ??
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sat Jul 14, 2012 1:28 pm     Reply with quote

temtronic wrote:
What's your report on using PCM pgmr's I2C testing program ??


can you please give me PCM pgmr's I2C testing program ??
please temtronic, and thank you for helping me.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Sun Jul 15, 2012 2:38 am     Reply with quote

Hasn't anyone heard of using search?.....

If you do a search for 'I2C diagnostic', and 'search for all terms', the very first thread links to where PCM programmer originally posted this.

<http://www.ccsinfo.com/forum/viewtopic.php?t=47707&postdays=0&postorder=asc&highlight=i2c+diagnostic&start=15>

It has been referenced by dozens (possibly hundreds) of other I2C threads, and looking through these would find links to it.

It really is a most 'basic' test, scanning the bus for devices, and if it finds them, telling you the addresses they are on. Brilliant basic test that the bus is working, pull-ups are adequate, and connections are OK.
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sun Jul 15, 2012 5:52 am     Reply with quote

Ttelmah wrote:
Hasn't anyone heard of using search?.....

If you do a search for 'I2C diagnostic', and 'search for all terms', the very first thread links to where PCM programmer originally posted this.

<http://www.ccsinfo.com/forum/viewtopic.php?t=47707&postdays=0&postorder=asc&highlight=i2c+diagnostic&start=15>

It has been referenced by dozens (possibly hundreds) of other I2C threads, and looking through these would find links to it.

It really is a most 'basic' test, scanning the bus for devices, and if it finds them, telling you the addresses they are on. Brilliant basic test that the bus is working, pull-ups are adequate, and connections are OK.



Ttelmah thank you for the link:

i tried I2C diagnostic it says nothing found !!

how come??
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jul 15, 2012 7:21 am     Reply with quote

Well we know his program works so possible causes include

1) incorrect pullup resistors on the I2C busses

2) no ground between devices

3) no power to devices

4) incorrect setup/configuration of devices

5) bad solder joint,loose wiring,etc.

6) 3 blue moons in the sky

It is very difficult to pinpoint why it fails to see your devices as your setup is not in front of us!

Since you're using PICs as I2C devices,I'd try it with a real I2C device,say a DS1307 RTC if you have one.Using a real device will prove the I2C test program works on your breadboard or test setup.

hth
jay
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sun Jul 15, 2012 10:20 am     Reply with quote

temtronic wrote:
Well we know his program works so possible causes include

1) incorrect pullup resistors on the I2C busses

2) no ground between devices

3) no power to devices

4) incorrect setup/configuration of devices

5) bad solder joint,loose wiring,etc.

6) 3 blue moons in the sky

It is very difficult to pinpoint why it fails to see your devices as your setup is not in front of us!

Since you're using PICs as I2C devices,I'd try it with a real I2C device,say a DS1307 RTC if you have one.Using a real device will prove the I2C test program works on your breadboard or test setup.

hth
jay


temtronic, thank you my friend i appreciate that i will try to check what you told me, and thanks to all.
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sun Jul 15, 2012 10:29 am     Reply with quote

guys i modified the above code to send a string from slave(pic_1) to master(pic_2), but didn't work it only sends the first char!

so, what can you advice me to make the slave sends a string like "ABCD" whenever the master requests a data?

this is the slave code:

Code:


#include <16F877.h>
#device adc=8
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x14)


#INT_SSP
void ssp_interrupt()
{
int8 incoming, state;

state = i2c_isr_state();

   
if(state < 0x80)     // Master is sending data
  {
   incoming = i2c_read(); 
  }

if(state == 0x80)   // Master is requesting data from slave
  {
   
 
    i2c_write('A');  //send first char to slave
    i2c_write('B');  //send second char to slave
    i2c_write('C');  //send third char to slave
 
  }


}


//======================================
void main ()
{


enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
   
while(1)
  {

  }

}







master code:

Code:



#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
   
#define SLAVE1_WRT_ADDR   0x14
#define SLAVE1_READ_ADDR  0x15

//====================================
void main()
{
char data[3]; //stores data sent by slave

while(1)
  {

   i2c_start();
   i2c_write(SLAVE1_READ_ADDR);
   data[0] = i2c_read(0); delay_ms(100); //stores first char sent by slave
   data[1] = i2c_read(0); delay_ms(100); //stores second char
   data[2] = i2c_read(0); delay_ms(100); //stores third char sent by slave
 
   i2c_stop();
 
   printf(" [ %s ] \r\n", data); //now display completed string on RS232
   
   delay_ms(500);
   
   
  }

}



when i make a simple run for the code above i only see the first char printed on RS232.
jeremiah



Joined: 20 Jul 2010
Posts: 1345

View user's profile Send private message

PostPosted: Sun Jul 15, 2012 1:04 pm     Reply with quote

try only NACK'ing the last byte you read in the master code. You are NACK'ing all 3. Usually when you NACK a read byte, that is the master telling the slave it is finished.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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