├── OneWire.cpp ├── OneWire.h ├── README.md ├── examples ├── DS18x20_Temperature │ └── DS18x20_Temperature.pde ├── DS2408_Switch │ └── DS2408_Switch.pde └── DS250x_PROM │ └── DS250x_PROM.pde └── keywords.txt /OneWire.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2007, Jim Studt (original old version - many contributors since) 3 | 4 | Version 2.3: Modifications by Norbert Truchsess, January 2013 5 | add search_alarms() to find only devices in alarmed state. 6 | 7 | this Version is tracked on Github: https://github.com/ntruchsess/OneWire 8 | 9 | Version 2.1 and 2.2 of this library was taken from: 10 | http://www.pjrc.com/teensy/td_libs_OneWire.html 11 | 12 | OneWire has been maintained by Paul Stoffregen (paul@pjrc.com) since 13 | January 2010. At the time, it was in need of many bug fixes, but had 14 | been abandoned the original author (Jim Studt). None of the known 15 | contributors were interested in maintaining OneWire. Paul typically 16 | works on OneWire every 6 to 12 months. Patches usually wait that 17 | long. If anyone is interested in more actively maintaining OneWire, 18 | please contact Paul. 19 | 20 | Version 2.2: 21 | Teensy 3.0 compatibility, Paul Stoffregen, paul@pjrc.com 22 | Arduino Due compatibility, http://arduino.cc/forum/index.php?topic=141030 23 | Fix DS18B20 example negative temperature 24 | Fix DS18B20 example's low res modes, Ken Butcher 25 | Improve reset timing, Mark Tillotson 26 | Add const qualifiers, Bertrik Sikken 27 | Add initial value input to crc16, Bertrik Sikken 28 | Add target_search() function, Scott Roberts 29 | 30 | Version 2.1: 31 | Arduino 1.0 compatibility, Paul Stoffregen 32 | Improve temperature example, Paul Stoffregen 33 | DS250x_PROM example, Guillermo Lovato 34 | PIC32 (chipKit) compatibility, Jason Dangel, dangel.jason AT gmail.com 35 | Improvements from Glenn Trewitt: 36 | - crc16() now works 37 | - check_crc16() does all of calculation/checking work. 38 | - Added read_bytes() and write_bytes(), to reduce tedious loops. 39 | - Added ds2408 example. 40 | Delete very old, out-of-date readme file (info is here) 41 | 42 | Version 2.0: Modifications by Paul Stoffregen, January 2010: 43 | http://www.pjrc.com/teensy/td_libs_OneWire.html 44 | Search fix from Robin James 45 | http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 46 | Use direct optimized I/O in all cases 47 | Disable interrupts during timing critical sections 48 | (this solves many random communication errors) 49 | Disable interrupts during read-modify-write I/O 50 | Reduce RAM consumption by eliminating unnecessary 51 | variables and trimming many to 8 bits 52 | Optimize both crc8 - table version moved to flash 53 | 54 | Modified to work with larger numbers of devices - avoids loop. 55 | Tested in Arduino 11 alpha with 12 sensors. 56 | 26 Sept 2008 -- Robin James 57 | http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 58 | 59 | Updated to work with arduino-0008 and to include skip() as of 60 | 2007/07/06. --RJL20 61 | 62 | Modified to calculate the 8-bit CRC directly, avoiding the need for 63 | the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010 64 | -- Tom Pollard, Jan 23, 2008 65 | 66 | Jim Studt's original library was modified by Josh Larios. 67 | 68 | Tom Pollard, pollard@alum.mit.edu, contributed around May 20, 2008 69 | 70 | Permission is hereby granted, free of charge, to any person obtaining 71 | a copy of this software and associated documentation files (the 72 | "Software"), to deal in the Software without restriction, including 73 | without limitation the rights to use, copy, modify, merge, publish, 74 | distribute, sublicense, and/or sell copies of the Software, and to 75 | permit persons to whom the Software is furnished to do so, subject to 76 | the following conditions: 77 | 78 | The above copyright notice and this permission notice shall be 79 | included in all copies or substantial portions of the Software. 80 | 81 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 82 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 83 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 84 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 85 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 86 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 87 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 88 | 89 | Much of the code was inspired by Derek Yerger's code, though I don't 90 | think much of that remains. In any event that was.. 91 | (copyleft) 2006 by Derek Yerger - Free to distribute freely. 92 | 93 | The CRC code was excerpted and inspired by the Dallas Semiconductor 94 | sample code bearing this copyright. 95 | //--------------------------------------------------------------------------- 96 | // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved. 97 | // 98 | // Permission is hereby granted, free of charge, to any person obtaining a 99 | // copy of this software and associated documentation files (the "Software"), 100 | // to deal in the Software without restriction, including without limitation 101 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 102 | // and/or sell copies of the Software, and to permit persons to whom the 103 | // Software is furnished to do so, subject to the following conditions: 104 | // 105 | // The above copyright notice and this permission notice shall be included 106 | // in all copies or substantial portions of the Software. 107 | // 108 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 109 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 110 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 111 | // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES 112 | // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 113 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 114 | // OTHER DEALINGS IN THE SOFTWARE. 115 | // 116 | // Except as contained in this notice, the name of Dallas Semiconductor 117 | // shall not be used except as stated in the Dallas Semiconductor 118 | // Branding Policy. 119 | //-------------------------------------------------------------------------- 120 | */ 121 | 122 | #include "OneWire.h" 123 | 124 | 125 | OneWire::OneWire(uint8_t pin) 126 | { 127 | pinMode(pin, INPUT); 128 | bitmask = PIN_TO_BITMASK(pin); 129 | baseReg = PIN_TO_BASEREG(pin); 130 | #if ONEWIRE_SEARCH 131 | reset_search(); 132 | #endif 133 | } 134 | 135 | 136 | // Perform the onewire reset function. We will wait up to 250uS for 137 | // the bus to come high, if it doesn't then it is broken or shorted 138 | // and we return a 0; 139 | // 140 | // Returns 1 if a device asserted a presence pulse, 0 otherwise. 141 | // 142 | uint8_t OneWire::reset(void) 143 | { 144 | IO_REG_TYPE mask = bitmask; 145 | volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; 146 | uint8_t r; 147 | uint8_t retries = 125; 148 | 149 | noInterrupts(); 150 | DIRECT_MODE_INPUT(reg, mask); 151 | interrupts(); 152 | // wait until the wire is high... just in case 153 | do { 154 | if (--retries == 0) return 0; 155 | delayMicroseconds(2); 156 | } while ( !DIRECT_READ(reg, mask)); 157 | 158 | noInterrupts(); 159 | DIRECT_WRITE_LOW(reg, mask); 160 | DIRECT_MODE_OUTPUT(reg, mask); // drive output low 161 | interrupts(); 162 | delayMicroseconds(480); 163 | noInterrupts(); 164 | DIRECT_MODE_INPUT(reg, mask); // allow it to float 165 | delayMicroseconds(70); 166 | r = !DIRECT_READ(reg, mask); 167 | interrupts(); 168 | delayMicroseconds(410); 169 | return r; 170 | } 171 | 172 | // 173 | // Write a bit. Port and bit is used to cut lookup time and provide 174 | // more certain timing. 175 | // 176 | void OneWire::write_bit(uint8_t v) 177 | { 178 | IO_REG_TYPE mask=bitmask; 179 | volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; 180 | 181 | if (v & 1) { 182 | noInterrupts(); 183 | DIRECT_WRITE_LOW(reg, mask); 184 | DIRECT_MODE_OUTPUT(reg, mask); // drive output low 185 | delayMicroseconds(10); 186 | DIRECT_WRITE_HIGH(reg, mask); // drive output high 187 | interrupts(); 188 | delayMicroseconds(55); 189 | } else { 190 | noInterrupts(); 191 | DIRECT_WRITE_LOW(reg, mask); 192 | DIRECT_MODE_OUTPUT(reg, mask); // drive output low 193 | delayMicroseconds(65); 194 | DIRECT_WRITE_HIGH(reg, mask); // drive output high 195 | interrupts(); 196 | delayMicroseconds(5); 197 | } 198 | } 199 | 200 | // 201 | // Read a bit. Port and bit is used to cut lookup time and provide 202 | // more certain timing. 203 | // 204 | uint8_t OneWire::read_bit(void) 205 | { 206 | IO_REG_TYPE mask=bitmask; 207 | volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; 208 | uint8_t r; 209 | 210 | noInterrupts(); 211 | DIRECT_MODE_OUTPUT(reg, mask); 212 | DIRECT_WRITE_LOW(reg, mask); 213 | delayMicroseconds(3); 214 | DIRECT_MODE_INPUT(reg, mask); // let pin float, pull up will raise 215 | delayMicroseconds(10); 216 | r = DIRECT_READ(reg, mask); 217 | interrupts(); 218 | delayMicroseconds(53); 219 | return r; 220 | } 221 | 222 | // 223 | // Write a byte. The writing code uses the active drivers to raise the 224 | // pin high, if you need power after the write (e.g. DS18S20 in 225 | // parasite power mode) then set 'power' to 1, otherwise the pin will 226 | // go tri-state at the end of the write to avoid heating in a short or 227 | // other mishap. 228 | // 229 | void OneWire::write(uint8_t v, uint8_t power /* = 0 */) { 230 | uint8_t bitMask; 231 | 232 | for (bitMask = 0x01; bitMask; bitMask <<= 1) { 233 | OneWire::write_bit( (bitMask & v)?1:0); 234 | } 235 | if ( !power) { 236 | noInterrupts(); 237 | DIRECT_MODE_INPUT(baseReg, bitmask); 238 | DIRECT_WRITE_LOW(baseReg, bitmask); 239 | interrupts(); 240 | } 241 | } 242 | 243 | void OneWire::write_bytes(const uint8_t *buf, uint16_t count, bool power /* = 0 */) { 244 | for (uint16_t i = 0 ; i < count ; i++) 245 | write(buf[i]); 246 | if (!power) { 247 | noInterrupts(); 248 | DIRECT_MODE_INPUT(baseReg, bitmask); 249 | DIRECT_WRITE_LOW(baseReg, bitmask); 250 | interrupts(); 251 | } 252 | } 253 | 254 | // 255 | // Read a byte 256 | // 257 | uint8_t OneWire::read() { 258 | uint8_t bitMask; 259 | uint8_t r = 0; 260 | 261 | for (bitMask = 0x01; bitMask; bitMask <<= 1) { 262 | if ( OneWire::read_bit()) r |= bitMask; 263 | } 264 | return r; 265 | } 266 | 267 | void OneWire::read_bytes(uint8_t *buf, uint16_t count) { 268 | for (uint16_t i = 0 ; i < count ; i++) 269 | buf[i] = read(); 270 | } 271 | 272 | // 273 | // Do a ROM select 274 | // 275 | void OneWire::select(const uint8_t rom[8]) 276 | { 277 | uint8_t i; 278 | 279 | write(0x55); // Choose ROM 280 | 281 | for (i = 0; i < 8; i++) write(rom[i]); 282 | } 283 | 284 | // 285 | // Do a ROM skip 286 | // 287 | void OneWire::skip() 288 | { 289 | write(0xCC); // Skip ROM 290 | } 291 | 292 | void OneWire::depower() 293 | { 294 | noInterrupts(); 295 | DIRECT_MODE_INPUT(baseReg, bitmask); 296 | interrupts(); 297 | } 298 | 299 | #if ONEWIRE_SEARCH 300 | 301 | // 302 | // You need to use this function to start a search again from the beginning. 303 | // You do not need to do it for the first search, though you could. 304 | // 305 | void OneWire::reset_search() 306 | { 307 | // reset the search state 308 | LastDiscrepancy = 0; 309 | LastDeviceFlag = FALSE; 310 | LastFamilyDiscrepancy = 0; 311 | for(int i = 7; ; i--) { 312 | ROM_NO[i] = 0; 313 | if ( i == 0) break; 314 | } 315 | } 316 | 317 | // Setup the search to find the device type 'family_code' on the next call 318 | // to search(*newAddr) if it is present. 319 | // 320 | void OneWire::target_search(uint8_t family_code) 321 | { 322 | // set the search state to find SearchFamily type devices 323 | ROM_NO[0] = family_code; 324 | for (uint8_t i = 1; i < 8; i++) 325 | ROM_NO[i] = 0; 326 | LastDiscrepancy = 64; 327 | LastFamilyDiscrepancy = 0; 328 | LastDeviceFlag = FALSE; 329 | } 330 | 331 | // 332 | // Perform a search. If this function returns a '1' then it has 333 | // enumerated the next device and you may retrieve the ROM from the 334 | // OneWire::address variable. If there are no devices, no further 335 | // devices, or something horrible happens in the middle of the 336 | // enumeration then a 0 is returned. If a new device is found then 337 | // its address is copied to newAddr. Use OneWire::reset_search() to 338 | // start over. 339 | // 340 | // --- Replaced by the one from the Dallas Semiconductor web site --- 341 | //-------------------------------------------------------------------------- 342 | // Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing 343 | // search state. 344 | // Return TRUE : device found, ROM number in ROM_NO buffer 345 | // FALSE : device not found, end of search 346 | // 347 | 348 | uint8_t OneWire::search(uint8_t *newAddr) 349 | { 350 | return search_internal(newAddr,0xF0); 351 | } 352 | 353 | // 354 | // Like search. Return devices that are in alarm state only. 355 | // 356 | 357 | uint8_t OneWire::search_alarms(uint8_t *newAddr) 358 | { 359 | return search_internal(newAddr,0xEC); 360 | } 361 | 362 | uint8_t OneWire::search_internal(uint8_t *newAddr, uint8_t command) 363 | { 364 | uint8_t id_bit_number; 365 | uint8_t last_zero, rom_byte_number, search_result; 366 | uint8_t id_bit, cmp_id_bit; 367 | 368 | unsigned char rom_byte_mask, search_direction; 369 | 370 | // initialize for search 371 | id_bit_number = 1; 372 | last_zero = 0; 373 | rom_byte_number = 0; 374 | rom_byte_mask = 1; 375 | search_result = 0; 376 | 377 | // if the last call was not the last one 378 | if (!LastDeviceFlag) 379 | { 380 | // 1-Wire reset 381 | if (!reset()) 382 | { 383 | // reset the search 384 | LastDiscrepancy = 0; 385 | LastDeviceFlag = FALSE; 386 | LastFamilyDiscrepancy = 0; 387 | return FALSE; 388 | } 389 | 390 | // issue the search command 391 | write(command); 392 | 393 | // loop to do the search 394 | do 395 | { 396 | // read a bit and its complement 397 | id_bit = read_bit(); 398 | cmp_id_bit = read_bit(); 399 | 400 | // check for no devices on 1-wire 401 | if ((id_bit == 1) && (cmp_id_bit == 1)) 402 | break; 403 | else 404 | { 405 | // all devices coupled have 0 or 1 406 | if (id_bit != cmp_id_bit) 407 | search_direction = id_bit; // bit write value for search 408 | else 409 | { 410 | // if this discrepancy if before the Last Discrepancy 411 | // on a previous next then pick the same as last time 412 | if (id_bit_number < LastDiscrepancy) 413 | search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); 414 | else 415 | // if equal to last pick 1, if not then pick 0 416 | search_direction = (id_bit_number == LastDiscrepancy); 417 | 418 | // if 0 was picked then record its position in LastZero 419 | if (search_direction == 0) 420 | { 421 | last_zero = id_bit_number; 422 | 423 | // check for Last discrepancy in family 424 | if (last_zero < 9) 425 | LastFamilyDiscrepancy = last_zero; 426 | } 427 | } 428 | 429 | // set or clear the bit in the ROM byte rom_byte_number 430 | // with mask rom_byte_mask 431 | if (search_direction == 1) 432 | ROM_NO[rom_byte_number] |= rom_byte_mask; 433 | else 434 | ROM_NO[rom_byte_number] &= ~rom_byte_mask; 435 | 436 | // serial number search direction write bit 437 | write_bit(search_direction); 438 | 439 | // increment the byte counter id_bit_number 440 | // and shift the mask rom_byte_mask 441 | id_bit_number++; 442 | rom_byte_mask <<= 1; 443 | 444 | // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask 445 | if (rom_byte_mask == 0) 446 | { 447 | rom_byte_number++; 448 | rom_byte_mask = 1; 449 | } 450 | } 451 | } 452 | while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 453 | 454 | // if the search was successful then 455 | if (!(id_bit_number < 65)) 456 | { 457 | // search successful so set LastDiscrepancy,LastDeviceFlag,search_result 458 | LastDiscrepancy = last_zero; 459 | 460 | // check for last device 461 | if (LastDiscrepancy == 0) 462 | LastDeviceFlag = TRUE; 463 | 464 | search_result = TRUE; 465 | } 466 | } 467 | 468 | // if no device found then reset counters so next 'search' will be like a first 469 | if (!search_result || !ROM_NO[0]) 470 | { 471 | LastDiscrepancy = 0; 472 | LastDeviceFlag = FALSE; 473 | LastFamilyDiscrepancy = 0; 474 | search_result = FALSE; 475 | } 476 | for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i]; 477 | return search_result; 478 | } 479 | 480 | #endif 481 | 482 | #if ONEWIRE_CRC 483 | // The 1-Wire CRC scheme is described in Maxim Application Note 27: 484 | // "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products" 485 | // 486 | 487 | #if ONEWIRE_CRC8_TABLE 488 | // This table comes from Dallas sample code where it is freely reusable, 489 | // though Copyright (C) 2000 Dallas Semiconductor Corporation 490 | static const uint8_t PROGMEM dscrc_table[] = { 491 | 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, 492 | 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, 493 | 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, 494 | 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, 495 | 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, 496 | 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, 497 | 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, 498 | 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, 499 | 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 500 | 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 501 | 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 502 | 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 503 | 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, 504 | 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 505 | 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 506 | 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; 507 | 508 | // 509 | // Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM 510 | // and the registers. (note: this might better be done without to 511 | // table, it would probably be smaller and certainly fast enough 512 | // compared to all those delayMicrosecond() calls. But I got 513 | // confused, so I use this table from the examples.) 514 | // 515 | uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len) 516 | { 517 | uint8_t crc = 0; 518 | 519 | while (len--) { 520 | crc = pgm_read_byte(dscrc_table + (crc ^ *addr++)); 521 | } 522 | return crc; 523 | } 524 | #else 525 | // 526 | // Compute a Dallas Semiconductor 8 bit CRC directly. 527 | // this is much slower, but much smaller, than the lookup table. 528 | // 529 | uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len) 530 | { 531 | uint8_t crc = 0; 532 | 533 | while (len--) { 534 | uint8_t inbyte = *addr++; 535 | for (uint8_t i = 8; i; i--) { 536 | uint8_t mix = (crc ^ inbyte) & 0x01; 537 | crc >>= 1; 538 | if (mix) crc ^= 0x8C; 539 | inbyte >>= 1; 540 | } 541 | } 542 | return crc; 543 | } 544 | #endif 545 | 546 | #if ONEWIRE_CRC16 547 | bool OneWire::check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc) 548 | { 549 | crc = ~crc16(input, len, crc); 550 | return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1]; 551 | } 552 | 553 | uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc) 554 | { 555 | static const uint8_t oddparity[16] = 556 | { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; 557 | 558 | for (uint16_t i = 0 ; i < len ; i++) { 559 | // Even though we're just copying a byte from the input, 560 | // we'll be doing 16-bit computation with it. 561 | uint16_t cdata = input[i]; 562 | cdata = (cdata ^ crc) & 0xff; 563 | crc >>= 8; 564 | 565 | if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4]) 566 | crc ^= 0xC001; 567 | 568 | cdata <<= 6; 569 | crc ^= cdata; 570 | cdata <<= 1; 571 | crc ^= cdata; 572 | } 573 | return crc; 574 | } 575 | #endif 576 | 577 | #endif 578 | -------------------------------------------------------------------------------- /OneWire.h: -------------------------------------------------------------------------------- 1 | #ifndef OneWire_h 2 | #define OneWire_h 3 | 4 | #include 5 | 6 | #if ARDUINO >= 100 7 | #include "Arduino.h" // for delayMicroseconds, digitalPinToBitMask, etc 8 | #else 9 | #include "WProgram.h" // for delayMicroseconds 10 | #include "pins_arduino.h" // for digitalPinToBitMask, etc 11 | #endif 12 | 13 | // You can exclude certain features from OneWire. In theory, this 14 | // might save some space. In practice, the compiler automatically 15 | // removes unused code (technically, the linker, using -fdata-sections 16 | // and -ffunction-sections when compiling, and Wl,--gc-sections 17 | // when linking), so most of these will not result in any code size 18 | // reduction. Well, unless you try to use the missing features 19 | // and redesign your program to not need them! ONEWIRE_CRC8_TABLE 20 | // is the exception, because it selects a fast but large algorithm 21 | // or a small but slow algorithm. 22 | 23 | // you can exclude onewire_search by defining that to 0 24 | #ifndef ONEWIRE_SEARCH 25 | #define ONEWIRE_SEARCH 1 26 | #endif 27 | 28 | // You can exclude CRC checks altogether by defining this to 0 29 | #ifndef ONEWIRE_CRC 30 | #define ONEWIRE_CRC 1 31 | #endif 32 | 33 | // Select the table-lookup method of computing the 8-bit CRC 34 | // by setting this to 1. The lookup table enlarges code size by 35 | // about 250 bytes. It does NOT consume RAM (but did in very 36 | // old versions of OneWire). If you disable this, a slower 37 | // but very compact algorithm is used. 38 | #ifndef ONEWIRE_CRC8_TABLE 39 | #define ONEWIRE_CRC8_TABLE 1 40 | #endif 41 | 42 | // You can allow 16-bit CRC checks by defining this to 1 43 | // (Note that ONEWIRE_CRC must also be 1.) 44 | #ifndef ONEWIRE_CRC16 45 | #define ONEWIRE_CRC16 1 46 | #endif 47 | 48 | #define FALSE 0 49 | #define TRUE 1 50 | 51 | // Platform specific I/O definitions 52 | 53 | #if defined(__AVR__) 54 | #define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) 55 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 56 | #define IO_REG_TYPE uint8_t 57 | #define IO_REG_ASM asm("r30") 58 | #define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 59 | #define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)) 60 | #define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) 61 | #define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) 62 | #define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) 63 | 64 | #elif defined(__MK20DX128__) 65 | #define PIN_TO_BASEREG(pin) (portOutputRegister(pin)) 66 | #define PIN_TO_BITMASK(pin) (1) 67 | #define IO_REG_TYPE uint8_t 68 | #define IO_REG_ASM 69 | #define DIRECT_READ(base, mask) (*((base)+512)) 70 | #define DIRECT_MODE_INPUT(base, mask) (*((base)+640) = 0) 71 | #define DIRECT_MODE_OUTPUT(base, mask) (*((base)+640) = 1) 72 | #define DIRECT_WRITE_LOW(base, mask) (*((base)+256) = 1) 73 | #define DIRECT_WRITE_HIGH(base, mask) (*((base)+128) = 1) 74 | 75 | #elif defined(__SAM3X8E__) 76 | // Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due. 77 | // http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268 78 | // If you have trouble with OneWire on Arduino Due, please check the 79 | // status of delayMicroseconds() before reporting a bug in OneWire! 80 | #define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER)) 81 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 82 | #define IO_REG_TYPE uint32_t 83 | #define IO_REG_ASM 84 | #define DIRECT_READ(base, mask) (((*((base)+15)) & (mask)) ? 1 : 0) 85 | #define DIRECT_MODE_INPUT(base, mask) ((*((base)+5)) = (mask)) 86 | #define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+4)) = (mask)) 87 | #define DIRECT_WRITE_LOW(base, mask) ((*((base)+13)) = (mask)) 88 | #define DIRECT_WRITE_HIGH(base, mask) ((*((base)+12)) = (mask)) 89 | #ifndef PROGMEM 90 | #define PROGMEM 91 | #endif 92 | #ifndef pgm_read_byte 93 | #define pgm_read_byte(addr) (*(const uint8_t *)(addr)) 94 | #endif 95 | 96 | #elif defined(__PIC32MX__) 97 | #define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin))) 98 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 99 | #define IO_REG_TYPE uint32_t 100 | #define IO_REG_ASM 101 | #define DIRECT_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0) //PORTX + 0x10 102 | #define DIRECT_MODE_INPUT(base, mask) ((*(base+2)) = (mask)) //TRISXSET + 0x08 103 | #define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) = (mask)) //TRISXCLR + 0x04 104 | #define DIRECT_WRITE_LOW(base, mask) ((*(base+8+1)) = (mask)) //LATXCLR + 0x24 105 | #define DIRECT_WRITE_HIGH(base, mask) ((*(base+8+2)) = (mask)) //LATXSET + 0x28 106 | 107 | #else 108 | #error "Please define I/O register types here" 109 | #endif 110 | 111 | 112 | class OneWire 113 | { 114 | private: 115 | IO_REG_TYPE bitmask; 116 | volatile IO_REG_TYPE *baseReg; 117 | 118 | #if ONEWIRE_SEARCH 119 | // global search state 120 | unsigned char ROM_NO[8]; 121 | uint8_t LastDiscrepancy; 122 | uint8_t LastFamilyDiscrepancy; 123 | uint8_t LastDeviceFlag; 124 | 125 | uint8_t search_internal(uint8_t *newAddr, uint8_t command); 126 | #endif 127 | 128 | public: 129 | OneWire( uint8_t pin); 130 | 131 | // Perform a 1-Wire reset cycle. Returns 1 if a device responds 132 | // with a presence pulse. Returns 0 if there is no device or the 133 | // bus is shorted or otherwise held low for more than 250uS 134 | uint8_t reset(void); 135 | 136 | // Issue a 1-Wire rom select command, you do the reset first. 137 | void select(const uint8_t rom[8]); 138 | 139 | // Issue a 1-Wire rom skip command, to address all on bus. 140 | void skip(void); 141 | 142 | // Write a byte. If 'power' is one then the wire is held high at 143 | // the end for parasitically powered devices. You are responsible 144 | // for eventually depowering it by calling depower() or doing 145 | // another read or write. 146 | void write(uint8_t v, uint8_t power = 0); 147 | 148 | void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); 149 | 150 | // Read a byte. 151 | uint8_t read(void); 152 | 153 | void read_bytes(uint8_t *buf, uint16_t count); 154 | 155 | // Write a bit. The bus is always left powered at the end, see 156 | // note in write() about that. 157 | void write_bit(uint8_t v); 158 | 159 | // Read a bit. 160 | uint8_t read_bit(void); 161 | 162 | // Stop forcing power onto the bus. You only need to do this if 163 | // you used the 'power' flag to write() or used a write_bit() call 164 | // and aren't about to do another read or write. You would rather 165 | // not leave this powered if you don't have to, just in case 166 | // someone shorts your bus. 167 | void depower(void); 168 | 169 | #if ONEWIRE_SEARCH 170 | // Clear the search state so that if will start from the beginning again. 171 | void reset_search(); 172 | 173 | // Setup the search to find the device type 'family_code' on the next call 174 | // to search(*newAddr) if it is present. 175 | void target_search(uint8_t family_code); 176 | 177 | // Look for the next device. Returns 1 if a new address has been 178 | // returned. A zero might mean that the bus is shorted, there are 179 | // no devices, or you have already retrieved all of them. It 180 | // might be a good idea to check the CRC to make sure you didn't 181 | // get garbage. The order is deterministic. You will always get 182 | // the same devices in the same order. 183 | uint8_t search(uint8_t *newAddr); 184 | 185 | // Like search, but finds devices in alarmed state only. 186 | uint8_t search_alarms(uint8_t *newAddr); 187 | #endif 188 | 189 | #if ONEWIRE_CRC 190 | // Compute a Dallas Semiconductor 8 bit CRC, these are used in the 191 | // ROM and scratchpad registers. 192 | static uint8_t crc8(const uint8_t *addr, uint8_t len); 193 | 194 | #if ONEWIRE_CRC16 195 | // Compute the 1-Wire CRC16 and compare it against the received CRC. 196 | // Example usage (reading a DS2408): 197 | // // Put everything in a buffer so we can compute the CRC easily. 198 | // uint8_t buf[13]; 199 | // buf[0] = 0xF0; // Read PIO Registers 200 | // buf[1] = 0x88; // LSB address 201 | // buf[2] = 0x00; // MSB address 202 | // WriteBytes(net, buf, 3); // Write 3 cmd bytes 203 | // ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16 204 | // if (!CheckCRC16(buf, 11, &buf[11])) { 205 | // // Handle error. 206 | // } 207 | // 208 | // @param input - Array of bytes to checksum. 209 | // @param len - How many bytes to use. 210 | // @param inverted_crc - The two CRC16 bytes in the received data. 211 | // This should just point into the received data, 212 | // *not* at a 16-bit integer. 213 | // @param crc - The crc starting value (optional) 214 | // @return True, iff the CRC matches. 215 | static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0); 216 | 217 | // Compute a Dallas Semiconductor 16 bit CRC. This is required to check 218 | // the integrity of data received from many 1-Wire devices. Note that the 219 | // CRC computed here is *not* what you'll get from the 1-Wire network, 220 | // for two reasons: 221 | // 1) The CRC is transmitted bitwise inverted. 222 | // 2) Depending on the endian-ness of your processor, the binary 223 | // representation of the two-byte return value may have a different 224 | // byte order than the two bytes you get from 1-Wire. 225 | // @param input - Array of bytes to checksum. 226 | // @param len - How many bytes to use. 227 | // @param crc - The crc starting value (optional) 228 | // @return The CRC16, as defined by Dallas Semiconductor. 229 | static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0); 230 | #endif 231 | #endif 232 | }; 233 | 234 | #endif 235 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007, Jim Studt (original old version - many contributors since) 2 | 3 | Version 2.3: Modifications by Norbert Truchsess, January 2013 4 | add search_alarms() to find only devices in alarmed state. 5 | 6 | this Version is tracked on Github: https://github.com/ntruchsess/OneWire 7 | 8 | Version 2.1 and 2.2 of this library was taken from: 9 | http://www.pjrc.com/teensy/td_libs_OneWire.html 10 | 11 | OneWire has been maintained by Paul Stoffregen (paul@pjrc.com) since 12 | January 2010. At the time, it was in need of many bug fixes, but had 13 | been abandoned the original author (Jim Studt). None of the known 14 | contributors were interested in maintaining OneWire. Paul typically 15 | works on OneWire every 6 to 12 months. Patches usually wait that 16 | long. If anyone is interested in more actively maintaining OneWire, 17 | please contact Paul. 18 | 19 | Version 2.2: 20 | Teensy 3.0 compatibility, Paul Stoffregen, paul@pjrc.com 21 | Arduino Due compatibility, http://arduino.cc/forum/index.php?topic=141030 22 | Fix DS18B20 example negative temperature 23 | Fix DS18B20 example's low res modes, Ken Butcher 24 | Improve reset timing, Mark Tillotson 25 | Add const qualifiers, Bertrik Sikken 26 | Add initial value input to crc16, Bertrik Sikken 27 | Add target_search() function, Scott Roberts 28 | 29 | Version 2.1: 30 | Arduino 1.0 compatibility, Paul Stoffregen 31 | Improve temperature example, Paul Stoffregen 32 | DS250x_PROM example, Guillermo Lovato 33 | PIC32 (chipKit) compatibility, Jason Dangel, dangel.jason AT gmail.com 34 | Improvements from Glenn Trewitt: 35 | - crc16() now works 36 | - check_crc16() does all of calculation/checking work. 37 | - Added read_bytes() and write_bytes(), to reduce tedious loops. 38 | - Added ds2408 example. 39 | Delete very old, out-of-date readme file (info is here) 40 | 41 | Version 2.0: Modifications by Paul Stoffregen, January 2010: 42 | http://www.pjrc.com/teensy/td_libs_OneWire.html 43 | Search fix from Robin James 44 | http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 45 | Use direct optimized I/O in all cases 46 | Disable interrupts during timing critical sections 47 | (this solves many random communication errors) 48 | Disable interrupts during read-modify-write I/O 49 | Reduce RAM consumption by eliminating unnecessary 50 | variables and trimming many to 8 bits 51 | Optimize both crc8 - table version moved to flash 52 | 53 | Modified to work with larger numbers of devices - avoids loop. 54 | Tested in Arduino 11 alpha with 12 sensors. 55 | 26 Sept 2008 -- Robin James 56 | http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 57 | 58 | Updated to work with arduino-0008 and to include skip() as of 59 | 2007/07/06. --RJL20 60 | 61 | Modified to calculate the 8-bit CRC directly, avoiding the need for 62 | the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010 63 | -- Tom Pollard, Jan 23, 2008 64 | 65 | Jim Studt's original library was modified by Josh Larios. 66 | 67 | Tom Pollard, pollard@alum.mit.edu, contributed around May 20, 2008 68 | 69 | Permission is hereby granted, free of charge, to any person obtaining 70 | a copy of this software and associated documentation files (the 71 | "Software"), to deal in the Software without restriction, including 72 | without limitation the rights to use, copy, modify, merge, publish, 73 | distribute, sublicense, and/or sell copies of the Software, and to 74 | permit persons to whom the Software is furnished to do so, subject to 75 | the following conditions: 76 | 77 | The above copyright notice and this permission notice shall be 78 | included in all copies or substantial portions of the Software. 79 | 80 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 81 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 82 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 83 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 84 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 85 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 86 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 87 | 88 | Much of the code was inspired by Derek Yerger's code, though I don't 89 | think much of that remains. In any event that was.. 90 | (copyleft) 2006 by Derek Yerger - Free to distribute freely. 91 | 92 | The CRC code was excerpted and inspired by the Dallas Semiconductor 93 | sample code bearing this copyright. 94 | //--------------------------------------------------------------------------- 95 | // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved. 96 | // 97 | // Permission is hereby granted, free of charge, to any person obtaining a 98 | // copy of this software and associated documentation files (the "Software"), 99 | // to deal in the Software without restriction, including without limitation 100 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 101 | // and/or sell copies of the Software, and to permit persons to whom the 102 | // Software is furnished to do so, subject to the following conditions: 103 | // 104 | // The above copyright notice and this permission notice shall be included 105 | // in all copies or substantial portions of the Software. 106 | // 107 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 108 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 109 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 110 | // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES 111 | // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 112 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 113 | // OTHER DEALINGS IN THE SOFTWARE. 114 | // 115 | // Except as contained in this notice, the name of Dallas Semiconductor 116 | // shall not be used except as stated in the Dallas Semiconductor 117 | // Branding Policy. 118 | //-------------------------------------------------------------------------- 119 | -------------------------------------------------------------------------------- /examples/DS18x20_Temperature/DS18x20_Temperature.pde: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // OneWire DS18S20, DS18B20, DS1822 Temperature Example 4 | // 5 | // http://www.pjrc.com/teensy/td_libs_OneWire.html 6 | // 7 | // The DallasTemperature library can do all this work for you! 8 | // http://milesburton.com/Dallas_Temperature_Control_Library 9 | 10 | OneWire ds(10); // on pin 10 (a 4.7K resistor is necessary) 11 | 12 | void setup(void) { 13 | Serial.begin(9600); 14 | } 15 | 16 | void loop(void) { 17 | byte i; 18 | byte present = 0; 19 | byte type_s; 20 | byte data[12]; 21 | byte addr[8]; 22 | float celsius, fahrenheit; 23 | 24 | if ( !ds.search(addr)) { 25 | Serial.println("No more addresses."); 26 | Serial.println(); 27 | ds.reset_search(); 28 | delay(250); 29 | return; 30 | } 31 | 32 | Serial.print("ROM ="); 33 | for( i = 0; i < 8; i++) { 34 | Serial.write(' '); 35 | Serial.print(addr[i], HEX); 36 | } 37 | 38 | if (OneWire::crc8(addr, 7) != addr[7]) { 39 | Serial.println("CRC is not valid!"); 40 | return; 41 | } 42 | Serial.println(); 43 | 44 | // the first ROM byte indicates which chip 45 | switch (addr[0]) { 46 | case 0x10: 47 | Serial.println(" Chip = DS18S20"); // or old DS1820 48 | type_s = 1; 49 | break; 50 | case 0x28: 51 | Serial.println(" Chip = DS18B20"); 52 | type_s = 0; 53 | break; 54 | case 0x22: 55 | Serial.println(" Chip = DS1822"); 56 | type_s = 0; 57 | break; 58 | default: 59 | Serial.println("Device is not a DS18x20 family device."); 60 | return; 61 | } 62 | 63 | ds.reset(); 64 | ds.select(addr); 65 | ds.write(0x44, 1); // start conversion, with parasite power on at the end 66 | 67 | delay(1000); // maybe 750ms is enough, maybe not 68 | // we might do a ds.depower() here, but the reset will take care of it. 69 | 70 | present = ds.reset(); 71 | ds.select(addr); 72 | ds.write(0xBE); // Read Scratchpad 73 | 74 | Serial.print(" Data = "); 75 | Serial.print(present, HEX); 76 | Serial.print(" "); 77 | for ( i = 0; i < 9; i++) { // we need 9 bytes 78 | data[i] = ds.read(); 79 | Serial.print(data[i], HEX); 80 | Serial.print(" "); 81 | } 82 | Serial.print(" CRC="); 83 | Serial.print(OneWire::crc8(data, 8), HEX); 84 | Serial.println(); 85 | 86 | // Convert the data to actual temperature 87 | // because the result is a 16 bit signed integer, it should 88 | // be stored to an "int16_t" type, which is always 16 bits 89 | // even when compiled on a 32 bit processor. 90 | int16_t raw = (data[1] << 8) | data[0]; 91 | if (type_s) { 92 | raw = raw << 3; // 9 bit resolution default 93 | if (data[7] == 0x10) { 94 | // "count remain" gives full 12 bit resolution 95 | raw = (raw & 0xFFF0) + 12 - data[6]; 96 | } 97 | } else { 98 | byte cfg = (data[4] & 0x60); 99 | // at lower res, the low bits are undefined, so let's zero them 100 | if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms 101 | else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms 102 | else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms 103 | //// default is 12 bit resolution, 750 ms conversion time 104 | } 105 | celsius = (float)raw / 16.0; 106 | fahrenheit = celsius * 1.8 + 32.0; 107 | Serial.print(" Temperature = "); 108 | Serial.print(celsius); 109 | Serial.print(" Celsius, "); 110 | Serial.print(fahrenheit); 111 | Serial.println(" Fahrenheit"); 112 | } 113 | -------------------------------------------------------------------------------- /examples/DS2408_Switch/DS2408_Switch.pde: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 4 | * DS2408 8-Channel Addressable Switch 5 | * 6 | * Writte by Glenn Trewitt, glenn at trewitt dot org 7 | * 8 | * Some notes about the DS2408: 9 | * - Unlike most input/output ports, the DS2408 doesn't have mode bits to 10 | * set whether the pins are input or output. If you issue a read command, 11 | * they're inputs. If you write to them, they're outputs. 12 | * - For reading from a switch, you should use 10K pull-up resisters. 13 | */ 14 | 15 | void PrintBytes(uint8_t* addr, uint8_t count, bool newline=0) { 16 | for (uint8_t i = 0; i < count; i++) { 17 | Serial.print(addr[i]>>4, HEX); 18 | Serial.print(addr[i]&0x0f, HEX); 19 | } 20 | if (newline) 21 | Serial.println(); 22 | } 23 | 24 | void ReadAndReport(OneWire* net, uint8_t* addr) { 25 | Serial.print(" Reading DS2408 "); 26 | PrintBytes(addr, 8); 27 | Serial.println(); 28 | 29 | uint8_t buf[13]; // Put everything in the buffer so we can compute CRC easily. 30 | buf[0] = 0xF0; // Read PIO Registers 31 | buf[1] = 0x88; // LSB address 32 | buf[2] = 0x00; // MSB address 33 | net->write_bytes(buf, 3); 34 | net->read_bytes(buf+3, 10); // 3 cmd bytes, 6 data bytes, 2 0xFF, 2 CRC16 35 | net->reset(); 36 | 37 | if (!OneWire::check_crc16(buf, 11, &buf[11])) { 38 | Serial.print("CRC failure in DS2408 at "); 39 | PrintBytes(addr, 8, true); 40 | return; 41 | } 42 | Serial.print(" DS2408 data = "); 43 | // First 3 bytes contain command, register address. 44 | Serial.println(buf[3], BIN); 45 | } 46 | 47 | OneWire net(10); // on pin 10 48 | 49 | void setup(void) { 50 | Serial.begin(9600); 51 | } 52 | 53 | void loop(void) { 54 | byte i; 55 | byte present = 0; 56 | byte addr[8]; 57 | 58 | if (!net.search(addr)) { 59 | Serial.print("No more addresses.\n"); 60 | net.reset_search(); 61 | delay(1000); 62 | return; 63 | } 64 | 65 | if (OneWire::crc8(addr, 7) != addr[7]) { 66 | Serial.print("CRC is not valid!\n"); 67 | return; 68 | } 69 | 70 | if (addr[0] != 0x29) { 71 | PrintBytes(addr, 8); 72 | Serial.print(" is not a DS2408.\n"); 73 | return; 74 | } 75 | 76 | ReadAndReport(&net, addr); 77 | } 78 | -------------------------------------------------------------------------------- /examples/DS250x_PROM/DS250x_PROM.pde: -------------------------------------------------------------------------------- 1 | /* 2 | DS250x add-only programmable memory reader w/SKIP ROM. 3 | 4 | The DS250x is a 512/1024bit add-only PROM(you can add data but cannot change the old one) that's used mainly for device identification purposes 5 | like serial number, mfgr data, unique identifiers, etc. It uses the Maxim 1-wire bus. 6 | 7 | This sketch will use the SKIP ROM function that skips the 1-Wire search phase since we only have one device connected in the bus on digital pin 6. 8 | If more than one device is connected to the bus, it will fail. 9 | Sketch will not verify if device connected is from the DS250x family since the skip rom function effectively skips the family-id byte readout. 10 | thus it is possible to run this sketch with any Maxim OneWire device in which case the command CRC will most likely fail. 11 | Sketch will only read the first page of memory(32bits) starting from the lower address(0000h), if more than 1 device is present, then use the sketch with search functions. 12 | Remember to put a 4.7K pullup resistor between pin 6 and +Vcc 13 | 14 | To change the range or ammount of data to read, simply change the data array size, LSB/MSB addresses and for loop iterations 15 | 16 | This example code is in the public domain and is provided AS-IS. 17 | 18 | Built with Arduino 0022 and PJRC OneWire 2.0 library http://www.pjrc.com/teensy/td_libs_OneWire.html 19 | 20 | created by Guillermo Lovato 21 | march/2011 22 | 23 | */ 24 | 25 | #include 26 | OneWire ds(6); // OneWire bus on digital pin 6 27 | void setup() { 28 | Serial.begin (9600); 29 | } 30 | 31 | void loop() { 32 | byte i; // This is for the for loops 33 | boolean present; // device present var 34 | byte data[32]; // container for the data from device 35 | byte leemem[3] = { // array with the commands to initiate a read, DS250x devices expect 3 bytes to start a read: command,LSB&MSB adresses 36 | 0xF0 , 0x00 , 0x00 }; // 0xF0 is the Read Data command, followed by 00h 00h as starting address(the beginning, 0000h) 37 | byte ccrc; // Variable to store the command CRC 38 | byte ccrc_calc; 39 | 40 | present = ds.reset(); // OneWire bus reset, always needed to start operation on the bus, returns a 1/TRUE if there's a device present. 41 | ds.skip(); // Skip ROM search 42 | 43 | if (present == TRUE){ // We only try to read the data if there's a device present 44 | Serial.println("DS250x device present"); 45 | ds.write(leemem[0],1); // Read data command, leave ghost power on 46 | ds.write(leemem[1],1); // LSB starting address, leave ghost power on 47 | ds.write(leemem[2],1); // MSB starting address, leave ghost power on 48 | 49 | ccrc = ds.read(); // DS250x generates a CRC for the command we sent, we assign a read slot and store it's value 50 | ccrc_calc = OneWire::crc8(leemem, 3); // We calculate the CRC of the commands we sent using the library function and store it 51 | 52 | if ( ccrc_calc != ccrc) { // Then we compare it to the value the ds250x calculated, if it fails, we print debug messages and abort 53 | Serial.println("Invalid command CRC!"); 54 | Serial.print("Calculated CRC:"); 55 | Serial.println(ccrc_calc,HEX); // HEX makes it easier to observe and compare 56 | Serial.print("DS250x readback CRC:"); 57 | Serial.println(ccrc,HEX); 58 | return; // Since CRC failed, we abort the rest of the loop and start over 59 | } 60 | Serial.println("Data is: "); // For the printout of the data 61 | for ( i = 0; i < 32; i++) { // Now it's time to read the PROM data itself, each page is 32 bytes so we need 32 read commands 62 | data[i] = ds.read(); // we store each read byte to a different position in the data array 63 | Serial.print(data[i]); // printout in ASCII 64 | Serial.print(" "); // blank space 65 | } 66 | Serial.println(); 67 | delay(5000); // Delay so we don't saturate the serial output 68 | } 69 | else { // Nothing is connected in the bus 70 | Serial.println("Nothing connected"); 71 | delay(3000); 72 | } 73 | } 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For OneWire 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | OneWire KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | reset KEYWORD2 16 | write_bit KEYWORD2 17 | read_bit KEYWORD2 18 | write KEYWORD2 19 | write_bytes KEYWORD2 20 | read KEYWORD2 21 | read_bytes KEYWORD2 22 | select KEYWORD2 23 | skip KEYWORD2 24 | depower KEYWORD2 25 | reset_search KEYWORD2 26 | search KEYWORD2 27 | crc8 KEYWORD2 28 | crc16 KEYWORD2 29 | check_crc16 KEYWORD2 30 | 31 | ####################################### 32 | # Instances (KEYWORD2) 33 | ####################################### 34 | 35 | 36 | ####################################### 37 | # Constants (LITERAL1) 38 | ####################################### 39 | --------------------------------------------------------------------------------