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

sensor networks
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
Olufola



Joined: 19 May 2009
Posts: 21

View user's profile Send private message

sensor networks
PostPosted: Sat Jun 13, 2009 9:14 am     Reply with quote

Hi,

I am presently trying to implement an i2c bus communication between one master PIC and three slave PICs (all the four PICs are 18F4520). I will state what I want to do exactly in one sentence in the paragraph that follws:
To setup an i2c bus in which a single master requests for data from three slave PICs in turn and continuously.

From the code attached to this post, the master should be displaying
Code:

[111 222 333]
[111 222 333]
[111 222 333]

and should be repeating this continuously.
What I am presently getting is
Code:
[255 255 255]
[255 255 255]
[255 255 255]

and this is what is repeated continuously.
I think all other things are working correctly save for this incorrect results.
I really need help.

The codes follow immediately:

Master code
Code:

#include <18F4520.h>
#device adc=10
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(MASTER,sda=PIN_C4,scl=PIN_C3,force_hw)
#fuses HS,NOWDT,NOPROTECT,NOLVP

int data1=0;
int data2=0;
int data3=0;
byte addr1 = 2; //slave address must be even number
byte addr2 = 4; //slave address must be even number
byte addr3 = 6; //slave address must be even number

void main()
{
 while (true)
 {
 //-----------------
 i2c_start();
 i2c_write(addr1);
 i2c_start();
 i2c_write(addr1 + 1);
 data1=i2c_read(0);
 i2c_stop();
 //-----------------
 i2c_start();
 i2c_write(addr1);
 i2c_start();
 i2c_write(addr2 + 1);
 data2=i2c_read(0);
 i2c_stop();
 //-----------------
 i2c_start();
 i2c_write(addr1);
 i2c_start();
 i2c_write(addr3 + 1);
 data3=i2c_read(0);
 i2c_stop();
 //-----------------
 printf("[ %3u %3u %3u ] \n\r", data1,data2,data3);
 delay_ms(10);
 }
 
}


The slave codes follows (Only the data sent and the addresses differ)
Code:

#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address = 2,force_hw)

#INT_SSP
void ssp_interupt ()
{
   BYTE  state;

   state = i2c_isr_state();

   if(state < 0x80)                     //Master is sending data
   {
   
   }
   if(state >= 0x80)                     //Master is requesting data
   {
      i2c_write(111);
   }
}

void main ()
{
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);

   while (TRUE)
   
   {
   
   }
}


Slave 2
Code:

#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address= 4,force_hw)

#INT_SSP
void ssp_interupt ()
{
   BYTE  state;

   state = i2c_isr_state();

   if(state < 0x80)                     //Master is sending data
   {
   
   }
   if(state >= 0x80)                     //Master is requesting data
   {
      i2c_write(222);
   }
}

void main ()
{
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);

   while (TRUE)
   
   {
   
   }
}


Slave three
Code:

#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address= 6,force_hw)

#INT_SSP
void ssp_interupt ()
{
   BYTE  state;

   state = i2c_isr_state();

   if(state < 0x80)                     //Master is sending data
   {
   
   }
   if(state >= 0x80)                     //Master is requesting data
   {
      i2c_write(333);
   }
}

void main ()
{
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);

   while (TRUE)
   
   {
   
   }
}

The compiler I am using is PCW. I posted a question earlier on this project when I was still new to the ccs C syntax. I have not been active in the forum since then to really get myself grounded in the CCS syntax.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jun 13, 2009 9:30 am     Reply with quote

Your i2c slave addresses are not allowed. See these posts:
http://www.ccsinfo.com/forum/viewtopic.php?t=36558&start=6
http://www.ccsinfo.com/forum/viewtopic.php?t=33966&start=3
Olufola



Joined: 19 May 2009
Posts: 21

View user's profile Send private message

PostPosted: Sat Jun 13, 2009 9:41 am     Reply with quote

