6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun May 12, 2024 5:07 am

All times are UTC




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Sun Feb 26, 2023 2:06 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
I think I have met my match on the programming side. Actually, its less the programming and more the technique I need to use to solve the problem that I am stuck with.

The DS18B20 returns a 16 bit sign-extended twos complement number like so:
Attachment:
Screenshot 2023-02-26 135012.png
Screenshot 2023-02-26 135012.png [ 18.73 KiB | Viewed 1075 times ]

and the datasheet shows these examples
Attachment:
Screenshot 2023-02-26 135052.png
Screenshot 2023-02-26 135052.png [ 37.2 KiB | Viewed 1075 times ]
.
In "Hardware mini-projects" Leo Nechaev shows code to read the older DS1820 and a routine for converting the two byte temperature that that device returns.
That device produces a lower resolution result i.e there is only 1 bit for 0.5 degreeC so he simply outputs .5 if the bit is set and .0 if it is clear.

I can't get my head around an algorithm for converting the low 4 bits of the DS18B20's results to fractions - i.e. ^0001 converts to 0.0625 (^ is implied binary point)
so binary 00000000 00010001 becomes decimal 1.0625

Does anyone have any thought/example code/example algorithms that might help me please?


Top
 Profile  
Reply with quote  
PostPosted: Sun Feb 26, 2023 2:37 pm 
Offline

Joined: Wed Jun 23, 2021 8:02 am
Posts: 165
To convert a binary fraction to base 10, multiply it by 10. That gives an integer part, which gives you the next digit, and a remaining fractional part. Repeat the process until the remainder fraction is zero or you have as many digits as you want. In the latter case you might need to round the result up if the first ignored digit would be 5 or more.
For example if you start with 1/16:
First iteration 1/16 -> 10/16, integer 0 remainder 10/16=5/8 -> output digit 0
2nd iteration 5/8 -> 50/8 = 6 + 2/8 -> output digit 6
3rd iteration 2/8 -> 20/8 = 2 + 4/8 -> output digit 2
4th iteration 4/8 -> 40/8 = 5 -> output digit 5
At this point the remainder is zero, so we stop. So we end up with the string 0625, which is what appears after the decimal point.


Top
 Profile  
Reply with quote  
PostPosted: Sun Feb 26, 2023 3:23 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
Fantastic.Thank you very much indeed!


Top
 Profile  
Reply with quote  
PostPosted: Sun Feb 26, 2023 4:41 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1929
Location: Sacramento, CA, USA
You seem like the type of person who likes to "DIY", but if you have a specific output format you would like to share, I'm sure a few of us would enjoy a friendly competition for smallest and/or fastest and/or soonest. Do you want leading and/or trailing zeros and/or decimal point suppression? Do you want the output right or left or center justified? Do you have a display buffer or a character stream output?

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Sun Feb 26, 2023 7:22 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
Hello Mike,
Thanks for your reply.
However, I really haven't got as far as thinking about output formats yet! After kernelthread's fantastic reply I have coded the fractional part of the output but without thinking about efficiency yet!

Ideally I suppose I want a simple fixed length output with a floating minus sign and leading zero
blanking. Nothing fancy. So, -1 would be " -1.000", 3.142 would be " 3.142". The thermometer can output from -55C to +125C and I intend to use it with 12 bit mode so it outputs up to 4 places of decimals after conversion - I will probably round to 3dp.


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 27, 2023 8:53 am 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1411
Location: Scotland
Let me be the first one to say: Wow! 1-Wire on a 6502 - neat!

I've done lots with 1-wire stuff but never on a 6502... Interesting concept but the timings should be easy to achieve - which I guess you've done.

Cheers,

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Mon Feb 27, 2023 5:05 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
Well, I can't take all the credit for the 1-wire code. There is (old) code on here (for the DS1820) that I borrowed. Unfortunately it didn't work with the DS15B20 - the newer device seems to conform more strictly to the 1-wire specs - so I fixed it. Now I need some other 1-wire devices to hook up - any suggestions? ;-)


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 12, 2023 2:57 pm 
Offline
User avatar

