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

I need a HELP !

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



Joined: 15 Apr 2011
Posts: 9

View user's profile Send private message

I need a HELP !
PostPosted: Fri Apr 15, 2011 12:28 am     Reply with quote

I am using ICD3 & PIC16F877A and two srf08 sonar sensors and I do face a problem in distinguishing and detection of both sensors. On an individual basis for 1 sensor the code work successfully but once I interface the second sensor the output fail.

Summary: This program stores the 1st echo of srf08 and if the object is less than 50 cm LED B0 and B1 glitter, so could anyone help me to figure out the error ?
Code:

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


main()
{
int i; int16 range[1]=0; int16 range[1]=0;
set_tris_b(0);
while(1)
 {
  i2c_start();                // initiate start condition
  i2c_write(0xE0);            // device address
  i2c_write(0x00);            // register address
  i2c_write(0x54);            // set units to cm
  i2c_stop();
  delay_ms(105);              // wait for returning ping
  i2c_start();                // initiate a new start condition
  i2c_write(0xE0);            // device address
  i2c_write(0x02);            // address of high byte register
  i2c_start();
  i2c_write(0xE1);            // device address put to read
  for (i=0;i<17;i++)
  {
  range[i] = i2c_read(1);    // read first byte and shift to the left
  range[i] = range[i] << 8;
  if(i<16)
  range[i] += i2c_read(1);   // read second byte and add to 1st
  else
  range[i] += i2c_read(0);
  }
  i2c_stop();

for (i=0;i<1;i++)
   {
      printf("range in cm = %lu\n\r", range[i]);
   }

output_B(0x00); // setting LED B0 B1 B2 to low
   if (range[i]<50)           // Set threshold to 50 cm
   {
     output_high(Pin_B0);      // give high output when statement is true

   }
i2c_start();                // initiate start condition
 
  i2c_write(0xA0);            // device new address
  i2c_write(0xAA);            // device new address
  i2c_write(0xA5);            // device new address
  i2c_write(0xE4);            // device address

  i2c_write(0x00);            // register address
  i2c_write(0x54);            // set units to cm
  i2c_stop();
  delay_ms(105);              // wait for returning ping
  i2c_start();                // initiate a new start condition
  i2c_write(0xE4);            // device address
  i2c_write(0x02);            // address of high byte register
  i2c_start();
  i2c_write(0xE5);            // device address put to read
  for (i=0;i<17;i++)
  {
  rangey[i] = i2c_read(1);    // read first byte and shift to the left
  rangey[i] = rangey[i] << 8;
  if(i<16)
  rangey[i] += i2c_read(1);   // read second byte and add to 1st
  else
  rangey[i] += i2c_read(0);
  }
  i2c_stop();

for (i=0;i<1;i++)
   {
      printf("range in cm = %lu\n\r", rangey[i]);
   }

output_B(0x00);
   if (rangey[i]<50)           // Set threshold to 50 cm
   {
     output_high(Pin_B1);      // give high output when statement is true

}}}
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Apr 15, 2011 5:46 am     Reply with quote

Code:
int i; int16 range[1]=0; int16 range[1]=0;
You are initialising the same array twice? Sloppy programming.

A real bug is that you are writing outside the array bounds. Range[1] declares only 1 int16, but you are using the array as if it has a size of 17 elements.
znses



Joined: 15 Apr 2011
Posts: 9

View user's profile Send private message

PostPosted: Fri Apr 15, 2011 12:50 pm     Reply with quote

sorry typo-error the second variable is int16 rangey[1]=0; It is not the same ... so Is there any error associated with the structure, initialization , usage of I2C or ranging ?>


Thanks alot for your contribution
znses



Joined: 15 Apr 2011
Posts: 9

View user's profile Send private message

PostPosted: Fri Apr 15, 2011 12:54 pm     Reply with quote

Do you mean that int16 range[1]=0; should be int16 range[17]=0; instead ?

But we will send only 1 rather than the 17th echos that is why I initialized the array to hold 1 element only because I want to store the 1st echo only ....


Thanks again.......
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Fri Apr 15, 2011 12:55 pm     Reply with quote

znses wrote:
sorry typo-error the second variable is int16 rangey[1]=0;

But that array still contains one element only, you want something like int16 rangey[X] (X being the number of elements you require)
temtronic



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

View user's profile Send private message

PostPosted: Fri Apr 15, 2011 1:09 pm     Reply with quote

If you're only storing the first echo, you do not need an array. A simple variable is all that is needed.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 15, 2011 1:25 pm     Reply with quote

I'm not sure what you're trying to do. First you talk to the SRF08,
then you try to change the i2c address.

Do you two SRF08 devices on the same i2c bus ? When they come
from the manufacturer, they are all set to address 0xE0. Read this
section of their tech info:
Quote:
Changing the I2C Bus Address

