Introduction: Mini Weather Station With Attiny85

About: I am a physician by trade. After a career in the pharmeceutical world I decided to take it a bit slower and do things I like. Other than my hobbies that involves grassroots medicine in S.E.&P Asia. I have buil…

In a recent instructable Indigod0g described a mini weather station that works pretty well, using two Arduinos. Maybe not everyone wants to sacrifice 2 Arduinos to get humidity and temperature readings and I commented that it should be possible to do a similar function with two Attiny85's. I guess talk is easy, so I better put my money where my mouth is.

In fact, if I combine two earlier instructables I wrote:

2-Wire LCD interface for Arduino or Attiny
and
Receiving and sending data between Attiny85 (Arduino IDE 1.06)
then most of the work is already done. Only need to adapt the software a bit.

I chose for a two wire lcd solution with a shift register, rather than an I2C LCD because on the Attiny the shift register is easier to implement than the I2C bus. However... if you for instance want to read a BMP180 or BMP085 pressure sensor, you need I2C for that anyway so you might as well use an I2C LCD then too. TinyWireM is a good library for I2C on an Attiny (but it requires extra space).

BOM
The transmitter:
DHT11
Attiny85
10 k resistor
433MHz transmitter module

The receiver
Attiny85
10k resistor
433 MHz receiver module

The display
74LS164 shift register
1N4148 diode
2x1k resistor
1x1k variable resistor
an LCD display 2x16

Step 1: Mini Weather Station With Attiny85: the Transmitter

The transmitter is a very basic configuration of the Attiny85 with a pull up resistor on the reset line.
A transmitter module is attached to digital pin '0' and the DHT11 data pin attaches to digital pin 4.
Attach a wire of 17.2 cm as antenna (for a much better antenna see step 5).
The software is as follows:

//will work on Attiny85/45

//RF433=D0 pin 5
//DHT11=D4 pin 3

// libraries
#include <dht.h> //From Rob Tillaart
#include <Manchester.h>
dht DHT11;
#define DHT11PIN 4
#define TX_PIN 0  //pin where your transmitter is connected
//variables
float h=0;
float t=0;
int transmit_t = 0;
int transmit_h = 0;
int transmit_data = 0;

void setup() 
{
  pinMode(1, INPUT);
  man.setupTransmit(TX_PIN, MAN_1200);
}

void loop() {
 int chk = DHT11.read11(DHT11PIN);
 h=DHT11.humidity;
 t=DHT11.temperature;
// I know, I am using 3 integer variables here
// where I could be using 1
// but that is just so it is easier to follow
 transmit_h=100* (int) h;
 transmit_t=(int) t;
 transmit_data=transmit_h+transmit_t;
  man.transmit(transmit_data);
  delay(500);
}

The software uses Manchester code to send the data.
It reads the DHT11 and stores the temperature and humidity in 2 separate floats. As the Manchester code doesnt send floats, but an integer, I have several options:
1- split the floats into two integers each and send those
2- send each float as an integer
3- send the two floats as one integer

With option 1 I need to combine the integers into floats again in the receiver and I have to identify which integer is what, making the code long winded
With option 2 I still need to identify which integer is for humidity and which for temperature. I cannot go by sequence alone in case one integer is lost in transmission, so I would need to send an identifier attached to the integer.
With option 3, I can send just one integer. Obviously this makes the readings a bit less accurate - within 1 degree- and one cannot send below zero temperatures, but it is just a simple code and there are ways around that. For now it is just about the principle.

So what I do is I turn the floats into integers and I multiply the humidity with 100. Then I add the temperature to the multiplied humidity.
Given the fact that the humidity will never be 100% the max number I will get is 9900. Given the fact that the temperature will also not be above 100 degrees, the max number will be 99, therefore the highest number i will send is 9999 and that is easy to separate at the receiver side.

Ofcourse my calculation in which i use 3 integers is overkill as it could easily be done with 1 variable. I just wanted to make the code easier to follow.

the code now compiles as:

Binary sketch size: 2,836 bytes (of a 8,192 byte maximum)
so that fits in an Attiny 45 or 85