Joined: Wed Feb 13, 2013 1:38 pm
Posts: 586
Location: Michigan, USA
May I ask where I might find the old DS1820 code you mentioned, please?


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 12, 2023 3:51 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
Michael wrote:
May I ask where I might find the old DS1820 code you mentioned, please?
It's in Hardware Mini Projects
http://6502.org/mini-projects/ds1820/ds1820.htm


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 13, 2023 2:06 pm 
Offline
User avatar

Joined: Wed Feb 13, 2013 1:38 pm
Posts: 586
Location: Michigan, USA
Thank you.

I've used DS18x20 temperature sensors in several different PIC microcontroller projects in the past. It's an interesting device and protocol. Instead of using a 256 byte 'CRC' table or a separate routine to perform the 'scratchpad' CRC test, I built a cumulative bit-level CRC calc' into my One Wire read/write bit routine that performs the calculation on-the-fly within each 60-microsecond read/write bit 'slot' which pretty much eliminates CRC calculation overhead. If anyone is interested, here's a couple excerpts (apologies -- PIC Assembly code);

Code:
 /*                                                                   *
  *  use remaining r/w 'slot' time for cumulative bit level CRC calc  *
  *  using data in Carry status bit                                   *
  *                                                                   */
   //asm clrf   _wreg           // wreg already 0 (see above)
     asm rlf    _wreg,W         // save C in wreg (0x00 or 0x01)
     asm xorwf  _crc,F          // xor b0 bits, result in 'crc'
     asm rrf    _crc,F          // is xor result 0 (C=0)?
     asm skpnc                  // yes, skip, else
     asm iorlw  0x18            // wreg = x8+x5+x4+1 poly and b0 bit
     asm rrf    _wreg,W         // restore C (wreg = 0x8C or 0x00)
     asm xorwf  _crc,F          // apply the polynomial, or not

   //asm movlb  owtris          // bank 1 (inserted by compiler)
     asm bsf    owtris,owpin    // set owpin to hi-z '1' @ 61-usecs
   //intcon.GIE = 1;            // interrupts on
   }                            //

Code:
  /******************************************************************
   *  main loop                                                     *
   ******************************************************************/
     
     while(1)                   //
     { owreset();               // reset one-wire devices
       owrw(OwSkipRom);         // send "skip rom" command
       owrw(OwConvert);         // start temperature conversion
       delay_ms(2);             // wait for conversion to complete
       lastdiscrep = 0;         // start new search
  //   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       do                       // repeat for each sensor
       { u08 i = 0;             //
         owsearch();            // put first/next ROMID in owbuff[]
         owreset();             // reset one-wire devices
         owrw(OwMatchRom);      // send "match rom" command
         do                     // send & print 64-bit rom id
         { putHex(owrw(owbuff[i++]));
         } while(i < 8);        // 8 bytes
    /*                                                              *
     *  read temperature and 'count_remain' bytes from the DS18x20  *
     *  scratchpad memory (optionally print the CRC8 result).       *
     *                                                              */
         owrw(OwScratch);       // send "read scratchpad" command
       //crc = 0;               // reset 'crc' variable
         rawtemplo = owrd();    // read temperature lo byte
         rawtemphi = owrd();    // read temperature hi byte
         owrd(); owrd();        // dummy scratchpad reads
         owrd(); owrd();        // dummy scratchpad reads
         frac = 16 - owrd();    // frac = 16 - 'count_remain'
       //owrd(); owrd();        // last scratch byte & crc byte
       //put232(" CRC=");       // print scratchpad CRC8 result
       //putHex(crc);           // should be "00" (no error)
         put232(' ');           //

    /*                                                              *
     *  expand DS18S20 9-bit temperature value (1/2° resolution)    *
     *  to DS18B20 12-bit format (1/16th° resolution).              *
     *                                                              */
         if(familyid == 0x10)   // if DS1820 or DS18S20
         { rawtemp16.0 = 0;     // clear the 0.5° bit
           rawtemp16 <<= 3;     // make room for fraction bits
           rawtemp16 |= frac;   // frac = (16 - 'count_remain')
         //rawtemp16 -= 4;      // subtract 1/4° (per datasheet)
         }


Attachments:
crc8.jpg
crc8.jpg [ 112.7 KiB | Viewed 841 times ]
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 11 guests


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 post attachments in this forum

Search for:
Jump to: