Raspberry Pi and area drawing on ILI9325

In previous three articles, we managed to create a united interface for NJU and SSD based LCD. Today we will add another LCD, the most important one, with ILI9325 chip and 240×320 size.
This one brings a new way of drawing. Not on pages but on pixels and with colours.
Page drawing:
part one
part two
part three

Source @ GitHub

Planning

We need to create a new chip and communication driver. But we cannot use Page drawing algorithm so we need to create new. A pixel drawing.
But if you look closely, some function in the Page class are the same as with the pixel. What does it mean? Refactoring! Yey:)

Extraction

Our condensed code is in the screen.py file. We need to to the same as with previous LCDs, separate logic from wiring and put all in the separate module.
In the driver package, create a new package named ili9325 and in it files: gpio.py and ili9325.py.

I hit the problem with cmd_data function. It is a proxy to call both command and data. But our interface does not have it. Question is, leave it or change to two calls?
I think we should change it. It would give us twice the code in init function but we won’t break the Driver interface.

We also have a forced auto_flush option. I’m leaving it for now because we will check if a buffer has a sense for TFT.

Another not foreseen case was with enable pin. We have to implement enable attribute in driver commands to comply with the interface but we are ignoring its value.

The first step is done. Drivers are separated and we can write a seed for a test script, an ili.py:

from driver.ili9325.gpio import GPIO
from driver.ili9325.ili9325 import ILI9325
drv = GPIO()
o = ILI9325(240, 320, drv)

o.init()

Drawing class

Remember that we took some drawing functions from TFT proof of concept to Page class? We now have to use those functions. We could copy them again but we should keep with DRY (do-not-repeat-yourself).
Let’s create new drawing class called Area and we will move there functions for ILI chip. Next, we will create a Pixel class with common drawing functions. Both Page and Area would inherit it and overwrite if necessary.
This should clean up a mess a little:) To make it more clear let’s see the diagram:

[I]Driver           [I]Chip             Pixel
  |                    |                /   \ 
  |                    |             Page  Area   
  |                    |             /     /
  |-ssd1306/Spi        |-ssd1306----/     /
  |-nju6450/Gpio       |-nju6450----     /
  --ili9325/Gpio       --ili9325---------

 

After all copy and paste, the code was refactored.
To test it I extended ili.py with:

o.draw_circle(60, 15, 15)
o.draw_circle(53, 10, 3)
o.draw_circle(67, 10, 3)
o.draw_arc(60, 15, 10, 45, 135)
o.draw_line(60, 12, 57, 17)
o.draw_line(60, 12, 63, 17)
o.draw_arc(60, 15, 3, 45, 135)

o.fill_rect(2, 2, 42, 29)
o.fill_rect(119, 2, 109, 12)
o.fill_rect(119, 17, 109, 19)

o.draw_rect(77, 6, 105, 16)
o.fill_rect(77, 16, 105, 25)

This is the same code that was used last time on NJU display. And it worked:) But we have a black background colour so it is almost invisible. Let’s add colour support to chip class.

Colours

This one is tricky because if we add colour to Chip interface we need to implement it in page drawing. And there, we have only 1 colour, enabled:)
We will try and do something with it. But first, we need to add colour selection for current LCD or maybe to Pixel class? Then in drivers, we could only write functions to convert selected colour to available on display.
We need two new abstract methods in Chip class to force us to create conversions for each chip implementation:

    @abc.abstractmethod
    def _converted_background_color(self):
        """convert RGB background to available color"""
        pass

    @abc.abstractmethod
    def _converted_color(self):
        """convert RGB color to available color"""
        pass

But with this SSD and NJU fails.We need to implement those functions there:

    def _converted_background_color(self):
        """convert RGB background to available color"""
        return 1;

    def _converted_color(self):
        """convert RGB color to available color"""
        return 1

Hopefully, this is enough. I do not have those LCDs hooked to current RPi. We need to confirm this later.
The last thing is to add colour properties to Chip interface:

    @property
    def color(self):
        return self.options['color']

    @color.setter
    def color(self, rgb):
        self.options['color'] = {
            'R': rgb[0], 'G': rgb[1], 'B': rgb[2]
        }

    @property
    def background_color(self):
        return self.options['background_color']

    @background_color.setter
    def background_color(self, rgb):
        self.options['background_color'] = {
            'R': rgb[0], 'G': rgb[1], 'B': rgb[2]
        }

With this we can improve a demo script by adding colours:

o.color = (10, 230, 200)
o.draw_circle(60, 15, 15)
o.color = (0, 250, 20)
o.draw_circle(53, 10, 3)
o.draw_circle(67, 10, 3)
o.color = (250, 150, 20)
o.draw_arc(60, 15, 10, 45, 135)
o.color = (10, 230, 200)
o.draw_line(60, 12, 57, 17)
o.draw_line(60, 12, 63, 17)
o.draw_arc(60, 15, 3, 45, 135)

o.background_color = (200, 0, 120)
o.fill_rect(2, 2, 42, 29)
o.background_color = (20, 200, 120)
o.fill_rect(119, 2, 109, 12)
o.fill_rect(119, 17, 109, 19)

o.background_color = (255, 255, 255)
o.fill_rect(77, 6, 105, 16)
o.background_color = (255, 0, 0)
o.fill_rect(77, 16, 105, 25)

And the result (it is so hard to take a picture:/):

Summary

Another post where everything went smoothly and friendly.
We added ILI9325 LCD driver to our package and GPIO connection driver for it.
With this, all LCDs we played with have one interface. Very useful:)

Advertisements

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s