|
|
View previous topic :: View next topic |
Author |
Message |
D-Kens Guest
|
Weird result on iButton search ROM |
Posted: Mon Feb 14, 2005 10:16 am |
|
|
Hi...
I followed Dallas AN 187 about "1-Wire Search Algorithm" to write a Search_ROM function on a PICC 16F877. I finally wrote a working code (or so it seems) and tried to read the ROM code on a 1-Wire Weather Station from AAG : I should find a DS18S20, a DS2423 and a DS2450.
My function returns a 64 bit code for both DS2423 and DS18S20 (according to the family codes), but I only get the beginning of the 64 code for the DS2450. After a random number of bits read by the search ROM algorithm, function returns an error (no device participating in the search).
I doubt the problem is in the code, as it works fine for the two other components, but I'll try have a closer look to the logic anyway. Does anyone know if the DS2450 has particular needs ?! Or I might be interested in a 100% working Search_ROM function for my 16F877...
Thanks,
Christophe. |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Mon Feb 14, 2005 5:14 pm |
|
|
I used this a few years back maybe it will be useful for you as a comparison to the code you wrote
Code: |
#define dow_pin pin_b0
#bit dow_pin_bit=6.0
char dev_id[8];
master_write_bit( short int send_bit)
{
output_low(dow_pin);
delay_us(10);
if(send_bit)
{
output_float(dow_pin);
if(!dow_pin_bit) return(false);
}
else
{
output_low(dow_pin);
if(!dow_pin_bit) return( false);
}
delay_us(50);
output_float(dow_pin);
delay_us(50);
}
void set_dev_id_bit(char *dev_id,int rom_bit_index,short int rom_bit)
{
// sets the bit referenced by rom_bit_index to the value
// on rom_bit
// rom_bit_index 0..63
int this_byte,value,this_bit;
this_byte=rom_bit_index / 8;
this_bit=rom_bit_index % 8;
value=*(dev_id+this_byte);
if (rom_bit==1)
bit_set(value,this_bit);
else
bit_clear(value,this_bit);
*(dev_id+this_byte)=value;
}
byte master_dow_search_rom(char *dev_id)
{
// for each bit of the unique 64 bit id that each device has
// the master reads twice and writes once
// on the first read each of the slaves repond with a specific bit
// on the second read they send the complement
// the master then selects a value for that bit ( 0 or 1)
// slaves with that value stay in the process and the others go offline
// until the next reset
//
// since any slave going low takes the line down for all
// the master can see the following for each bit position in the id
// if slaves have 0 and 1 bits ..... 0 0
// if all slaves have 0 ..... 0 1
// if all slaves have 1 ..... 1 0
// note: 1 1 is an error
// master uses the 0 0 state to select among the slaves
// for the 0 1 state it sends 0 to keep all slaves for the next round
// for the 1 0 state it sends 1 to keep all slaves for the next round
//
// sent_bit_actual is not the bit from a single device
// ( unless it is the only one still selected )
// but is the wire or value of the conflicting devices
// any device which is pulling low will win
short int sent_bit_actual,sent_bit_complement;
int rom_bit_index,last_discrepancy,marker;
last_discrepancy=0;
done=false;
next:
if(done)goto exit;
if( !master_reset()) return (false); // problem with wire
if( !master_read_presence())
{
last_discrepancy=0;
return(false); // no slaves detected
}
// now inventory the attached slaves
rom_bit_index=0;
marker=0;
master_write_byte(0x0f); // search rom command sent to slaves
read_dow:
sent_bit_actual=master_read_bit();
sent_bit_complement=master_read_bit();
if (sent_bit_actual==1 && sent_bit_complement==1)
{
last_discrepancy=1; // 1 1 something is wrong
return(false);
}
if ( sent_bit_actual==0 && sent_bit_complement==0)
{
if(rom_bit_index==last_discrepancy)
set_dev_id_bit(dev_id,rom_bit_index,1);
if(rom_bit_index>last_discrepancy)
{
set_dev_id_bit(dev_id,rom_bit_index,0);
marker=rom_bit_index;
}
else
{
if (get_dev_id_bit(dev_id,rom_bit_index)==0)
marker=rom_bit_index;
}
}
else set_dev_id_bit(dev_id,rom_bit_index,sent_bit_actual);
master_write_bit(get_dev_id_bit(dev_id,rom_bit_index));
rom_bit_index++;
if(rom_bit_index<=63)goto read_dow;
last_discrepancy=marker;
if(last_discrepancy==0) done=true;
exit:
return(true);
}
[color=darkred][/color][color=darkred][/color][color=darkred][/color][color=darkred][/color][color=darkred][/color][color=darkred][/color][color=darkred][/color][color=darkred][/color][color=darkred][/color] |
|
|
|
D-Kens Guest
|
|
Posted: Wed Feb 16, 2005 6:41 am |
|
|
Ok, thanks for your code, but I found the answer !!! As I suspected, the problem was not in my code but on the board itself. The DS2450 seems to need more power than the one provided only by the 1-Wire bus for complex operations like Search_ROM : that's why the function worked fine for reading codes of other components, but failed on that specific one.
Added a capacitor to the board, to store some extra power when the line is high, and now I can read the ROM code of all 3 components that share the DATA line. Time for me to try and address each component individually now : wish me luck !!! May the Force be with me... |
|
|
chrisdotronics Guest
|
search rom for 1 wire device |
Posted: Thu Mar 17, 2005 10:07 pm |
|
|
Hi!
I would you like your code (.c file full integral) to talking a wheather station ?
I tried but found just ds18s20 on wheather station??????
Thank!!! |
|
|
|
|
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
|