Simple cpp wrapper of a ds18b20, onewire 'c' library. Supports multiple sensors.

Dependencies:   mbed

Dependents:   LPC11U68_DS18B20Sensor

Fork of DS18B20Sensor by Steve Spence

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers onewire.cpp Source File

onewire.cpp

00001 /**
00002 * @file onewire.c
00003 * @brief library 1-Wire(www.maxim-ic.com)
00004 * @author Maciej Rajtar (Published 10 May 2010 www.mbed.org)
00005 * @author Frederic BLANC
00006 */
00007 #include "mbed.h"
00008 #include "onewire.h"
00009 #include "DS18X20.h"
00010 #include "crc8.h"
00011 
00012 DigitalInOut ow_pin(ONEWIRE_PIN);
00013 
00014 /**
00015 *     @brief PUL-UP bus OW
00016 *    @return OW_OK
00017 *     @date 20/06/2011
00018 */
00019 uint8_t ow_PullUp(void)
00020 {
00021     ow_pin.mode(PullUp); //PULL-UP bus OW
00022 return OW_OK;
00023 }
00024 /**
00025 *     @brief search_sensors
00026 *    @param  [out] nSensors number of device onewire
00027 *    @param  [out] gSensorIDs[][] array of id romcode
00028 *    @return OW_OK or OW_PRESENCE_ERR or OW_DATA_ERR
00029 *     @date 20/06/2011
00030 */
00031 uint8_t search_sensors(uint8_t *nSensors,uint8_t *gSensorIDs ) {
00032     uint8_t i;
00033     uint8_t id[OW_ROMCODE_SIZE];
00034     uint8_t diff;
00035     printf( "Scanning Bus\n" );
00036     diff = OW_SEARCH_FIRST;
00037     for (*nSensors = 0 ; (diff != OW_LAST_DEVICE) && (*nSensors < MAXSENSORS) ;++(*nSensors) ) {
00038         ow_find_sensor( &diff, &id[0] );
00039         if ( diff == OW_PRESENCE_ERR ) {
00040             printf( "No Sensor found\n" );
00041             return diff;
00042         }
00043         if ( diff == OW_DATA_ERR ) {
00044             printf( "Bus Error\n" );
00045             return diff;
00046         }
00047         for (i=0;i<OW_ROMCODE_SIZE;i++)
00048             gSensorIDs[(*nSensors)*OW_ROMCODE_SIZE+i]=id[i];
00049 
00050     }
00051     return OW_OK;
00052 }
00053 /**
00054 *     @brief show_id
00055 *    @param  [in] id[] = rom_code
00056 *    @param  [in] n number of id[n]
00057 *    @param  [out] text id
00058 *    @return OW_OK or OW_ERROR_CRC
00059 *     @date 20/06/2011
00060 */
00061 uint8_t ow_show_id( uint8_t id[], size_t n ,char *text) {
00062     size_t i;
00063     char hex[4];
00064     sprintf(text,"");
00065     
00066     for ( i = 0; i < n; i++ ) {
00067         if ( i == 0 ) strcat(text, " FC: " );
00068         else if ( i == n-1 ) strcat(text, "CRC: " );
00069         if ( i == 1 ) strcat(text, " SN: " );
00070         sprintf(hex,"%2.2X ",id[i]);
00071         strcat(text,hex);
00072         if ( i == 0 ) {
00073             if ( id[0] == DS18S20_ID ) strcat(text,"(18S)");
00074             else if ( id[0] == DS18B20_ID ) strcat(text,"(18B)");
00075             else strcat(text,"( ? )");
00076         }
00077     }
00078     if ( crc8( id, OW_ROMCODE_SIZE) )
00079         return OW_ERROR_CRC;
00080     return OW_OK;
00081 }
00082 
00083 /**
00084 *     @brief test pin onewire bus
00085 *    @return etat pin ow
00086 *     @date 20/06/2011
00087 */
00088 uint8_t ow_test_pin (void){
00089     if (ow_pin)
00090         return 1;
00091 return 0;   
00092 }
00093 /**
00094 *     @brief onewire reset bus
00095 *    @return pin ow or OW_SHORT_CIRCUIT
00096 *     @date 20/06/2011
00097 */
00098 uint8_t ow_reset(void) { // reset.  Should improve to act as a presence pulse
00099     uint8_t err;
00100 
00101     ow_pin.output();
00102     ow_pin = 0;     // bring low for 500 us
00103     wait_us(500);
00104     ow_pin.input();
00105     wait_us(60);
00106     err = ow_pin;
00107     wait_us(240);
00108     if ( ow_pin == 0 )    {    // short circuit
00109         err = OW_SHORT_CIRCUIT;
00110     }
00111     return err;
00112 }
00113 
00114 /**
00115 *     @brief read write onewire
00116 *    @param  [in/out] b data
00117 *    @return data
00118 *     @date 20/06/2011
00119 */
00120 uint8_t ow_bit_io( uint8_t b ) {
00121 
00122     ow_pin.output(); // drive bus low
00123     ow_pin = 0;
00124     wait_us(1); // Recovery-Time wuffwuff was 1
00125     
00126     if ( b ) 
00127         ow_pin.input(); // if bit is 1 set bus high (by ext. pull-up)
00128     //  delay was 15uS-1 see comment above
00129     wait_us(15-1);
00130     if ( ow_pin == 0 ) b = 0; // sample at end of read-timeslot
00131     wait_us(60-15);
00132     ow_pin.input();
00133     return b;
00134 }
00135 
00136 /**
00137 *     @brief byte write on onewire
00138 *    @param  [in] b data
00139 *    @return data
00140 *     @date 20/06/2011
00141 */
00142 uint8_t ow_byte_wr( uint8_t b ) {
00143     uint8_t i = 8, j;
00144 
00145     do {
00146         j = ow_bit_io( b & 1 );
00147         b >>= 1;
00148         if ( j )
00149             b |= 0x80;
00150     } while ( --i );
00151     return b;
00152 }
00153 
00154 /**
00155 *     @brief byte read on onewire
00156 *    @param  [in] uint8_t b
00157 *    @return 
00158 *     @date 20/06/2011
00159 */
00160 uint8_t ow_byte_rd( void ) {
00161     // read by sending 0xff (a dontcare?)
00162     return ow_byte_wr( 0xFF );
00163 }
00164 
00165 
00166 /**
00167 *     @brief search romcode
00168 *    @param  [in] uint8_t diff
00169 *    @param  [out] id romcode
00170 *    @return next_diff or OW_LAST_DEVICE or OW_DATA_ERR or OW_PRESENCE_ERR
00171 *     @date 20/06/2011
00172 */
00173 uint8_t ow_rom_search( uint8_t diff, uint8_t id[] ) {
00174     uint8_t i, j, next_diff;
00175     uint8_t b;
00176 
00177     if ( ow_reset() )
00178         return OW_PRESENCE_ERR;    // error, no device found
00179     ow_byte_wr( OW_SEARCH_ROM );            // ROM search command
00180     next_diff = OW_LAST_DEVICE;            // unchanged on last device
00181     i = OW_ROMCODE_SIZE * 8;                    // 8 bytes
00182     do {
00183         j = 8;                                // 8 bits
00184         do {
00185             b = ow_bit_io( 1 );                // read bit
00186             if ( ow_bit_io( 1 ) ) {            // read complement bit
00187                 if ( b )                    // 11
00188                     return OW_DATA_ERR;        // data error
00189             } else {
00190                 if ( !b ) {                    // 00 = 2 devices
00191                     if ( diff > i || ((*id & 1) && diff != i) ) {
00192                         b = 1;                // now 1
00193                         next_diff = i;        // next pass 0
00194                     }
00195                 }
00196             }
00197             ow_bit_io( b );                 // write bit
00198             *id >>= 1;
00199             if ( b ) 
00200                 *id |= 0x80;            // store bit
00201             --i;
00202         } while ( --j );
00203         id++;                                // next byte
00204     } while ( i );
00205     return next_diff;                // to continue search
00206 }
00207 
00208 /**
00209 *     @brief write command
00210 *    @param  [in] command
00211 *    @param  [in] id romcode
00212 *     @date 20/06/2011
00213 */
00214 uint8_t ow_command( uint8_t command, uint8_t id[] ) {
00215     uint8_t i;
00216 
00217     ow_reset();
00218     if ( id ) {
00219         ow_byte_wr( OW_MATCH_ROM );            // to a single device
00220         i = OW_ROMCODE_SIZE;
00221         do {
00222             ow_byte_wr( *id );
00223             ++id;
00224         } while ( --i );
00225     } else {
00226         ow_byte_wr( OW_SKIP_ROM );            // to all devices
00227     }
00228     ow_byte_wr( command );
00229     return 0;
00230 }
00231 /**
00232 *     @brief parasite enable
00233 *     @date 20/06/2011
00234 */
00235 uint8_t ow_parasite_enable(void) {
00236     ow_pin.output();
00237     ow_pin = 1;
00238     return 0;
00239 }
00240 /**
00241 *     @brief parasite disable
00242 *     @date 20/06/2011
00243 */
00244 uint8_t ow_parasite_disable(void) {
00245 
00246     ow_pin.input();
00247     return 0;
00248 }
00249 
00250 
00251 /**
00252 *     @brief find Sensors on 1-Wire-Bus
00253 *    @param  [in/out] diff is the result of the last rom-search
00254 *    @param  [out] is the rom-code of the sensor found
00255 *    @return  OW_OK or OW_ERROR 
00256 */
00257 uint8_t ow_find_sensor(uint8_t *diff, uint8_t id[]) {
00258     for (;;) 
00259     {
00260         *diff = ow_rom_search( *diff, &id[0] );
00261         if ( *diff==OW_PRESENCE_ERR)
00262             return OW_ERROR;
00263         if ( *diff==OW_DATA_ERR )
00264             return OW_ERROR;
00265         if ( *diff == OW_LAST_DEVICE )
00266             return OW_OK ;
00267         if ( id[0] == DS18B20_ID || id[0] == DS18S20_ID ) 
00268             return OW_OK ;
00269     }
00270 }
00271 
00272 /**
00273 *     @brief output byte d (least sig bit first)
00274 *    @param  [in] d output byte (least sig bit first)
00275 *    @return  OW_OK 
00276 */
00277 uint8_t OneWireOutByte(uint8_t d) { // output byte d (least sig bit first).
00278     for (int n=8; n!=0; n--) {
00279         if ((d & 0x01) == 1) { // test least sig bit
00280             ow_pin.output();
00281             ow_pin = 0;
00282             wait_us(5);
00283             ow_pin.input();
00284             wait_us(80);
00285         } else {
00286             ow_pin.output();
00287             ow_pin = 0;
00288             wait_us(80);
00289             ow_pin.input();
00290         }
00291         d=d>>1; // now the next bit is in the least sig bit position.
00292     }
00293     return OW_OK;
00294 }
00295 /**
00296 *     @brief read byte, least sig byte first
00297 *    @return  byte, least sig byte first 
00298 */
00299 uint8_t OneWireInByte(void) { // read byte, least sig byte first
00300     uint8_t d = 0, b;
00301     for (int n=0; n<8; n++) {
00302         ow_pin.output();
00303         ow_pin = 0;
00304         wait_us(5);
00305         ow_pin.input();
00306         wait_us(5);
00307         b =ow_pin;
00308         wait_us(50);
00309         d = (d >> 1) | (b << 7); // shift d to right and insert b in most sig bit position
00310     }
00311     return d;
00312 }
00313