GY-63_MS5611/sketches/DHT_Simulator/DHT_Simulator.ino
2021-01-29 12:31:58 +01:00

211 lines
4.7 KiB
C++

//
// FILE: DHT_simulator.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.2.1
// PURPOSE: Simulation of the DHT protocol
// DATE: 2014-06-14
// URL: https://github.com/RobTillaart/DHT_Simulator
// TODO
// - split loop into some functions?
// SET ACTUAL PINS PER PLATFORM
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.
#if defined(__AVR__)
const int humPin = A0; // analog pins for potmeters.
const int tempPin = A2;
#elif defined(ESP32)
const int humPin = 14;
const int tempPin = 15;
#elif defined(ESP8266)
const int humPin = 2;
const int tempPin = 3;
#else // CI
const int humPin = A0;
const int tempPin = A2;
#endif
// DATA TO SEND
byte b[5]; // actual bytes sent
int humidity; // humidity * 10 - prevent float operations
int temperature; // temperature * 10
// CONFIGURE
const bool randomize = true; // use random generator
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
/////////////////////////////////////////
void setup()
{
Serial.begin(115200);
Serial.print("Start ");
Serial.println(__FILE__);
pinMode(dataPin, INPUT_PULLUP);
pinMode(CRCPin, INPUT_PULLUP);
pinMode(TimeOutPin, INPUT_PULLUP);
pinMode(PulseLenPin, INPUT_PULLUP);
}
void loop()
{
yield(); // keep ESP happy
count++;
uint32_t now = millis();
if (now - lastTime >= 1000)
{
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();
}
// READ "ERROR" PINS
CRCerror = digitalRead(CRCPin) == LOW;
TimeOutError = digitalRead(TimeOutPin) == LOW;
PulseLenError = digitalRead(PulseLenPin) == LOW;
// WAKE UP SIGNAL DETECTED
if (digitalRead(dataPin) == LOW)
{
uint32_t start = micros();
// wait max 1500 us until signal goes high
while (digitalRead(dataPin) == LOW)
{
if (micros() - start > 1500)
{
// Serial.println("ERROR: low puise too long");
return;
}
}
if (micros() - start > 500) // serious request...
{
DHTsend(humidity, temperature);
Serial.print(humidity);
Serial.print("\t");
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");
}
}
}
void DHTsend(int H, int T)
{
pinMode(dataPin, OUTPUT);
// SEND ACK
digitalWrite(dataPin, LOW);
delayMicroseconds(80); // 80 us
digitalWrite(dataPin, HIGH);
delayMicroseconds(80); // 80 us
if (TimeOutError)
{
delayMicroseconds(100); // inject extra 100 microseconds
}
// PREPARE DATA
b[0] = H / 256;
b[1] = H & 255;
b[2] = 0;
if (T < 0)
{
T = -T;
b[2] = 0x80;
}
b[2] |= T / 256;
b[3] = T & 255;
// CRC
b[4] = b[0] + b[1] + b[2] + b[3];
if (CRCerror) b[4]++; // inject CRC error
// SEND DATA
for (int i = 0; i < 5; i++)
{
DHTsendbyte(b[i]);
}
// END OF TRANSMISSION SIGNAL
digitalWrite(dataPin, LOW);
delayMicroseconds(50); // 50 us
pinMode(dataPin, INPUT_PULLUP);
}
// timing manual tuned
void DHTsendbyte(byte b)
{
byte mask = 128;
for (int i = 0; i < 8; i++)
{
digitalWrite(dataPin, LOW);
delayMicroseconds(45); // 50 us
if (PulseLenError)
{
delayMicroseconds(10); // inject extra pulselength // TWEAK amount
}
digitalWrite(dataPin, HIGH);
if (b & mask) delayMicroseconds(60); // 70 us
else delayMicroseconds(24); // 26 us
mask >>= 1;
}
}
// -- END OF FILE --