NOTE the dht.h library I use is the one from Rob Tillaart. That library is also suitable for a DHT22. I am using version 1.08. However the Attiny85 may have problems reading a DHT22 with lower versions of the library. It has been confirmed to me that the 1.08 and 1.14 -though working on a regular Arduino- have trouble reading a DHT22 on the Attiny85. If you want to use a DHT22 on the Attiny85, use the 1.20 version of this library. It all ha sto do with timing. The 1.20 version of the library has a faster read. (Thanks for that user experience Jeroen)

Step 2: Mini Weather Station With Attiny85: the Receiver

Again the Attiny85 is used in a basic configuration with the Reset pin pulled high with a 10 k resistor. The Receiver module is attached to digital pin 1 (pin 6 on the chip). The LCD is attached to digital pins 0 and two.
Attach a wire of 17.2 cm as antenna.
The code is as follows:

#include <Manchester.h>
#include <LiquidCrystal_SR.h>
LiquidCrystal_SR lcd(0,2,TWO_WIRE);
#define RX_PIN 1 //= physical pin 6

void setup() {
  lcd.begin(16,2);
  lcd.home();
  man.setupReceive(RX_PIN, MAN_1200);
  man.beginReceive();
}

void loop() { if (man.receiveComplete()) { uint16_t m = man.getMessage(); man.beginReceive(); lcd.print("Humid: "); lcd.print(m/100); lcd.setCursor(0,1); lcd.print("Temp "); lcd.print(m%100); } }

The code is fairly simple: the transmitted integer is received and stored in variable 'm'.
It is divided by 100 to give the humidity and the modulo of 100 gives the temperature.
So suppose the integer received was 3325
3325/100=33
3325 % 100=25
This code compiles as 3380 bytes and therefore can only be used with an attiny85, not with a 45

Step 3: Mini Weather Station With Attiny85/45: the Display

For the display it is best that I refer to my instructable on a two wire display.
In short, a common 16x2 display uses a shiftregister so it can operate with two digital pins.
Ofcourse if you prefer to use an I2C ready display, that is possible too, but then you need to implement an I2C protocol on the Attiny. The Tinywire protocol can do that. Though some sources say that that expects a 1 Mhz clock, I didnt have any trouble (in another project) to use it on 8Mhz
Anyway I just didnt bother here and used a shift register.

Step 4: Mini Weather Station With Attiny85/45: Possibilities/Conclusions

As said, I made this instructable to show that one can make a mini weather station with two attiny85's (even with one attiny85+ 1 attiny45).
It only sends humidity and temperature, using a DHT11.
However, the Attiny has 5 digital pins to use, 6 even with some trickery. Therefore it is possible to send data from more sensors.
In my project- as seen in the pics on stripboard and on a professional PCB (OSHPark)- I send/receive data from a DHT11, from an LDR and from a PIR, all using two attiny85's
The limitation in using an attiny85 as receiver though is the presentation of the data in a flashy style. As the memory is limited: Texts like 'Temperature, Humidity, light level, subject approaching' will fill up valuable memory space pretty fast.
Nevertheless, no reason to use two Arduino's just to send/receive temperature and humidity.

Additionallly, it is possible to have the transmitter go to sleep and only have it wake up to send data say every 10 minutes and thus feed it from a button cell.
Obviously, not only temperature or humidity data can be send but one can have an array of small transmitters sending soil moisture readings as well, or add an anemometer, or a rain meter

Step 5: Mini Weather Station: the Antenna

The antenna is an important part of any 433Mhz set up.
I have experimented with the standard 17.2 cm 'rod' antenna and had a short flirt with a coil antenna, What seemed to work best is a coil loaded antenna that is easy to make. The design is from Ben Schueler and apparently was published in 'Elektor' magazine. A PDF with the description of this 'Air cooled 433 MHz Antenna' is easy to follow. (Link disappeared, check here)

Step 6: Adding a BMP180

Want to add barometric pressure sensor like the BMP180? check my other instructable on that.