Introduction to LittleFs, Write LittleFs, Read Little Fs and Delete in LittleFs
by lavanya4520 in Circuits > Electronics
18365 Views, 5 Favorites, 0 Comments
Introduction to LittleFs, Write LittleFs, Read Little Fs and Delete in LittleFs
If one is familiar with using firebase to fetch and update data to real time databases, then it’s known that it’s an annoying problem that the data will be destroyed when the NodeMCU resets. So, here, let’s learn how to overcome the problem of data being destroyed once the NodeMCU resets. This problem persists in Arduino as well. To solve this in Arduino, we use EEPROM. It stands for Electrically Erasable Programmable Read-Only Memory. It is a non-volatile memory where data is written. Here, non-volatile means that the data won’t be lost as soon as the power supply is cut. Hence, data is written permanently and it won’t change unless the user decides to. This data can be erased and rewritten electrically hence the name “Electrically Erasable Programmable Read-only memory”. To understand EEPROM consider it as something similar to the hard-drive on a computer.
But boards like NodeMCU have a flash memory which is more advanced than EEPROMs. In EEPROM, data is stored as bytes and hence, storing large amounts of data will be complex and the number of reads and writes is limited. Whereas in flash memory, it is like a thumb drive (pendrive) which has far more reads and writes than EEPROM. Along with this, by using a file system, we can create files, folders and users have the control to rename or delete whatever they create. Even though the file system is stored on the same flash chip as the program, when a new sketch is programmed, it does not modify file system contents. There are two file systems for utilizing the onboard flash on the ESP8266. One is SPIFFS and the other one is LittleFS. SPIFFS is currently deprecated and may be removed in future releases of the ESP core so let’s learn about LittleFS.
LittleFS for the ESP8266 is mostly like a regular file system in a computer where navigation, creating, renaming, deleting or modifying the files are possible.
(Note: This article was originally published in CircuitDigest along with my co-author Neutrino. You can find the complete code and explanation here.)
Supplies
Components required to build the circuit to interface 16x2 LCD display with ESP8266:
(Amazon Affiliate links are provided along with components)
● 16x2 LCD Display (https://amzn.to/3uwVlIa)
● I2C module (PC8574T - Remote 8-bit I/O expander for I2C-bus) (https://amzn.to/3vyhszi)
● Bread board (https://amzn.to/3wHKgFD)
● Jumper wires (Male to Female) (https://amzn.to/3oXO7Mc)
Understanding How to Save Data to the Flash Memory of the NodeMCU (Write to LittleFs)
This is writing the data to the flash memory. This is very simple. The code is written in such a way that it allows the user to type the data very easily. Just open the serial monitor and type the data and press ‘enter’ (Make sure that the Baud rate = 115200 and no line ending is selected). whatever is typed is taken as the data and it is saved to LittleFs file system. The LittleFs file system is mounted on Flash memory of ESP8266. Other than writing in the LittleFs file system, two other tasks can be done. Those are reading and deleting. To do that, the code is written in such a way that it takes input from the user and does the function that the user requests.
When the user enters “D” the file is deleted.
(NOTE: it is case sensitive. And any error like “DD” or “dD” instead of “D” will be considered as input data and this will be overwritten on the existing data). And “R” to read the file. (NOTE: it is case sensitive. And any error like “RR” or “rR” instead of “R” will be considered as input data and this will be overwritten on the existing data).
Understanding How to Read Data From the Flash Memory of the NodeMCU (Read From LittleFs)
When an attempt is made to read the data without writing anything first, the LCD displays the message by saying “No saved Data” Reading data from the flash memory of the NodeMCU is not complex at all.
The “readData()” function is used to read the data and “lcd.write(file.read());” function is used to print the data on the LCD display.
Understanding How to Delete Data From the Flash Memory of the NodeMCU (Delete From LittleFs)
When a file should be deleted from LittleFs, a simple function called “LittleFS.remove();” is used. This function deletes the contents of the file whose path should be given by the user.
Let’s Verify the Reading, Writing and Deleting in LittleFs Through a Simple Circuit of NodeMCU, LCD Display and I2C Module
First let’s start with 16x2 LCD Display basics and display a simple message on the LCD.
LCD stands for Liquid Crystal Display; is a cost-effective way of displaying text output of microcontrollers/development boards. A 16x2 LCD display can display 16 characters on each line and has 2 such lines. In case there are more lines of information that need to be displayed, messages can scroll through the LCD screen. Now, when it comes to displaying information that is more than “ON or OFF” there’s a limitation with LEDs and Seven Segment Displays since they can display “ON or OFF” state and alphanumeric characters respectively. This limitation can be circumvented easily by using LCD but they take up most of the pins of the microcontroller or the NodeMCU. To avoid this, we use an I2C module; by using I2C module, interfacing LCD can be achieved by only 4 pins.
First, interfacing the LCD display with ESP8266. This is the basic project and using this we can read the data from LittleFs.
As we can see in the Pinout diagram, we need to connect 8 data pins of LCD to NodeMCU, this will leave no pins of NodeMCU for other use. Hence we use the I2C module.
Circuit Connections for Interfacing 16x2 LCD Display With I2C and ESP8266
First, connect the I2C module to the LCD display. Solder Female Header pins to LCD display and connect the I2C module in such a way that the four pins of the I2C (GND, VCC, SDA, SCL) point outwards.
Now to power the circuit, connect, GND pin of the I2C module to the GND pin of ESP8266 and connect the VCC of the I2C module to the Vin pin of ESP8266. (These two pins supply the power to the LCD screen)
Connect SDA of I2C module to D2 pin of ESP8266 Connect SCL of I2C module to D1 pin of ESP8266
Including the Required Library to Upload the Code for ESP8266 Library
Including the required library to upload the code for ESP8266 Library .zip file is included at the bottom of this page.
Go to Arduino IDE ---> Sketch - --> Include Library ---> Add .ZIP Library ---> and select this zip file and press open.
Now, Compile and Upload the code.
Explanation of Programming to Display “Hello World!” on 16x2 LCD Display:
Basics are important. So, let's see how to program to display "Hello World!"
#include<LiquidCrystal_I2C.h>
This Library is included to work with LCD displays.
#include<Wire.h>
This library is included to interface using the I2C module.
int lcdColumns = 16;
int lcdRows = 2;
These two lines are used to set the LCD number of columns and rows; in our case, it’s 16 columns and 2 rows.
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
This is to set LCD address, number of columns and rows. (if you don't know your display address, run an I2C scanner sketch)
void setup()
{
lcd.init(); lcd.backlight();
}
Void setup function is run only once so here, initialization and declaration is done. “lcd.init();” is used to initialize LCD and “lcd.backlight();” is used to turn ON backlight of the LCD display.
void loop()
{
lcd.setCursor(0, 0);
In the void loop, “.setCursor” function is used to set the cursor to the required position. Since we want to display the message “Hello World!” in the first column, first row, we give the position “(0,0)”
lcd.print("Hello World!");
delay(1000);
lcd.print” function will print whatever the message is given. Here, Let’s display “Hello World!”. delay(1000);” will create a delay of 1 second. This makes sure that the message displayed will stay long enough for us to see it properly.
lcd.clear();
This function will clear the display to print new message.
lcd.setCursor(0,1);
Now, to create a little animation, let’s set cursor to first column, second row so after displaying the message on the first row for a second, it will shift to second row.
lcd.print("Hello World!");
delay(1000);
After setting to second row, print the same message to display and the delay will make sure that the message will stay for 1 second on the second row as well.
lcd.clear();
This will clear the screen so next time it’s convenient to print messages. This is not absolutely required but it’s good practice to write program this way.
Output of Interfacing LCD Display With ESP8266
Output is shown in the figure above. The LCD screen should display “Hello World!” in the first row for about a second and shift the same message on the second row.
Writing, Reading and Deleting in LittleFs With 16x2 LCD Display and ESP8266
The circuit for using LittleFs to write, read and delete files from flash memory remains same as the previous one to display “Hello World”
#include<LiquidCrystal_I2C.h>
#include<Wire.h>
#include "LittleFS.h"
These above libraries are required to work with LCD display, I2C and LittleFs.
int lcdColumns = 16;
int lcdRows = 2;
This is to set the LCD number of columns and rows. In our case, 16x2 which means 16 columns and 2 rows.
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
This function is used to set the LCD address, number of columns and rows.
void readData();
void writeData(String data);
void deleteData();
These are function prototypes. To read the data to the flash memory use the custom function “readData()”. Similarly, “writeData” and “deleteData” are custom functions to write data and to delete data from LittleFs respectively.
void setup()
{
Serial.begin(115200);
Start the serial monitor and set the baud rate to 115200.
lcd.init();
lcd.backlight();
“lcd.init” function will initialise LCD and .backlight function will turn on LCD backlight
lcd.setCursor(0, 0);
lcd.print("Little FS Demo");
delay(1000);
Like before, this will set the cursor to the first column, first row and print the message “Little FS Demo” and wait for a second.
if(!LittleFS.begin())
{
Serial.println("An Error has occurred while mounting LittleFS");
Here, this part of program is used because in case Little Fs fails to start then an error message should be display to notify the user that Little Fs failed to start.
lcd.clear();
lcd.print("Mounting Error");
delay(1000);
return;
}
To check whether the file has opened correctly, if it doesn’t open correctly, it will print an error message and end the function. Or it will print the data written whatever was written earlier. On the LCD display, “Mounting Error” message will be displayed.
readData();
}
This snippet of code is used to read the saved data.
void loop()
{
if(Serial.available())
{
String data = Serial.readString();
Serial.println(data);
Go to the “loop function” and create an “if statement” which triggers when the Serial receives some data from the serial monitor. Then read the data and store it in a string “data”, and to read the string we’ll use the “serial.readString function()”. Along with this print the data which should be written to the flash of the nodeMCU. “Serial.available” function will take input from the user on the serial monitor and store it in the “data” string. Then it’ll check to see what command the user has entered.
if(data == "D")
{
deleteData();
Serial.println("File deleted!");
return;
}
If the user has entered “D” it will call “deleteData” function to delete the file and display the “File deleted!” message on the LCD display.
else if(data == "R")
{
readData();
Return;
}
In a similar way, if the user has entered “R” it will call the function “readData” to read the file from flash memory. Serial.println("Writing Data...");
writeData(data);
Serial.println("done Writing Data!");
}
}
void readData()
{
File file = LittleFS.open("/SavedFile.txt", "r");
Create another function called “readData()”. Create a file object and pass in the path for the file and the letter ‘r’ to indicate that the file is being read. To read the data, first the file must be accessed, that’s why this is used. This will open the LittleFs file and inside that saved text file.
if(!file)
{
Serial.println("No Saved Data!");
lcd.clear();
lcd.print("No Saved Data!"); return;
}
Then check if the file opens, if so, check for the data from the file by using a “while loop” and “file.available()” because “file.read()” function outputs one character at a time. So use the “serial.write” function to print one character at a time.The “if” condition will check if the file exists. If not, it’ll print a message saying “No Saved Data!” on the serial monitor and it’ll clear the LCD display and display the same message.
lcd.clear();
lcd.print("Saved Data :");
lcd.setCursor(0,1);
while(file.available())
{
lcd.write(file.read());
}
lcd.setCursor(0,0);
file.close();
}
If the file is found, then the “lcd.clear” function will clear the LCD and display the message “Saved Data:” to indicate that it is about to read the data from flash memory and from the second row, it'll start displaying the message. Hence the cursor is set to the first column, second row position and the file is read from flash memory and the same is written on the LCD display screen. After displaying, it’ll reset the cursor position and “file.close function” will close the file.
void writeData(String data)
{
//Open the file
File file = LittleFS.open("/SavedFile.txt", "w");
//Write to the file
file.print(data);
delay(1);
//Close the file
file.close();
Inside “writeData” custom function first create a file where you want to save the data, for that use “File file = LittleFS.open()” inside this put the path where it should be saved. I will just say "/SavedFile.txt.” If the file already exists it will rewrite the data in the file or if it doesn’t exist it will create a new file called SavedFile.txt. The second parameter for this function is ‘w’ which indicates that it is writing to a file. “writeFunction” function is called to write to the Flash memory using LittleFs. “LittleFs” is open to access the saved text file. Then “file.print” is used to write the data. Delay of one second is caused to give time to save properly and “file.close” is used to close the file after writing.
Serial.println("Write successful");
lcd.clear();
lcd.print("Data Saved :");
// set cursor to first column, second row
lcd.setCursor(0,1);
// print the data on the LCD
lcd.print(data);
// reset cursor position
lcd.setCursor(0,0);
}
On the serial monitor, “Write successful” message is displayed. LCD is then cleared to print “Data Save:” then the cursor is set to (0,1) position to print the written data on the LCD. Then the cursor position is set back to (0,0).
void deleteData()
{
//Remove the file
LittleFS.remove("/SavedFile.txt");
lcd.clear();
lcd.print("Data Deleted");
}
Create another custom function called “deleteData()” Here use the snippet “LittleFS.remove("/SavedFile.txt");” where the “/SavedFile.txt” is the path of the file which has to be deleted. “deleteData” function is to remove the file. So, first, the saved text file is accessed and then deleted. Then a message “Data Deleted” is printed on the LCD. Expected output of LittleFs: For the first time, since there is no data to be displayed, the LCD screen will display the message “No data Saved” Once the data is entered through Serial Monitor, the data can be read by typing “R” or deleted by typing “D” in the Serial Monitor.
Now to Test If It Is Truly Saving to the Flash Memory
When the NodeMCU is disconnected from power and reconnected, it will read from the flash memory of NodeMCU. Now Disconnect the NodeMCU from the PC and reconnect again. This should directly call the read function and display the data stored in the flash memory.
Final Thoughts
This was just an introduction to LittleFS type of documentation. You can take is a step further and take input from sensor and try to store the collected data in LittleFS (although it's not a viable project since the available flash memory is less and not effective to store data). Or make a note of only pivotal points and use it to make decisions and control the actuators.
This concludes our projects on LittleFS. I really want to thank Neutrino for all the support and cooperative work. If you have any questions regarding the project, do not hesitate to comment down below.