Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jbechter committed Jul 11, 2014
0 parents commit 40662c6
Show file tree
Hide file tree
Showing 6 changed files with 380 additions and 0 deletions.
148 changes: 148 additions & 0 deletions DS2438.cpp
@@ -0,0 +1,148 @@
/*
* DS2438.cpp
*
* by Joe Bechter
*
* (C) 2012, bechter.com
*
* All files, software, schematics and designs are provided as-is with no warranty.
* All files, software, schematics and designs are for experimental/hobby use.
* Under no circumstances should any part be used for critical systems where safety,
* life or property depends upon it. You are responsible for all use.
* You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
* 1. No part of this software or design may be used to cause injury or death to humans or animals.
* 2. Use is non-commercial.
* 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
*
*/

#include "DS2438.h"

DS2438::DS2438(OneWire *ow, uint8_t *address) {
_ow = ow;
_address = address;
};

void DS2438::begin(uint8_t mode) {
_mode = mode & (DS2438_MODE_CHA | DS2438_MODE_CHB | DS2438_MODE_TEMPERATURE);
_temperature = 0;
_voltageA = 0.0;
_voltageB = 0.0;
_error = true;
_timestamp = 0;
}

void DS2438::update() {
uint8_t data[9];

_error = true;
_timestamp = millis();

if (_mode & DS2438_MODE_CHA || _mode == DS2438_MODE_TEMPERATURE) {
boolean doTemperature = _mode & DS2438_MODE_TEMPERATURE;
if (!startConversion(DS2438_CHA, doTemperature)) {
return;
}
if (!readPageZero(data))
return;
if (doTemperature) {
_temperature = (double)(((((int16_t)data[2]) << 8) | (data[1] & 0x0ff)) >> 3) * 0.03125;
}
if (_mode & DS2438_MODE_CHA) {
_voltageA = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0;
}
}
if (_mode & DS2438_MODE_CHB) {
boolean doTemperature = _mode & DS2438_MODE_TEMPERATURE & !(_mode & DS2438_MODE_CHA);
if (!startConversion(DS2438_CHB, doTemperature)) {
return;
}
if (!readPageZero(data))
return;
if (doTemperature) {
_temperature = (double)(((((int16_t)data[2]) << 8) | (data[1] & 0x0ff)) >> 3) * 0.03125;
}
_voltageB = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0;
}
_error = false;
}

double DS2438::getTemperature() {
return _temperature;
}

float DS2438::getVoltage(int channel) {
if (channel == DS2438_CHA) {
return _voltageA;
} else if (channel == DS2438_CHB) {
return _voltageB;
} else {
return 0.0;
}
}

boolean DS2438::isError() {
return _error;
}

unsigned long DS2438::getTimestamp() {
return _timestamp;
}

boolean DS2438::startConversion(int channel, boolean doTemperature) {
if (!selectChannel(channel))
return false;
_ow->reset();
_ow->select(_address);
if (doTemperature) {
_ow->write(DS2438_TEMPERATURE_CONVERSION_COMMAND, 0);
delay(DS2438_TEMPERATURE_DELAY);
_ow->reset();
_ow->select(_address);
}
_ow->write(DS2438_VOLTAGE_CONVERSION_COMMAND, 0);
delay(DS2438_VOLTAGE_CONVERSION_DELAY);
return true;
}

boolean DS2438::selectChannel(int channel) {
uint8_t data[9];
if (readPageZero(data)) {
if (channel == DS2438_CHB)
data[0] = data[0] | 0x08;
else
data[0] = data[0] & 0xf7;
writePageZero(data);
return true;
}
return false;
}

void DS2438::writePageZero(uint8_t *data) {
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_WRITE_SCRATCHPAD_COMMAND, 0);
_ow->write(DS2438_PAGE_0, 0);
for (int i = 0; i < 8; i++)
_ow->write(data[i], 0);
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_COPY_SCRATCHPAD_COMMAND, 0);
_ow->write(DS2438_PAGE_0, 0);
}

boolean DS2438::readPageZero(uint8_t *data) {
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_RECALL_MEMORY_COMMAND, 0);
_ow->write(DS2438_PAGE_0, 0);
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_READ_SCRATCHPAD_COMMAND, 0);
_ow->write(DS2438_PAGE_0, 0);
for (int i = 0; i < 9; i++)
data[i] = _ow->read();
return _ow->crc8(data, 8) == data[8];
}


