Как время выполнения инструкций кода влияет на сигнал между Arduino и DHT11?
Я проверяю код для DHT11 от CircuitGeeks, вариант без использования библиотеки. Проблема в несоответствии протокола DHT11/DHT22 и сигналов, которые считываются с датчика в скетче. Несмотря на это, скетч работает, и я хотел бы узнать, как.
#define DHT11_PIN 12
unsigned long TON_TIME = 0;
unsigned long TOFF_TIME = 0;
unsigned char data_byte[5];
unsigned int data_packet[40];
unsigned char bit_data = 0;
unsigned char checksum_byte = 0;
int bit_counter = 0;
void setup() {
Serial.begin(9600);
Serial.println("DHT11 Humidity & Temperature Sensor\n");
delay(1000);//Ожидание перед доступом к датчику
}
void loop() {
pinMode(DHT11_PIN, OUTPUT);
digitalWrite(DHT11_PIN, LOW);
delay(18);
digitalWrite(DHT11_PIN, HIGH);
pinMode(DHT11_PIN, INPUT_PULLUP);
TOFF_TIME = pulseIn(DHT11_PIN, LOW);
if (TOFF_TIME <= 84 && TOFF_TIME >= 76) {
while (1) {
TON_TIME = pulseIn(DHT11_PIN, HIGH);
if (TON_TIME <= 28 && TON_TIME >= 20) {
bit_data = 0;
}
else if (TON_TIME <= 74 && TON_TIME >= 65) {
bit_data = 1;
}
else if (bit_counter == 40) {
break;
}
data_byte[bit_counter / 8] |= bit_data << (7 - (bit_counter % 8));
data_packet[bit_counter] = bit_data;
bit_counter++;
}
}
checksum_byte = data_byte[0] + data_byte[1] + data_byte[2] + data_byte[3];
if (checksum_byte == data_byte[4] && checksum_byte != 0) {
Serial.println("Humidity: ");
for (int c = 0; c <= 7; c++) {
Serial.print(data_packet[c]);
}
Serial.print("\t");
for (int c = 0; c <= 7; c++) {
Serial.print(data_packet[c + 8]);
}
Serial.print("\t");
Serial.print(data_byte[0]);
Serial.print("%");
Serial.println(" ");
Serial.println("Temperature: ");
for (int c = 0; c <= 7; c++) {
Serial.print(data_packet[c + 16]);
}
Serial.print("\t");
for (int c = 0; c <= 7; c++) {
Serial.print(data_packet[c + 24]);
}
Serial.print("\t");
Serial.print(data_byte[2]);
Serial.print("C");
Serial.println(" ");
Serial.println("Checksum Byte: ");
for (int c = 0; c <= 7; c++) {
Serial.print(data_packet[c + 32]);
}
Serial.println(" ");
Serial.print("CHECKSUM_OK");
Serial.println("");
Serial.println("");
}
bit_counter = 0;
data_byte[0] = data_byte[1] = data_byte[2] = data_byte[3] = data_byte[4] = 0;
delay(1000);
}
Если посмотреть на код, то 18 мс уровня LOW для инициализации. Затем около 40 мкс уровня HIGH, это можно считать временем между инструкциями digitalWrite(DHT11_PIN, HIGH);
и TOFF_TIME = pulseIn(DHT11_PIN, LOW);
. Но затем после 80 мкс уровня LOW TOFF_TIME = pulseIn(DHT11_PIN, LOW);
должен быть 80 мкс уровня HIGH. Вместо этого код продолжается условиями проверки длины импульсов, которые отвечают за биты данных. Если длительность импульса 26-28 мкс, то это 0, если 70 мкс - то это 1. Я понимаю, что с помощью инструкции TON_TIME = pulseIn(DHT11_PIN, HIGH);
мы найдем длительность только ВЫСОКИХ импульсов битов данных.
Почему передается 80 мкс HIGH уровень, однако это не влияет на взаимодействие с датчиком? Проходит ли он во время выполнения инструкций из if (TOFF_TIME <= 84 && TOFF_TIME >= 76)
в TON_TIME = pulseIn(DHT11_PIN, HIGH);
?
@Artur Krush, 👍1
1 ответ
Лучший ответ:
В конце 80 мкс LOW от HDT11, pulseIn(DHT11_PIN, LOW)
возвращается. В этот момент времени линия данных ВЫСОКАЯ, где-то около
начало положительного импульса 80 мкс. Теперь код выполняет
первый pulseIn(DHT11_PIN, HIGH)
.
Вы не сможете измерить длину положительного импульса, если вы пропустили
нарастающий фронт. Таким образом, когда pulseIn()
находит линию HIGH, он сначала
подождите, пока он не перейдет в состояние LOW, затем подождите, пока он не перейдет обратно в состояние
ВЫСОКИЙ, и только потом начинать отсчет времени.
См., например, реализацию цикла подсчета в AVR ядро, или, скорее, код C, который служил для генерации сборки Реализация. Имеет три цикла ожидания:
- подождать окончания любого предыдущего импульса
- подождать начала импульса
- подождать, пока пульс остановится
- Какова работа pulseIn?
- Как использовать две функции pulseIn() одновременно в Arduino?
- Как измерить ультразвуковой датчик без импульсного метода?
- Импульсный тахометр
- Код считывания датчика DHT22 странно интерпретирует отрицательные значения (распространенная проблема)
- Датчики Dht 11 дают нулевое значение
- Можно ли использовать Arduino Uno для измерения частоты прямоугольной волны до 600 кГц?
- Непрерывное чтение двух последовательных периодов импульса