Automatic printer head maintenance system for Canon G3010 printer using ESP32-S3.
This application connects to a Canon G3010 printer via WiFi Direct and sends a maintenance print job every 3 days to prevent printhead clogging by printing 4x4cm color squares (Black, Yellow, Cyan, Magenta).
- WiFi Direct Connection: Connects directly to printer's WiFi Direct network
- Raw TCP Printing: Sends print jobs via port 9100 (RAW protocol)
- Deep Sleep: Sleeps for 3 days between print cycles to conserve power
- SPIFFS Storage: Stores 825KB print file on internal flash
- Boot Counter: Tracks total maintenance cycles in RTC memory
- ESP32-S3 development board
- Canon G3010 (or similar G-series) printer with WiFi Direct enabled
- USB cable for programming
-
Copy the config template:
cp main/config.h.example main/config.h
-
Edit
main/config.hwith your printer's WiFi Direct settings:- SSID: Found in printer's WiFi Direct settings
- Password: Found in printer's WiFi Direct settings
- IP Address: Usually
192.168.114.1for Canon WiFi Direct - Port:
9100(RAW TCP printing)
Note: Find your printer's WiFi Direct credentials by printing a network configuration page from your printer menu.
PrinterMonitorCleaner/
├── CMakeLists.txt # Main project config
├── partitions.csv # Custom partition table
├── sdkconfig.defaults # Default configuration
├── README.md # This file
├── clean.prn # Print file (user provides)
└── main/
├── CMakeLists.txt # Component config
├── config.h.example # Config template (copy to config.h)
├── config.h # Your private config (gitignored)
└── printer_cleaner_main.c # Main application
Install ESP-IDF v5.0 or later:
# Follow official ESP-IDF installation guide
# https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/cd PrinterMonitorCleaner
idf.py set-target esp32s3
idf.py menuconfigVerify in menuconfig:
- Component config → ESP32S3-Specific → Check flash size matches your board
- Partition Table → Should show "Custom partition table CSV"
idf.py buildThe print file must be uploaded to the SPIFFS partition. Here's how:
# Create a directory for SPIFFS contents
mkdir spiffs_data
copy clean.prn spiffs_data\
# Generate SPIFFS image (size: 0x1B0000 = 1769472 bytes)
python %IDF_PATH%\components\spiffs\spiffsgen.py 1769472 spiffs_data spiffs_image.bin --page-size 256 --block-size 4096If you have the clean.prn file in the project root:
# Windows PowerShell
mkdir spiffs_data
copy clean.prn spiffs_data\
python $env:IDF_PATH\components\spiffs\spiffsgen.py 1769472 spiffs_data spiffs_image.bin --page-size 256 --block-size 4096Replace COMX with your ESP32-S3's COM port (e.g., COM3, COM4):
# Flash firmware, partition table, and SPIFFS in one command
idf.py -p COMX flash
# Flash SPIFFS partition separately
python %IDF_PATH%\components\esptool_py\esptool\esptool.py --chip esp32s3 --port COMX --baud 460800 write_flash 0x150000 spiffs_image.binOr use individual commands:
# Flash application and partitions
idf.py -p COMX flash
# Flash SPIFFS image to storage partition (offset 0x150000)
esptool.py --chip esp32s3 --port COMX --baud 460800 write_flash 0x150000 spiffs_image.binidf.py -p COMX monitorExpected output:
I (xxx) PrinterCleaner: ========================================
I (xxx) PrinterCleaner: Printer Cleaner - Boot count: 1
I (xxx) PrinterCleaner: ========================================
I (xxx) PrinterCleaner: Wakeup was not caused by deep sleep (first boot or reset)
I (xxx) PrinterCleaner: Initializing SPIFFS
I (xxx) PrinterCleaner: Partition size: total: 1769472, used: 845824
I (xxx) PrinterCleaner: Print file found: /spiffs/clean.prn (size: 825436 bytes)
I (xxx) PrinterCleaner: Connecting to printer WiFi Direct...
I (xxx) PrinterCleaner: Connected to AP SSID:YOUR_PRINTER_SSID
I (xxx) PrinterCleaner: Got IP:192.168.114.xxx
I (xxx) PrinterCleaner: Sending print job to printer...
I (xxx) PrinterCleaner: Socket created, connecting to 192.168.114.1:9100
I (xxx) PrinterCleaner: Successfully connected to printer
I (xxx) PrinterCleaner: Print file size: 825436 bytes
I (xxx) PrinterCleaner: Sent 825436/825436 bytes
I (xxx) PrinterCleaner: Print job sent successfully! Total: 825436 bytes
I (xxx) PrinterCleaner: ✓ Print job completed successfully!
I (xxx) PrinterCleaner: Total maintenance cycles: 1
I (xxx) PrinterCleaner: Entering deep sleep for 259200 seconds (3 days)
I (xxx) PrinterCleaner: Going to sleep now...
- Boot & Initialize: ESP32 wakes up (timer or first boot), initializes NVS and SPIFFS
- WiFi Connection: Connects to printer's WiFi Direct network
- TCP Connection: Opens socket to printer's port 9100
- File Transfer: Streams
clean.prnfile (825KB) in 4KB chunks - Deep Sleep: Enters deep sleep for 3 days (259,200 seconds)
- Repeat: Wakes up after 3 days and repeats the cycle
Edit in main/printer_cleaner_main.c:
#define SLEEP_TIME_SECONDS (3 * 24 * 60 * 60) // 3 daysExamples:
- 1 day:
(1 * 24 * 60 * 60) - 1 week:
(7 * 24 * 60 * 60) - 12 hours (testing):
(12 * 60 * 60)
Edit main/config.h (copy from config.h.example first):
#define WIFI_SSID "YOUR_PRINTER_SSID"
#define WIFI_PASS "YOUR_PRINTER_PASSWORD"
#define PRINTER_IP "192.168.114.1"
#define PRINTER_PORT 9100-
Create your print file using Windows:
- Design your page in Word/Paint
- Print → Select Canon G3010
- Choose "Print to File"
- Save as
clean.prn
-
Verify file size:
(Get-Item "clean.prn").Length / 1KB
-
If larger than 1.5MB, increase SPIFFS partition in partitions.csv
E (xxx) PrinterCleaner: Failed to mount or format filesystem
Solution: Make sure you flashed the SPIFFS image to 0x150000
E (xxx) PrinterCleaner: Print file not found: /spiffs/clean.prn
Solution:
- Create
spiffs_datafolder withclean.prn - Generate SPIFFS image
- Flash to offset 0x150000
E (xxx) PrinterCleaner: Failed to connect to SSID:YOUR_PRINTER_SSID
Solution:
- Verify printer WiFi Direct is enabled
- Check SSID and password are correct
- Make sure you're within range of printer
E (xxx) PrinterCleaner: Socket unable to connect: errno 113
Solution:
- Verify printer IP address (usually 192.168.114.1 for WiFi Direct)
- Test from PC first:
Test-NetConnection -ComputerName 192.168.114.1 -Port 9100
Solution:
- Verify the print file works from PC:
$bytes = [System.IO.File]::ReadAllBytes("C:\clean.prn") $client = [System.Net.Sockets.TcpClient]::new("192.168.114.1", 9100) $client.GetStream().Write($bytes, 0, $bytes.Length) $client.Close()
- Check printer has paper and ink
- Check printer display for errors
- Active (printing): ~80mA @ 3.3V for 20-30 seconds
- Deep Sleep: ~10µA @ 3.3V
- Average over 3 days: ~11µA (extremely low)
With a 1000mAh battery, the system can run for approximately 10+ years!
For quick testing, change sleep time to 1 minute:
#define SLEEP_TIME_SECONDS 60 // 1 minute for testingRebuild and flash to test the cycle without waiting 3 days.
MIT License - Free to use and modify
- ESP-IDF SPIFFS Documentation
- ESP-IDF Deep Sleep Guide
- Port 9100 Raw Printing Protocol
- ESP32 WiFi Documentation
For issues with:
- ESP-IDF: ESP32 Forum
- This project: Create an issue in your repository
Created for Canon G3010 printer head maintenance ⚙️🖨️