DHT11 значения, NRF24L01, прерывания

Тема в разделе "Arduino & Shields", создана пользователем ORLENOK, 11 фев 2018.

Метки:
  1. ORLENOK

    ORLENOK Гик

    День добрый!

    Имеется arduino nano с подключенным к ней NRF24L01 и DHT11.
    Ардуина засыпает. При срабатывании прерывания - просыпается. Должно происходить чтений значений с dht, и записываться в массив данных. Во время пробуждения чтение с датчика может происходить несколько раз (2-4). Потом опять в сон. В тестовом варианте пробуждения раз в 40 секунд. В дальнейшем планируется раз в несколько минут.

    Проблема в том, что зачастую при первом обращении к dht, он выдает первое значение как бы из прошлого пробуждения.
    Например, первый запуск, все ок, считались значения.
    Во время сна - активно дышу на датчик, поднимается влажность, температура.
    Ардуина просыпается пишет первое значение, допустим, 36.00 29.00, а дальше
    65.00 30.00
    75.00 30.00
    59.00 30.00
    Т.е. значение отличается в два раза, оно явно не текущее.
    Вопрос в том, как быть и что делать? Какие есть идеи?
    Код (C++):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    #include "printf.h"
    #include "DHT.h"
    #include  <avr/sleep.h>

    #define DHTPIN 5

    // Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 9 & 10
    RF24 radio(9, 10);
    // Topology
    uint64_t address =  0x1230123012;
    volatile float sendingData[] = {0,0};

    enum STATE {state_sleep = 0, state_interrupt,state_wait};
    uint8_t currentState = state_sleep;
    uint64_t t1 = 0;

    DHT dht(DHTPIN, DHT11); //Connect DHT

    void setup() {
      Serial.begin(9600);
      dht.begin();
      delay(5000);
      printf_begin();
      Serial.println("ROLE: RESPONSER");
     
      // Setup and configure radio
      radio.begin();
      radio.setAutoAck(1);                    // Ensure autoACK is enabled
      radio.enableAckPayload();               // Allow optional ack payloads
      radio.maskIRQ(1, 1, 0);
      radio.setPALevel(RF24_PA_LOW);
      radio.setRetries(0, 15);                // Smallest time between retries, max no. of retries
      radio.setDataRate(RF24_2MBPS);
      radio.openReadingPipe(1, address);
      radio.startListening();            
      attachInterrupt(0, interruptGo,FALLING); //0 for pin 2, 1 for pin 3
      delay(500);
      goSleep();
    }

    void loop()
    {
      switch(currentState)
      {
        case state_interrupt:
        {
          delay(1000);
          sendingData[0] = dht.readHumidity();
          delay(1000);
          sendingData[1] = dht.readTemperature();
          delay(1000);

          readDataSendResponse();
          currentState = state_wait;
          t1 = millis();
          break;
        }
        case state_wait:
        {
          if(millis() - t1 > 10000)
          {
            currentState = state_sleep;
          }
          else
          {
            delay(500);
          }
          break;
        }
        case state_sleep:
        {
          goSleep();  
        }
      }
    }

    void goSleep()
    {
      delay(1000);
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);
      cli();
      sleep_enable();
      sleep_bod_disable();
      sei();
      sleep_cpu();
      sleep_disable();
    }

    void interruptGo()
    {
      currentState = state_interrupt;
    }

    void readDataSendResponse()
    {
      byte pipeNo = 1;
      float gotData;
     
      Serial.print(" Set AckPayload: ");
      printSendingData(sendingData, sizeof(sendingData) / sizeof(sendingData[0]));
      Serial.println();
      radio.writeAckPayload(pipeNo, sendingData, sizeof(sendingData) ); // This can be commented out to send empty payloads.
     
      while (radio.available(&pipeNo))
      {
        radio.read(&gotData, sizeof(gotData));
      }
    }

    void printSendingData(float *sendingData, size_t len)
    {
      for (int i = 0; i < len; i++)
      {
        Serial.print(sendingData[i]);
        Serial.print(" ");
      }
    }
     
    delay вставлял везде от безысходности...
    С радостью выслушаю критику по коду, пожелания и предложения.
     
  2. DIYMan

    DIYMan Guest

    Код нормальный, на delay от безысходности - не обращаем внимания :) По поводу проблемы - а что мешает отбрасывать первые пару измерений после пробуждения? Или применить фильтр, отбрасывающий из массива измерений крайние значения и берущий медиану? Или какой другой фильтр, типа арифметического среднего? Правильный ответ - ничего не мешает ;)
     
  3. ORLENOK

    ORLENOK Гик

    Помог такой код:
    Код (C++):
    case state_interrupt:
        {
          for(int i =0;i< 10;i++)
          {
            dht.readHumidity();
            dht.readTemperature();
            delay(100);
          }
    //....
    Без delay внутри цикла не работает.