One Wire Search ROM

Thread Starter

sevenfold4

Joined Jan 12, 2015
80
Hey guys, i am posting my problem here again, in hopes that my mind will flicker and i understand everything again, or if that won't work then maybe one of you could show me the light.
As my title shows, i am trying to read from 1wire ds2401 device. I should basically just get a lot of bits that will show a serial number.
Here are the functions that should take care of all the madness inside.

Code:
int OWReadBit(void)
{
        int result;

        DW=1; // Drives DQ low

        DW=0; // Releases the bus
        t0delay(0);
        result = DR; // Sample the bit value from the slave
        t0delay(3); //

        return ~result;
}
int OWReadByte(void)
{
        int loop, result=0;

        for (loop = 0; loop < 8; loop++)
        {
                // shift the result to get it ready for the next bit
                result >>= 1;
     
                // if result is one, then set MS bit
                if (OWReadBit())
                {
                    result=result | 0x80;
                }
        }
        return result;
}
void OWWriteBit(int bit)
{
    *led=bit;
        if (bit==1) //write 1
        {
                // Write '1' bit
                DW=1; // Drives DQ low
                //tickDelay(A);
                DW=0; // Releases the bus
                 t0delay(4);
        }
        else if(bit==0) //write 0
        {
                // Write '0' bit
                DW=1; // Drives DQ low
                 t0delay(3);
                DW=0; // Releases the bus
                 t0delay(0);
        }

}
void OWWriteByte(int data)
{
        int loop;

        // Loop to write each bit in the byte, LS-bit first
        for (loop = 0; loop < 8; loop++)
        {
                OWWriteBit(data & 0x01);

                // shift the data byte for the next bit
                data = data>>1;
     
     
        }
}
i "borrowed" the OWReadByte function, because i didn't get my own function to work, but neither does this(at least i know it worked for someone).
DW-Data Write
and
DR - Data Read
I keep getting the same result, when i am reading. I am trying to put the result from ReadByte onto LEDs to see the output, but thus far i keep getting the same thing.

The device is connected directly to Port 3.4 and 3.5 and nothing should be able to screw it up.

The "reset" of the 1 wire is good and that is why i am not posting it here. I checked it with oscilloscope and i get a nice presence.

Also, the input and output signals should be inverted because of the circuits, that is why inversion can be seen in the code.

To recap
I am calling the function OWWriteByte(0x0F); to run the "read ROM" and then i am trying to get the result without any luck. On the LEDs i keep getting 0b01111111

EDIT!
So now i can get something on the LCD, something.
I get some weird characters.

EDIT!
So i did some decoding, from binary to hex, and i think i am actually getting the right values, just in wrong order.

EDIT!
So i decided to try and use sprintf in this way

