INTRODUCTION
Given this, maintaining data even after a power cycle is required in IoT development. For example, problems such as data loss when the module reset in case of working with NodeMCU what is and Firebase. Board flash memory is completely different than EEPROM; it’s not limited in read/write cycles or its capacity; this is something that modern development boards like NodeMCU use. In order to take full advantage of this, the ESP8266 ecosystem has brought something completely new into the game, acquiring LittleFS as a file system that has some improvements over the old SPIFFS file system. If you do not know what NodeMCU is an open-source platform for NodeMCU based esp8266 with GPIO, Wi Fi and programmable Memory to be used for IoT projects.
In this guide we will explore how we can read, write and erase data on ESP8266 with LittleFS. With LittleFS you get a non volatile storage solution, which allows to create, files, folders and manage the already stored contents in a file system with a format just like in a thumb drive. But first, let’s dig in setting up LittleFS with ESP8266 NodeMCU for persistent data storage.
Why we choose LittleFS on ESP8266?
LittleFS is the successor of the deprecated SPIFFS and when it comes to flash memory on NodeMCU uses better memory management and is more durable. EEPROM, similar to a thumb drive, allows many more than read/write cycles and storage flexibility than EEPROM. Unlike EEPROM, which is byte based, LittleFS allows users to store data into files and folders, giving higher flexibility. Additionally, LittleFS is code upload agnostic, so new code will not overwrite or modify existing files.
The components required for the setup!
To demonstrate how to work with LittleFS on ESP8266, we’ll use the following components:
-
- 16×2 LCD Display
-
- The LCD is connected to I2C Module (PCF8574T)
-
- Breadboard
-
- Male-to-Female Jumper Wires
-
- ESP8266 NodeMCU
Introduction with NodeMCU and LittleFS
The ESP8266 chip powers NodeMCu, which is an open source platform to design Wi-Fi connected devices. It separates its flash memory out into places for storing code, and a file system. Users can store non volatile data reliably using LittleFS, a small file system.
LittleFS is a miniature version of a mainstream file system. Instead of handling each byte of data, it stores files in a way that withstands power disruption, which is essential for projects where data must be reliable for storage.
How to write data into flash memory with LittleFS
To prove it, here are some examples of how to read, write and delete using LittleFS. Here we try to create a simple program that communicates with the ESP8266 through the serial monitor.
Writing Data to LittleFS
Writing to LittleFS is easy. In the serial monitor you prompt the user to provide data. Then, after input is provided, the code writes the data to a file in the LittleFS embedded file system. It is configuring the system to be very attentive to user input. For example, if we want to store content that we type, we just enter to store the content, and select 115200 as the baud rate (usually default) and ‘No line ending’ in our serial monitor.
LittleFS is used to mount the filesystem on the ESP8266’s flash memory. Invalid input (incorrect commands or additional characters) is handled carefully — invalid input will overwrite existing data.
Reading Data from LittleFS
The program will open the file stored in LittleFS and displays the content of that file on a 16×2 LCD screen. If you have nothing saved, you are alerted with a “ No saved data” message. Further, Wire.h and LiquidCrystal_I2C libraries are used to configure the LCD.
Deleting Data from LittleFS
Just as easily, deleting data is possible using LittleFS.remove() which removes a certain file if passed the file path by the user. Like writing, however, deleting is not an exact science … you need accurate input in order to preserve accurate data.
Test littleFS with ESP8266 and I2C LCD
We will use a 16×2 LCD display, connect it to the I2C module, to display data from the ESP8266 NodeMCU. The I2C driver reduces the number of GPIO pins needed, allowing us to connect the LCD using only four pins:
GND to ESP8266’s GND
VCC to ESP8266’s Vin
SDA to ESP8266’s D2
SCL to ESP8266’s D1
Soldered header pins connect the I2C module directly to the LCD. Doing so frees up some GPIOs for other uses, keeps the code simple, and still does the job.
Arduino code to have littlefs and I2C LCD working on a leaf liter board.
If you want to give this a try, you’ll need to install the LiquidCrystal_I2C.h and the LittleFS.h libraries from the GitHub or using the Arduino Library Manager, before you begin writing code. Now that the libraries are installed, you can get programming.
Testing the LCD Display
To test the I2C LCD display, initialize the LiquidCrystal_I2C and Wire libraries, and set up a basic program that displays a message. For example:
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
int lcdColumns = 16;
int lcdRows = 2;
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
void setup() {
lcd.init();
lcd.backlight();
}
void loop() {
lcd.setCursor(0, 0);
lcd.print("Hello World!");
delay(1000);
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Hello World!");
delay(1000);
lcd.clear();
}
-
- The above code tests whether the LCD is properly connected and configured by displaying “Hello World!” in different rows.
Writing Data to LittleFS
Now, incorporate LittleFS to read, write, and delete data from the flash memory:
#include <LittleFS.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
int lcdColumns = 16;
int lcdRows = 2;
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
void readData();
void writeData(String data);
void deleteData();
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
if (!LittleFS.begin()) {
Serial.println("An Error has occurred while mounting LittleFS");
return;
}
}
void loop() {
// Call writeData(), readData(), or deleteData() functions based on user input
}
-
- This setup initializes LittleFS and configures the LCD. User functions like readData(), writeData(), and deleteData() perform the main operations.
lcd.setCursor(0, 0);
lcd.print(“Little FS Demo”);
delay(1000);
Managing non volatile memory efficiently is essential when working with IoT applications using NodeMCU platform and you need to store the persistent data. The ESP8266 chip at the heart of NodeMCU comes with onboard flash memory is capable to support a number of file systems including LittleFS and SPIFFS. LittleFS is reliable and efficient, greatly improving why of storing files and directories on a smaller space and without the limitations of EEPROM. In this tutorial, we have taken a look at how we can use LittleFS on ESP8266 NodeMCU, and how to interface it to 16×2 LCD using I2C for data monitoring.
Understanding NodeMCU and LittleFS: What is NodeMCU?
An open source IoT platform based on ESP8266 Wi-Fi SoC comes with a firmware called NodeMCU. It is widely used platform for Wi-Fi connected projects. It has multiple GPIO pins and, best of all, can be programmed quickly with the Arduino IDE. But since projects will need a persistent storage to save data, LittleFS facilitates this within the on board flash memory of the NodeMCU.
It is a lightweight, wear leveling file system optimised for microcontrollers memory limitations. LittleFS is different from EEPROM, since unlike EEPROM (which has limited storage capacity and wears), it enables developers to store, modify, and even delete data through file based operations, which is good for advanced IoT projects.
Why LittleFS?
Explanation:
This is a small section on why we chose LittleFS over SPIFFS, but for the full reasoning, see the bootloader source code.
Previously, ESP8266 had a common file system called SPIFFS packed with memory usage and efficiency limitations. LittleFS introduces enhancements such as:
Improved wear leveling: Prevents overuse of the flash memory.
Resilience to power failures: It will protect files from corruption.
Dynamic memory allocation: Better utilizations of the memory than SPIFFS.
First, now let’s implement LittleFS to read, write, and delete data on ESP8266 NodeMCU and then use an LCD for displaying output.
Required Components
-
- ESP8266 NodeMCU
-
- 16×2 LCD Display
-
- I2C Module (PCF8574T)
-
- Breadboard
-
- Jumper Wires
-
- LCD and LittleFS setup and initialization
Next setup the LiquidCrystal_I2C and Wire libraries with Arduino IDE. The LCD module comes with an I2C module so communication can only be done with 2 pins (SDA and SCL) while other gpio pins are still available.
Testing the LCD Connection: To test the I2C LCD connection use following code.
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
int lcdColumns = 16;
int lcdRows = 2;
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Testing LCD...");
}
void loop() {
// Optional scrolling or message change
}
-
- The I2C address 0x27 may vary depending on your module, so you can use an I2C scanner to confirm it.
Mounting LittleFS: In the setup function, initialize LittleFS:
#include <LittleFS.h>
void setup() {
Serial.begin(115200);
if (!LittleFS.begin()) {
Serial.println("An Error occurred while mounting LittleFS");
lcd.clear();
lcd.print("Mount Error");
return;
}
lcd.print("LittleFS Ready");
}
-
- This snippet checks if the file system mounts successfully. If not, it displays an error on both the serial monitor and LCD screen.
Writing, Reading, and Deleting Data with LittleFS
Writing Data: The writeData function stores the user input from the serial monitor into the flash memory:
void writeData(String data) {
File file = LittleFS.open("/SavedFile.txt", "w");
if (!file) {
Serial.println("Failed to open file for writing");
return;
}
file.print(data);
file.close();
lcd.clear();
lcd.print("Data Saved:");
lcd.setCursor(0, 1);
lcd.print(data);
}
-
- In this function, a file named SavedFile.txt is created (or overwritten). It then writes the received string into the file and displays confirmation on the LCD screen.
Reading Data: Create a readData function to retrieve the saved data:
cpp
Copy code
void readData() {
File file = LittleFS.open(“/SavedFile.txt”, “r”);
if (!file) {
Serial.println(“No Saved Data!”);
lcd.clear();
lcd.print(“No Data Found”);
return;
}
lcd.clear();
lcd.print(“Saved Data:”);
lcd.setCursor(0, 1);
while (file.available()) {
lcd.write(file.read());
}
file.close();
}
-
- This function checks if the file exists and reads its content, character-by-character, displaying it on the LCD.
Deleting Data: The deleteData function is simple and straightforward:
void deleteData() {
LittleFS.remove("/SavedFile.txt");
lcd.clear();
lcd.print("Data Deleted");
}
-
- This command deletes the saved file and updates the LCD screen accordingly.
Main Program Flow with Serial Input
In the loop function, handle serial commands to execute reading, writing, and deletion based on user input:
void loop() {
if (Serial.available()) {
String data = Serial.readString();
if (data == "D") {
deleteData();
Serial.println("File Deleted");
} else if (data == "R") {
readData();
} else {
writeData(data);
Serial.println("Data Written Successfully");
}
}
}
The serial monitor commands:
-
- “D” for deleting the file.
-
- “R” for reading and displaying data.
-
- Any other text to save as new data.
Saving Sensor Data using LittleFS
Beyond handling serial input, NodeMCU with LittleFS can save sensor data periodically. Modify the code to capture sensor readings every 5 seconds and save them:
Setup Sensor Input:
int sensorReading = 0;
unsigned long lastSensorWriteTime = 0;
void readSensorValue() {
// Replace with your sensor reading code
sensorReading = analogRead(A0); // Example for analog sensor
}
Modify Loop to Periodically Store Sensor Data:
void loop() {
readSensorValue();
if ((millis() – lastSensorWriteTime) > 5000) {
writeData(String(sensorReading));
lastSensorWriteTime = millis();
}
if (Serial.available()) {
String data = Serial.readString();
if (data == “D”) {
deleteData();
} else if (data == “R”) {
readData();
}
}
}
Final Thoughts
With NodeMCU and LittleFS you can store persistent data, the sensor values or user inputs, even after a power cycle. As compared to EEPROM, this approach is more robust and scalable, offering file like operations and protection against power failure. Building more interactive and informative project is possible thanks to LittleFS and NodeMCU’s ability to talk to displays (I2C LCD). Whatever your level as a developer, LittleFS is a tool that will benefit you in making your IoT systems more reliable and functional.
CODE :
//Provided to you by ElectroGlobal
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include "LittleFS.h"
// set the LCD number of columns and rows
int lcdColumns = 16;
int lcdRows = 2;
// set LCD address, number of columns and rows
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
//function prototypes
void readData();
void writeData(String data);
void deleteData();
void setup() {
//Start the serial monitor
Serial.begin(115200);
// initialize LCD
lcd.init();
// turn on LCD backlight
lcd.backlight();
// set cursor to first column, first row
lcd.setCursor(0, 0);
lcd.print("Little FS Demo");
delay(1000);
//Start LittleFS
if(!LittleFS.begin()){
Serial.println("An Error has occurred while mounting LittleFS");
//Print the error on display
lcd.clear();
lcd.print("Mounting Error");
delay(1000);
return;
}
//Read the saved data
readData();
}
void loop() {
//Take input from user on serial monitor
if(Serial.available())
{
String data = Serial.readString();
Serial.println(data);
if(data == "D") // To delete the file
{
deleteData();
Serial.println("File deleted!");
return;
}
else if(data == "R") // To read the file
{
readData();
return;
}
Serial.println("Writing Data...");
writeData(data);
Serial.println("done Writing Data!");
}
}
void readData()
{
//Open the file
File file = LittleFS.open("/SavedFile.txt", "r");
//Check if the file exists
if(!file){
//Read the file data and display it on LCD
Serial.println("No Saved Data!");
lcd.clear();
lcd.print("No Saved Data!");
return;
}
lcd.clear();
lcd.print("Saved Data :");
// set cursor to first column, second row
lcd.setCursor(0,1);
//Display on the LCD
while(file.available()){
lcd.write(file.read());
}
//reset cursor poisition
lcd.setCursor(0,0);
//Close the file
file.close();
}
void writeData(String data)
{
//Open the file
File file = LittleFS.open("/SavedFile.txt", "w");
//Write to the file
file.print(data);
//Close the file
file.close();
delay(1);
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);
}
void deleteData()
{
//Remove the file
LittleFS.remove("/SavedFile.txt");
lcd.clear();
lcd.print("Data Deleted");
}
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
// set the LCD number of columns and rows
int lcdColumns = 16;
int lcdRows = 2;
// set LCD address, number of columns and rows
// if you don't know your display address, run an I2C scanner sketch
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
void setup()
{
// initialize LCD
lcd.init();
// turn on LCD backlight
lcd.backlight();
}
void loop(){
// set cursor to first column, first row
lcd.setCursor(0, 0);
// print message
lcd.print("Hello World!");
delay(1000);
// clears the display to print new message
lcd.clear();
// set cursor to first column, second row
lcd.setCursor(0,1);
lcd.print("Hello World!");
delay(1000);
lcd.clear();
}