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 Wireless Weather Station
- Mini weather station with Attiny85
- Easy IoT weather station with multiple sensors
- ATtiny84 & RFM12B wireless sensor node
- DHT11 HUMIDITY & TEMPERATURE SENSOR MODULE
- DHT22 running @ 8MHZ
- DHT22 not working with 8mhz clockspeed?
- Adafruit DHT Library and ATtiny85
- Class for DHTxx sensors
- An Arduino library for reading the DHT family of temperature and humidity sensors
- Using a RHT03 (aliases: RHT-22, DHT22, AM2302) temperature/humidity sensor from Arduino
- Arduino-library for DHT11/DHT22 sensors reading
- Efficient DHT library for Arduino
- Feuchtesensor AM2302/DHT22
- 7 Segment Digital Thermometer using ATtiny 85
- Wiring up DHT humidity sensors
- Attiny85 RF Transmitter to Arduino Uno Receiver
- Arduino library for the DHT22 humidity and temperature sensor
- Arduino library for DHT11DHT22, etc Temp & Humidity Sensors
- A simplified DHT11/DHT22/AM2302 library for use with the Trinket/Gemma
- Arduino library for the DHT22 humidity and temperature sensor
- Arduino sketch code for reading RHT03 (also known as DHT22, RHT22, and AM2302) temperature/humidity sensor
Arduino/AVR nRF24L01 projects and libraries:
- Optimized fork of nRF24L01 for Arduino and Raspberry
- Optimized Network Layer for nRF24L01(+) Radios on Arduino and Raspberry Pi
- nrf24l01+ control with 3 ATtiny85 pins
- NRF24L01 real life range test
- Optimized fork of nRF24L01 for Arduino and Raspberry Pi
- NRF24L01 SIX CHANNELS TO ONE RECEIVER
- Arduino attiny support files for nRF24L01 RF modules
- ARDUINO + RASPBERRY PI Switching light with NRF24l01+
Programming the ATtiny85 from Raspberry-Pi:
- Programming the ATtiny85 from Raspberry Pi
- Arduino IDE Installation
- Arduino for other Chips
- Tiny AVR Programmer Hookup Guide
- ATtiny85 with Arduino IDE and Gertboard
- Setting up the Arduino IDE on Raspbian
Arduino/AVR FR433 libraries:
- 433Kit is a collection of code and documentation designed to assist you in the connection and usage of RF 433MHz transmit and receive modules to/with your Arduino and Rapberry Pi
- Tiny AVR Programmer Hookup Guide
Troubleshooting:
-
1@sineverba I added some links to the question that I used for the project or that were helpful for me.SashkaCosmonaut– SashkaCosmonaut2016年07月31日 08:43:07 +00:00Commented Jul 31, 2016 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.SashkaCosmonaut– SashkaCosmonaut2016年07月31日 13:00:31 +00:00Commented Jul 31, 2016 at 13:00
-
1@sineverba I have added the final code for both ATtiny85 transmitter and Raspberry Pi receiver to my answer below.SashkaCosmonaut– SashkaCosmonaut2016年08月01日 09:15:24 +00:00Commented Aug 1, 2016 at 9:15
-
1@sineverba I have also added the Makefile code to compile Raspberry Pi receiver to the answer below.SashkaCosmonaut– SashkaCosmonaut2016年08月01日 09:25:01 +00:00Commented Aug 1, 2016 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/RF24SashkaCosmonaut– SashkaCosmonaut2016年08月01日 09:39:04 +00:00Commented Aug 1, 2016 at 9:39
2 Answers 2
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:
- RobTillaart/Arduino DHT11, 21, 22, 33 library
- Arduino driver for nRF24L01 http://maniacbug.github.com/RF24
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(¤tPipe))
{
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 <[email protected]>
# 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 [email protected] -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
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.SashkaCosmonaut– SashkaCosmonaut2015年12月03日 13:58:47 +00:00Commented Dec 3, 2015 at 13:58
-
Done! The question has been edited.SashkaCosmonaut– SashkaCosmonaut2015年12月03日 14:45:27 +00:00Commented Dec 3, 2015 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– frarugi872015年12月03日 15:31:05 +00:00Commented Dec 3, 2015 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 delayfrarugi87– frarugi872015年12月03日 15:34:33 +00:00Commented Dec 3, 2015 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!SashkaCosmonaut– SashkaCosmonaut2015年12月06日 15:54:52 +00:00Commented Dec 6, 2015 at 15:54
Explore related questions
See similar questions with these tags.