67 changes: 67 additions & 0 deletions DS2438.h
@@ -0,0 +1,67 @@
/*
* DS2438.h
*
* by Joe Bechter
*
* (C) 2012, bechter.com
*
* All files, software, schematics and designs are provided as-is with no warranty.
* All files, software, schematics and designs are for experimental/hobby use.
* Under no circumstances should any part be used for critical systems where safety,
* life or property depends upon it. You are responsible for all use.
* You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
* 1. No part of this software or design may be used to cause injury or death to humans or animals.
* 2. Use is non-commercial.
* 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
*
*/

#ifndef DS2438_h
#define DS2438_h

#include <Arduino.h>
#include <OneWire.h>

#define DS2438_TEMPERATURE_CONVERSION_COMMAND 0x44
#define DS2438_VOLTAGE_CONVERSION_COMMAND 0xb4
#define DS2438_WRITE_SCRATCHPAD_COMMAND 0x4e
#define DS2438_COPY_SCRATCHPAD_COMMAND 0x48
#define DS2438_READ_SCRATCHPAD_COMMAND 0xbe
#define DS2438_RECALL_MEMORY_COMMAND 0xb8
#define DS2438_PAGE_0 0x00

#define DS2438_CHA 0
#define DS2438_CHB 1

#define DS2438_MODE_CHA 0x01
#define DS2438_MODE_CHB 0x02
#define DS2438_MODE_TEMPERATURE 0x04

#define DS2438_TEMPERATURE_DELAY 10
#define DS2438_VOLTAGE_CONVERSION_DELAY 8

class DS2438 {
public:
DS2438(OneWire *ow, uint8_t *address);
void begin(uint8_t mode=(DS2438_MODE_CHA | DS2438_MODE_CHB | DS2438_MODE_TEMPERATURE));
void update();
double getTemperature();
float getVoltage(int channel=DS2438_CHA);
boolean isError();
unsigned long getTimestamp();
private:
OneWire *_ow;
uint8_t *_address;
uint8_t _mode;
double _temperature;
float _voltageA;
float _voltageB;
unsigned long _timestamp;
boolean _error;
boolean startConversion(int channel, boolean doTemperature);
boolean selectChannel(int channel);
void writePageZero(uint8_t *data);
boolean readPageZero(uint8_t *data);
};

#endif
13 changes: 13 additions & 0 deletions LICENSE
@@ -0,0 +1,13 @@
Copyright 2013, bechter.com - All Rights Reserved

