Weather data logger using PIC18F46K22 and BME280 sensor

This project shows how to build a data logger that logs temperature (in °C), humidity (in %RH) and pressure (in hectopascal) using PIC18F46K22 microcontroller and BME280 barometric pressure, humidity and temperature sensor.
The logged data is saved to a text file stored in SD card. DS3231 real time clock chip is used to get time and date information.
Time, date, temperature, humidity and pressure values are displayed on 20×4 LCD screen.
MikroC PRO for PIC compiler is used in this project.

FAT32 Library for mikroC compiler:
MikroElektronika provides a nice library for FAT32 file system (& SD card). This library can be downloaded from the following link:
FAT32 Library for mikroC compiler

The extension of the downloaded file is .mpkg, and in order to open and install the library we need a small software named: Package Manager, it’s also a free software provided by MikroElektronika, download link is below:
Package Manager download

To see how to interface PIC18F46K22 with SD card, visit the following post:
PIC18F46K22 Interface with SD card – Write & read files | mikroC Projects

and to see how to interface PIC microcontroller with BME280 sensor using mikroC PRO for PIC compiler, take a look at this project:
PIC MCU with BME280 pressure, temperature and humidity sensor | mikroC Projects

Hardware Required:
This is a list of all components required to build this project.

  • PIC18F46K22 microcontroller   —->  datasheet
  • FAT32 formatted SD card (MMC, SD, SDHC, microSD ….)
  • micro SD card module
  • (optional) USB-to-serial UART converter (like: FT232RL module)
  • 20×4 LCD screen
  • BME280 sensor module (with built-in 3.3V regulator and level shifter)  —->  BME280 datasheet
  • DS3231 board    —->  DS3231 datasheet
  • 330 ohm resistor
  • 2 x push button
  • 10k ohm variable resistor or potentiometer
  • 3V coin cell battery
  • Breadboard
  • 5V source
  • Jumper wires

Weather data logger using PIC18F46K22 and BME280 sensor circuit:
The image below shows project hardware circuit diagram.

The BME280 chip works with maximum voltage of 3.6V (supply voltage range is from 1.71 to 3.6V) which means we’ve to use a 3V3 voltage regulator to supply it from a 5V source.
Also, if we’re working with a 5V system (development board, microcontroller …) like the PIC18F46K22 microcontroller we’ve to use a voltage level shifter (level converter) which converts the 3.3V (comes from the BME280 chip) into 5V (goes to the PIC18F46K22) and vice versa. This level shifter is for the I2C bus lines (clock and data).
The BME280 module shown in the circuit diagram has a built-in 3.3V regulator and level shifter.

