├── DS2438.cpp ├── DS2438.h ├── LICENSE ├── README.txt └── examples ├── DS2438Humidity └── DS2438Humidity.ino └── DS2438TemperatureAndVoltage └── DS2438TemperatureAndVoltage.ino /DS2438.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * DS2438.cpp 3 | * 4 | * by Joe Bechter 5 | * 6 | * (C) 2012, bechter.com 7 | * 8 | * All files, software, schematics and designs are provided as-is with no warranty. 9 | * All files, software, schematics and designs are for experimental/hobby use. 10 | * Under no circumstances should any part be used for critical systems where safety, 11 | * life or property depends upon it. You are responsible for all use. 12 | * You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided 13 | * 1. No part of this software or design may be used to cause injury or death to humans or animals. 14 | * 2. Use is non-commercial. 15 | * 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source. 16 | * 17 | */ 18 | 19 | #include "DS2438.h" 20 | 21 | DS2438::DS2438(OneWire *ow, uint8_t *address) { 22 | _ow = ow; 23 | _address = address; 24 | }; 25 | 26 | void DS2438::begin(uint8_t mode) { 27 | _mode = mode & (DS2438_MODE_CHA | DS2438_MODE_CHB | DS2438_MODE_TEMPERATURE); 28 | _temperature = 0; 29 | _voltageA = 0.0; 30 | _voltageB = 0.0; 31 | _error = true; 32 | _timestamp = 0; 33 | } 34 | 35 | void DS2438::update() { 36 | uint8_t data[9]; 37 | 38 | _error = true; 39 | _timestamp = millis(); 40 | 41 | if (_mode & DS2438_MODE_CHA || _mode == DS2438_MODE_TEMPERATURE) { 42 | boolean doTemperature = _mode & DS2438_MODE_TEMPERATURE; 43 | if (!startConversion(DS2438_CHA, doTemperature)) { 44 | return; 45 | } 46 | if (!readPageZero(data)) 47 | return; 48 | if (doTemperature) { 49 | _temperature = (double)(((((int16_t)data[2]) << 8) | (data[1] & 0x0ff)) >> 3) * 0.03125; 50 | } 51 | if (_mode & DS2438_MODE_CHA) { 52 | _voltageA = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0; 53 | } 54 | } 55 | if (_mode & DS2438_MODE_CHB) { 56 | boolean doTemperature = _mode & DS2438_MODE_TEMPERATURE && !(_mode & DS2438_MODE_CHA); 57 | if (!startConversion(DS2438_CHB, doTemperature)) { 58 | return; 59 | } 60 | if (!readPageZero(data)) 61 | return; 62 | if (doTemperature) { 63 | _temperature = (double)(((((int16_t)data[2]) << 8) | (data[1] & 0x0ff)) >> 3) * 0.03125; 64 | } 65 | _voltageB = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0; 66 | } 67 | _error = false; 68 | } 69 | 70 | double DS2438::getTemperature() { 71 | return _temperature; 72 | } 73 | 74 | float DS2438::getVoltage(int channel) { 75 | if (channel == DS2438_CHA) { 76 | return _voltageA; 77 | } else if (channel == DS2438_CHB) { 78 | return _voltageB; 79 | } else { 80 | return 0.0; 81 | } 82 | } 83 | 84 | boolean DS2438::isError() { 85 | return _error; 86 | } 87 | 88 | unsigned long DS2438::getTimestamp() { 89 | return _timestamp; 90 | } 91 | 92 | boolean DS2438::startConversion(int channel, boolean doTemperature) { 93 | if (!selectChannel(channel)) 94 | return false; 95 | _ow->reset(); 96 | _ow->select(_address); 97 | if (doTemperature) { 98 | _ow->write(DS2438_TEMPERATURE_CONVERSION_COMMAND, 0); 99 | delay(DS2438_TEMPERATURE_DELAY); 100 | _ow->reset(); 101 | _ow->select(_address); 102 | } 103 | _ow->write(DS2438_VOLTAGE_CONVERSION_COMMAND, 0); 104 | delay(DS2438_VOLTAGE_CONVERSION_DELAY); 105 | return true; 106 | } 107 | 108 | boolean DS2438::selectChannel(int channel) { 109 | uint8_t data[9]; 110 | if (readPageZero(data)) { 111 | if (channel == DS2438_CHB) 112 | data[0] = data[0] | 0x08; 113 | else 114 | data[0] = data[0] & 0xf7; 115 | writePageZero(data); 116 | return true; 117 | } 118 | return false; 119 | } 120 | 121 | void DS2438::writePageZero(uint8_t *data) { 122 | _ow->reset(); 123 | _ow->select(_address); 124 | _ow->write(DS2438_WRITE_SCRATCHPAD_COMMAND, 0); 125 | _ow->write(DS2438_PAGE_0, 0); 126 | for (int i = 0; i < 8; i++) 127 | _ow->write(data[i], 0); 128 | _ow->reset(); 129 | _ow->select(_address); 130 | _ow->write(DS2438_COPY_SCRATCHPAD_COMMAND, 0); 131 | _ow->write(DS2438_PAGE_0, 0); 132 | } 133 | 134 | boolean DS2438::readPageZero(uint8_t *data) { 135 | _ow->reset(); 136 | _ow->select(_address); 137 | _ow->write(DS2438_RECALL_MEMORY_COMMAND, 0); 138 | _ow->write(DS2438_PAGE_0, 0); 139 | _ow->reset(); 140 | _ow->select(_address); 141 | _ow->write(DS2438_READ_SCRATCHPAD_COMMAND, 0); 142 | _ow->write(DS2438_PAGE_0, 0); 143 | for (int i = 0; i < 9; i++) 144 | data[i] = _ow->read(); 145 | return _ow->crc8(data, 8) == data[8]; 146 | } 147 | 148 | 149 | -------------------------------------------------------------------------------- /DS2438.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DS2438.h 3 | * 4 | * by Joe Bechter 5 | * 6 | * (C) 2012, bechter.com 7 | * 8 | * All files, software, schematics and designs are provided as-is with no warranty. 9 | * All files, software, schematics and designs are for experimental/hobby use. 10 | * Under no circumstances should any part be used for critical systems where safety, 11 | * life or property depends upon it. You are responsible for all use. 12 | * You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided 13 | * 1. No part of this software or design may be used to cause injury or death to humans or animals. 14 | * 2. Use is non-commercial. 15 | * 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source. 16 | * 17 | */ 18 | 19 | #ifndef DS2438_h 20 | #define DS2438_h 21 | 22 | #include 23 | #include 24 | 25 | #define DS2438_TEMPERATURE_CONVERSION_COMMAND 0x44 26 | #define DS2438_VOLTAGE_CONVERSION_COMMAND 0xb4 27 | #define DS2438_WRITE_SCRATCHPAD_COMMAND 0x4e 28 | #define DS2438_COPY_SCRATCHPAD_COMMAND 0x48 29 | #define DS2438_READ_SCRATCHPAD_COMMAND 0xbe 30 | #define DS2438_RECALL_MEMORY_COMMAND 0xb8 31 | #define DS2438_PAGE_0 0x00 32 | 33 | #define DS2438_CHA 0 34 | #define DS2438_CHB 1 35 | 36 | #define DS2438_MODE_CHA 0x01 37 | #define DS2438_MODE_CHB 0x02 38 | #define DS2438_MODE_TEMPERATURE 0x04 39 | 40 | #define DS2438_TEMPERATURE_DELAY 10 41 | #define DS2438_VOLTAGE_CONVERSION_DELAY 8 42 | 43 | class DS2438 { 44 | public: 45 | DS2438(OneWire *ow, uint8_t *address); 46 | void begin(uint8_t mode=(DS2438_MODE_CHA | DS2438_MODE_CHB | DS2438_MODE_TEMPERATURE)); 47 | void update(); 48 | double getTemperature(); 49 | float getVoltage(int channel=DS2438_CHA); 50 | boolean isError(); 51 | unsigned long getTimestamp(); 52 | private: 53 | OneWire *_ow; 54 | uint8_t *_address; 55 | uint8_t _mode; 56 | double _temperature; 57 | float _voltageA; 58 | float _voltageB; 59 | unsigned long _timestamp; 60 | boolean _error; 61 | boolean startConversion(int channel, boolean doTemperature); 62 | boolean selectChannel(int channel); 63 | void writePageZero(uint8_t *data); 64 | boolean readPageZero(uint8_t *data); 65 | }; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013, bechter.com - All Rights Reserved 2 | 3 | 1. All files, software, schematics and designs are provided as-is with no warranty. 4 | 2. All files, software, schematics and designs are for experimental/hobby use. 5 | Under no circumstances should any part be used for critical systems where safety, 6 | life or property depends upon it. You are responsible for all use. 7 | 3. You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided 8 | 1. No part of this software or design may be used to cause injury or death to humans or animals. 9 | 2. Use is non-commercial. 10 | 3. Credit is given to the author (i.e. portions © bechter.com), 11 | and provide a link to this site (http://projects.bechter.com). 12 | 13 | 14 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | DS2438 Arduino OneWire Library 2 | 3 | To install, download and rename the arduino-onewire-DS2438 folder to DS2438 and copy the DS2438 folder structure to your Arduino libraries folder. 4 | 5 | Requires Arduino 1.0 or greater and OneWire Arduino library (see http://playground.arduino.cc/Learning/OneWire). 6 | 7 | For additional information see http://projects.bechter.com 8 | 9 | -------------------------------------------------------------------------------- /examples/DS2438Humidity/DS2438Humidity.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * DS2438Humidity 3 | * 4 | * This example demonstrates the use of the DS2438 Library and the Arduino OneWire library 5 | * to read a relative humidity sensor that uses a Dallas Semiconductor DS2438 battery monitor. 6 | * This example is for a 1-Wire device similar to the HobbyBoards H3-R1-A humidity sensor. 7 | * 8 | * by Joe Bechter 9 | * 10 | * (C) 2012, bechter.com 11 | * 12 | * All files, software, schematics and designs are provided as-is with no warranty. 13 | * All files, software, schematics and designs are for experimental/hobby use. 14 | * Under no circumstances should any part be used for critical systems where safety, 15 | * life or property depends upon it. You are responsible for all use. 16 | * You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided 17 | * 1. No part of this software or design may be used to cause injury or death to humans or animals. 18 | * 2. Use is non-commercial. 19 | * 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source. 20 | * 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | // define the Arduino digital I/O pin to be used for the 1-Wire network here 28 | const uint8_t ONE_WIRE_PIN = 2; 29 | 30 | // define the 1-Wire address of the DS2438 battery monitor here (lsb first) 31 | uint8_t DS2438_address[] = { 0x26, 0x45, 0xe6, 0xf7, 0x00, 0x00, 0x00, 0x4e }; 32 | 33 | OneWire ow(ONE_WIRE_PIN); 34 | DS2438 ds2438(&ow, DS2438_address); 35 | 36 | float temperature; 37 | float heatindex; 38 | float dewpoint; 39 | float humidity; 40 | 41 | void setup() { 42 | Serial.begin(9600); 43 | ds2438.begin(); 44 | } 45 | 46 | void loop() { 47 | ds2438.update(); 48 | if (ds2438.isError() || ds2438.getVoltage(DS2438_CHA) == 0.0) { 49 | Serial.println("Error reading from DS2438 device"); 50 | } else { 51 | temperature = ds2438.getTemperature(); 52 | heatindex = temperature; 53 | float rh = (ds2438.getVoltage(DS2438_CHA) / ds2438.getVoltage(DS2438_CHB) - 0.16) / 0.0062; 54 | humidity = (float)(rh / (1.0546 - 0.00216 * temperature)); 55 | if (humidity < 0.0) { 56 | humidity = 0.0; 57 | } else if (humidity > 100.0) { 58 | humidity = 100.0; 59 | } 60 | float tempK = temperature + 273.15; 61 | dewpoint = tempK / ((-0.0001846 * log(humidity / 100.0) * tempK) + 1.0) - 273.15; 62 | if (temperature >= 26.7 && humidity >= 40.0) { 63 | float t = temperature * 9.0 / 5.0 + 32.0; // heat index formula assumes degF 64 | rh = humidity; 65 | float heatindexF = -42.38 + 2.049 * t + 10.14 * rh + -0.2248 * t * rh + -0.006838 * t * t 66 | + -0.05482 * rh * rh + 0.001228 * t * t * rh + 0.0008528 * t * rh * rh 67 | + -0.00000199 * t * t * rh * rh; 68 | heatindex = (heatindexF - 32.0) * 5.0 / 9.0; 69 | } 70 | if (heatindex < temperature) 71 | heatindex = temperature; 72 | } 73 | Serial.print("Temperature = "); 74 | Serial.print(temperature, 1); 75 | Serial.print("C ("); 76 | Serial.print(temperature * 9.0 / 5.0 + 32.0, 1); 77 | Serial.print("F), Heat Index = "); 78 | Serial.print(heatindex, 1); 79 | Serial.print("C ("); 80 | Serial.print(heatindex * 9.0 / 5.0 + 32.0, 1); 81 | Serial.print("F), Dewpoint = "); 82 | Serial.print(dewpoint, 1); 83 | Serial.print("C ("); 84 | Serial.print(dewpoint * 9.0 / 5.0 + 32.0, 1); 85 | Serial.print("F), Relative Humidity = "); 86 | Serial.print(humidity, 0); 87 | Serial.println("%."); 88 | delay(500); 89 | } 90 | -------------------------------------------------------------------------------- /examples/DS2438TemperatureAndVoltage/DS2438TemperatureAndVoltage.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * DS2438TemperatureAndVoltage 3 | * 4 | * This example demonstrates the use of the DS2438 Library to read temperature and 5 | * voltage from a Dallas Semiconductor DS2438 battery monitor using the Arduino 6 | * OneWire library. 7 | * 8 | * by Joe Bechter 9 | * 10 | * (C) 2012, bechter.com 11 | * 12 | * All files, software, schematics and designs are provided as-is with no warranty. 13 | * All files, software, schematics and designs are for experimental/hobby use. 14 | * Under no circumstances should any part be used for critical systems where safety, 15 | * life or property depends upon it. You are responsible for all use. 16 | * You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided 17 | * 1. No part of this software or design may be used to cause injury or death to humans or animals. 18 | * 2. Use is non-commercial. 19 | * 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source. 20 | * 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | // define the Arduino digital I/O pin to be used for the 1-Wire network here 28 | const uint8_t ONE_WIRE_PIN = 2; 29 | 30 | // define the 1-Wire address of the DS2438 battery monitor here (lsb first) 31 | uint8_t DS2438_address[] = { 0x26, 0x45, 0xe6, 0xf7, 0x00, 0x00, 0x00, 0x4e }; 32 | 33 | OneWire ow(ONE_WIRE_PIN); 34 | DS2438 ds2438(&ow, DS2438_address); 35 | 36 | void setup() { 37 | Serial.begin(9600); 38 | ds2438.begin(); 39 | } 40 | 41 | void loop() { 42 | ds2438.update(); 43 | if (ds2438.isError()) { 44 | Serial.println("Error reading from DS2438 device"); 45 | } else { 46 | Serial.print("Temperature = "); 47 | Serial.print(ds2438.getTemperature(), 1); 48 | Serial.print("C, Channel A = "); 49 | Serial.print(ds2438.getVoltage(DS2438_CHA), 1); 50 | Serial.print("v, Channel B = "); 51 | Serial.print(ds2438.getVoltage(DS2438_CHB), 1); 52 | Serial.println("v."); 53 | } 54 | delay(500); 55 | } 56 | --------------------------------------------------------------------------------