Browse Source

Fixed DallasSensor

fastled
Xose Pérez 7 years ago
parent
commit
ebe0d5e410
14 changed files with 3393 additions and 3239 deletions
  1. +3
    -1
      code/espurna/config/prototypes.h
  2. +6
    -4
      code/espurna/config/sensors.h
  3. BIN
      code/espurna/data/index.html.gz
  4. +33
    -16
      code/espurna/sensor.ino
  5. +4
    -0
      code/espurna/sensors/AnalogSensor.h
  6. +17
    -11
      code/espurna/sensors/BaseSensor.h
  7. +6
    -2
      code/espurna/sensors/DHTSensor.h
  8. +0
    -105
      code/espurna/sensors/DS18B20Sensor.h
  9. +234
    -0
      code/espurna/sensors/DallasSensor.h
  10. +7
    -3
      code/espurna/sensors/EventSensor.h
  11. +3078
    -3071
      code/espurna/static/index.html.gz.h
  12. +5
    -0
      code/espurna/utils.ino
  13. +0
    -25
      code/html/index.html
  14. +0
    -1
      code/platformio.ini

+ 3
- 1
code/espurna/config/prototypes.h View File

@ -75,7 +75,9 @@ template<typename T> bool idbSend(const char * topic, unsigned char id, T payloa
// Sensors
// -----------------------------------------------------------------------------
#include "sensors/BaseSensor.h"
#include <DallasTemperature.h> // WTF!
#if DS18B20_SUPPORT
#include <OneWire.h>
#endif
// -----------------------------------------------------------------------------
// Utils


+ 6
- 4
code/espurna/config/sensors.h View File

@ -39,7 +39,7 @@
#endif
#ifndef DHT_PIN
#define DHT_PIN 13
#define DHT_PIN 12
#endif
#ifndef DHT_TYPE
@ -68,7 +68,7 @@
//--------------------------------------------------------------------------------
#ifndef ANALOG_SUPPORT
#define ANALOG_SUPPORT 1
#define ANALOG_SUPPORT 0
#endif
#ifndef ANALOG_PIN
@ -92,7 +92,7 @@
//--------------------------------------------------------------------------------
#ifndef COUNTER_SUPPORT
#define COUNTER_SUPPORT 1 // Do not build with counter support by default
#define COUNTER_SUPPORT 0 // Do not build with counter support by default
#endif
#ifndef COUNTER_PIN
@ -121,7 +121,7 @@
//--------------------------------------------------------------------------------
#ifndef DS18B20_SUPPORT
#define DS18B20_SUPPORT 1
#define DS18B20_SUPPORT 0
#endif
#ifndef DS18B20_PIN
@ -140,6 +140,8 @@
#define DS18B20_TEMPERATURE_TOPIC "temperature"
#endif
#define DS18B20_RESOLUTION 9
//--------------------------------------------------------------------------------
// Internal power montior
// Enable support by passing ADC_VCC_ENABLED=1 build flag


BIN
code/espurna/data/index.html.gz View File


+ 33
- 16
code/espurna/sensor.ino View File

@ -141,6 +141,30 @@ void _sensorAPISetup() {
}
#endif
void _sensorTick() {
for (unsigned char i=0; i<_sensors.size(); i++) {
_sensors[i]->tick();
}
}
void _sensorPre() {
for (unsigned char i=0; i<_sensors.size(); i++) {
_sensors[i]->pre();
if (!_sensors[i]->status()) {
DEBUG_MSG("[SENSOR] Error reading data from %s (error: %d)\n",
_sensors[i]->name().c_str(),
_sensors[i]->error()
);
}
}
}
void _sensorPost() {
for (unsigned char i=0; i<_sensors.size(); i++) {
_sensors[i]->post();
}
}
// -----------------------------------------------------------------------------
// Values
// -----------------------------------------------------------------------------
@ -170,8 +194,8 @@ void sensorInit() {
#endif
#if DS18B20_SUPPORT
#include "sensors/DS18B20Sensor.h"
sensorRegister(new DS18B20Sensor(DS18B20_PIN, DS18B20_PULLUP));
#include "sensors/DallasSensor.h"
sensorRegister(new DallasSensor(DS18B20_PIN, SENSOR_READ_INTERVAL, DS18B20_PULLUP));
#endif
#if ANALOG_SUPPORT
@ -244,6 +268,9 @@ void sensorLoop() {
static unsigned long last_update = 0;
static unsigned long report_count = 0;
// Tick hook
_sensorTick();
// Check if we should read new data
if ((millis() - last_update > SENSOR_READ_INTERVAL) || (last_update == 0)) {
@ -254,15 +281,7 @@ void sensorLoop() {
char buffer[64];
// Pre-read hook
for (unsigned char i=0; i<_sensors.size(); i++) {
_sensors[i]->pre();
if (!_sensors[i]->status()) {
DEBUG_MSG("[SENSOR] Error reading data from %s (error: %d)\n",
_sensors[i]->name().c_str(),
_sensors[i]->error()
);
}
}
_sensorPre();
// Get readings
for (unsigned char i=0; i<_magnitudes.size(); i++) {
@ -283,7 +302,7 @@ void sensorLoop() {
_magnitudes[i].current = value;
// Debug
/*
#if TRUE
{
dtostrf(value, 1-sizeof(buffer), decimals, buffer);
DEBUG_MSG("[SENSOR] %s - %s: %s%s\n",
@ -293,7 +312,7 @@ void sensorLoop() {
_sensorUnits(magnitude.type).c_str()
);
}
*/
#endif
if (report_count == 0) {
@ -330,9 +349,7 @@ void sensorLoop() {
}
// Post-read hook
for (unsigned char i=0; i<_sensors.size(); i++) {
_sensors[i]->post();
}
_sensorPost();
#if WEB_SUPPORT
wsSend(_sensorWebSocketOnSend);


+ 4
- 0
code/espurna/sensors/AnalogSensor.h View File

@ -30,13 +30,17 @@ class AnalogSensor : public BaseSensor {
// Type for slot # index
magnitude_t type(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index == 0) return MAGNITUDE_ANALOG;
_error = SENSOR_ERROR_OUT_OF_RANGE;
return MAGNITUDE_NONE;
}
// Current value for slot # index
double value(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index == 0) return analogRead(_gpio);
_error = SENSOR_ERROR_OUT_OF_RANGE;
return 0;
}


+ 17
- 11
code/espurna/sensors/BaseSensor.h View File

@ -27,6 +27,9 @@ typedef enum magnitude_t {
} magnitude_t;
#define SENSOR_ERROR_OK 0
#define SENSOR_ERROR_OUT_OF_RANGE 1
class BaseSensor {
public:
@ -40,20 +43,14 @@ class BaseSensor {
// General interrupt handler
void InterruptHandler() {}
// Loop-like method, call it in your main loop
virtual void tick() {}
// Pre-read hook (usually to populate registers with up-to-date data)
void pre() {}
virtual void pre() {}
// Post-read hook (usually to reset things)
void post() {}
// Return sensor status (true for ready)
bool status() { return _error == 0; }
// Return sensor last internal error
int error() { return _error; }
// Number of available slots
unsigned char count() { return _count; }
virtual void post() {}
// Descriptive name of the sensor
virtual String name();
@ -67,6 +64,15 @@ class BaseSensor {
// Current value for slot # index
virtual double value(unsigned char index);
// Return sensor status (true for ready)
bool status() { return _error == 0; }
// Return sensor last internal error
int error() { return _error; }
// Number of available slots
unsigned char count() { return _count; }
protected:


+ 6
- 2
code/espurna/sensors/DHTSensor.h View File

@ -34,7 +34,7 @@ class DHTSensor : public BaseSensor {
void pre() {
if ((_last_ok > 0) && (millis() - _last_ok < DHT_MIN_INTERVAL)) {
_error = 0;
_error = SENSOR_ERROR_OK;
return;
}
@ -121,7 +121,7 @@ class DHTSensor : public BaseSensor {
_last_ok = millis();
_errors = 0;
_error = 0;
_error = SENSOR_ERROR_OK;
}
@ -139,15 +139,19 @@ class DHTSensor : public BaseSensor {
// Type for slot # index
magnitude_t type(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index == 0) return MAGNITUDE_TEMPERATURE;
if (index == 1) return MAGNITUDE_HUMIDITY;
_error = SENSOR_ERROR_OUT_OF_RANGE;
return MAGNITUDE_NONE;
}
// Current value for slot # index
double value(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index == 0) return _temperature;
if (index == 1) return _humidity;
_error = SENSOR_ERROR_OUT_OF_RANGE;
return 0;
}


+ 0
- 105
code/espurna/sensors/DS18B20Sensor.h View File

@ -1,105 +0,0 @@
// -----------------------------------------------------------------------------
// DHT Sensor
// -----------------------------------------------------------------------------
#pragma once
#include "Arduino.h"
#include "BaseSensor.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#define DS18B20_OK 0
#define DS18B20_NOT_FOUND 1
#define DS18B20_OUT_OF_RANGE 2
#define DS18B20_CONVERSION_ERROR 3
class DS18B20Sensor : public BaseSensor {
public:
DS18B20Sensor(unsigned char gpio, bool pull_up = false): BaseSensor() {
_gpio = gpio;
if (pull_up) pinMode(_gpio, INPUT_PULLUP);
init();
}
// Pre-read hook (usually to populate registers with up-to-date data)
void pre() {
_device->requestTemperatures();
// TODO: enable?
/*
while (!_device->isConversionComplete()) {
delay(1);
}
*/
}
// Descriptive name of the sensor
String name() {
char buffer[20];
snprintf(buffer, sizeof(buffer), "DS18B20 %s@ GPIO%d",
_device->isParasitePowerMode() ? "(P) " : "",
_gpio
);
return String(buffer);
}
// Descriptive name of the slot # index
String slot(unsigned char index) {
if (index < _count) {
DeviceAddress address;
_device->getAddress(address, index);
char buffer[40];
snprintf(buffer, sizeof(buffer), "%02X%02X%02X%02X%02X%02X%02X%02X @ %s",
address[0], address[1], address[2], address[3],
address[4], address[5], address[6], address[7],
name().c_str()
);
return String(buffer);
}
_error = DS18B20_OUT_OF_RANGE;
return String();
}
// Type for slot # index
magnitude_t type(unsigned char index) {
if (index < _count) return MAGNITUDE_TEMPERATURE;
_error = DS18B20_OUT_OF_RANGE;
return MAGNITUDE_NONE;
}
// Current value for slot # index
double value(unsigned char index) {
if (index < _count) {
double t = _device->getTempCByIndex(index);
if (t != DEVICE_DISCONNECTED_C) {
_error = DS18B20_OK;
return t;
}
_error = DS18B20_CONVERSION_ERROR;
}
_error = DS18B20_OUT_OF_RANGE;
return 0;
}
protected:
void init() {
OneWire * wire = new OneWire(_gpio);
_device = new DallasTemperature(wire);
_device->begin();
_device->setWaitForConversion(false);
_count = _device->getDeviceCount();
if (_count == 0) _error = DS18B20_NOT_FOUND;
}
unsigned char _gpio;
DallasTemperature * _device;
};

+ 234
- 0
code/espurna/sensors/DallasSensor.h View File

@ -0,0 +1,234 @@
// -----------------------------------------------------------------------------
// DHT Sensor
// -----------------------------------------------------------------------------
#pragma once
#include "Arduino.h"
#include "BaseSensor.h"
#include <vector>
#include <OneWire.h>
#define DS_CHIP_DS18S20 0x10
#define DS_CHIP_DS1822 0x22
#define DS_CHIP_DS18B20 0x28
#define DS_CHIP_DS1825 0x3B
#define DS_PARASITE 1
#define DS_DISCONNECTED -127
#define DS_CMD_START_CONVERSION 0x44
#define DS_CMD_READ_SCRATCHPAD 0xBE
#define DS_ERROR_NOT_FOUND -1
#define DS_ERROR_FAILED_RESET -2
#define DS_ERROR_FAILED_READ -3
#define DS_ERROR_CRC -4
class DallasSensor : public BaseSensor {
public:
DallasSensor(unsigned char gpio, unsigned long interval, bool pull_up = false): BaseSensor() {
// Cache params
_gpio = gpio;
_interval = interval / 2;
// OneWire
_wire = new OneWire(_gpio);
// Must be done after the OneWire initialization
if (pull_up) pinMode(_gpio, INPUT_PULLUP);
// Search devices
loadDevices();
}
// Loop-like method, call it in your main loop
void tick() {
static unsigned long last = 0;
if (millis() - last < _interval) return;
last = millis();
// Every second we either start a conversion or read the scratchpad
static bool conversion = true;
if (conversion) {
// Start conversion
_wire->reset();
_wire->skip();
_wire->write(DS_CMD_START_CONVERSION, DS_PARASITE);
} else {
// Read scratchpads
for (unsigned char index=0; index<_devices.size(); index++) {
// Read scratchpad
if (_wire->reset() == 0) {
_error = DS_ERROR_FAILED_RESET;
return;
}
_wire->select(_devices[index].address);
_wire->write(DS_CMD_READ_SCRATCHPAD);
uint8_t data[9];
for (unsigned char i = 0; i < 9; i++) {
data[i] = _wire->read();
}
#if false
Serial.printf("[DS18B20] Data = ");
for (unsigned char i = 0; i < 9; i++) {
Serial.printf("%02X ", data[i]);
}
Serial.printf(" CRC = %02X\n", OneWire::crc8(data, 8));
#endif
if (_wire->reset() != 1) {
_error = DS_ERROR_FAILED_READ;
return;
}
if (OneWire::crc8(data, 8) != data[8]) {
_error = DS_ERROR_CRC;
return;
}
memcpy(_devices[index].data, data, 9);
}
}
conversion = !conversion;
}
// Descriptive name of the sensor
String name() {
char buffer[20];
snprintf(buffer, sizeof(buffer), "OneWire @ GPIO%d", _gpio);
return String(buffer);
}
// Descriptive name of the slot # index
String slot(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index < _count) {
char buffer[40];
uint8_t * address = _devices[index].address;
snprintf(buffer, sizeof(buffer), "%s (%02X%02X%02X%02X%02X%02X%02X%02X) @ GPIO%d",
chipAsString(index).c_str(),
address[0], address[1], address[2], address[3],
address[4], address[5], address[6], address[7],
_gpio
);
return String(buffer);
}
_error = SENSOR_ERROR_OUT_OF_RANGE;
return String();
}
// Type for slot # index
magnitude_t type(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index < _count) return MAGNITUDE_TEMPERATURE;
_error = SENSOR_ERROR_OUT_OF_RANGE;
return MAGNITUDE_NONE;
}
// Current value for slot # index
double value(unsigned char index) {
if (index >= _count) {
_error = SENSOR_ERROR_OUT_OF_RANGE;
return 0;
}
uint8_t * data = _devices[index].data;
// Registers
// byte 0: temperature LSB
// byte 1: temperature MSB
// byte 2: high alarm temp
// byte 3: low alarm temp
// byte 4: DS18S20: store for crc
// DS18B20 & DS1822: configuration register
// byte 5: internal use & crc
// byte 6: DS18S20: COUNT_REMAIN
// DS18B20 & DS1822: store for crc
// byte 7: DS18S20: COUNT_PER_C
// DS18B20 & DS1822: store for crc
// byte 8: SCRATCHPAD_CRC
int16_t raw = (data[1] << 8) | data[0];
if (chip(index) == DS_CHIP_DS18S20) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
raw = (raw & 0xFFF0) + 12 - data[6]; // "count remain" gives full 12 bit resolution
}
} else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw & ~7; // 9 bit res, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
// 12 bit res, 750 ms
}
_error = SENSOR_ERROR_OK;
return (float) raw / 16.0;
}
protected:
unsigned char chip(unsigned char index) {
if (index < _count) return _devices[index].address[0];
return 0;
}
String chipAsString(unsigned char index) {
unsigned char chip_id = chip(index);
if (chip_id == DS_CHIP_DS18S20) return String("DS18S20");
if (chip_id == DS_CHIP_DS18B20) return String("DS18B20");
if (chip_id == DS_CHIP_DS1822) return String("DS1822");
if (chip_id == DS_CHIP_DS1825) return String("DS1825");
return String("Unknown");
}
void loadDevices() {
uint8_t address[8];
_wire->reset_search();
while (_wire->search(address)) {
// Check CRC
if (_wire->crc8(address, 7) == address[7]) {
ds_device_t device;
memcpy(device.address, address, 8);
_devices.push_back(device);
}
}
_count = _devices.size();
}
typedef struct {
uint8_t address[8];
uint8_t data[9];
} ds_device_t;
std::vector<ds_device_t> _devices;
unsigned char _gpio;
unsigned long _interval;
OneWire * _wire;
};

+ 7
- 3
code/espurna/sensors/EventSensor.h View File

@ -40,18 +40,22 @@ class EventSensor : public BaseSensor {
// Type for slot # index
magnitude_t type(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index == 0) return MAGNITUDE_EVENTS;
_error = SENSOR_ERROR_OUT_OF_RANGE;
return MAGNITUDE_NONE;
}
// Current value for slot # index
double value(unsigned char index) {
double value = 0;
_error = SENSOR_ERROR_OK;
if (index == 0) {
value = _events;
double value = _events;
_events = 0;
return value;
};
return value;
_error = SENSOR_ERROR_OUT_OF_RANGE;
return 0;
}


+ 3078
- 3071
code/espurna/static/index.html.gz.h
File diff suppressed because it is too large
View File


+ 5
- 0
code/espurna/utils.ino View File

@ -274,3 +274,8 @@ double roundTo(double num, unsigned char positions) {
while (positions-- > 0) multiplier *= 10;
return round(num * multiplier) / multiplier;
}
void nice_delay(unsigned long ms) {
unsigned long start = millis();
while (millis() - start < ms) delay(1);
}

+ 0
- 25
code/html/index.html View File

@ -171,31 +171,6 @@
<div id="sensors">
</div>
<div class="pure-g module module-analog">
<label class="pure-u-1 pure-u-sm-1-4">Analog</label>
<input class="pure-u-1 pure-u-sm-3-4" type="text" name="analogValue" readonly />
</div>
<div class="pure-g module module-counter">
<label class="pure-u-1 pure-u-sm-1-4">Counts / last minute</label>
<input class="pure-u-1 pure-u-sm-3-4" type="text" name="counterValue" readonly />
</div>
<div class="pure-g module module-ds">
<label class="pure-u-1 pure-u-sm-1-4">Temperature (<span name="tmpUnits"></span>)</label>
<input class="pure-u-1 pure-u-sm-3-4" type="text" name="dsTmp" readonly />
</div>
<div class="pure-g module module-dht">
<label class="pure-u-1 pure-u-sm-1-4">Temperature (<span name="tmpUnits"></span>)</label>
<input class="pure-u-1 pure-u-sm-3-4" type="text" name="dhtTmp" readonly />
</div>
<div class="pure-g module module-dht">
<label class="pure-u-1 pure-u-sm-1-4">Humidity (%)</label>
<input class="pure-u-1 pure-u-sm-3-4" type="text" name="dhtHum" readonly />
</div>
<div class="pure-g module module-emon module-hlw module-v9261f module-ech1560">
<label class="pure-u-1 pure-u-sm-1-4">Current</label>
<input class="pure-u-1 pure-u-sm-3-4" type="text" name="pwrCurrent" post=" A" readonly />


+ 0
- 1
code/platformio.ini View File

@ -20,7 +20,6 @@ lib_deps =
Embedis
NtpClientLib
OneWire
DallasTemperature
Brzo I2C
EspSoftwareSerial
https://bitbucket.org/xoseperez/justwifi.git#1.1.4


Loading…
Cancel
Save