Hey guys, I am new to this Forum.
I am trying to implement an emulator for an DHT11 (test purposes).
Currently I am facing the following problem:
The data-array right calculated but I have trouble with the time (Interrupt). In this Data array (DHT11_value_array) I am calculating the timing sequence which should be sent out later by an ISR. I have connected an Oscilloscope to the defined Pin but the amount of pulses sent out by the ISR varies widely.
I hope anybody can help me - thanks!
#define DHT_PIN 18
#define TRIGGER 20
void DHT11_data(float temp, float hum); // converts DHT11 data
hw_timer_t *Timer0 = NULL;
void IRAM_ATTR onTimer0(); // function prototype ISR
u_int8_t DHT11_value_array[83] = {0};
u_int32_t low_sig_time = 0;
u_int8_t high_sig_time = 0;
void setup()
{
setCpuFrequencyMhz(240); // set CPU frequency (MHz)
pinMode(DHT_PIN, INPUT_PULLUP);
pinMode(TRIGGER, OUTPUT);
Timer0 = timerBegin(0, 80, true); // timerBegin(timer number, CLK divider, counter mode) 12,5 ns * 80 = 1 us
timerAttachInterrupt(Timer0, &onTimer0, true); // timerAttachInterrupt(ISR-function, time in us (-> CLK divider), edge)
}
void loop()
{
low_sig_time = pulseIn(DHT_PIN, LOW); // should be ~ 18 ms = 18000 us
high_sig_time = pulseIn(DHT_PIN, HIGH); // should be ~ 20 to 40 us
if (low_sig_time > 17500 && low_sig_time < 18500 &&
high_sig_time > 19 && high_sig_time < 41) // check if requested conditions are met
{
DHT11_data(25.1, 60.6); // calculate data-array with given values -> temp 25,1°C; hum60,6%
}
digitalWrite(TRIGGER, HIGH); // Trigger signal for osci
DHT11_data(25.1, 60.6); // test signal - no secound ESP available
delay(1);
digitalWrite(TRIGGER, LOW); // Trigger signal for osci
delay(5);
}
void DHT11_data(float temp, float hum)
{
u_int64_t DHT11_values = (u_int64_t)((u_int64_t)(hum * 100) << (3 * 8)); // shift humidity-data & concatenate
DHT11_values |= (u_int32_t)(((u_int32_t)(temp * 100)) << 8); // shift temperature-data & concatenate
DHT11_values |= (u_int8_t)((u_int16_t)(hum + temp) & 0xFF); // mask the last 8 bits of checksum & concatenate
DHT11_value_array[0] = 80; // start sequenc time (LOW)
DHT11_value_array[1] = 80; // start sequenc time (HIGH)
DHT11_value_array[82] = 50; // stop sequenc time (LOW)
for (u_int8_t i = 82; i > 1; i -= 2)
{
DHT11_value_array[i] = 50;
if ((DHT11_values & (1 << ((i - 2) / 2))) >= 1)
{
DHT11_value_array[i + 1] = 70; // logic 1
}
else
{
DHT11_value_array[i + 1] = 27; // logic 0
}
}
pinMode(DHT_PIN, OUTPUT); // change DHT_PIN to OUTPUT
digitalWrite(DHT_PIN, LOW); // initial level
timerAlarmWrite(Timer0, DHT11_value_array[0], true); // set CC Register
timerAlarmEnable(Timer0); // Enable Timer
}
void IRAM_ATTR onTimer0()
{
static u_int8_t cnt = 1;
if (cnt == 1)
{
digitalWrite(DHT_PIN, HIGH);
timerAlarmWrite(Timer0, DHT11_value_array[cnt], true); // set CC Register
digitalWrite(TRIGGER, LOW);
}
else if (cnt > 1 && cnt < 82)
{
digitalWrite(DHT_PIN, cnt % 2);
timerAlarmWrite(Timer0, DHT11_value_array[cnt], true); // set CC Register
}
if (cnt >= 82) // reset sequenc
{
cnt = 0;
timerAlarmDisable(Timer0); // Disable Timer
pinMode(DHT_PIN, INPUT_PULLUP);
}
cnt++;
}
In the scope screenshots you can see that the amount of pulses varies.