You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.1 KiB
136 lines
3.1 KiB
/* Emulates a DS18B20 using a DHT22 |
|
* |
|
* Provided by Destroyedlolo. (http://destroyedlolo.info) |
|
* |
|
* 23/03/2018 - First version |
|
*/ |
|
|
|
#include <Arduino.h> |
|
#include <LowLevel.h> |
|
#include <OneWireSlave.h> |
|
|
|
Pin oneWireData(2); // Where the 1-wire bus is connected to |
|
|
|
const byte owROM[7] = { 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }; |
|
|
|
enum OW_Cmd { |
|
START_CONVERSION = 0x44, |
|
READ_SCRATCHPAD = 0xBE |
|
}; |
|
|
|
volatile byte scratchpad[9]; |
|
|
|
/* |
|
* DHT22 related |
|
*/ |
|
#include <SimpleDHT.h> // https://github.com/winlinvip/SimpleDHT |
|
|
|
SimpleDHT22 DHT; |
|
#define pinDHT 3 |
|
|
|
/* |
|
* Let's go |
|
*/ |
|
#define DEBUG // Comment out to be silence |
|
|
|
enum DeviceState { |
|
WAIT4RESET, |
|
WAIT4COMMAND, |
|
CONVERTING, |
|
TEMPERATUREREADY |
|
}; |
|
|
|
volatile DeviceState state = DeviceState::WAIT4RESET; |
|
volatile unsigned long conversionStartTime = 0; |
|
volatile int ignByte = 0; // Bytes to be ignored |
|
|
|
void owRcv( OneWireSlave::ReceiveEvent evt, byte cmd ){ |
|
switch( evt ){ |
|
case OneWireSlave::RE_Reset: |
|
state = DeviceState::WAIT4COMMAND; |
|
ignByte = 0; |
|
#ifdef DEBUG |
|
Serial.println(F("Reset")); |
|
#endif |
|
break; |
|
case OneWireSlave::RE_Error: |
|
state = DeviceState::WAIT4RESET; |
|
#ifdef DEBUG |
|
Serial.println(F("Error")); |
|
#endif |
|
break; |
|
case OneWireSlave::RE_Byte: |
|
if( state == DeviceState::WAIT4COMMAND ) switch( cmd ){ |
|
case OW_Cmd::START_CONVERSION: |
|
// Do a new request only if enough time passed |
|
if( !conversionStartTime || millis() < conversionStartTime || millis() > conversionStartTime + 2000 ){ |
|
state = DeviceState::CONVERTING; |
|
OWSlave.beginWriteBit(0, true); // send zeros as long as the conversion is not finished |
|
} |
|
#ifdef DEBUG |
|
else |
|
Serial.println(F("Ignored StartConv")); |
|
#endif |
|
break; |
|
case OW_Cmd::READ_SCRATCHPAD: |
|
state = DeviceState::WAIT4RESET; |
|
OWSlave.beginWrite((const byte*)scratchpad, 9, 0); |
|
break; |
|
#ifdef DEBUG |
|
default: |
|
Serial.print(F("Unknown command :")); |
|
Serial.println( cmd, HEX ); |
|
#endif |
|
} |
|
} |
|
} |
|
|
|
void setTemperature( float temp ){ // Write given temperature to the scratchpad |
|
int16_t raw = (int16_t)(temp * 16.0f + 0.5f); |
|
|
|
// We don't care about race condition as well as only one command |
|
// can be processed at a time otherwise we are failing in error/collision |
|
// condition. |
|
scratchpad[0] = (byte)raw; |
|
scratchpad[1] = (byte)(raw >> 8); |
|
scratchpad[8] = OWSlave.crc8((const byte*)scratchpad, 8); |
|
} |
|
|
|
void setup(){ |
|
Serial.begin(115200); // debugging |
|
|
|
for(int i = 2; i<8; i++) |
|
scratchpad[i] = 0; |
|
setTemperature( 85 ); |
|
|
|
OWSlave.setReceiveCallback(&owRcv); |
|
OWSlave.begin(owROM, oneWireData.getPinNumber()); |
|
} |
|
|
|
|
|
void loop(){ |
|
delay(10); |
|
|
|
if(state == DeviceState::CONVERTING){ // start conversion |
|
float temperature = 0; |
|
float humidite = 0; |
|
int err; |
|
|
|
conversionStartTime = millis(); |
|
if((err = DHT.read2(pinDHT, &temperature, &humidite, NULL)) != SimpleDHTErrSuccess){ |
|
#ifdef DEBUG |
|
Serial.print("\nError while reading, err="); |
|
Serial.println(err); |
|
#endif |
|
temperature = 85; |
|
} else { |
|
#ifdef DEBUG |
|
Serial.print("Temperature :"); |
|
Serial.println(temperature); |
|
#endif |
|
setTemperature( temperature ); |
|
} |
|
state = DeviceState::TEMPERATUREREADY; |
|
OWSlave.beginWriteBit(1, true); |
|
} |
|
}
|
|
|