http://www.robot-electronics.co.uk/htm/srf08tech.shtml

They say that to change the i2c address, that you must have only one
SRF08 device on the bus. Are you doing that ?

The idea is, you buy two SRF08 devices. Then you put one of them on
your PIC's i2c bus. You run a special progam (following their instructions)
and change the i2c address of that one SRF08. When you're done,
you now have one device at 0xE0, and the 2nd one is at 0xE4 (let's say).

Now you can put both devices on the same i2c bus and you can
talk to both of them. Then it will work.
znses



Joined: 15 Apr 2011
Posts: 9

View user's profile Send private message

PostPosted: Fri Apr 15, 2011 1:42 pm     Reply with quote

I was setting the two sensors at the same I2C and at the same time do you mean I have to connect 1 sensor using the same program then I connect the second sensor to I2C Pic's lines ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 15, 2011 1:49 pm     Reply with quote

I mean:

1. Connect only one sensor to the PIC.

2. Make a special "i2c address changing" program, which you will run
only one time.

3. Run the address changing program on the sensor. It now has a new
i2c address. (Let's say it's now 0xE4).

4. Don't change the address of the other sensor. Leave it at the factory
address of 0xE0.


Now,

A. Connect both sensors to the PIC, on the same i2c bus.

B. Write a program that will read the data from each sensor.
Use the correct i2c address (0xE0 or 0xE4) to talk to the desired sensor.

And especially,

Don't run the "address changing" program again. You only need it once.
Your purpose is to change the address of ONE of the sensors, so it's
different than the factory default address.

-------------

If you can't understand this, another way to do the project is to have two
i2c busses. In other words, use 2 pins for the first bus, and use two other
PIC pins for the 2nd bus. (Total of 4 PIC pins are required).

Then you can use "streams" with the #use i2c() statement, and in
the CCS i2c functions, you can specify a "stream" to tell the compiler
which i2c bus to use.

Maybe that's too difficult also. Maybe do it the first way.
znses



Joined: 15 Apr 2011
Posts: 9

View user's profile Send private message

PostPosted: Fri Apr 15, 2011 2:06 pm     Reply with quote

Regarding address changing program >> The first method


The following program can be called as I2C address changing program ?
Code:

#include <16f877a.h>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20000000)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
main()
{
  i2c_start();                // initiate start condition
  i2c_write(0xA0);            // device new address
  i2c_write(0xAA);            // device new address
  i2c_write(0xA5);            // device new address
  i2c_write(0xE4);            // device address
  i2c_stop();
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 15, 2011 4:19 pm     Reply with quote

The program to change the SRF08 i2c address should look more like this.
I don't have an SRF08 to test, but I think this program has a chance to work.
Code:

#include <16F877.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)


#define SRF08_NEW_ADDR  0xE4   // Set your new address here

#define SRF08_CURRENT_ADDR  0xE0   // Factory Default

#define SRF08_CMD_REG  0x00    // Address of Command Register

//-------------------------------------
void srf08_write_byte(int8 dev_addr, int8 reg, int8 data)
{
i2c_start();
i2c_write(dev_addr);
i2c_write(reg);
i2c_write(data);
i2c_stop();
}

//---------------------------------
// Send the special sequence that allows you to change
// the i2c address.
void srf08_set_new_address(int8 new_addr)
{
srf08_write_byte(SRF08_CURRENT_ADDR, SRF08_CMD_REG, 0xA0);
srf08_write_byte(SRF08_CURRENT_ADDR, SRF08_CMD_REG, 0xAA);
srf08_write_byte(SRF08_CURRENT_ADDR, SRF08_CMD_REG, 0xA5);
srf08_write_byte(SRF08_CURRENT_ADDR, SRF08_CMD_REG, new_addr);
}

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

//--------------------------------------
// Scan i2c addreses 0x10 to 0xF6.
// Return the address of 1st device found, if any.
// If nothing found, return 0.

int8 find_first_i2c_device(void)
{
int8 i;

for(i=0x10; i<0xF8; i+=2)
   {
    if(get_ack_status(i))  // Did we find an i2c device ?
       return(i);          // If so, return the address
   }

return(0);  // If nothing found after scan, return 0
}


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

addr = find_first_i2c_device();
if(addr)
   printf("Initial address = %X \n\r", addr);
else
   printf("Initial address not in range 0x10 to 0xF6\n\r");
 
printf("Setting new address to %X \n\r", SRF08_NEW_ADDR);

srf08_set_new_address(SRF08_NEW_ADDR);

addr = find_first_i2c_device();

if(addr)
   printf("Found new address = %X \n\r", addr);
else
   printf("New address not in range 0x10 to 0xF6\n\r");

printf("Done\n\r");

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