It’s highly recommended to add a voltage level translator to MISO line in order to step up the 3.3V that comes from the SD card into 5V which goes to SDI1 pin (#23) of the PIC18F46K22 microcontroller (schmitt trigger input requires at least 0.8xVDD = 4V), as an example we can use the integrated circuit 74HCT125.

In this project I used micro SD card module, this module is supplied from circuit 5V source, it contains the AMS1117-3V3 voltage regulator which is used to supply the SD card with 3.3V. Also this module contains an IC which is 74LVC125A and it is used as level translator (from 5V to 3.3V).

BME280 data logger with PIC18F46K22 and SD card

All the grounded terminals are connected together.

The PIC18F46K22 microcontroller does have 2 MSSP modules: MSSP1 and MSSP2 (MSSP: Master Synchronous Serial Port), each one of them may work as hardware SPI module or hardware I2C module. The SD card uses SPI protocol, it’s connected to MSSP1 module (used as SPI) hardware pins (SCK1, SDI1 and SDO1). So the micro SD card module is connected to the circuit as follows (from left to right):

The first pin of the micro SD card module (GND) is connected to circuit ground.
The second pin of the micro SD card module (VCC) is connected to circuit +5V.
The third pin of the micro SD card module (MISO) is connected to pin SDI1 (RC4) of the PIC18F46K22.
The fourth pin of the micro SD card module (MOSI) is connected to pin SDO1 (RC5) of the PIC18F46K22.
The fifth pin of the micro SD card module (SCK) is connected to pin SCK1 (RC3) of the PIC18F46K22.
The last pin of the micro SD card module (CS) is connected to pin RC2 of the PIC18F46K22.

The DS3231 RTC chip uses I2C protocol, its board clock and data pins (SCL and SDA) are connected to MSSP2 module which is configured to operate in I2C mode. So, the SCL and SDA pins of the DS3231 board are respectively connected to SCL2 (RD0) and SDA2 (RD1) of the PIC18F46K22 microcontroller.

In the circuit there are two push buttons: B1 and B2, they are connected to pins RB0 (#33) and RB1 (#34) respectively, these buttons are used to set time and date of the real time clock.

Generally, the BME280 module has at least 4 pins because it can work in SPI mode or I2C mode. For the I2C mode we need 4 pins: VCC, GND, SCL and SDA, where:
GND (ground) is connected to circuit ground (0V)
VCC is the supply pin, it is connected to +5V
SCL is I2C bus serial clock line, connected to PIC18F46K22 SCL2 (RD0) pin
SDA is I2C bus serial data line, connected to PIC18F46K22 SDA2 (RD1) pin.

The DS3231 RTC and the BME280 sensor are connected to the same I2C bus (slave devices), the I2C slave address of the DS3231 chip differs from the one of the BME280 sensor, that allows the master device (PIC18F46K22) to talk to one of them (only one at a time).

The 20×4 LCD screen (4 rows and 20 columns) is used to display time, date, pressure, humidity and temperature where:
RS —> pin RD2
E   —> pin RD3
D4 —> pin RD4
D5 —> pin RD5
D6 —> pin RD6
D7 —> pin RD7
VSS, RW, D0, D1, D2, D3 and K are connected to circuit ground
VEE to the variable resistor (or potentiometer) output
VDD to +5V and A to +5V through 330 ohm resistor.

VEE pin is used to control the contrast of the LCD. A (anode) and K (cathode) are the back light LED pins.

The FT232RL board (USB to serial converter) RX pin is connected to PIC18F46K22 TX1 pin (RC6) which is USART1 module transmission pin (the PIC18F46K22 has 2 hardware USART modules). This board is used just to send some data from the microcontroller to PC.

In this project the PIC18F46K22 microcontroller runs with its internal oscillator @ 16 MHz and MCLR pin is configured as input.

Weather logger using PIC18F46K22 and BME280 sensor C code:
The C code below is for mikroC PRO for PIC compiler, it was tested with version 7.2.0.

To be able to compile project C code with no error, a driver (library) for the DS3231 RTC is required, download link is below. After you download the driver file which named DS3231.c, add it to your project folder.
DS3231 mikroC library

For more details about the DS1307 library, visit the following post:
DS3231 RTC Library for mikroC Compiler | mikroC Projects

Also, another library for the BME280 sensor is required, its full name (with extension) is BME280.c, download link is below:
BME280 Library for mikroC compiler

The SD card chip select pin (SS) is connected to pin RC2 of the PIC18F46K22, it’s defined in the C code as:

The connection of the two push buttons are defined in the code as shown below:

The BME280 sensor library is configured to work with hardware I2C2 module and the device salve address is 0xEC:

The microcontroller reads pressure, temperature & humidity values from the BME280 sensor and saves them (with time and date) to the SD card every second, for that I used the following if condition:

where the variable p_second is used to save only one value every 1 second.

Functions used in the code:
FAT32_Init(): this function initializes the FAT32 library as well as the SD card, it returns 0 if OK and non-zero if error.

FAT32_Exists(“BME280Log.txt”): search if there is a file named “BME280Log.txt” exists in the selected directory, return 0 if the file isn’t present, otherwise it returns a non-zero value (for example the file exists).

FAT32_Open(“BME280Log.txt”, FILE_WRITE): this function creates a new file named “BME280Log.txt”, returns 0 if OK and non-zero if error.

FAT32_Open(“BME280Log.txt”, FILE_APPEND): this function opens the file named “BME280Log.txt” and moves the cursor to the end of the file, returns 0 if OK and non-zero if error.

FAT32_Write(fileHandle, “…”, 26): writes a text (for example “…” ) of length (for example 26 characters) to the file associated with fileHandler.

FAT32_Close(fileHandle): closes the file associated with fileHandler, returns 0 if OK and non-zero if error.

char debounce (): this function is for button B1 debounce, returns 1 if button is debounced.

void wait(): this function is just a delay of 500 ms except that it can be interrupted by the two push buttons (B1 and B2). In this function Timer0 module is used to count the 500 milliseconds, it is used as 16-bit timer with prescaler = 32 (==> 1 tick every 8 microseconds ==> 62500 x 8 = 500000 us = 500 ms).

char edit(char x_pos, char y_pos, char parameter): this function is for setting the real time clock, returns the edited parameter.

void dow_print(): displays day of the week (Monday, Tuesday …) on the LCD.

void rtc_print(): displays time and date on the LCD. This function calls the previous one for displaying day of the week.

BME280_begin(MODE_NORMAL, SAMPLING_X1, SAMPLING_X1, SAMPLING_X1, FILTER_OFF, STANDBY_0_5): this function initializes the BME280 sensor, returns 1 if OK and 0 if error (for example wrong device address).

Reading the values of temperature, humidity and pressure is done as shown below.
Note that the BME280 library returns the temperature in hundredths °C which means we’ve to divide it by 100, it returns the humidity in relative humidity percent (RH%) in 1024 steps which means we’ve to divide it by 1024 and it returns the pressure in Pa, to get the pressure in hPa we’ve to divide it by 100.

Temperature, humidity and pressure values (with time and date) are displayed on the 20×4 LCD screen.
If there is a problem with the BME280 sensor (for example wrong device address) the LCD will display Error instead of the values of the 3 quantities. That Error will also be printed in the text file “BME280Log.txt”.

1 bar = 10000 Pa = 100 hPa. ( 1 hPa = 100 Pa)
Pa: Pascal
hPa: hectoPascal

Rest of code is described through comments.

Full mikroC code:

This project was tested in real hardware circuit using original Samsung micro SD card with capacity of 32GB. The following image shows a part from the logger file (BME280Log.txt) created by the hardware circuit:

BME280 data logger sd card text file

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.