1. All files, software, schematics and designs are provided as-is with no warranty.
2. All files, software, schematics and designs are for experimental/hobby use.
Under no circumstances should any part be used for critical systems where safety,
life or property depends upon it. You are responsible for all use.
3. You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
1. No part of this software or design may be used to cause injury or death to humans or animals.
2. Use is non-commercial.
3. Credit is given to the author (i.e. portions © bechter.com),
and provide a link to this site (http://projects.bechter.com).


8 changes: 8 additions & 0 deletions README.txt
@@ -0,0 +1,8 @@
DS2438 Arduino OneWire Library

To install, copy the DS2438 folder structure to your Arduino libraries folder.

Requires Arduino 1.0 or greater and OneWire Arduino library (see http://playground.arduino.cc/Learning/OneWire).

For additional information see http://projects.bechter.com

89 changes: 89 additions & 0 deletions examples/DS2438Humidity/DS2438Humidity.ino
@@ -0,0 +1,89 @@
/*
* DS2438Humidity
*
* This example demonstrates the use of the DS2438 Library and the Arduino OneWire library
* to read a relative humidity sensor that uses a Dallas Semiconductor DS2438 battery monitor.
* This example is for a 1-Wire device similar to the HobbyBoards H3-R1-A humidity sensor.
*
* by Joe Bechter
*
* (C) 2012, bechter.com
*
* All files, software, schematics and designs are provided as-is with no warranty.
* All files, software, schematics and designs are for experimental/hobby use.
* Under no circumstances should any part be used for critical systems where safety,
* life or property depends upon it. You are responsible for all use.
* You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
* 1. No part of this software or design may be used to cause injury or death to humans or animals.
* 2. Use is non-commercial.
* 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
*
*/

#include <Arduino.h>
#include <OneWire.h>
#include <DS2438.h>

// define the Arduino digital I/O pin to be used for the 1-Wire network here
const uint8_t ONE_WIRE_PIN = 2;

// define the 1-Wire address of the DS2438 battery monitor here (lsb first)
uint8_t DS2438_address[] = { 0x26, 0x45, 0xe6, 0xf7, 0x00, 0x00, 0x00, 0x4e };

OneWire ow(ONE_WIRE_PIN);
DS2438 ds2438(&ow, DS2438_address);

float temperature;
float heatindex;
float dewpoint;
float humidity;

void setup() {
Serial.begin(9600);
ds2438.begin();
}

void loop() {
ds2438.update();
if (ds2438.isError() || ds2438.getVoltage(DS2438_CHA) == 0.0) {
Serial.println("Error reading from DS2438 device");
} else {
temperature = ds2438.getTemperature();
heatindex = temperature;
float rh = (ds2438.getVoltage(DS2438_CHA) / ds2438.getVoltage(DS2438_CHB) - 0.16) / 0.0062;
humidity = (float)(rh / (1.0546 - 0.00216 * temperature));
if (humidity < 0.0) {
humidity = 0.0;
} else if (humidity > 100.0) {
humidity = 100.0;
}
float tempK = temperature + 273.15;
dewpoint = tempK / ((-0.0001846 * log(humidity / 100.0) * tempK) + 1.0) - 273.15;
if (temperature >= 26.7 && humidity >= 40.0) {
float t = temperature * 9.0 / 5.0 + 32.0; // heat index formula assumes degF
rh = humidity;
float heatindexF = -42.38 + 2.049 * t + 10.14 * rh + -0.2248 * t * rh + -0.006838 * t * t
+ -0.05482 * rh * rh + 0.001228 * t * t * rh + 0.0008528 * t * rh * rh
+ -0.00000199 * t * t * rh * rh;
heatindex = (heatindexF - 32.0) * 5.0 / 9.0;
}
if (heatindex < temperature)
heatindex = temperature;
}
Serial.print("Temperature = ");
Serial.print(temperature, 1);
Serial.print("C (");
Serial.print(temperature * 9.0 / 5.0 + 32.0, 1);
Serial.print("F), Heat Index = ");
Serial.print(heatindex, 1);
Serial.print("C (");
Serial.print(heatindex * 9.0 / 5.0 + 32.0, 1);
Serial.print("F), Dewpoint = ");
Serial.print(dewpoint, 1);
Serial.print("C (");
Serial.print(dewpoint * 9.0 / 5.0 + 32.0, 1);
Serial.print("F), Relative Humidity = ");
Serial.print(humidity, 0);
Serial.println("%.");
delay(500);
}
@@ -0,0 +1,55 @@
/*
* DS2438TemperatureAndVoltage
*
* This example demonstrates the use of the DS2438 Library to read temperature and
* voltage from a Dallas Semiconductor DS2438 battery monitor using the Arduino
* OneWire library.
*
* by Joe Bechter
*
* (C) 2012, bechter.com
*
* All files, software, schematics and designs are provided as-is with no warranty.
* All files, software, schematics and designs are for experimental/hobby use.
* Under no circumstances should any part be used for critical systems where safety,
* life or property depends upon it. You are responsible for all use.
* You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
* 1. No part of this software or design may be used to cause injury or death to humans or animals.
* 2. Use is non-commercial.
* 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
*
*/

#include <Arduino.h>
#include <OneWire.h>
#include <DS2438.h>

// define the Arduino digital I/O pin to be used for the 1-Wire network here
const uint8_t ONE_WIRE_PIN = 2;

// define the 1-Wire address of the DS2438 battery monitor here (lsb first)
uint8_t DS2438_address[] = { 0x26, 0x45, 0xe6, 0xf7, 0x00, 0x00, 0x00, 0x4e };

OneWire ow(ONE_WIRE_PIN);
DS2438 ds2438(&ow, DS2438_address);

void setup() {
Serial.begin(9600);
ds2438.begin();
}

void loop() {
ds2438.update();
if (ds2438.isError()) {
Serial.println("Error reading from DS2438 device");
} else {
Serial.print("Temperature = ");
Serial.print(ds2438.getTemperature(), 1);
Serial.print("C, Channel A = ");
Serial.print(ds2438.getVoltage(DS2438_CHA), 1);
Serial.print("v, Channel B = ");
Serial.print(ds2438.getVoltage(DS2438_CHB), 1);
Serial.println("v.");
}
delay(500);
}

0 comments on commit 40662c6

Please sign in to comment.