Как время выполнения инструкций кода влияет на сигнал между Arduino и DHT11?

pulsein 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); ?

, 👍1


1 ответ


Лучший ответ:

2

В конце 80 мкс LOW от HDT11, pulseIn(DHT11_PIN, LOW) возвращается. В этот момент времени линия данных ВЫСОКАЯ, где-то около начало положительного импульса 80 мкс. Теперь код выполняет первый pulseIn(DHT11_PIN, HIGH).

Вы не сможете измерить длину положительного импульса, если вы пропустили нарастающий фронт. Таким образом, когда pulseIn() находит линию HIGH, он сначала подождите, пока он не перейдет в состояние LOW, затем подождите, пока он не перейдет обратно в состояние ВЫСОКИЙ, и только потом начинать отсчет времени.

См., например, реализацию цикла подсчета в AVR ядро, или, скорее, код C, который служил для генерации сборки Реализация. Имеет три цикла ожидания:

  • подождать окончания любого предыдущего импульса
  • подождать начала импульса
  • подождать, пока пульс остановится
,