Code:
while(1)
    {

        if(getkey()=='g')
        {
        sprintf(str_2, "%X", ~OWReadByte());
lcd_delay();
lcd_string(str_2);
lcd_delay();
I get the family code and CRC and the Serial in between. I have a example hex program where the hex values from the serial are flipped tho, which is odd. I don't know if i am wrong or the example maker is wrong. The family and CRC match tho.
A problem i countered is that all the hex values have ff in front of them, and i can not understand where that comes from.
For example, ff01 when it should be just 01

EDIT
I can now print the whole thing out
I masked the FFs out.
Code:
sprintf(str_2, "%02X", (~OWReadByte()&0xFF));
I still have a problem with the fact that the serial code it self comes out backwards.
 
Last edited:

spinnaker

Joined Oct 29, 2009
7,830
I have a library that I wrote that works. I will post it once I get home. One wire is far,far too complicated to try and troubleshoot your issue via a forum.
 

Thread Starter

sevenfold4

Joined Jan 12, 2015
80
I have a library that I wrote that works. I will post it once I get home. One wire is far,far too complicated to try and troubleshoot your issue via a forum.
That would be awesome man,
I could not figure the serial thing out so i moved on, I can get a temperature reading with the DS18B20 in hex, but did not have much luck converting the actual thing.
 

spinnaker

Joined Oct 29, 2009
7,830
This should have everything you need. Let me know how it works out. It is designed for a Pic and XC8 but the code is written in a way that it should not be hard to modify for any micro or compiler.

The files that you will need to configure for your hardware and compiler are OW_config.h and OW_delay.h
 

Attachments

Thread Starter

sevenfold4

Joined Jan 12, 2015
80
Thanks for the upload.
Sadly, with the MCU and compiler i use, i will not be able to use the delay.h. I made a timer delay so that will not be a problem tho.
I will read it, and get back to you.

Edit,
Could you explain to me how the struct OW_info works here?
I see that in the end, it should have the values of family, id and crc, but it has been used in so many places, that i can not understand where it gets those values.

Also
I checked my functions with the one you gave me, and everything seems to be in order. When i am doing the following calculation
Code:
d = ( (~value[1] <<11)+~value[0]) *0.0625;
0.0625 because in the datasheet it says 12 bits is default resolution. I did also try with 0.5 like the one you gave me, but not much difference.
and then use
Code:
sprintf(str_2, "%02d", d);
like this, i get 16700 on the LCD, it is changing, meaning it is reading something, but i am not sure what to do with this value, since the temperature in this room certainly is not 16.
 
Last edited:

Thread Starter

sevenfold4

Joined Jan 12, 2015
80
I am uploading my code, it is a little bit messy, but everything should be clear, except the OW_readTemp where all the magic is happening. It is a playground at the moment, thus a little bit messy
Maybe this way you will have a little bit better overview of what is going on.

It does not really matter what i do, the value i get ranged between 16xxx to 18xxx, depending on the things i change.

Also, when i Init>Skip Rom>Read scratchpad i should be able to read the value +85 in some format. What i see on the display is following at certain values
value[0]=17008
value[1]=17278
value[2]=17279=value[3]
value[4]=17152
value[5]=0
value[6]=17266
value[7]=17263
value[8]=16928
value[9]=0

rest are 0 as well
Maybe it tells you something, maybe it doesn't.
All i know is that i can not understand this anymore.

Also, i can not use floats, i think.

So i did some hands on calculations, if i add LS(value 0) and MS (value 8) in hex i get 17096 and if this value gets divided by 2 i.e 17096/2=8548(In decimal) , which may or may not be the value i am hunting. Since the default value from the DS18B20 should be 85C.
Is this just a coincidence?
If i do it in my program
Code:
d =(value[0]+value[8]);
d=(d/2);
lcd_delay();
*instruction = 0b10000001;
sprintf(str_2, "%x", d);
And print it onto LCD i see a value Hex 4248, what is far from right(16968 in dec).

I feel like i am chasing wind... Would someone please put me out of my misery.
 

Attachments

Last edited:

spinnaker

Joined Oct 29, 2009
7,830
Thanks for the upload.
Sadly, with the MCU and compiler i use, i will not be able to use the delay.h. I made a timer delay so that will not be a problem tho.
I will read it, and get back to you.

Edit,
Could you explain to me how the struct OW_info works here?
I see that in the end, it should have the values of family, id and crc, but it has been used in so many places, that i can not understand where it gets those values.

Also
I checked my functions with the one you gave me, and everything seems to be in order. When i am doing the following calculation
Code:
d = ( (~value[1] <<11)+~value[0]) *0.0625;
0.0625 because in the datasheet it says 12 bits is default resolution. I did also try with 0.5 like the one you gave me, but not much difference.
and then use
Code:
sprintf(str_2, "%02d", d);
like this, i get 16700 on the LCD, it is changing, meaning it is reading something, but i am not sure what to do with this value, since the temperature in this room certainly is not 16.
YIKES! I have GOT to clean up that code and comment it!


OW_info is used to address a specific device. It is also used by OW_Search2 to get a list of devices on the wire.

to let a list of devices, you need to create a call back function and do something with that data,

Code:
void cb(struct OW_info *info, unsigned int count)
{

  volatile int x = info->family;


}

void main()
{
   .......
   .......
    
     OW_search2(OW_ALARMSEARCH,cb);
   ..........
}
In theroy what you could do is process your temperatures returned inside your callback. But what I do is just call the search one time and use the debugger to get the device info. Then paste it into my code.

So to get the temp for a device, you just do

Code:
     struct OW_info fridgROM = {0x10,0x3a, 0x7f, 0x55,0x01,0x08,0x00,0x5f};   // got this data during a debug session
    frigTemp = DSOWTherm_getCentigrade(fridgROM);

The advantage of the "debug" method to identify your devices is it is an easy way to know which one is which. The right way to do it is to use the search / callback method then write code to allow the end user to configure which device is which while changing the temp on each device to help identify the physical device. If devices are swapped out then the end user would just need to go through the configure process.

If you have only one device then you still might want to use the search / callback method. That way you can swap out devices and not have to change your code.

I have another project that will use these sensors. I think what I will do is to work on that segment of the project cleaning up the code. It will use one sensor so I will use the search method. Might take me the weekend though.
 

spinnaker

Joined Oct 29, 2009
7,830
There us also a way for all of the devices to report their temp or alarms. I need to check my code again to see if I did that. If not I might add it but it might be just as easy and more straight forward to use the search method.
 

Thread Starter

sevenfold4

Joined Jan 12, 2015
80
Ok that cleared up some questions. At the moment i have a DS2141 digital serial number an the DS18B20 thermometer.
I am not too worried about identifying them at the moment. The fact that i can not get a proper value on my display is.
I look forward to that code of yours if you have the time.
Thanks

Edit
I decided to try to read the scratchpad to see if i get the default value of +85
I did, but(always a but)
hen i am bit shifting to get the s location in MSB which should be either 0 or 1 after shifting 3 or 4 times it instead starts getting doubled.
i.e. if bit 0 is 5 bit 1 is 10 etc. bit 6 320, but because of the overflow it shows 64 on the display.

Did i already say that ,at this point, using floats in sprintf is impossible. It just does not work. I think it is compiler specific problem and i have tried some things, like using
-DUSE_FLOATS=1 when compiling, but nothing.

So with some stupid way i got floats working, losing most of my memory space in the progress.
When using the code you gave me

Code:
if((value_z[1]) & 0xff == 0xff)
    {
        d = -(((~value_z[0]) +1) /2.0);
    }
    else
    {
        d =  value_z[0];
        d = (d   / 2.0);
    }
The value declines when heat is applied. I have tried playing around with different things, but he value always seems to be dropping.
 
Last edited:

Thread Starter

sevenfold4

Joined Jan 12, 2015
80
I have been researching the Search ROm command for 2 days now, and decided to try and copy>paste from your library.
I have been doing a lot of changes, but now i am stuck at this error, and i just can not understand the reason behind it.
C:\sdcc\code>sdcc test3.c --model-large
test3.c:165: error 98: conflict with previous definition of 'OW_search' for attribute 'type'
from type 'int function ( struct OW_info generic* fixed, unsigned-char fixed) fixed'
to type 'int function ( struct OW_info generic* fixed, unsigned-char fixed) fixed'
I am about to start pulling my hair out, because I can not get the Search ROM to work.
 

spinnaker

Joined Oct 29, 2009
7,830
Don't pull your hair out. I have this all working. I removed all floating point requirements. I am putting the finishing touches. I should be able to post something by the end of the week.

Why aren't you using the search rom function I already posted?
 

Thread Starter

sevenfold4

Joined Jan 12, 2015
80
Don't pull your hair out. I have this all working. I removed all floating point requirements. I am putting the finishing touches. I should be able to post something by the end of the week.

Why aren't you using the search rom function I already posted?
I tried, i did all the necessary changes to match my hardware/software but i am getting the error 98 i posted earlier, and i can not figure it out.

The error is on line 166, and i just can not find it. I removed searchType from the function and made it global, just to try different things.

Also, i can not seem to find what is OW_update_cb and cb
 

Attachments

Last edited:

Thread Starter

sevenfold4

Joined Jan 12, 2015
80
managed to fix the error 98. Turns out i had to declare the struct before prototyping it. Did not know that's how struct works.

Now i am just wondering what parameters does OW_search take in other than searchType = 0x70
 

spinnaker

Joined Oct 29, 2009
7,830
Took me a little longer than I expected but I wanted to organize the code to make it as easy to use and transportable as possible. Also create a help file.


Please review the help file. Let me know if you see any typos or if there is something that can be made more clear.
The background One Wire functions are not yet documented but you should not need them if just performing temperature measurements.

Use the alarm functions at your own risk as I have yet to test them and the function calls might change.

I will update the alarm functions later along with the additional documentation. Might take me a couple of weeks as I need to move on to other projects right now. Once I have everything final, I will probably post it to my website and one or two other places but wanted to give you first look.

I still need to include sample code in the help file to deal with negative numbers. If you need help interpreting the results from getting temperature let me know.

There is a full working sample for the Pic 18F26K22 but you should be able to convert it easy enough for your mcu.
 

Attachments

Thread Starter

sevenfold4

Joined Jan 12, 2015
80
Took me a little longer than I expected but I wanted to organize the code to make it as easy to use and transportable as possible. Also create a help file.


Please review the help file. Let me know if you see any typos or if there is something that can be made more clear.
The background One Wire functions are not yet documented but you should not need them if just performing temperature measurements.

Use the alarm functions at your own risk as I have yet to test them and the function calls might change.

I will update the alarm functions later along with the additional documentation. Might take me a couple of weeks as I need to move on to other projects right now. Once I have everything final, I will probably post it to my website and one or two other places but wanted to give you first look.

I still need to include sample code in the help file to deal with negative numbers. If you need help interpreting the results from getting temperature let me know.

There is a full working sample for the Pic 18F26K22 but you should be able to convert it easy enough for your mcu.
From my first glimpse, it all looks beautiful. the onewire help file is really well made. I'll jump into it and give some feedback.

EDIT
You are missing pointer signs from Dallas_OW_thermometer.h
e.g.
Code:
int DSOWTherm_convertSpecific(struct OW_ROM OWrom);
I still do not understand how to use callback.
in one place you use it as a function
Code:
 cb(&OWrom, count);
and in other place as a function parameter
Code:
int OW_search(unsigned char searchType, OW_update_cb cb)
I have been doing some reading on structures and callbacks now, but i still can not understand how is this used.
same goes for OW_update_cb
test.c:176: error 78: incompatible types
from type 'void function ( struct OW_ROM generic* fixed, unsigned-int fixed) fixed'
to type 'void generic* function ( struct OW_ROM generic* fixed, unsigned-int fixed) fixed'
I think i am calling the function the right way
Code:
count = OW_search(0xF0, cb);
 
Last edited:

spinnaker

Joined Oct 29, 2009
7,830
You don't need to pass a structure by reference if there are no changes to the values.

You don't have to use OW_search. You can use the helper function DSOWTherm_searchSensors

int OW_search(unsigned char searchType, OW_update_cb cb) is the function declaration not the call.

Read more on callback functions

Look at the sample code. I spent a lot of time on the sample code so you can learn from it.
 

Thread Starter

sevenfold4

Joined Jan 12, 2015
80
You don't need to pass a structure by reference if there are no changes to the values.

You don't have to use OW_search. You can use the helper function DSOWTherm_searchSensors

int OW_search(unsigned char searchType, OW_update_cb cb) is the function declaration not the call.

Read more on callback functions

Look at the sample code. I spent a lot of time on the sample code so you can learn from it.
I did and am trying DSOWTherm_searchSensors
but I am getting
C:\sdcc\code\final>sdcc test.c --model-large -DUSE_FLOATS=1
test.c:462: error 78: incompatible types
from type 'void function ( struct OW_ROM generic* fixed, unsigned-int fixed) fixed'
to type 'void generic* function ( struct OW_ROM generic* fixed, unsigned-int fixed) fixed'
and the line that is giving the error is
Code:
totalDevices =  DSOWTherm_searchSensors(GetDevice);
 
Top