2014-06-26 14:54:44 -04:00
|
|
|
//
|
|
|
|
// FILE: DHT_simulator.ino
|
|
|
|
// AUTHOR: Rob Tillaart
|
2021-01-29 06:31:58 -05:00
|
|
|
// VERSION: 0.2.1
|
2020-07-17 06:42:59 -04:00
|
|
|
// PURPOSE: Simulation of the DHT protocol
|
2014-06-26 14:54:44 -04:00
|
|
|
// DATE: 2014-06-14
|
2020-07-17 06:42:59 -04:00
|
|
|
// URL: https://github.com/RobTillaart/DHT_Simulator
|
2014-06-26 14:54:44 -04:00
|
|
|
|
|
|
|
// TODO
|
2020-07-17 06:42:59 -04:00
|
|
|
// - split loop into some functions?
|
|
|
|
|
|
|
|
|
|
|
|
// SET ACTUAL PINS PER PLATFORM
|
2021-01-29 06:31:58 -05:00
|
|
|
const int dataPin = 5; // connect to MCU ( !! also connect GND !! )
|
|
|
|
const int CRCPin = 6; // connect switch to simulate CRC errors.
|
|
|
|
const int TimeOutPin = 7; // connect switch to simulate timeout errors.
|
|
|
|
const int PulseLenPin = 8; // connect switch to simulate pulselength errors.
|
|
|
|
|
2020-07-17 06:42:59 -04:00
|
|
|
|
|
|
|
#if defined(__AVR__)
|
2021-01-29 06:31:58 -05:00
|
|
|
const int humPin = A0; // analog pins for potmeters.
|
2020-07-17 06:42:59 -04:00
|
|
|
const int tempPin = A2;
|
|
|
|
#elif defined(ESP32)
|
2021-01-29 06:31:58 -05:00
|
|
|
const int humPin = 14;
|
2020-07-17 06:42:59 -04:00
|
|
|
const int tempPin = 15;
|
|
|
|
#elif defined(ESP8266)
|
2021-01-29 06:31:58 -05:00
|
|
|
const int humPin = 2;
|
2020-07-17 06:42:59 -04:00
|
|
|
const int tempPin = 3;
|
2021-01-29 06:31:58 -05:00
|
|
|
#else // CI
|
|
|
|
const int humPin = A0;
|
|
|
|
const int tempPin = A2;
|
2020-07-17 06:42:59 -04:00
|
|
|
#endif
|
2014-06-26 14:54:44 -04:00
|
|
|
|
|
|
|
|
2020-07-17 06:42:59 -04:00
|
|
|
// DATA TO SEND
|
2021-01-29 06:31:58 -05:00
|
|
|
byte b[5]; // actual bytes sent
|
|
|
|
int humidity; // humidity * 10 - prevent float operations
|
|
|
|
int temperature; // temperature * 10
|
2020-07-17 06:42:59 -04:00
|
|
|
|
|
|
|
|
|
|
|
// CONFIGURE
|
|
|
|
const bool randomize = true; // use random generator
|
2021-01-29 06:31:58 -05:00
|
|
|
const bool debug = false; // test data generation
|
|
|
|
|
|
|
|
bool CRCerror = false; // inject CRC error
|
|
|
|
bool TimeOutError = false; //
|
|
|
|
bool PulseLenError = false; //.
|
|
|
|
uint32_t count = 0; // count values per second generated
|
|
|
|
uint32_t lastTime = 0; // keep track of timing
|
2020-07-17 06:42:59 -04:00
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////
|
|
|
|
void setup()
|
2014-06-26 14:54:44 -04:00
|
|
|
{
|
|
|
|
Serial.begin(115200);
|
2014-06-26 14:58:20 -04:00
|
|
|
Serial.print("Start ");
|
|
|
|
Serial.println(__FILE__);
|
2014-06-26 14:54:44 -04:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
pinMode(dataPin, INPUT_PULLUP);
|
|
|
|
pinMode(CRCPin, INPUT_PULLUP);
|
|
|
|
pinMode(TimeOutPin, INPUT_PULLUP);
|
|
|
|
pinMode(PulseLenPin, INPUT_PULLUP);
|
2014-06-26 14:54:44 -04:00
|
|
|
}
|
|
|
|
|
2020-07-17 06:42:59 -04:00
|
|
|
void loop()
|
2014-06-26 14:54:44 -04:00
|
|
|
{
|
2020-07-17 06:42:59 -04:00
|
|
|
yield(); // keep ESP happy
|
|
|
|
|
|
|
|
count++;
|
|
|
|
uint32_t now = millis();
|
|
|
|
if (now - lastTime >= 1000)
|
2014-06-26 14:54:44 -04:00
|
|
|
{
|
2020-07-17 06:42:59 -04:00
|
|
|
uint32_t nps = round((1000.0 * count) / (now - lastTime));
|
|
|
|
Serial.print("DATA PER SECOND: ");
|
|
|
|
Serial.println(nps);
|
|
|
|
lastTime = now;
|
|
|
|
count = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (randomize)
|
|
|
|
{
|
|
|
|
humidity = random(20, 1000);
|
|
|
|
temperature = random(-200, 1800);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
analogRead(humPin);
|
|
|
|
humidity = analogRead(humPin);
|
|
|
|
analogRead(tempPin);
|
|
|
|
temperature = analogRead(tempPin) * 2 - 200;
|
|
|
|
}
|
|
|
|
humidity = constrain(humidity, 0, 1000);
|
|
|
|
temperature = constrain(temperature, -200, 1800);
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Serial.print(humidity);
|
|
|
|
Serial.print("\t");
|
|
|
|
Serial.print(temperature);
|
|
|
|
Serial.println();
|
2014-06-26 14:54:44 -04:00
|
|
|
}
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
// READ "ERROR" PINS
|
|
|
|
CRCerror = digitalRead(CRCPin) == LOW;
|
|
|
|
TimeOutError = digitalRead(TimeOutPin) == LOW;
|
|
|
|
PulseLenError = digitalRead(PulseLenPin) == LOW;
|
|
|
|
|
|
|
|
|
2014-06-26 14:54:44 -04:00
|
|
|
// WAKE UP SIGNAL DETECTED
|
2020-07-17 06:42:59 -04:00
|
|
|
if (digitalRead(dataPin) == LOW)
|
2014-06-26 14:54:44 -04:00
|
|
|
{
|
|
|
|
uint32_t start = micros();
|
2020-07-17 06:42:59 -04:00
|
|
|
// wait max 1500 us until signal goes high
|
2014-06-26 14:58:20 -04:00
|
|
|
while (digitalRead(dataPin) == LOW)
|
|
|
|
{
|
2020-07-17 06:42:59 -04:00
|
|
|
if (micros() - start > 1500)
|
|
|
|
{
|
|
|
|
// Serial.println("ERROR: low puise too long");
|
|
|
|
return;
|
|
|
|
}
|
2014-06-26 14:58:20 -04:00
|
|
|
}
|
2020-07-17 06:42:59 -04:00
|
|
|
if (micros() - start > 500) // serious request...
|
2014-06-26 14:54:44 -04:00
|
|
|
{
|
2020-07-17 06:42:59 -04:00
|
|
|
DHTsend(humidity, temperature);
|
2014-06-26 14:54:44 -04:00
|
|
|
|
2020-07-17 06:42:59 -04:00
|
|
|
Serial.print(humidity);
|
2014-06-26 14:54:44 -04:00
|
|
|
Serial.print("\t");
|
2020-07-17 06:42:59 -04:00
|
|
|
Serial.print(temperature);
|
|
|
|
Serial.print("\t");
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
|
|
{
|
|
|
|
if (b[i] < 0x10) Serial.print('0');
|
|
|
|
Serial.print(b[i], HEX);
|
|
|
|
Serial.print(' ');
|
|
|
|
}
|
|
|
|
Serial.println();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Serial.println("ERROR: low puise too short");
|
2014-06-26 14:54:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-26 14:58:20 -04:00
|
|
|
|
2014-06-26 14:54:44 -04:00
|
|
|
void DHTsend(int H, int T)
|
|
|
|
{
|
2020-07-17 06:42:59 -04:00
|
|
|
pinMode(dataPin, OUTPUT);
|
2014-06-26 14:58:20 -04:00
|
|
|
// SEND ACK
|
|
|
|
digitalWrite(dataPin, LOW);
|
|
|
|
delayMicroseconds(80); // 80 us
|
|
|
|
digitalWrite(dataPin, HIGH);
|
|
|
|
delayMicroseconds(80); // 80 us
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
if (TimeOutError)
|
|
|
|
{
|
|
|
|
delayMicroseconds(100); // inject extra 100 microseconds
|
|
|
|
}
|
|
|
|
|
2014-06-26 14:58:20 -04:00
|
|
|
// PREPARE DATA
|
2014-06-26 14:54:44 -04:00
|
|
|
b[0] = H / 256;
|
|
|
|
b[1] = H & 255;
|
|
|
|
|
2014-06-26 14:58:20 -04:00
|
|
|
b[2] = 0;
|
2020-07-17 06:42:59 -04:00
|
|
|
if (T < 0)
|
2014-06-26 14:54:44 -04:00
|
|
|
{
|
2014-06-26 14:58:20 -04:00
|
|
|
T = -T;
|
2014-06-26 14:54:44 -04:00
|
|
|
b[2] = 0x80;
|
|
|
|
}
|
|
|
|
|
2014-06-26 14:58:20 -04:00
|
|
|
b[2] |= T / 256;
|
|
|
|
b[3] = T & 255;
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2014-06-26 14:58:20 -04:00
|
|
|
// CRC
|
|
|
|
b[4] = b[0] + b[1] + b[2] + b[3];
|
2021-01-29 06:31:58 -05:00
|
|
|
if (CRCerror) b[4]++; // inject CRC error
|
2014-06-26 14:54:44 -04:00
|
|
|
|
2014-06-26 14:58:20 -04:00
|
|
|
// SEND DATA
|
2014-06-26 14:54:44 -04:00
|
|
|
for (int i = 0; i < 5; i++)
|
|
|
|
{
|
|
|
|
DHTsendbyte(b[i]);
|
|
|
|
}
|
2014-06-26 14:58:20 -04:00
|
|
|
|
|
|
|
// END OF TRANSMISSION SIGNAL
|
|
|
|
digitalWrite(dataPin, LOW);
|
|
|
|
delayMicroseconds(50); // 50 us
|
|
|
|
pinMode(dataPin, INPUT_PULLUP);
|
2014-06-26 14:54:44 -04:00
|
|
|
}
|
|
|
|
|
2014-06-26 14:58:20 -04:00
|
|
|
// timing manual tuned
|
2014-06-26 14:54:44 -04:00
|
|
|
void DHTsendbyte(byte b)
|
|
|
|
{
|
|
|
|
byte mask = 128;
|
2020-07-17 06:42:59 -04:00
|
|
|
for (int i = 0; i < 8; i++)
|
2014-06-26 14:54:44 -04:00
|
|
|
{
|
|
|
|
digitalWrite(dataPin, LOW);
|
2014-06-26 14:58:20 -04:00
|
|
|
delayMicroseconds(45); // 50 us
|
2021-01-29 06:31:58 -05:00
|
|
|
if (PulseLenError)
|
|
|
|
{
|
|
|
|
delayMicroseconds(10); // inject extra pulselength // TWEAK amount
|
|
|
|
}
|
2014-06-26 14:54:44 -04:00
|
|
|
digitalWrite(dataPin, HIGH);
|
2014-06-26 14:58:20 -04:00
|
|
|
if (b & mask) delayMicroseconds(60); // 70 us
|
|
|
|
else delayMicroseconds(24); // 26 us
|
2014-06-26 14:54:44 -04:00
|
|
|
mask >>= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-17 06:42:59 -04:00
|
|
|
// -- END OF FILE --
|