This post shows how to make a temperature and humidity datalogger using PIC18F4550 microcontroller, SD card and DHT11 sensor where the temperature and humidity measurements are saved in a text file (located on the SD card). The compiler used in this project is CCS PIC C.
In this project the PIC18F4550 reads relative humidity and temperature data from the DHT11 sensor and after creating a text file on the SD card named “1Log.txt”, it starts writing that data to the text file.
A 16×2 LCD screen is connected to the microcontroller in order to display the relative humidity and temperature measurements.
To be able to build this project we need MMC/SD card driver and FAT library for CCS C compiler, their download links are in the topic below (official post of the two libraries), the names of the two files (with the extension) respectively are: mmcsd_m.c and fat_m.c. After downloading just add the two files to the project folder or to CCS C drivers folder:
SD Card driver and FAT Library for CCS C compiler
Related Projects:
Interfacing PIC18F4550 with DHT11 humidity and temperature sensor
Read and write files from and to SD card with PIC18F4550 – CCS C
Hardware Required:
- PIC18F4550 microcontroller
- FAT32 formatted SD card (MMC, SD, SDHC, micro SD ….)
- DHT11 relative humidity and temperature sensor
- microSD card module (adapter)
- USB-to-serial UART module (optional)
- 16×2 LCD screen
- 8MHz crystal oscillator
- 2 x 22pF ceramic capacitors
- 4.7k ohm resistor
- 10k ohm variable resistor or potentiometer
- Breadboard
- 5V source
- Jumper wires
PIC18F4550 SD card data logger circuit:
PIC18F4550 datalogger circuit diagram is shown below.
In this project the microcontroller runs with an external crystal oscillator of 8MHz and MCLR pin is configured as a digital input pin (in the software).
The temperature and humidity measurements are displayed on the 16×2 LCD screen and stored on the microSD card. The microSD card is placed in the module (adapter).
The USB to serial UART module such as FT232RL is used to connect the microcontroller with the laptop (PC), in this example it shows the initialization status of the SD card and FAT system.
As a hint, instead of the microSD card module we can use AMS1117-3V3 to supply the SD card and three voltage dividers for SS, SCK and MOSI lines; each voltage divider consists of two resistors: 2.2k ohm and 3.3k ohm. Related project link above shows the circuit diagram.
PIC18F4550 SD card data logger C code:
The C code below is for CCS C compiler, it was tested with version 5.051.
As written above, to be able to compile the C code below, we need MMC/SD driver and FAT library (mmcsd_m.c and fat_m.c), their download links are in this page:
SD Card driver and FAT Library for CCS C compiler
The compilation of the project C code may give some warnings, just ignore them!
With the 8MHz and PLL2 the microcontroller becomes working at 48MHZ (12 MIPS) which is the highest speed of the PIC18F4550 and its hardware SPI module.
In this example I used software SPI just to show how the FAT library works with soft SPI mode. Hardware SPI is much faster the the soft one.
I used Timer1 module to measure pulse widths, with a prescaler of 8, Timer1 increments by 1.5 every 1us (15 every 10us).
Used functions:
void Start_Signal(void): sends the start signal to the DHT11 sensor.
int1 Check_Response(void): reads the response signal that comes from the DHT11 sensor, returns 1 if OK and zero if error.
int1 Read_Data(int8 *dht_data): reads humidity and temperature data from the DHT11 sensor and save data to pointer ‘dht_data‘, returns 0 if OK and 1 if error.
fat_init(): initializes the FAT system and the media card, returns 0 if OK and non-zero if there was an error.
mk_file: creates a new file on the SD card, returns 0 if OK, non-zero if error.
fatopen: opens a file, returns 0 if OK, non-zero if error.
fatputs: puts a string into the opened file, returns 0 if OK, non-zero if error.
fatclose: closes the opened file, after writing to the file we must call this function, returns 0 if OK, non-zero if there error.
Full CCS C code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | // Temperature and humidity data logger using PIC18F4550, SD card and DHT11 sensor // C code for CCS C compiler // http://simple-circuit.com/ // LCD module connections #define LCD_RS_PIN PIN_D0 #define LCD_RW_PIN PIN_D1 #define LCD_ENABLE_PIN PIN_D2 #define LCD_DATA4 PIN_D3 #define LCD_DATA5 PIN_D4 #define LCD_DATA6 PIN_D5 #define LCD_DATA7 PIN_D6 // End LCD module connections // SD card module connections #define MMCSD_PIN_SELECT PIN_B0 #define MMCSD_PIN_SCK PIN_B1 #define MMCSD_PIN_MOSI PIN_B2 #define MMCSD_PIN_MISO PIN_B3 // End SD card module connections // DHT11 sensor connection #define DHT11_PIN PIN_B4 // DHT11 Data pin is connected to RB4 // End DHT11 sensor connection #include <18F4550.h> #device PASS_STRINGS = IN_RAM #fuses NOMCLR HSPLL PLL2 CPUDIV1 #use delay(clock = 48MHz) #use fast_io(B) #use fast_io(D) #use rs232 (baud=9600, xmit=PIN_C0, rcv=PIN_C1) // Initialize UART protocol (needed for FAT library) #include <lcd.c> // Include LCD driver source file #include <mmcsd_m.c> // Include MMC/SD card driver source file #include <fat_m.c> // Include FAT library source file char temperature[] = "Temp = 00.0 C "; char humidity[] = "RH = 00.0 % "; int8 T_Byte1, T_Byte2, RH_Byte1, RH_Byte2, CheckSum ; FILE MyLog; void Start_Signal(void){ output_drive(DHT11_PIN); // Configure connection pin as output output_low(DHT11_PIN); // Connection pin output low delay_ms(25); output_high(DHT11_PIN); // Connection pin output high delay_us(30); output_float(DHT11_PIN); // Configure connection pin as input } int1 Check_Response(void){ set_timer1(0); // Set Timer1 value to 0 setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); // Start Timer1 with internal clock source + 8 prescaler while(!input(DHT11_PIN) && get_timer1() < 150); // Wait until DHT11_PIN becomes high (cheking of 80µs low time response) if(get_timer1() > 149) // If response time > 99µS ==> Response error return 0; // Return 0 (Device has a problem with response) else { set_timer1(0); // Set Timer1 value to 0 while(input(DHT11_PIN) && get_timer1() < 150); // Wait until DHT11_PIN becomes low (cheking of 80µs high time response) if(get_timer1() > 149) // If response time > 99µS ==> Response error return 0; // Return 0 (Device has a problem with response) else return 1; // Return 1 (response OK) } } int1 Read_Data(int8 *dht_data) { int8 j; *dht_data = 0; for(j = 0; j < 8; j++){ set_timer1(0); // Reset Timer1 while(!input(DHT11_PIN)) // Wait until DHT11_PIN becomes high if(get_timer1() > 150) { // If low time > 100 ==> Time out error (Normally it takes 50µs) return 1; } set_timer1(0); // Reset Timer1 while(input(DHT11_PIN)) // Wait until DHT11_PIN becomes low if(get_timer1() > 150) { // If high time > 100 ==> Time out error (Normally it takes 26-28µs for 0 and 70µs for 1) return 1; // Return 1 (timeout error) } if(get_timer1() > 70) // If high time > 50 ==> Sensor sent 1 bit_set(*dht_data, (7 - j)); // Set bit (7 - i) } return 0; // Return 0 (data read OK) } void main(void) { char txt[4]; int8 i; int16 line = 0; lcd_init(); // Initialize LCD module lcd_putc('\f'); // clear LCD command delay_ms(2000); // wait 2 seconds // Initializing the FAT library as well as the SD card ---> returns 0 if OK printf("Initializing FAT library ... "); i = fat_init(); if( i == 0) { // initialization OK printf("OK"); mk_file("/DHT11Log.txt"); // Create a new file with name 'DHT11Log.txt' fatopen("/DHT11Log.txt", "w", &MyLog); // Open 'DHT11Log.txt' with write permission 'w' fatputs("Temperature and humidity data logger using PIC18F4550 microcontroller and DHT11 sensor\r\n\r\n" , &MyLog); fatclose(&MyLog); } else // FAT initialization error printf("Error!"); while(TRUE) { if( i == 0) { // If the FAT library was initialized with no error fatopen("/DHT11Log.txt", "a", &MyLog); // Open 'DHT11Log.txt' with append permission 'a' sprintf(txt, "%03Lu", ++line); fatputs(txt, &MyLog); fatputs(": Temperature = ", &MyLog); } Start_Signal(); // Send start signal to the sensor if(Check_Response()) { // Check if there is a response from sensor (If OK start reding humidity and temperature data) // Read (and save) data from the DHT11 sensor and check time out errors if(Read_Data(&RH_Byte1) || Read_Data(&RH_Byte2) || Read_Data(&T_Byte1) || Read_Data(&T_Byte2) || Read_Data(&CheckSum)) { lcd_putc('\f'); // clear LCD lcd_gotoxy(5, 1); // Go to column 5 row 1 lcd_putc("Time out!"); // Display "Time out!" } else { // If there is no time out error if(CheckSum == ((RH_Byte1 + RH_Byte2 + T_Byte1 + T_Byte2) & 0xFF)) { // If there is no checksum error temperature[7] = T_Byte1 / 10 + 48; temperature[8] = T_Byte1 % 10 + 48; // % is the modules operator temperature[10] = T_Byte2 / 10 + 48; humidity[7] = RH_Byte1 / 10 + 48; humidity[8] = RH_Byte1 % 10 + 48; humidity[10] = RH_Byte2 / 10 + 48; temperature[11] = 223; // Put degree symbol (°) // Print data on the LCD lcd_gotoxy(1, 1); // Go to column 1 row 1 printf(lcd_putc, temperature); // Display temperature lcd_gotoxy(1, 2); // Go to column 1 row 2 printf(lcd_putc, humidity); // Display humidity if( i == 0) { // If the FAT library was initialized with no error // Write data to SD card file (DHT11Log.txt) sprintf(txt, "%02u", T_Byte1); fatputs(txt, &MyLog); // write temperature fatputs("°C | Humidity = ", &MyLog); sprintf(txt, "%02u", RH_Byte1); fatputs(txt, &MyLog); // write humidity fatputs("%", &MyLog); } } // If there is checksum error else { lcd_putc('\f'); // LCD clear lcd_gotoxy(1, 1); // Go to column 1 row 1 lcd_putc("Checksum Error!"); } } } // If there is response problem (from the sensor) else { lcd_putc('\f'); // LCD clear lcd_gotoxy(3, 1); // Go to column 3 row 1 lcd_putc("No response"); lcd_gotoxy(1, 2); // Go to column 1 row 2 lcd_putc("from the sensor"); } if( i == 0) { // If the FAT library was initialized with no error fatputs("\r\n" , &MyLog); // Start new line fatclose(&MyLog); // Close 'DHT11Log.txt' file } setup_timer_1(T1_DISABLED); // Disable Timer1 module delay_ms(1000); // Wait 1 second } } // End of code |
I tested this project with Samsung 8GB (SDHC) and 2GB (SDSC) microSD cards, both are formatted with FAT32 file system, I got the file shown below:
The following video shows Proteus simulation of the project, I got the same result as the hardware circuit. Note that the simulation circuit is not the same as the hardware circuit, the hardware circuit diagram is shown above.
Proteus simulation file download:
Download
SD card image file download:
Download
#fuses NOMCLR HSPLL PLL2 CPUDIV1—————working fine
//#fuses MCLR, HSPLL, PLL2, CPUDIV1 ——- MCLR NOT WORKING PLEASE TELL ME
#use delay(clock=48000000,crystal=8000000) —— working fine
I WANT MCLR PIN TO WORK AS MCLR PIN
IS FILE WITH MBR SUPPORT HAVE DIFFERENT DOWNLOAD LINK OR WE HAVE DOWNLOADED CORRECT FILE HOW TO CHECK IT
SIMULATION WORKING FINE BUT I WANT MCLR PIN TO WORK WITH THE SAME CODE
THANK YOU FOR YOUR SUPPORT
I REQUEST AUTHOR TO REPLY, author contact details ????
If you wan to use the MCLR pin you’ve to add it’s circuit and the easiest one is by connecting the MCLR pin to VCC (+5V) through 10k ohm resistor.
Currently there is only one link for the FAT library which supports SD cards with or without MBR.
La nueva biblioteca FAT es la fat_m u otra?
Good work you have done. your tutorial is very detailed and easy to follow. Like Ismael, I tested your code with the same type of hardware you have used, it works well on Proteus but on hardware, it detects the FAT but when creating files or folders the pic is frozen, and you can never create files or folders on the SD card. any solution?
The FAT library has been updated to ‘support’ SD cards with MBR. Re-download it again and add it to your project!
You’re facing this error may be because your SD card has MBR, the updated library may work for you.
Thanks very much for your response, I downloaded the new FAT library that support SD card with MBR, and every thing worked well now. I am able to create directory and files. Please continue with the good work. see logged file below.
Temperature and Humidity Logger created by Legened
Temp= 27.0ßC RH = 37.0 %
Temp= 27.0ßC RH = 41.0 %
Temp= 26.0ßC RH = 41.0 %
Temp= 27.0ßC RH = 40.0 %
Temp= 26.0ßC RH = 41.0 %
Temp= 26.0ßC RH = 40.0 %
Temp= 26.0ßC RH = 40.0 %
Temp= 27.0ßC RH = 39.0 %
Temp= 26.0ßC RH = 40.0 %
Temp= 26.0ßC RH = 40.0 %
Temp= 26.0ßC RH = 40.0 %
Temp= 26.0ßC RH = 40.0 %
Temp= 26.0ßC RH = 40.0 %