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 support@ccsinfo.com

receive i2c data from pic16f887 to pc by rs232
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Mar 13, 2012 12:39 pm     Reply with quote

Here is a diagnostic program (see below) which will look for any i2c slave
devices that are on the i2c bus, and report the slave address for each
one. For example, if I run this program on my PicDem2-Plus board, it
shows the following result in a terminal window (TeraTerm) on my PC:
Quote:

Start:
ACK addr: 9A
ACK addr: A0

Number of i2c chips found: 2

This means it found the TC74 temperature chip (slave address 0x9A)
and the 24LC256 eeprom (slave address 0xA0). Run the program on
your board and see what it finds.
Code:

#include <16F887.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(clock=4M)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

// This function writes the slave address to the i2c bus.
// If a slave chip is at that address, it should respond to
// this with an "ACK".   This function returns TRUE if an
// ACK was found.  Otherwise it returns FALSE.
int8 get_ack_status(int8 address)
{
int8 status;

i2c_start();
status = i2c_write(address);  // Status = 0 if got an ACK
i2c_stop();

if(status == 0)
   return(TRUE);
else
   return(FALSE);
}


//=================================
void main()
{
int8 i;
int8 status;
int8 count = 0;

printf("\n\rStart:\n\r");

delay_ms(1000);

// Try all slave addresses from 0x10 to 0xEF.
// See if we get a response from any slaves
// that may be on the i2c bus.
for(i=0x10; i < 0xF0; i+=2)
   {
    status = get_ack_status(i);
    if(status == TRUE)
      { 
       printf("ACK addr: %X\n\r", i);
       count++;
       delay_ms(2000);
      }
   }

if(count == 0)
   printf("\n\rNothing Found");
else
   printf("\n\rNumber of i2c chips found: %u", count);

while(1);

 


-----
Edit: Added carriage return/ linefeed to properly format the output.


Last edited by PCM programmer on Wed Mar 14, 2012 12:05 pm; edited 1 time in total
Jampe



Joined: 09 Mar 2012
Posts: 27

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 11:30 am     Reply with quote

PCM programmer , thank you for your demo but I got this :

Quote:

Start:
ACK addr: 10ACK addr: 12ACK addr: 14ACK addr:
16ACK addr: 18ACK addr: 1AACK addr: 1CACK addr
: 1EACK addr: 20ACK addr: 22ACK addr: 24ACK ad
dr: 26ACK addr: 28ACK addr: 2AACK addr: 2CACK
addr: 2EACK addr: 30ACK addr: 32ACK addr: 34AC
K addr: 36ACK addr: 38ACK addr: 3AACK addr: 3C
ACK addr: 3EACK addr: 40ACK addr: 42ACK addr:
44ACK addr: 46ACK addr: 48ACK addr: 4AACK addr
: 4CACK addr: 4EACK addr: 50ACK addr: 52ACK ad
dr: 54ACK addr: 56ACK addr: 58ACK addr: 5AACK
addr: 5CACK addr: 5EACK addr: 60ACK addr: 62AC
K addr: 64ACK addr: 66ACK addr: 68ACK addr: 6A
ACK addr: 6CACK addr: 6EACK addr: 70ACK addr:
72ACK addr: 74ACK addr: 76ACK addr: 78ACK addr
: 7AACK addr: 7CACK addr: 7EACK addr: 80ACK ad
dr: 82ACK addr: 84ACK addr: 86ACK addr: 88ACK
addr: 8AACK addr: 8CACK addr: 8EACK addr: 90AC
K addr: 92ACK addr: 94ACK addr: 96ACK addr: 98
ACK addr: 9AACK addr: 9CACK addr: 9EACK addr:
A0ACK addr: A2ACK addr: A4ACK addr: A6ACK addr
: A8ACK addr: AAACK addr: ACACK addr: AEACK ad
dr: B0ACK addr: B2ACK addr: B4ACK addr: B6ACK
addr: B8ACK addr: BAACK addr: BCACK addr: BEAC
K addr: C0ACK addr: C2ACK addr: C4ACK addr: C6
ACK addr: C8ACK addr: CAACK addr: CCACK addr:
CEACK addr: D0ACK addr: D2ACK addr: D4ACK addr
: D6ACK addr: D8ACK addr: DAACK addr: DCACK ad
dr: DEACK addr: E0ACK addr: E2ACK addr: E4ACK
addr: E6ACK addr: E8ACK addr: EAACK addr: ECAC
K addr: EE
Number of i2c chips found: 112


By the way , I bought the pull-up resistors (1.8k) as you said , it doesn't solve my problem and jeremiah's code is showing me "0f" .
Where am I wrong?
I've done everything you told me.
Again , I'm very glad you are trying to help me..
Jampe.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 12:38 pm     Reply with quote

I'm sorry about the bad formatting. I posted a slightly earlier version of
the code and it was missing some carriage returns. I have edited my
post and the correct code is now there.


With regard to the output you posted, it obvious it's getting an ACK on
every address. I was able to simulate this by grounding pin C4.
So I wonder if your connections are correct.

Do you have pull-up resistors on pins C3 and C4 ? Or did you accidently
install pull-down resistors by mistake ? Or is some other connection
incorrect, such as power and ground ?

Your pull-up resistor connections should be like this:
Code:


              +5v
               |
               <
               > 1.8K       
               <         
To PIC         |          To i2c slave
pin C4 ------------------ SDA pin 
                     


              +5v
               |
               <
               > 1.8K       
               <         
To PIC         |          To i2c slave
pin C3 ------------------ SCL pin 
                     
Jampe



Joined: 09 Mar 2012
Posts: 27

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 2:48 pm     Reply with quote

Thank you for your reply , I used your new code and this is the output :

Quote:

Start:
ACK addr: E4

Number of i2c chips found: 1


I checked the connections and they seems alright.
If the addr is E4 , so my write address is E4?

Thanks,
Jampe.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 2:54 pm     Reply with quote

Yes, the write address is 0xE4, and the read address is 0xE5.
So your #define statements should look like this:
Code:

#define  I2C_WRITE_ADDR 0xE4
#define  I2C_READ_ADDR  0xE5
 
Jampe



Joined: 09 Mar 2012
Posts: 27

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 3:03 pm     Reply with quote

I wrote as you say and it shows "data=08" all the time.

This is the code :
Code:

#include <16F887.h>
#device adc=16
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay (clock=20000000)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define  I2C_WRITE_ADDR 0xE4
#define  I2C_READ_ADDR  0xE5
void main()
{
int8 data;
while(TRUE)
 {
 i2c_start();                // initiate start condition
  i2c_write(I2C_WRITE_ADDR);            // device address
  i2c_write(0x00);            // register address
  i2c_start(); 
  i2c_write(I2C_READ_ADDR);            // device address
  data = i2c_read(0);
  i2c_stop();
 printf("data=%x\n",data);
}
}


Maybe is the component broken ?
jeremiah



Joined: 20 Jul 2010
Posts: 1319

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 3:06 pm     Reply with quote

I believe that code just reads the Firmware version or board version, so the value won't change. If it is indeed a revision 8, then that part looks good.

If you want to read the light sensor value, then change the 0x00 to 0x01. If you want to read the first echo high byte, then change 0x00 to 0x02, etc. This is all in the tables located on the page you linked to me in an earlier post.

If you want to read multiple bytes, then change the code to:
Code:

#include <16F887.h>
#device adc=16
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay (clock=20000000)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define  I2C_WRITE_ADDR 0xE4
#define  I2C_READ_ADDR  0xE5
void main() {
  int8 data[2];  //keep track of the size of this!
  while(TRUE){
    i2c_start();                // initiate start condition
    i2c_write(I2C_WRITE_ADDR);            // device address
    i2c_write(0x02);            // register address
    i2c_start(); 
    i2c_write(I2C_READ_ADDR);            // device address
    data[0] = i2c_read();
    data[1] = i2c_read(0);   //NACK last byte
    i2c_stop();
    printf("data=%x %x\n",data[0],data[1]);
  }
}


EDIT: This is assuming of course that the device lets you read more than one byte at a time. If it doesn't, then issue the previous code twice using different register addresses
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 3:32 pm     Reply with quote

Try this code to get the range in inches. I don't guarantee this works
because I don't have an SRF08 to test.
Code:

#include <16F887.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4M)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#define SRF08_WRT_ADDR  0xE4
#define SRF08_RD_ADDR   0xE5

int16 srf08_get_range(void);

//=======================
void main()
{
int16 result;

while(1)
  {
   result = srf08_get_range();
   printf("Range in inches = %lu\n\r", result);
   delay_ms(1000);
  }

}

//========================

int16 srf08_get_range(void)
{
int8 lsb;
int8 msb;
int16 range;

// This 1st part sends the ranging command
// to the SRF08 to start it ranging.
i2c_start();
i2c_write(SRF08_WRT_ADDR);
i2c_write(0);         
i2c_write(80);  // The range will be returned in inches     
i2c_stop();         

// Now wait for the ranging to complete.
delay_ms(100);    // Must be 65 ms minimum.     

// Finally get the range from the SRF08.
i2c_start();
i2c_write(SRF08_WRT_ADDR);
i2c_write(2);
i2c_start();   
i2c_write(SRF08_RD_ADDR);
msb = i2c_read();   
lsb = i2c_read(0);
i2c_stop();

range = make16(msb, lsb);
return(range);
}
Jampe



Joined: 09 Mar 2012
Posts: 27

View user's profile Send private message

PostPosted: Thu Mar 15, 2012 12:47 am     Reply with quote

Thank you for your codes..
jeremiah , your code output "data=00 00"..
PCM programmer , your code didn't print anything.
Does that make sense?
For be sure , this is the way I've connected the sensor :

http://img818.imageshack.us/img818/179/img3669copy.jpg

Thanks ,
Jampe.
temtronic



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

View user's profile Send private message

PostPosted: Thu Mar 15, 2012 5:39 am     Reply with quote

Electronics101...

From your picture, it appears you've connected the resistors in 'series' NOT in 'parallel'.
Consult any I2C device's datasheet to see how the I2C bus 'pullup' resistors are connected.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 15, 2012 9:35 am     Reply with quote

Go to this page and scroll down to the photo for "Arduino and two-wire
interface":
http://nearfuturelaboratory.com/tag/diy/
There you will see two photos with an X,Y,Z board. These photos show
how to install pull-up resistors.

Notice in each photo, two wires are connected between the X,Y,Z board
and another board. These are the SCL and SDA connection wires.

Also each photo shows two resistors going from SCL and SDA to the
Vcc power bus. Power is marked with a red stripe on the breadboard.
In your case, Vcc = +5 volts.

That's how you're supposed to do it. I showed you this in the schematic
that I posted earlier.
Jampe



Joined: 09 Mar 2012
Posts: 27

View user's profile Send private message

PostPosted: Thu Mar 15, 2012 10:08 am     Reply with quote

Thank you all! it works!
temtronic, thanks for your explanation.
PCM programmer, your code is working! Thank you all for your help.
Thank you for your patience and rapidly responses!
The SRF08 sensor works!

I tried to change this code to my ADXL345 sensor I don't see anything..
It connected as "9 Degrees of Freedom - Sensor Stick" so I didn't use pull-up resistors (built-in).

http://www.sparkfun.com/products/10724

Code:

#include <i2c4.h>
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#define WRT_ADDR  0xA6
#define RD_ADDR   0xA7

int16 adxl345_get_data(void);

//=======================
void main()
{
int16 result;
while(1)
  {
   result = adxl345_get_data();
   printf("data = %lu\n\r", result);
   delay_ms(1000);
  }

}

//========================

int16 adxl345_get_data(void)
{
int8 lsb;
int8 msb;
int16 data;

i2c_start();
i2c_write(WRT_ADDR);
i2c_write(0);       
i2c_write(0x32);  // X-axis
i2c_stop();         

delay_ms(100);    // Waiting 100ms   

// Finally get the data from the ADXL345
i2c_start();
i2c_write(WRT_ADDR);
i2c_write(2);
i2c_start();   
i2c_write(RD_ADDR);
msb = i2c_read();   
lsb = i2c_read(0);
i2c_stop();

data = make16(msb, lsb);
return(data);
}


Thanks ,
Jampe.
jcal54321



Joined: 06 Mar 2009
Posts: 10
Location: Salinas, CA

View user's profile Send private message

I2C tester code from PCM Programmer works great!
PostPosted: Sat Jun 09, 2012 6:39 pm     Reply with quote

I just wanted to add that the I2C tester program posted here works great. I am using a PIC18F2520 and communicating with all three sensors on Sparkfun's 9DOF Stick (P/N SEN-10724).

Since my PIC is working with 5 VDC and the 9DOF Stick is working from 3.3 VDC, I had to use a TI P82B96 Dual Bidirectional Bus Buffer in between the two components. I connected the IC per Figure 2 of the P82B96 datasheet. Pins 1 and 7 connected directly to SDA and SCL of the 9DOF Stick. Pins 2 and 3, which are tied together as shown in Figure 2, are pulled up to 5 VDC through a 2.6K resistor and connected to SDA on the PIC. A similar configuration for pins 5 and 6 to SCL on the PIC.

Anyway, just wanted to post this, in case anyone will find it useful. The I2C tester code is a great place to start. Here is the output from the program received by Hyperterminal:

Code:
Start:
ACK addr: 3C
ACK addr: A6
ACK addr: D0

Number of i2c chips found: 3
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 Previous  1, 2, 3  Next
Page 2 of 3

 
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