I just used 0x12, 0x14 and 0x16 for the addresses respectively and I got the same results.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jun 13, 2009 9:59 am     Reply with quote

I didn't look closely at your code after I saw the address problem.
But another quick look shows this problem.:
Quote:
i2c_write(333);

The i2c_write function can only send a byte. A byte can have a value
from 0 to 255 (0x00 to 0xFF). You can't send 333 like that.
Olufola



Joined: 19 May 2009
Posts: 21

View user's profile Send private message

PostPosted: Sat Jun 13, 2009 10:44 am     Reply with quote

Thanks. But I just changed the 333 to 123 and the message is still [255 255 255]
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jun 13, 2009 11:12 am     Reply with quote

I think you have problems with your master code, and also with the
edits that you have done to the #int_ssp isr code in the slave.
Also, do you have pull-up resistors installed on the SDA and SCL lines ?

I can't work on this any more today, but I can work on it tomorrow.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 14, 2009 3:24 pm     Reply with quote

Here is a simple i2c slave demo. The slave PIC reads the ADC value
every 500 ms and saves it in a global variable. This emulates a sensor.
The master PIC reads the ADC value from the slave. The master does
not send an internal address byte to the slave. It only sends the i2c
slave device address, and then it reads the data byte.

Also, notice that the master is not using FORCE_HW mode in the
#use i2c() statement. In some PICs, this can cause problems. It's best
to start by using a software i2c Master. When you get that working
reliably, then add the FORCE_HW to the master and try it.

I'm using the equivalent of 2.2K pullups on SDA and SCL. This was
tested on two PicDem2-Plus boards, with vs. 4.093 of the compiler.

Here is the output of the master PIC, as I slowly turn a trimpot that is
connected to the AN0 analog input pin. I turned the pot all the way to
the right, and then back to 0 again.
Quote:

read 00
read 30
read 8C
read F3
read FF
read FF
read D8
read 88
read 15
read 00


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

//====================================
void main()
{
int8 data;

while(1)
  {
   i2c_start();
   i2c_write(SLAVE1_READ_ADDR);
   data = i2c_read(0);
   i2c_stop();

   printf("read %X \n\r", data);

   delay_ms(1000);
  }

}


i2c slave:
Code:
#include <16F877.h>
#device adc=8
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#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);
  }

}



---------
Edit #1: Fixed a typo
Edit #2: Changed the PROTECT fuse to NOPROTECT. There is no need
for code protection in a test program.


Last edited by PCM programmer on Sun Aug 16, 2009 12:20 pm; edited 2 times in total
Olufola



Joined: 19 May 2009
Posts: 21

View user's profile Send private message

PostPosted: Mon Jun 15, 2009 12:27 pm     Reply with quote

I am very sorry for replying so late. Actually, I did not get any notification in my yahoo box. I will try your demo code straightaway.
Olufola



Joined: 19 May 2009
Posts: 21

View user's profile Send private message

PostPosted: Mon Jun 15, 2009 12:49 pm     Reply with quote

Wow! The code worked perfectly for communication between 1 master and 1 Slave. I will soon post the results obtained for the single master and three slaves scenario. Thanks, I might not need to learn MPASM to implement my sensor network afterall.
Olufola



Joined: 19 May 2009
Posts: 21

View user's profile Send private message

PostPosted: Mon Jun 15, 2009 3:30 pm     Reply with quote

I have modified the code for the case of three slaves. I made each of the slaves send a constant number so that I can easily track any errors in the transmission. From the codes below, the output I should be getting should be
Code:

      [34 179 80]
      [34 179 80]
      [34 179 80]

i.e. slave1 should be sending 34, slave2 should be sending 179 and slave3 should be sending 80 and this should continue indefinitely. What I am presently getting is
Code:

[179 179 179]
[179 179 179]
[179 179 179]

and I noticed that whatever the value slave2 sends is what the master receives for the three slaves. It seems as if whatever slave2 sends overrides every other value sent on the bus and what the master gets for each of the three slaves is whatever slave2 sends. I mean that if slave2 sends 56, I get as my output
Code:

[56 56 56]
[56 56 56]
[56 56 56]

and in general if slave2 sends dd, what I get as my output is
Code:

[dd dd dd]
[dd dd dd]
[dd dd dd]

The codes from PCM Programmer that I modified follows:
Master code
Code:

#include <18f4520.H>
#fuses XT, NOWDT, PROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
   
#define SLAVE1_WRT_ADDR   0x64
#define SLAVE1_READ_ADDR  0x65

#define SLAVE2_WRT_ADDR   0x14
#define SLAVE2_READ_ADDR  0x15

#define SLAVE3_WRT_ADDR   0x96
#define SLAVE3_READ_ADDR  0x97

//====================================
void main()
{
int8 data1,data2,data3;

while(1)
  {
   i2c_start();
   i2c_write(SLAVE1_READ_ADDR);
   data1 = i2c_read(0);
   i2c_stop();
   delay_ms(10);

   i2c_start();
   i2c_write(SLAVE2_READ_ADDR);
   data2 = i2c_read(0);
   i2c_stop();
   delay_ms(10);

   i2c_start();
   i2c_write(SLAVE3_READ_ADDR);
   data3 = i2c_read(0);
   i2c_stop();

   printf(" [ %3U %3U %3U ] \r\n", data1,data2,data3);
   delay_ms(120);
  }

}


Slave1 Code
Code:

#include <18F4520.h>
#device adc=8
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x64)

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(34);
  }

}

//======================================
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);
  }

}


Slave2 Code
Code:

#include <18F4520.h>
#device adc=8
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#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(179);
  }

}

//======================================
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);
  }

}


Slave3 Code
Code:

#include <18F4520.h>
#device adc=8
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x96)

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(80);
  }
}

//======================================
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);
  }

}

I don't know if anything is wrong with the modifications I have made. I replied earlier that the original code from PCM programmer worked perfectly for one master and One slave scenario but I cannot get it to work for the three slaves case.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 15, 2009 3:49 pm     Reply with quote

What happens if you disconnect two of the slaves, so you only have one
slave connected to the master at a time ? Can you make each of the
slaves work alone with the master ?

Also, post the size of the pullup resistors that you have on SDA and SCL.
Do you only have one set of pullup resistors ? That's what you need.
(Don't use 3 sets of pullups).
Olufola



Joined: 19 May 2009
Posts: 21

View user's profile Send private message

PostPosted: Tue Jun 16, 2009 2:01 pm     Reply with quote

I am using just two pull up resistors (2.2k). When I disconnect slave1 and slave3, I still get [179 179 179], but should I disconnect just slave2, I start getting [255 255 255]. It is obvious that the master is using the data from slave2 as the data sent from each of the three slaves.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jun 16, 2009 2:16 pm     Reply with quote

You are disconnecting the boards in various combinations.

What happens if you:

1. Test the master with only Slave1 connected ?

2. Test it with only Slave2 connected ?

3. Test it with only Slave3 connected ?

Post the results that you get in each test.
Olufola



Joined: 19 May 2009
Posts: 21

View user's profile Send private message

PostPosted: Tue Jun 16, 2009 3:41 pm     Reply with quote

What happens if you:

1. Test the master with only Slave1 connected ?
With only slave1 connected, I got [255 255 255] continuously

2. Test it with only Slave2 connected ?
With only slave2 connected, I got [179 179 179] continuously

3. Test it with only Slave3 connected ?
With only slave3 connected, I got [255 255 255] continuously
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jun 16, 2009 3:49 pm     Reply with quote

You need to get the Slave1 and Slave3 boards working.

Look for wiring problems on those boards.

Make sure that the correct version of software (with the correct Slave
address) was programmed into Slave1 and Slave3.

Make a simple LED blinking program for the Slave1 and Slave3 boards
(not an i2c slave program), so you can prove that the PIC is working
on each of those boards.
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