Weather Station in a Hat
As a kid, I often watched a cartoon called Inspector Gadget. It was about a detective, who wore a seemingly inconspicuous hat with a lot of hidden features which helped him get out of sticky situations. A magnifying glass, a helicopter rotor, a siren, flashlight, a parachute umbrella and a variety of other items. It would be wonderful to make a hat with something functional (and maybe practical) inside.
We like data these days. Numbers which give us some kind of interesting information and especially when there is a lot of them. And if you like visual interpretation, you can also create nice graphs to track something and to share it with your friends. For example, just a simple weather-associated data such as temperature, humidity, atmospheric pressure or altitude. Of course you have such a station on your smartphone, but it's not particularly stylish. So why not create a specific gadget which can track all of that and put it in a Hat? Lets get started.
Supplies
You will need following items for this project:
- Any kind of hat you like
- Shears
- Jute rope
- Cloth waste
- A fabric glue or superglue
- Knife or scalpel
- A needle
- Ruler
- Cardboard
- Artificial hair
- Hot glue gun
For electronics, you will need:
- Soldering iron
- Universal printed circuit board 5x7cm
- ESP8266 D1 mini
- Real time clock module DS1307
- Temperature and Humidity sensor DHT11
- BMP280 Altitude and Pressure module
- 16340 battery module with boost converter
- 16340 Li-ion battery
- microSD card SPI module with microSD card
- 2x 10k resistors
- Some thin wires (26AWG)
- Small drill bit
- Plastic spacers
Description of Modules
A couple of modules are used in this project. The main one is the microcontroller, which is ESP8266 D1 mini. It is a bit smaller than standard ESP modules, but just as powerful. It features multiple digital IO pins, Wifi and also an on-board programmer chip.
For measuring Temperature, Altitude and Atmospheric pressure, BMP280 module with Bosch sensor is used. Module communicates via I2C protocol and does not require any external components.
Humidity will be acquired via a very popular DHT11 sensor, which requires only one pull-up resistor.
Data will be stored on an sdCard module, which will communicate with ESP via SPI-bus. One external resistor is used for connection. This one also requires a 5V input, because it has an on-board voltage regulator.
For powering the circuit, I chose a small module with a 16340 lithium-ion battery. Module features a charging circuit and also a boost converter to 5 Volts. The 16340 battery size is sufficient enough for hours of data logging, but if you want to have something with more energy, you can easily get an 18650 or similar modules, for example this one.
Circuit Design and Breadboarding
Because most modules communicate using I2C communication, the electronic circuit is fairly simple. The SPI protocol is only used by the microSD card module. We only need two external 10k resistors in addition to all of the modules.
On the breadboard, I first attempted connecting all of the modules with the microcontroller. I got functional circuits after a little fiddling, after I checked modules one by one to see if they worked properly.
When I was sure it worked like intended, I drew a schematic.
Downloads
Programming - Installing Packages and Libraries
Because the Arduino IDE does not detect the ESP8266 by default, we must first install a package for it:
- Open Arduino IDE and click File - Preferences
- On the Additional Boards manager URLs, paste the following link:
https://arduino.esp8266.com/stable/package_esp8266com_index.json
- Click Ok and then on Tools - Board - Board Manager
- When the Boards Manager opens, type ESP8266 in search field and install the library by clicking Install
- After Installation is done, close the window and go to Tools - Board. Select LOLIN(WEMOS) D1 R2 & mini
You will also need a few libraries. Click on Tools - Manage Libraries and then find and install following ones:
- Adafruit BMP280 (from Adafruit)
- Adafruit Unified Sensor (from Adafruit)
- DHT sensor library for ESPx (from beegee_tokyo)
- RTClib (from Adafruit)
- SD (from Arduino)
Identifying Module Addresses
In order to communicate with the modules, we need to know their I2C addresses. We will use a scanner code uploaded from Wemos developer:
#include <Wire.h> const int sclPin = D1; const int sdaPin = D2; void setup() { Wire.begin(sdaPin, sclPin); Serial.begin(9600); Serial.println("I2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for (address = 1; address < 127; address++) { // The i2c scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address < 16) { Serial.print("0"); } Serial.print(address, HEX); Serial.println(" !"); nDevices++; } else if (error == 4) { Serial.print("Unknown error at address 0x"); if (address < 16) { Serial.print("0"); } Serial.println(address, HEX); } } if (nDevices == 0) { Serial.println("No I2C devices found\n"); } else { Serial.println("Done.\n"); } delay(2000); }
You can find more examples on Wemos github:
https://github.com/wemos/D1_mini_Examples/blob/master/examples/02.Special/Wire/I2C_Scanner/I2C_Scanner.ino
Programming - Code
The code is quite simple. I will divide it into a few parts in order to comment on it. You can find the whole .ino file in attachments.
#include <Wire.h> #include <SPI.h> #include <SD.h> #include <Adafruit_Sensor.h> #include <Adafruit_BMP280.h> #include "DHTesp.h" #include "RTClib.h" DHTesp dht; Adafruit_BMP280 bme; RTC_DS1307 RTC; File myFile; String nameString = ""; String dataString = ""; String separator = ", ";
This part of the code contains included libraries, associated objects and a few variables, which will be needed later.
void setup() { Serial.begin(9600); dht.setup(D0, DHTesp::DHT11); bme.begin(); Wire.begin(); RTC.begin(); RTC.adjust(DateTime(__DATE__, __TIME__)); Serial.print('Time and date set'); DateTime now = RTC.now(); nameString = String(now.year()) + "_" + String(now.month()) + "_" + String(now.day()) + "_" + String(now.hour()) + "_" + String(now.minute()) + "_" + String(now.second()) + ".txt"; SD.begin(D8); }
Setup function will only run once. First, serial communication is enabled and also the digital pin D0 is associated with DHT11 sensor.
Next, the rest of the sensors are initiated, and time and date are expanded to date and time on your computer.
String nameString is filled with the current year, month, day, hour, minute and second separated by "_" and extension .txt is added. This string will be the name of the created text file after powering up and it will contain all of the data. For example, file with name 2022_4_27_14_37_51.txt means that the start of data logging occurred in 27th of May 2022, at 14:37:51 local time.
void loop() { DateTime now = RTC.now(); float h = dht.getHumidity(); dataString = String(now.hour()) + separator + String(now.minute()) + separator + String(now.second()) + separator + String(h) + separator + String(bme.readTemperature()) + separator + String(bme.readPressure()) + separator + String(bme.readAltitude(1013.25)) ; Serial.println(nameString); Serial.println(); myFile = SD.open(nameString, FILE_WRITE); if (myFile) { Serial.print("Writing to test.txt..."); myFile.println(dataString); myFile.close(); Serial.println("done."); } else { Serial.println("error opening test.txt"); } delay(500); }
In the Loop function, RTC.now() function is called to obtain the current time. Then, all sensor data is collected and added into a single string, which will be written in the .txt file. An input constant 1013.25 is equal to pressure at sea level in hectopascal. Separator separates the data, in order for them to be easily exported later. I used a comma, but you can also use a semicolon or space. Every 0.5 seconds a new series of data is collected and uploaded into the file.
Downloads
Cardboard Base
Electronics will be placed on a base, which will hold them in place and also separate it from the head. I used cardboard for the base, since its a very available material. It is easy to cut and firm enough to hold the electronics.
First I measured the largest inside diameter of the hat, and then I cut down the first version of the base. Then I was cutting bits from it, making it smaller and proper shape to fit. I stopped cutting when the inside vertical dimension from the base to the top of the hat was around 6 cm, which should be enough to fit all electronics in.
PCB Construction
First, I tried placing multiple modules on the universal board, so I could find the most compact option and arrangement. I decided to put the microcontroller in the middle and microSD card reader and Real Time Clock next to it. Temperature and altitude sensors will be placed outside the hat in later steps.
On the PCB I soldered down the microcontroller socket and then I started connecting one module after the other. I printed the schematics and after each soldered and connected module, I marked down the completed traces with a highlighter.
Don't forget to solder down resistors and also to connect the Vcc pin of microSD card module to 5V (not 3V3), otherwise it wont work.
Cardboard Base Completion
Arrangement of the PCB with the battery module was done in such a way, that the highest components were placed in the middle of the base. In the middle is the most vertical space inside the hat.
I attached some plastic spacers to the PCB, but since the holes were not big enough, drilling was necessary. You can use a small hand drill for that, since the PCB is thin. Be careful on the edges so you wont break the corner of the board (as I did in the process).
Glue the spacers into the cardboard base, and let it dry for an hour. This way you can unscrew the PCB for later repair or modification.
Cutting Hole for Sensors
First I tried to just stitch the cables from outside in, but the hat was very rigid and I had a lot of trouble getting wires through out the needle. After that, I decided to cut a small hole for the sensors instead. Since I am clumsy, the cut was a lot bigger than I initially wanted it to be. But it is fine - we will hide it later with some rope.
Mounting Sensors
Sensors were mounted in a way, that cables were hiding inside of the hat, and most of the PCB area was outside. This way it is possible for them to sense the correct temperature and humidity. Sensors will be covered later.
Securing the Base
The base must be secured properly, but it also must be able to detach from the hat for battery charging and access to the card. For that I used some velcro. Small pieces were attached to the sides of the hat vnutro. Then I attached a counterpart to the base.
Hat Decoration - Beer Label
To make a small decoration, I designed a beer outline and cut the label from cloth scrapings. There is two parts of it - a mug and a head. Then I glued them down and also attached a strain of artificial hair, to resemble a wheat in the wind.
Hat Decoration - Jute Rope
In order to hide the sensors, I used a simple jute rope of 2 colors. I cut approx. 80cm of each color and then cut it in half. Then I made knots on each end and placed them around the hat, to cover the sensors. I glued the ropes every 5 cm around with the glue gun, and also the knots.
Data Visualisation
Collected data were imported to Excel, where I used a simple line plot with two vertical axes to visualize them. Approx. 35 minutes after the start, we stopped by to get some beverages in a cabin, which you can see on the temperature graph. Since the humidity sensor has quite low resolution, I am thinking about replacing it with some better version. But overall, I am happy with the results.
Pictures and Results
Some more photos of the hat. Thank you for stopping by.