One Wire Search ROM

Discussion in 'Embedded Systems and Microcontrollers' started by sevenfold4, Jan 21, 2015.

  1. sevenfold4

    Thread Starter Member

    Jan 12, 2015
    80
    7
    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 (Text):
    1. int OWReadBit(void)
    2. {
    3.         int result;
    4.  
    5.         DW=1; // Drives DQ low
    6.  
    7.         DW=0; // Releases the bus
    8.         t0delay(0);
    9.         result = DR; // Sample the bit value from the slave
    10.         t0delay(3); //
    11.  
    12.         return ~result;
    13. }
    14. int OWReadByte(void)
    15. {
    16.         int loop, result=0;
    17.  
    18.         for (loop = 0; loop < 8; loop++)
    19.         {
    20.                 // shift the result to get it ready for the next bit
    21.                 result >>= 1;
    22.      
    23.                 // if result is one, then set MS bit
    24.                 if (OWReadBit())
    25.                 {
    26.                     result=result | 0x80;
    27.                 }
    28.         }
    29.         return result;
    30. }
    31. void OWWriteBit(int bit)
    32. {
    33.     *led=bit;
    34.         if (bit==1) //write 1
    35.         {
    36.                 // Write '1' bit
    37.                 DW=1; // Drives DQ low
    38.                 //tickDelay(A);
    39.                 DW=0; // Releases the bus
    40.                  t0delay(4);
    41.         }
    42.         else if(bit==0) //write 0
    43.         {
    44.                 // Write '0' bit
    45.                 DW=1; // Drives DQ low
    46.                  t0delay(3);
    47.                 DW=0; // Releases the bus
    48.                  t0delay(0);
    49.         }
    50.  
    51. }
    52. void OWWriteByte(int data)
    53. {
    54.         int loop;
    55.  
    56.         // Loop to write each bit in the byte, LS-bit first
    57.         for (loop = 0; loop < 8; loop++)
    58.         {
    59.                 OWWriteBit(data & 0x01);
    60.  
    61.                 // shift the data byte for the next bit
    62.                 data = data>>1;
    63.      
    64.      
    65.         }
    66. }
    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 (Text):
    1. while(1)
    2.     {
    3.  
    4.         if(getkey()=='g')
    5.         {
    6.         sprintf(str_2, "%X", ~OWReadByte());
    7. lcd_delay();
    8. lcd_string(str_2);
    9. 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 (Text):
    1. 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: Jan 21, 2015
  2. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    988
    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.
     
  3. sevenfold4

    Thread Starter Member

    Jan 12, 2015
    80
    7
    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.
     
  4. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    988
    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
     
  5. sevenfold4

    Thread Starter Member

    Jan 12, 2015
    80
    7
    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 (Text):
    1. 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 (Text):
    1. 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: Jan 22, 2015
  6. sevenfold4

    Thread Starter Member

    Jan 12, 2015
    80
    7
    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 (Text):
    1. d =(value[0]+value[8]);
    2. d=(d/2);
    3. lcd_delay();
    4. *instruction = 0b10000001;
    5. 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.
     
    Last edited: Jan 22, 2015
  7. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    988
    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 (Text):
    1.  
    2. void cb(struct OW_info *info, unsigned int count)
    3. {
    4.  
    5.   volatile int x = info->family;
    6.  
    7.  
    8. }
    9.  
    10. void main()
    11. {
    12.    .......
    13.    .......
    14.    
    15.      OW_search2(OW_ALARMSEARCH,cb);
    16.    ..........
    17. }
    18.  
    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 (Text):
    1.  
    2.  
    3.      struct OW_info fridgROM = {0x10,0x3a, 0x7f, 0x55,0x01,0x08,0x00,0x5f};   // got this data during a debug session
    4.     frigTemp = DSOWTherm_getCentigrade(fridgROM);
    5.  
    6.  
    7.  

    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.
     
  8. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    988
    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.
     
  9. sevenfold4

    Thread Starter Member

    Jan 12, 2015
    80
    7
    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 (Text):
    1. if((value_z[1]) & 0xff == 0xff)
    2.     {
    3.         d = -(((~value_z[0]) +1) /2.0);
    4.     }
    5.     else
    6.     {
    7.         d =  value_z[0];
    8.         d = (d   / 2.0);
    9.     }
    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: Jan 23, 2015
  10. sevenfold4

    Thread Starter Member

    Jan 12, 2015
    80
    7
    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.
    I am about to start pulling my hair out, because I can not get the Search ROM to work.
     
  11. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    988
    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?
     
  12. sevenfold4

    Thread Starter Member

    Jan 12, 2015
    80
    7
    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
     
    Last edited: Jan 28, 2015
  13. sevenfold4

    Thread Starter Member

    Jan 12, 2015
    80
    7
    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
     
  14. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    988
    Hang in there. I should have a full demo as well as help files in a couple of days.
     
  15. sevenfold4

    Thread Starter Member

    Jan 12, 2015
    80
    7
    Ok thanks man. I'll be in your debt
     
  16. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    988
    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.
     
  17. sevenfold4

    Thread Starter Member

    Jan 12, 2015
    80
    7
    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 (Text):
    1. 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 (Text):
    1.  cb(&OWrom, count);  
    and in other place as a function parameter
    Code (Text):
    1. 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
    I think i am calling the function the right way
    Code (Text):
    1. count = OW_search(0xF0, cb);
     
    Last edited: Feb 2, 2015
  18. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    988
    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.
     
  19. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    988
    Also look at the help file. I have an example of calling a callback function in help.
     
  20. sevenfold4

    Thread Starter Member

    Jan 12, 2015
    80
    7
    I did and am trying DSOWTherm_searchSensors
    but I am getting
    and the line that is giving the error is
    Code (Text):
    1. totalDevices =  DSOWTherm_searchSensors(GetDevice);
     
Loading...