3

I am trying to make a sensor that gets temperature and humidity values from a DHT22 and send it through NRF24L01+ to a Raspberry Pi 2 Model B.

To connect NRF24L01+ to ATtiny85 and to free two pins for the DHT22, I used this link.

There is a scheme of my sensor: enter image description here

There is a photo of the test board with the sensor (sorry, it is very untidy, because I remade it many times before to fix the problem): enter image description here

I program the ATtiny85 with Arduino IDE (with 8 MHz clock).

I used this library and radio communication is working perfectly (it can't be an error during the radio transmission).

Here is the code of my ATtiny85:

#include <DHT.h>
#include <RF24.h>

byte currentNodeAddr[6] = "1Node";  // Address of this node

// Struct for sending measured data
struct Data {
  uint16_t temp;  // Temperature value
  uint16_t hum;   // Humidity value
  int status;     // DHT22 module status
} data;

RF24 radio(2,2);  // Create instance of RF24 radio object
DHT dht;          // Create instance of DHT22 module object

void setup() {
  // Set up the radio
  radio.begin();
  radio.openWritingPipe(currentNodeAddr);
  radio.stopListening();
  dht.setup(3); // Set up the sensor on PB3 pin
}

void loop() {
  // This DHT library can calculate the delay but it may be 2+ sec
  delay(dht.getMinimumSamplingPeriod());
  // Get values from DHT22
  data.temp = dht.getTemperature();
  data.hum = dht.getHumidity();
  radio.write(&data, sizeof(Data));  // Send data to the Raspberry
}

But I can't the get temperature and humidity values from the DHT22. I used a lot of different libraries for DHT22 (for example, github.com/ringerc/Arduino-DHT22, github.com/nethoncho/Arduino-DHT22, github.com/jscrane/DHT22, etc.) and none of them works (they return zeros, NAN, or, generally, timeout error). And it seems that the connection with the DHT22 is correct (there were connection errors and I fixed them). I tried to use a lot of DHT22 modules, so the problem can't be a defective module.

Yes, I put a 2 second (and more) delay in between read requests. Yes, I added a 10k resistor between pin 1 and 2 of the DHT22.

Now I am thinking that the libraries work fine, but may be free pins (PB3 or PB4) of ATtiny85 can't receive data for some reason.

Tell me please where may be an error or a bug? Thank you in advance! And also many thanks to authors of all links and repositories that I have mentioned here!

EDIT (in accordance with frarugi87's answer):

At first I have grounded 3 and 4 pins of the DHT22.

When I program ATtiny at the 1 MHz, values are sent every 2 seconds (as it should be), but when I program ATtiny at 8 MHz, values are sent every 16 seconds (is it correct?).

I used the suggested code to check the radio library and it seems it works pretty well (values are being incremented and sent): Test radio library

After that I used the suggested library (RobTillaart/Arduino v. 0.1.21) and at first time it returned some strange values (humidity and the status were 0 and temperature was MAX_INT value), but when I have tried to get only status value as string, the library also has returned -2 (DHTLIB_ERROR_TIMEOUT). This time I program ATTiny at 8 MHz: enter image description here

Also I tried to get values without NRF24L01+ through I2C connection between the ATtiny85 and the Raspberry Pi. Result was the same (DHTLIB_ERROR_TIMEOUT): enter image description here

Maybe the problem is in timings of ATtiny85 or in the program process? I used these links (1, 2, 3) to set up Arduino IDE on Raspbian.

Here is list of useful links for this project which I found to implement it (I hope the authors will not mind that I posted their links here):

Arduino/AVR DHT projects and libraries:

Arduino/AVR nRF24L01 projects and libraries:

Programming the ATtiny85 from Raspberry-Pi:

Arduino/AVR FR433 libraries:

Troubleshooting:

  • 1
    @sineverba I added some links to the question that I used for the project or that were helpful for me. – Alexander Jul 31 '16 at 8:43
  • 1
    @sineverba That's right. In this project I only worked with ATtiny85. As you can see in the question and in articles of the "Programming the ATtiny85 from Raspberry-Pi:" section, with Raspberry Pi you can assemble a scheme for programming AVR microcontrollers, install Arduino IDE and program ATtiny in the same manner as Arduino. But look at the answer. You have to choose microcontroller speed carefully (thats why I asked this question). But I used pretty old software 8 month ago. Maybe for now situation is better. By the way, I also plan to continue the work on this project in this month. – Alexander Jul 31 '16 at 13:00
  • 1
    @sineverba I have added the final code for both ATtiny85 transmitter and Raspberry Pi receiver to my answer below. – Alexander Aug 1 '16 at 9:15
  • 1
    @sineverba I have also added the Makefile code to compile Raspberry Pi receiver to the answer below. – Alexander Aug 1 '16 at 9:25
  • 1
    @sineverba Also in the answer I wrote that I used the next libraries: RobTillaart/Arduino DHT11, 21, 22, 33 library, Arduino driver for nRF24L01 http://maniacbug.github.com/RF24 – Alexander Aug 1 '16 at 9:39
1

Thanks to Rob Tillaart, the autor of the Arduino DHT library suggested by @frarugi87 (also thank him), the problem has been solved (see this issue for more information).

In my case to fix the problem there is only needed to to set a specific value of DHTLIB_TIMEOUT by leaving the definition #define DHTLIB_TIMEOUT 1000 in the dht.h file of this library and commenting other definitions written next to it:

// #ifndef F_CPU
#define DHTLIB_TIMEOUT 1000 // should be approx. clock/40000
// #else
// #define DHTLIB_TIMEOUT (F_CPU/40000)
// #endif

The ATtiny is programmed on 8 MHz. The DHT22 is working at a voltage of 3.3V with a 3K3 resistor.

The cause of the problem may be the way I program the ATtiny85 with old version of Arduino IDE installed in the Raspberry Pi (see comments to the @frarugi87's answer).

Libraries used:

Here is the final code of the ATtiny85 transmitter and the Raspberry Pi reseiver respectively (I took the most part of the code from different examples of RF24 libraries and DHT libraries! Excuse me, if the code is not tidy.).

NRF24Transmitter.ino:

#include <dht.h>
#include <RF24.h>

#define DHT22_PIN 3
#define LONG_DELAY_MS 900000

byte currentNodeAddr[6] = "1Node";  // Address of this node

// Struct for sending measured data
struct Data {
  float temp;  // Temperature value
  float hum;   // Humidity value
  int status;     // DHT22 module status
} data;

RF24 radio(2,2);  // Create instance of RF24 radio object
dht DHT;          // Create instance of DHT22 module object

void setup() {
  // Set up the radio
  radio.begin();
  radio.openWritingPipe(currentNodeAddr);
  radio.stopListening();
}

void loop() {

  unsigned long startMillis = millis();
  while (millis() - startMillis < LONG_DELAY_MS);

  do {
    data.status = DHT.read22(DHT22_PIN);
    data.temp = DHT.temperature;
    data.hum = DHT.humidity;

    if (data.status != DHTLIB_OK) {
      delay(1000);
    }

  } while(data.status != DHTLIB_OK);

  radio.write(&data, sizeof(Data));  // Send data to the Raspberry
}

Receiver.cpp:

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>
#include <RF24/RF24.h>

using namespace std;

uint8_t addresses[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node"};

// Struct for sending measured data
struct Data 
{
    float temp;  // Temperature value
    float hum;   // Humidity value
    int status;     // DHT22 module status
} data;

RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ);

int main(int argc, char** argv)
{
    uint8_t currentPipe = 1;
    data.temp = -888;
    data.hum = -888;

    printf("BEGIN: %d\n", (int)radio.begin());

    radio.setAutoAck(1);
    radio.setRetries(15,15);
//  radio.setDataRate(RF24_1MBPS);
//  radio.setPALevel(RF24_PA_MAX);
//  radio.setCRCLength(RF24_CRC_16);

    radio.openReadingPipe(1, addresses[0]);
    radio.openReadingPipe(2, addresses[1]);
    radio.openReadingPipe(3, addresses[2]);
    radio.openReadingPipe(4, addresses[3]);
    radio.openReadingPipe(5, addresses[4]);

    radio.startListening();

    radio.printDetails();

    sleep(1);

    cout << "Start!" << endl;

    while(true)
    {
        cout << "Waiting for data..." << endl;

        while (radio.available(&currentPipe)) 
        {
            cout << "Reading: " << addresses[currentPipe - 1] << "..." << endl;

            radio.read(&data, sizeof(Data));

            cout << "Temp: " << data.temp << endl;
            cout << "Hum: " << data.hum << endl;
            cout << "Status: " << data.status << endl;
        }

        sleep(1);
    }   

    return 0;
}

Here is Makefile to compile the receiver.cpp:

#############################################################################
#
# Makefile for librf24 examples on Raspberry Pi
#
# License: GPL (General Public License)
# Author:  gnulnulf <arco@appeltaart.mine.nu>
# Date:    2013/02/07 (version 1.0)
#
# Description:
# ------------
# use make all and make install to install the examples
# You can change the install directory by editing the prefix line
#
prefix := /usr/local

# Detect the Raspberry Pi by the existence of the bcm_host.h file
BCMLOC=/opt/vc/include/bcm_host.h

ifneq ("$(wildcard $(BCMLOC))","")
# The recommended compiler flags for the Raspberry Pi
CCFLAGS=-Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s
endif

# define all programs
#PROGRAMS = scanner pingtest gettingstarted
PROGRAMS = receiver #gettingstarted gettingstarted_call_response transfer pingpair_dyn test
SOURCES = ${PROGRAMS:=.cpp}

all: ${PROGRAMS}

${PROGRAMS}: ${SOURCES}
    g++ ${CCFLAGS} -Wall -I../ -lrf24-bcm $@.cpp -o $@

clean:
    rm -rf $(PROGRAMS)

install: all
    receiver -d $(prefix) || mkdir $(prefix)
    receiver -d $(prefix)/bin || mkdir $(prefix)/bin
    for prog in $(PROGRAMS); do \
      install -m 0755 $$prog $(prefix)/bin; \
    done

.PHONY: install
0

Ok, let's troubleshoot it.

Try with the following sketch:

#include <RF24.h>

byte currentNodeAddr[6] = "1Node";  // Address of this node

// Struct for sending measured data
struct Data {
  uint16_t temp;  // Temperature value
  uint16_t hum;   // Humidity value
  int status;     // DHT22 module status
} data;

RF24 radio(2,2);  // Create instance of RF24 radio object

void setup() {
    // Set up the radio
    radio.begin();
    radio.openWritingPipe(currentNodeAddr);
    radio.stopListening();
    data.temp = 0;
    data.hum = 1;
    data.status = 2;
}

void loop() {
    data.temp++;
    data.hum++;
    data.status++;
    radio.write(&data, sizeof(Data));
    delay(2000);
}

You should see a bunch of data being sent to the raspberry every second (you should see temp = 1, hum = 2, status = 3 then, after two seconds, temp = 2, hum = 3, status = 4 and so on. Of course you need something to display the data.

If there is some problems then it's the radio library fault, otherwise let's integrate the DHT22.

So, AFTER having tried the previous sketch and confirming that everything is working, download the library from here, install it and then use this sketch:

#include <RF24.h>
#include <dht.h>

dht DHT;

const byte DHT22_Pin = 3;

byte currentNodeAddr[6] = "1Node";  // Address of this node

// Struct for sending measured data
struct Data {
  uint16_t temp;  // Temperature value
  uint16_t hum;   // Humidity value
  int status;     // DHT22 module status
} data;

RF24 radio(2,2);  // Create instance of RF24 radio object

void setup() {
    // Set up the radio
    radio.begin();
    radio.openWritingPipe(currentNodeAddr);
    radio.stopListening();
}

void loop() {
    data.status = DHT.read22(DHT22_Pin);
    data.temp = (int)DHT.humidity;
    data.hum = (int)DHT.temperature;

    radio.write(&data, sizeof(Data));

    delay(2000);
}

Now, instead of displaying increasing numbers, it should say the temperature, the humidity and, most important, the status:

 0 -> OK
-1 -> ERROR_CHECKSUM
-2 -> ERROR_TIMEOUT
-3 -> ERROR_CONNECT
-4 -> ERROR_ACK_L
-5 -> ERROR_ACK_H

Check if this works.

IMPORTANT NOTE: I read somewhere that sometimes the ground pin on the DHT is 3 instead of 4. Try grounding both pins if something does not work.

  • Thank you very much for your answer! I will describe results by editing the question. – Alexander Dec 3 '15 at 13:58
  • Done! The question has been edited. – Alexander Dec 3 '15 at 14:45
  • This "When I program ATtiny at the 1 MHz, values are sent every 2 seconds (as it should be), but when I program ATtiny at 8 MHz, values are sent every 16 seconds (is it correct?)." is absolutely not normal You should have experienced the opposite behavior. First of all I onticed you are using an old version of the Arduino IDE (1.0.1). Try updating to 1.6.x (instructions here if sudo apt-get upgrade does not find the version; you need to use latest raspbian version - jessie) – frarugi87 Dec 3 '15 at 15:31
  • Then setup arduino 1.6.x to use the attiny85: see here how to do that, particularly "Adding Third Party Boards to the Arduino v1.6.4+ IDE" and I think you can use the recommended attiny85 board repository, but the second one (drazzy) is more updated; you can choose one. Then select the board from the list and try uploading again. With both 1MHz and 8MHz the 2seconds delay should remain 2 seconds delay – frarugi87 Dec 3 '15 at 15:34
  • You are right, it is not normal. But this is all I could install and get to work on the Raspbian Wheezy. I will try it again later with your suggestion. By the way, a solution has been finally found. I will post it a little bit later in another answer. Thank you for your your help and for useful links! – Alexander Dec 6 '15 at 15:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.