Getting an ili9341 display to ESP32-S2 mini with micropython via SPI connection

https://github.com/jeffmer/micropython-ili9341

If you are using an ili9341 display with an ESP32-s2 mini by wemos, like I was, you may run into a few hiccups.

Firstly, I was using the Adafruit 2.8 tft breakout and an external power supply for it. That meant when I applied 3.3v to the IMG1,IMG2,IMG3 pins it did not register properly. So you have to use the ESP32’s or whatever board’s 3.3 or 5v line to signal to the ili9341 that you are trying to talk to it via SPI.

Secondly, the ili934xnew.py will sometimes throw an error when trying to import the class ILI9341. The only way I was able to solve this was putting it under a try: command during the import process.

Thirdly, the fonts do not like to work sometimes and you will get the following error: Object has no attribute height. The only way to fix this was by using ttf_to_py.py and making a smaller font like size 12 instead of 32 or 26.

Fourthly, the pins on the ESP32-S2 should all work with SPI but I used the specified SPI connectors via the documentation. All GPIOs can do PWM on the board.

Here is the main documentation for the code:

https://github.com/jeffmer/micropython-ili9341

Here is my sample code for the ESP32-S2 mini:


"""
ESP32-S2 mini micropython 
with 320x240 ILI9341 SPI Display
"""
# Get error: cannot import ILI9341
# Using a try statement 'fixes' it...
try:
  from ili934xnew import ILI9341, color565
except:
  print("Minor issue with ili934xnew")
#import ili934xnew
from machine import Pin, SPI
from micropython import const
import os
import gc
import time
import glcdfont
import fs8
import fs16


def df():
  s = os.statvfs('//')
  return ('{0} MB'.format((s[0]*s[3])/1048576))

def free(full=False):
  F = gc.mem_free()
  A = gc.mem_alloc()
  T = F+A
  P = '{0:.2f}%'.format(F/T*100)
  if not full: return P
  else : return ('Total:{0} Free:{1} ({2})'.format(T,F,P))

SCR_WIDTH = const(320)
SCR_HEIGHT = const(240)
SCR_ROT = const(3)
CENTER_Y = int(SCR_WIDTH/2)
CENTER_X = int(SCR_HEIGHT/2)

print(os.uname())
TFT_CLK_PIN = const(12)
TFT_MOSI_PIN = const(11)

TFT_MISO_PIN = const(4)

TFT_CS_PIN = const(7)
TFT_RST_PIN = const(5)
TFT_DC_PIN = const(9)


spi = SPI(
    1,
    baudrate=40000000,
    miso=Pin(TFT_MISO_PIN),
    mosi=Pin(TFT_MOSI_PIN),
    sck=Pin(TFT_CLK_PIN))
print(spi)

display = ILI9341(
    spi,
    cs=Pin(TFT_CS_PIN),
    dc=Pin(TFT_DC_PIN),
    rst=Pin(TFT_RST_PIN),
    w=SCR_WIDTH,
    h=SCR_HEIGHT,
    r=SCR_ROT)

display.erase()
display.set_pos(0,0)

p=[2,2,222]

#for x in range(200):
#  for y in range(200):

#    display.pixel(x,y,x+y)
print('Displaying Hello World')
display.set_font(fs16)
display.set_color(color565(255, 255, 255), color565(12, 12, 12))
display.print("Getting an ili9341 display to work on a ESP32-S2 mini with micropython with SPI connection")
display.pixel(p[0],p[1],p[2])
    
time.sleep(1)
print('did stuff')

Other projects with ili9341 and esp32: https://www.rototron.info/projects/esp32-pwned-password-checker/

Wiring

Adafruit has this wonderful wiring guide for the board: https://learn.adafruit.com/user-space-spi-tft-python-library-ili9341-2-8/wiring

But since the ESP32-S2 mini really has all of the pins able to communicate via SPI i specified the left column of headers to connect like this:

Leave a Reply

Your email address will not be published. Required fields are marked *