Sunday, 29 December 2019

Raspberry PI4 Olimex MOD-LCD3310 Python SPI

How to connect MOD-LCD3310 to Raspberry pi4  via SPI interface

  1. Rasberry pi4 with rasbian -->
  2. One Olimex MOD-LCD3310 LCD -->
  3. Ribbon cables female/female (need 8)
First download and install Python and is modules from github.com https://github.com/Bingzo/replicape/tree/master/libs/spi

#sudo sudo python setup.py build

and install (if you do not wish to use this module you and only build and use it from the build directory with out install)

sudo sudo python setup.py  install

Pinout

The olimex MOD-LCD3310 UEXT pinout is shown bellow. 

Rasberri Pi pinout and it's numbering can be found here https://pinout.xyz/ 
For my setup i used Raspberri Pi4 pins as follows


 -----------------------------------------
| Raspberri PI |              |           |
| Physical pin |  MOD-LCD331  |    Name   |
|--------------|--------------|-----------| 
|      1       |      1       |    3.3V   |
|     19       |      8       |    MOSI   |
|     21       |      7       |    MISO   |
|     23       |      9       |  SCLK/SCK |
|     24       |     10       |  CE0/SSEL |
|     39       |      2       |    GNT    |
|     27       |      6       |  GPIO0/SDA|
|     28       |      5       |  GPIO1/SCL|
 -----------------------------------------
Something like this :)


Download the 3310.py code from github https://github.com/OLIMEX/raspberrypi/tree/master/MOD-LCD-3310

Install missing python modules to Raspberri and enable spi via raspi-config --> Interfacing Options --> SPI

pip install termcolor RPi.GPIO

Execute code using old spi module


import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(0, GPIO.OUT)     #SDA -> LCD_C/#D
GPIO.setup(1, GPIO.OUT)     #SCL -> #LCD_RESET
GPIO.output(0, True)
GPIO.output(1, True)
from spi import SPI
lcd = SPI(0, 0)
lcd.msh = 1000000

#define some variables
SEND_CMD = 0
SEND_CHR = 1

LCD_X_RES = 84
LCD_Y_RES = 48

PIXEL_OFF = 0
PIXEL_ON = 1
PIXEL_XOR = 2

FONT_1X = 1
FONT_2X = 2

LCD_CACHE_SIZE = ((LCD_X_RES * LCD_Y_RES) / 8)



LcdMemIdx = 0
LcdMemory = [0x00] * LCD_CACHE_SIZE
LCD_START_LINE_ADDR = 64

SEND_CMD = 0
SEND_CHR = 1

def LCD_DC_HIGH():
    GPIO.output(0, True)
    return

def LCD_DC_LOW():
    GPIO.output(0, False)
    return

def LCDClear():
    #"Clear LCD"
    for i in range(LCD_CACHE_SIZE):
        LcdMemory[i] = 0x00
    return

def LCDReset():
    GPIO.output(1, False)
    time.sleep(0.05)
    GPIO.output(1, True)

def LCDUpdate():
    #"Update LCD memory"
    
    for y in range(6):
        LCDSend(0x80, SEND_CMD)
        LCDSend(0x40 | y, SEND_CMD)
        for x in range(84):
            LCDSend(LcdMemory[(y * 84) +x], SEND_CHR)
    return

def LCDSend(data, cd):
    #print
    if cd == SEND_CHR:
        LCD_DC_HIGH()
    else:
        LCD_DC_LOW()
        
    lcd.writebytes([data])    
    return
    
    
def LCDInit():
    #"Init LCD Controller"
    LCDReset()
    
    LCDSend(0x03, SEND_CMD)
    time.sleep(1)
    LCDSend( 0x21, SEND_CMD)                                        #LCD Extended Commands
    LCDSend( 0xC8, SEND_CMD)                                        #Set KCD Vop (contrast)
    LCDSend( 0x04 | int(not(not(LCD_START_LINE_ADDR & (1 << 6)))), SEND_CMD)   #Set Temp S6 for start line
    LCDSend( 0x40 | (LCD_START_LINE_ADDR & ((1<<6 0x08="" 0x0c="" 0x12="" 0x20="" 1:68="" addressing="" bias="" blank="" commands="" contrast="" def="" et="" extended="" for="" horizontal="" in="" lcd="" lcdclear="" lcdcontrast="" lcdsend="" lcdupdate="" line="" mode="" normal="" ontrast="" pre="" s="" send_cmd="" standard="" start="" temp="" vop="" x20="" x21="" x80="" xff="">




Code with SPIDEV:


import RPi.GPIO as GPIO
import time
import spidev
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(0, GPIO.OUT)     #SDA -> LCD_C/#D
GPIO.setup(1, GPIO.OUT)     #SCL -> #LCD_RESET
GPIO.output(0, True)
GPIO.output(1, True)

lcd = spidev.SpiDev()

lcd.open(0,0)
lcd.max_speed_hz = 1000000


#define some variables
SEND_CMD = 0
SEND_CHR = 1

LCD_X_RES = 84
LCD_Y_RES = 48

PIXEL_OFF = 0
PIXEL_ON = 1
PIXEL_XOR = 2

FONT_1X = 1
FONT_2X = 2

LCD_CACHE_SIZE = ((LCD_X_RES * LCD_Y_RES) / 8)



LcdMemIdx = 0
LcdMemory = [0x00] * LCD_CACHE_SIZE
LCD_START_LINE_ADDR = 64

SEND_CMD = 0
SEND_CHR = 1

def LCD_DC_HIGH():
    GPIO.output(0, True)
    return

def LCD_DC_LOW():
    GPIO.output(0, False)
    return

def LCDClear():
    #"Clear LCD"
    for i in range(LCD_CACHE_SIZE):
        LcdMemory[i] = 0x00
    return

def LCDReset():
    GPIO.output(1, False)
    time.sleep(0.05)
    GPIO.output(1, True)

def LCDUpdate():
    #"Update LCD memory"
    
    for y in range(6):
        LCDSend(0x80, SEND_CMD)
        LCDSend(0x40 | y, SEND_CMD)
        for x in range(84):
            LCDSend(LcdMemory[(y * 84) +x], SEND_CHR)
    return

def LCDSend(data, cd):
    #print
    if cd == SEND_CHR:
        LCD_DC_HIGH()
    else:
        LCD_DC_LOW()
        
    lcd.writebytes([data])    
    return
    
    
def LCDInit():
    #"Init LCD Controller"
    LCDReset()
    
    LCDSend(0x03, SEND_CMD)
    time.sleep(1)
    LCDSend( 0x21, SEND_CMD)                                        #LCD Extended Commands
    LCDSend( 0xC8, SEND_CMD)                                        #Set KCD Vop (contrast)
    LCDSend( 0x04 | int(not(not(LCD_START_LINE_ADDR & (1 << 6)))), SEND_CMD)   #Set Temp S6 for start line
    LCDSend( 0x40 | (LCD_START_LINE_ADDR & ((1<<6 0x08="" 0x0c="" 0x12="" 0x20="" 1:68="" __name__="=" addressing="" bias="" blank="" commands="" contrast="" def="" et="" extended="" for="" horizontal="" if="" in="" lcd="" lcdclear="" lcdcontrast="" lcdsend="" lcdupdate="" line="" main__="" mode="" normal="" ontrast="" pre="" s="" send_cmd="" standard="" start="" temp="" vop="" x20="" x21="" x80="" xff="">