I have a Raspberry Pi with an Display and Buttons (here). And I have a program, that uses the Library (in the appendix) from the Display. The program creates a home screen with dynamic apps. Each app consists of a folder in an “Apps” folder. This contains a 25×25 pixel PNG file, which is required for the home screen, and a .py file, which contains the program code. The newest code from the main program is this;
<code>from PIL import Image, ImageDraw, ImageFont
import disp # a self-built driver to solve the problems with the double assignment.
import SH1106 # the library, in the appendix
disp.DispSingleton.disp = SH1106.SH1106() # initialize the driver
Disp = disp.DispSingleton()
# here I have deleted some lines of code that are not important for the question. It
def update_display(): # this creates a homescreen
image = Image.new('1', (Disp.width, Disp.height), "WHITE")
draw = ImageDraw.Draw(image)
draw_icons(draw, program_files, current_page, selected_icon)
def run_script(script_file):
subprocess.run(["python3", script_file])
if Read.Joystick_Up == 1:
selected_icon = (selected_icon - 4) % ICONS_PER_PAGE
selected_icon += ICONS_PER_PAGE
elif Read.Joystick_Down == 1:
# as with Read.Joystick_Up, with slightly different values.
elif Read.Joystick_Left == 1:
# as with Read.Joystick_Up, with slightly different values.
elif Read.Joystick_Right == 1:
# as with Read.Joystick_Up, with slightly different values.
elif Read.Joystick_Press == 1:
program_index = current_page * ICONS_PER_PAGE + selected_icon
if program_index < len(program_files): # start a app from the homescreen
print('33[94m' + "program", program_files[program_index], "started" + '33[0m')
print("start thread:", program_files[program_index]['script_file'],)
x = threading.Thread(target=run_script, args=(program_files[program_index]['script_file'],))
print('33[94m' + "program", program_files[program_index], "stopped" + '33[0m')
current_page = (current_page - 1) % total_pages
current_page += total_pages
current_page = (current_page + 1) % total_pages
<code>from PIL import Image, ImageDraw, ImageFont
import disp # a self-built driver to solve the problems with the double assignment.
import SH1106 # the library, in the appendix
disp.DispSingleton.disp = SH1106.SH1106() # initialize the driver
Disp = disp.DispSingleton()
Read = disp.Read(Disp)
# here I have deleted some lines of code that are not important for the question. It
def update_display(): # this creates a homescreen
image = Image.new('1', (Disp.width, Disp.height), "WHITE")
draw = ImageDraw.Draw(image)
draw_icons(draw, program_files, current_page, selected_icon)
Disp.Update(image)
def run_script(script_file):
import subprocess
subprocess.run(["python3", script_file])
# Event-Loop
while True:
update_display()
Read.update()
if Read.Joystick_Up == 1:
selected_icon = (selected_icon - 4) % ICONS_PER_PAGE
if selected_icon < 0:
selected_icon += ICONS_PER_PAGE
time.sleep(0.2)
elif Read.Joystick_Down == 1:
# as with Read.Joystick_Up, with slightly different values.
elif Read.Joystick_Left == 1:
# as with Read.Joystick_Up, with slightly different values.
elif Read.Joystick_Right == 1:
# as with Read.Joystick_Up, with slightly different values.
elif Read.Joystick_Press == 1:
program_index = current_page * ICONS_PER_PAGE + selected_icon
if program_index < len(program_files): # start a app from the homescreen
print('33[94m' + "program", program_files[program_index], "started" + '33[0m')
# start program and wait
print("start thread:", program_files[program_index]['script_file'],)
x = threading.Thread(target=run_script, args=(program_files[program_index]['script_file'],))
print(x)
x.start()
while True:
if x.run == False:
break
print('33[94m' + "program", program_files[program_index], "stopped" + '33[0m')
time.sleep(0.2)
elif Read.Key_1 == 1:
current_page = (current_page - 1) % total_pages
if current_page < 0:
current_page += total_pages
time.sleep(0.2)
elif Read.Key_2 == 1:
current_page = (current_page + 1) % total_pages
time.sleep(0.2)
</code>
from PIL import Image, ImageDraw, ImageFont
import disp # a self-built driver to solve the problems with the double assignment.
import SH1106 # the library, in the appendix
disp.DispSingleton.disp = SH1106.SH1106() # initialize the driver
Disp = disp.DispSingleton()
Read = disp.Read(Disp)
# here I have deleted some lines of code that are not important for the question. It
def update_display(): # this creates a homescreen
image = Image.new('1', (Disp.width, Disp.height), "WHITE")
draw = ImageDraw.Draw(image)
draw_icons(draw, program_files, current_page, selected_icon)
Disp.Update(image)
def run_script(script_file):
import subprocess
subprocess.run(["python3", script_file])
# Event-Loop
while True:
update_display()
Read.update()
if Read.Joystick_Up == 1:
selected_icon = (selected_icon - 4) % ICONS_PER_PAGE
if selected_icon < 0:
selected_icon += ICONS_PER_PAGE
time.sleep(0.2)
elif Read.Joystick_Down == 1:
# as with Read.Joystick_Up, with slightly different values.
elif Read.Joystick_Left == 1:
# as with Read.Joystick_Up, with slightly different values.
elif Read.Joystick_Right == 1:
# as with Read.Joystick_Up, with slightly different values.
elif Read.Joystick_Press == 1:
program_index = current_page * ICONS_PER_PAGE + selected_icon
if program_index < len(program_files): # start a app from the homescreen
print('33[94m' + "program", program_files[program_index], "started" + '33[0m')
# start program and wait
print("start thread:", program_files[program_index]['script_file'],)
x = threading.Thread(target=run_script, args=(program_files[program_index]['script_file'],))
print(x)
x.start()
while True:
if x.run == False:
break
print('33[94m' + "program", program_files[program_index], "stopped" + '33[0m')
time.sleep(0.2)
elif Read.Key_1 == 1:
current_page = (current_page - 1) % total_pages
if current_page < 0:
current_page += total_pages
time.sleep(0.2)
elif Read.Key_2 == 1:
current_page = (current_page + 1) % total_pages
time.sleep(0.2)
This is the disp file (disp.py), that should solve the problems with the double assignment;
<code>class DispSingleton(): # Both the program for the homescreen and the running program should access the same data to prevent duplicate use.
self.width = self.disp.width
self.height = self.disp.height
self.disp.ShowImage(self.disp.getbuffer(image))
def __init__(self, disp_instance):
self.disp_instance = disp_instance
self.Joystick_Up = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_UP_PIN)
self.Joystick_Down = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_DOWN_PIN)
self.Joystick_Left = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_LEFT_PIN)
self.Joystick_Right = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_RIGHT_PIN)
self.Joystick_Press = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_PRESS_PIN)
self.Key_1 = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY1_PIN)
self.Key_2 = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY2_PIN)
self.Key_3 = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY3_PIN)
<code>class DispSingleton(): # Both the program for the homescreen and the running program should access the same data to prevent duplicate use.
def __init__(self):
self.disp.Init()
self.width = self.disp.width
self.height = self.disp.height
def Update(self, image):
self.disp.ShowImage(self.disp.getbuffer(image))
def Clear(self):
self.disp.clear()
class Read:
def __init__(self, disp_instance):
self.disp_instance = disp_instance
self.update()
def update(self):
self.Joystick_Up = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_UP_PIN)
self.Joystick_Down = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_DOWN_PIN)
self.Joystick_Left = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_LEFT_PIN)
self.Joystick_Right = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_RIGHT_PIN)
self.Joystick_Press = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_PRESS_PIN)
self.Key_1 = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY1_PIN)
self.Key_2 = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY2_PIN)
self.Key_3 = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY3_PIN)
</code>
class DispSingleton(): # Both the program for the homescreen and the running program should access the same data to prevent duplicate use.
def __init__(self):
self.disp.Init()
self.width = self.disp.width
self.height = self.disp.height
def Update(self, image):
self.disp.ShowImage(self.disp.getbuffer(image))
def Clear(self):
self.disp.clear()
class Read:
def __init__(self, disp_instance):
self.disp_instance = disp_instance
self.update()
def update(self):
self.Joystick_Up = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_UP_PIN)
self.Joystick_Down = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_DOWN_PIN)
self.Joystick_Left = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_LEFT_PIN)
self.Joystick_Right = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_RIGHT_PIN)
self.Joystick_Press = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY_PRESS_PIN)
self.Key_1 = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY1_PIN)
self.Key_2 = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY2_PIN)
self.Key_3 = self.disp_instance.disp.RPI.digital_read(self.disp_instance.disp.RPI.GPIO_KEY3_PIN)
and a example of the code from a app;
from PIL import Image, ImageDraw
sys.path.append(os.path.expanduser('~/Display'))
image = Image.new('1', (Disp.width, Disp.height), "WHITE")
draw = ImageDraw.Draw(image)
print('33[92m' + "Home initialized" + '33[0m')
draw.polygon([(20, 20), (30, 2), (40, 20)], outline=255, fill=0)
home = Home() # initialize Home
<code>import os
import sys
from PIL import Image, ImageDraw
sys.path.append(os.path.expanduser('~/Display'))
import home
Disp = home.Disp
Read = home.Read
image = Image.new('1', (Disp.width, Disp.height), "WHITE")
draw = ImageDraw.Draw(image)
class Home:
def __init__(self):
print('33[92m' + "Home initialized" + '33[0m')
draw.polygon([(20, 20), (30, 2), (40, 20)], outline=255, fill=0)
Disp.Update(image)
home = Home() # initialize Home
</code>
import os
import sys
from PIL import Image, ImageDraw
sys.path.append(os.path.expanduser('~/Display'))
import home
Disp = home.Disp
Read = home.Read
image = Image.new('1', (Disp.width, Disp.height), "WHITE")
draw = ImageDraw.Draw(image)
class Home:
def __init__(self):
print('33[92m' + "Home initialized" + '33[0m')
draw.polygon([(20, 20), (30, 2), (40, 20)], outline=255, fill=0)
Disp.Update(image)
home = Home() # initialize Home
When I run the program, everything works fine. But when I select an application and click on “Run”, this error message appears;
<code>start thread: /home/laurin/Display/Apps/lamps/code.py
<Thread(Thread-2 (run_script), initial)>
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gpiozero/pins/pi.py", line 408, in pin
KeyError: PinInfo(number=22, name='GPIO25', names=frozenset({'J8:22', '25', 'BOARD22', 'WPI6', 'GPIO25', 25, 'BCM25'}), pull='', row=11, col=2, interfaces=frozenset({'', 'sdio', 'dpi', 'jtag', 'gpio'}))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/laurin/Display/Apps/lamps/code.py", line 7, in <module>
File "/home/laurin/Display/home.py", line 145, in <module>
disp.DispSingleton.disp = SH1106.SH1106()
File "/home/laurin/Display/Lib/SH1106.py", line 16, in __init__
self.RPI = config.RaspberryPi()
File "/home/laurin/Display/Lib/config.py", line 67, in __init__
self.GPIO_RST_PIN = self.gpio_mode(RST_PIN,self.OUTPUT)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/laurin/Display/Lib/config.py", line 88, in gpio_mode
return DigitalOutputDevice(Pin,active_high = True,initial_value =False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/gpiozero/devices.py", line 103, in __call__
self = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/gpiozero/output_devices.py", line 192, in __init__
super().__init__(pin, active_high=active_high,
File "/usr/lib/python3/dist-packages/gpiozero/output_devices.py", line 74, in __init__
super().__init__(pin, pin_factory=pin_factory)
File "/usr/lib/python3/dist-packages/gpiozero/mixins.py", line 75, in __init__
super().__init__(*args, **kwargs)
File "/usr/lib/python3/dist-packages/gpiozero/devices.py", line 549, in __init__
pin = self.pin_factory.pin(pin)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/gpiozero/pins/pi.py", line 410, in pin
pin = self.pin_class(self, info)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/gpiozero/pins/lgpio.py", line 126, in __init__
File "/usr/lib/python3/dist-packages/lgpio.py", line 755, in gpio_claim_input
return _u2i(_lgpio._gpio_claim_input(handle&0xffff, lFlags, gpio))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/lgpio.py", line 458, in _u2i
raise error(error_text(v))
<code>start thread: /home/laurin/Display/Apps/lamps/code.py
<Thread(Thread-2 (run_script), initial)>
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gpiozero/pins/pi.py", line 408, in pin
pin = self.pins[info]
~~~~~~~~~^^^^^^
KeyError: PinInfo(number=22, name='GPIO25', names=frozenset({'J8:22', '25', 'BOARD22', 'WPI6', 'GPIO25', 25, 'BCM25'}), pull='', row=11, col=2, interfaces=frozenset({'', 'sdio', 'dpi', 'jtag', 'gpio'}))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/laurin/Display/Apps/lamps/code.py", line 7, in <module>
import home
File "/home/laurin/Display/home.py", line 145, in <module>
disp.DispSingleton.disp = SH1106.SH1106()
^^^^^^^^^^^^^^^
File "/home/laurin/Display/Lib/SH1106.py", line 16, in __init__
self.RPI = config.RaspberryPi()
^^^^^^^^^^^^^^^^^^^^
File "/home/laurin/Display/Lib/config.py", line 67, in __init__
self.GPIO_RST_PIN = self.gpio_mode(RST_PIN,self.OUTPUT)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/laurin/Display/Lib/config.py", line 88, in gpio_mode
return DigitalOutputDevice(Pin,active_high = True,initial_value =False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/gpiozero/devices.py", line 103, in __call__
self = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/gpiozero/output_devices.py", line 192, in __init__
super().__init__(pin, active_high=active_high,
File "/usr/lib/python3/dist-packages/gpiozero/output_devices.py", line 74, in __init__
super().__init__(pin, pin_factory=pin_factory)
File "/usr/lib/python3/dist-packages/gpiozero/mixins.py", line 75, in __init__
super().__init__(*args, **kwargs)
File "/usr/lib/python3/dist-packages/gpiozero/devices.py", line 549, in __init__
pin = self.pin_factory.pin(pin)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/gpiozero/pins/pi.py", line 410, in pin
pin = self.pin_class(self, info)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/gpiozero/pins/lgpio.py", line 126, in __init__
lgpio.gpio_claim_input(
File "/usr/lib/python3/dist-packages/lgpio.py", line 755, in gpio_claim_input
return _u2i(_lgpio._gpio_claim_input(handle&0xffff, lFlags, gpio))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/lgpio.py", line 458, in _u2i
raise error(error_text(v))
lgpio.error: 'GPIO busy'
</code>
start thread: /home/laurin/Display/Apps/lamps/code.py
<Thread(Thread-2 (run_script), initial)>
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gpiozero/pins/pi.py", line 408, in pin
pin = self.pins[info]
~~~~~~~~~^^^^^^
KeyError: PinInfo(number=22, name='GPIO25', names=frozenset({'J8:22', '25', 'BOARD22', 'WPI6', 'GPIO25', 25, 'BCM25'}), pull='', row=11, col=2, interfaces=frozenset({'', 'sdio', 'dpi', 'jtag', 'gpio'}))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/laurin/Display/Apps/lamps/code.py", line 7, in <module>
import home
File "/home/laurin/Display/home.py", line 145, in <module>
disp.DispSingleton.disp = SH1106.SH1106()
^^^^^^^^^^^^^^^
File "/home/laurin/Display/Lib/SH1106.py", line 16, in __init__
self.RPI = config.RaspberryPi()
^^^^^^^^^^^^^^^^^^^^
File "/home/laurin/Display/Lib/config.py", line 67, in __init__
self.GPIO_RST_PIN = self.gpio_mode(RST_PIN,self.OUTPUT)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/laurin/Display/Lib/config.py", line 88, in gpio_mode
return DigitalOutputDevice(Pin,active_high = True,initial_value =False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/gpiozero/devices.py", line 103, in __call__
self = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/gpiozero/output_devices.py", line 192, in __init__
super().__init__(pin, active_high=active_high,
File "/usr/lib/python3/dist-packages/gpiozero/output_devices.py", line 74, in __init__
super().__init__(pin, pin_factory=pin_factory)
File "/usr/lib/python3/dist-packages/gpiozero/mixins.py", line 75, in __init__
super().__init__(*args, **kwargs)
File "/usr/lib/python3/dist-packages/gpiozero/devices.py", line 549, in __init__
pin = self.pin_factory.pin(pin)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/gpiozero/pins/pi.py", line 410, in pin
pin = self.pin_class(self, info)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/gpiozero/pins/lgpio.py", line 126, in __init__
lgpio.gpio_claim_input(
File "/usr/lib/python3/dist-packages/lgpio.py", line 755, in gpio_claim_input
return _u2i(_lgpio._gpio_claim_input(handle&0xffff, lFlags, gpio))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/lgpio.py", line 458, in _u2i
raise error(error_text(v))
lgpio.error: 'GPIO busy'
what I have tried:
- Transfer the Disp file when creating the new app.
- Both programs pull the data from the same source so that it is only created once. (Singleton, See above)
Restrict access from Home to the GPIO pins while the program is running.
what I have found and tried:
- What is the best way of implementing singleton in Python, method 2
How can I solve this problem?
Thank you.
The Librarys:
SH1106.py;
Device_SPI = config.Device_SPI
Device_I2C = config.Device_I2C
LCD_WIDTH = 128 #LCD width
LCD_HEIGHT = 64 #LCD height
self.RPI = config.RaspberryPi()
self._dc = self.RPI.GPIO_DC_PIN
self._rst = self.RPI.GPIO_RST_PIN
self.Device = self.RPI.Device
""" Write register address and data """
if(self.Device == Device_SPI):
self.RPI.digital_write(self._dc,False)
self.RPI.spi_writebyte([cmd])
self.RPI.i2c_writebyte(0x00, cmd)
# GPIO.output(self._dc, GPIO.HIGH)
# config.spi_writebyte([val])
self.RPI = config.RaspberryPi()
self._dc = self.RPI.GPIO_DC_PIN
self._rst = self.RPI.GPIO_RST_PIN
self.Device = self.RPI.Device
if (self.RPI.module_init() != 0):
self.command(0xAE);#--turn off oled panel
self.command(0x02);#---set low column address
self.command(0x10);#---set high column address
self.command(0x40);#--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
self.command(0x81);#--set contrast control register
self.command(0xA0);#--Set SEG/Column Mapping
self.command(0xC0);#Set COM/Row Scan Direction
self.command(0xA6);#--set normal display
self.command(0xA8);#--set multiplex ratio(1 to 64)
self.command(0x3F);#--1/64 duty
self.command(0xD3);#-set display offset Shift Mapping RAM Counter (0x00~0x3F)
self.command(0x00);#-not offset
self.command(0xd5);#--set display clock divide ratio/oscillator frequency
self.command(0x80);#--set divide ratio, Set Clock as 100 Frames/Sec
self.command(0xD9);#--set pre-charge period
self.command(0xF1);#Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
self.command(0xDA);#--set com pins hardware configuration
self.command(0xDB);#--set vcomh
self.command(0x40);#Set VCOM Deselect Level
self.command(0x20);#-Set Page Addressing Mode (0x00/0x01/0x02)
self.command(0xA4);# Disable Entire Display On (0xa4/0xa5)
self.command(0xA6);# Disable Inverse Display On (0xa6/a7)
self.command(0xAF);#--turn on oled panel
if (self.RPI.module_init() != 0):
self.command(0xAE);#--turn off oled panel
self.command(0x02);#---set low column address
self.command(0x10);#---set high column address
self.command(0x40);#--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
self.command(0x81);#--set contrast control register
self.command(0xA0);#--Set SEG/Column Mapping
self.command(0xC0);#Set COM/Row Scan Direction
self.command(0xA6);#--set normal display
self.command(0xA8);#--set multiplex ratio(1 to 64)
self.command(0x3F);#--1/64 duty
self.command(0xD3);#-set display offset Shift Mapping RAM Counter (0x00~0x3F)
self.command(0x00);#-not offset
self.command(0xd5);#--set display clock divide ratio/oscillator frequency
self.command(0x80);#--set divide ratio, Set Clock as 100 Frames/Sec
self.command(0xD9);#--set pre-charge period
self.command(0xF1);#Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
self.command(0xDA);#--set com pins hardware configuration
self.command(0xDB);#--set vcomh
self.command(0x40);#Set VCOM Deselect Level
self.command(0x20);#-Set Page Addressing Mode (0x00/0x01/0x02)
self.command(0xA4);# Disable Entire Display On (0xa4/0xa5)
self.command(0xA6);# Disable Inverse Display On (0xa6/a7)
self.command(0xAF);#--turn on oled panel
self.RPI.digital_write(self._rst,True)
self.RPI.digital_write(self._rst,False)
self.RPI.digital_write(self._rst,True)
def getbuffer(self, image):
# print "bufsiz = ",(self.width/8) * self.height
buf = [0xFF] * ((self.width//8) * self.height)
image_monocolor = image.convert('1')
imwidth, imheight = image_monocolor.size
pixels = image_monocolor.load()
# print "imwidth = %d, imheight = %d",imwidth,imheight
if(imwidth == self.width and imheight == self.height):
for y in range(imheight):
# Set the bits for the column of pixels at the current position.
buf[x + (y // 8) * self.width] &= ~(1 << (y % 8))
# print x,y,x + (y * self.width)/8,buf[(x + y * self.width) / 8]
elif(imwidth == self.height and imheight == self.width):
for y in range(imheight):
newy = self.height - x - 1
buf[(newx + (newy // 8 )*self.width) ] &= ~(1 << (y % 8))
# def ShowImage(self,Image):
# GPIO.output(self._dc, GPIO.HIGH);
# for i in range(0,self.width * self.height/8):
# config.spi_writebyte([~Image[i]])
def ShowImage(self, pBuf):
self.command(0xB0 + page)
# set low column address #
# set high column address #
if(self.Device == Device_SPI):
self.RPI.digital_write(self._dc,True)
for i in range(0,self.width):#for(int i=0;i<self.width; i++)
if(self.Device == Device_SPI):
self.RPI.spi_writebyte([~pBuf[i+self.width*page]]);
self.RPI.i2c_writebyte(0x40, ~pBuf[i+self.width*page])
"""Clear contents of image buffer"""
_buffer = [0xff]*(self.width * self.height//8)
#print "%d",_buffer[i:i+4096]
<code>import config
import time
import numpy as np
Device_SPI = config.Device_SPI
Device_I2C = config.Device_I2C
LCD_WIDTH = 128 #LCD width
LCD_HEIGHT = 64 #LCD height
class SH1106(object):
def __init__(self):
self.width = LCD_WIDTH
self.height = LCD_HEIGHT
#Initialize DC RST pin
self.RPI = config.RaspberryPi()
self._dc = self.RPI.GPIO_DC_PIN
self._rst = self.RPI.GPIO_RST_PIN
self.Device = self.RPI.Device
""" Write register address and data """
def command(self, cmd):
if(self.Device == Device_SPI):
self.RPI.digital_write(self._dc,False)
self.RPI.spi_writebyte([cmd])
else:
self.RPI.i2c_writebyte(0x00, cmd)
# def data(self, val):
# GPIO.output(self._dc, GPIO.HIGH)
# config.spi_writebyte([val])
def Restart(self):
# __init__
self.width = LCD_WIDTH
self.height = LCD_HEIGHT
#Initialize DC RST pin
self.RPI = config.RaspberryPi()
self._dc = self.RPI.GPIO_DC_PIN
self._rst = self.RPI.GPIO_RST_PIN
self.Device = self.RPI.Device
# Init
if (self.RPI.module_init() != 0):
return -1
"""Initialize dispaly"""
self.reset()
self.command(0xAE);#--turn off oled panel
self.command(0x02);#---set low column address
self.command(0x10);#---set high column address
self.command(0x40);#--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
self.command(0x81);#--set contrast control register
self.command(0xA0);#--Set SEG/Column Mapping
self.command(0xC0);#Set COM/Row Scan Direction
self.command(0xA6);#--set normal display
self.command(0xA8);#--set multiplex ratio(1 to 64)
self.command(0x3F);#--1/64 duty
self.command(0xD3);#-set display offset Shift Mapping RAM Counter (0x00~0x3F)
self.command(0x00);#-not offset
self.command(0xd5);#--set display clock divide ratio/oscillator frequency
self.command(0x80);#--set divide ratio, Set Clock as 100 Frames/Sec
self.command(0xD9);#--set pre-charge period
self.command(0xF1);#Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
self.command(0xDA);#--set com pins hardware configuration
self.command(0x12);
self.command(0xDB);#--set vcomh
self.command(0x40);#Set VCOM Deselect Level
self.command(0x20);#-Set Page Addressing Mode (0x00/0x01/0x02)
self.command(0x02);#
self.command(0xA4);# Disable Entire Display On (0xa4/0xa5)
self.command(0xA6);# Disable Inverse Display On (0xa6/a7)
time.sleep(0.1)
self.command(0xAF);#--turn on oled panel
def Init(self):
if (self.RPI.module_init() != 0):
return -1
"""Initialize dispaly"""
self.reset()
self.command(0xAE);#--turn off oled panel
self.command(0x02);#---set low column address
self.command(0x10);#---set high column address
self.command(0x40);#--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
self.command(0x81);#--set contrast control register
self.command(0xA0);#--Set SEG/Column Mapping
self.command(0xC0);#Set COM/Row Scan Direction
self.command(0xA6);#--set normal display
self.command(0xA8);#--set multiplex ratio(1 to 64)
self.command(0x3F);#--1/64 duty
self.command(0xD3);#-set display offset Shift Mapping RAM Counter (0x00~0x3F)
self.command(0x00);#-not offset
self.command(0xd5);#--set display clock divide ratio/oscillator frequency
self.command(0x80);#--set divide ratio, Set Clock as 100 Frames/Sec
self.command(0xD9);#--set pre-charge period
self.command(0xF1);#Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
self.command(0xDA);#--set com pins hardware configuration
self.command(0x12);
self.command(0xDB);#--set vcomh
self.command(0x40);#Set VCOM Deselect Level
self.command(0x20);#-Set Page Addressing Mode (0x00/0x01/0x02)
self.command(0x02);#
self.command(0xA4);# Disable Entire Display On (0xa4/0xa5)
self.command(0xA6);# Disable Inverse Display On (0xa6/a7)
time.sleep(0.1)
self.command(0xAF);#--turn on oled panel
def reset(self):
"""Reset the display"""
self.RPI.digital_write(self._rst,True)
time.sleep(0.1)
self.RPI.digital_write(self._rst,False)
time.sleep(0.1)
self.RPI.digital_write(self._rst,True)
time.sleep(0.1)
def getbuffer(self, image):
# print "bufsiz = ",(self.width/8) * self.height
buf = [0xFF] * ((self.width//8) * self.height)
image_monocolor = image.convert('1')
imwidth, imheight = image_monocolor.size
pixels = image_monocolor.load()
# print "imwidth = %d, imheight = %d",imwidth,imheight
if(imwidth == self.width and imheight == self.height):
# print ("Vertical")
for y in range(imheight):
for x in range(imwidth):
# Set the bits for the column of pixels at the current position.
if pixels[x, y] == 0:
buf[x + (y // 8) * self.width] &= ~(1 << (y % 8))
# print x,y,x + (y * self.width)/8,buf[(x + y * self.width) / 8]
elif(imwidth == self.height and imheight == self.width):
# print ("Vertical")
for y in range(imheight):
for x in range(imwidth):
newx = y
newy = self.height - x - 1
if pixels[x, y] == 0:
buf[(newx + (newy // 8 )*self.width) ] &= ~(1 << (y % 8))
return buf
# def ShowImage(self,Image):
# self.SetWindows()
# GPIO.output(self._dc, GPIO.HIGH);
# for i in range(0,self.width * self.height/8):
# config.spi_writebyte([~Image[i]])
def ShowImage(self, pBuf):
for page in range(0,8):
# set page address #
self.command(0xB0 + page)
# set low column address #
self.command(0x02);
# set high column address #
self.command(0x10);
# write data #
# time.sleep(0.01)
if(self.Device == Device_SPI):
self.RPI.digital_write(self._dc,True)
for i in range(0,self.width):#for(int i=0;i<self.width; i++)
if(self.Device == Device_SPI):
self.RPI.spi_writebyte([~pBuf[i+self.width*page]]);
else :
self.RPI.i2c_writebyte(0x40, ~pBuf[i+self.width*page])
def clear(self):
"""Clear contents of image buffer"""
_buffer = [0xff]*(self.width * self.height//8)
self.ShowImage(_buffer)
#print "%d",_buffer[i:i+4096]
</code>
import config
import time
import numpy as np
Device_SPI = config.Device_SPI
Device_I2C = config.Device_I2C
LCD_WIDTH = 128 #LCD width
LCD_HEIGHT = 64 #LCD height
class SH1106(object):
def __init__(self):
self.width = LCD_WIDTH
self.height = LCD_HEIGHT
#Initialize DC RST pin
self.RPI = config.RaspberryPi()
self._dc = self.RPI.GPIO_DC_PIN
self._rst = self.RPI.GPIO_RST_PIN
self.Device = self.RPI.Device
""" Write register address and data """
def command(self, cmd):
if(self.Device == Device_SPI):
self.RPI.digital_write(self._dc,False)
self.RPI.spi_writebyte([cmd])
else:
self.RPI.i2c_writebyte(0x00, cmd)
# def data(self, val):
# GPIO.output(self._dc, GPIO.HIGH)
# config.spi_writebyte([val])
def Restart(self):
# __init__
self.width = LCD_WIDTH
self.height = LCD_HEIGHT
#Initialize DC RST pin
self.RPI = config.RaspberryPi()
self._dc = self.RPI.GPIO_DC_PIN
self._rst = self.RPI.GPIO_RST_PIN
self.Device = self.RPI.Device
# Init
if (self.RPI.module_init() != 0):
return -1
"""Initialize dispaly"""
self.reset()
self.command(0xAE);#--turn off oled panel
self.command(0x02);#---set low column address
self.command(0x10);#---set high column address
self.command(0x40);#--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
self.command(0x81);#--set contrast control register
self.command(0xA0);#--Set SEG/Column Mapping
self.command(0xC0);#Set COM/Row Scan Direction
self.command(0xA6);#--set normal display
self.command(0xA8);#--set multiplex ratio(1 to 64)
self.command(0x3F);#--1/64 duty
self.command(0xD3);#-set display offset Shift Mapping RAM Counter (0x00~0x3F)
self.command(0x00);#-not offset
self.command(0xd5);#--set display clock divide ratio/oscillator frequency
self.command(0x80);#--set divide ratio, Set Clock as 100 Frames/Sec
self.command(0xD9);#--set pre-charge period
self.command(0xF1);#Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
self.command(0xDA);#--set com pins hardware configuration
self.command(0x12);
self.command(0xDB);#--set vcomh
self.command(0x40);#Set VCOM Deselect Level
self.command(0x20);#-Set Page Addressing Mode (0x00/0x01/0x02)
self.command(0x02);#
self.command(0xA4);# Disable Entire Display On (0xa4/0xa5)
self.command(0xA6);# Disable Inverse Display On (0xa6/a7)
time.sleep(0.1)
self.command(0xAF);#--turn on oled panel
def Init(self):
if (self.RPI.module_init() != 0):
return -1
"""Initialize dispaly"""
self.reset()
self.command(0xAE);#--turn off oled panel
self.command(0x02);#---set low column address
self.command(0x10);#---set high column address
self.command(0x40);#--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
self.command(0x81);#--set contrast control register
self.command(0xA0);#--Set SEG/Column Mapping
self.command(0xC0);#Set COM/Row Scan Direction
self.command(0xA6);#--set normal display
self.command(0xA8);#--set multiplex ratio(1 to 64)
self.command(0x3F);#--1/64 duty
self.command(0xD3);#-set display offset Shift Mapping RAM Counter (0x00~0x3F)
self.command(0x00);#-not offset
self.command(0xd5);#--set display clock divide ratio/oscillator frequency
self.command(0x80);#--set divide ratio, Set Clock as 100 Frames/Sec
self.command(0xD9);#--set pre-charge period
self.command(0xF1);#Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
self.command(0xDA);#--set com pins hardware configuration
self.command(0x12);
self.command(0xDB);#--set vcomh
self.command(0x40);#Set VCOM Deselect Level
self.command(0x20);#-Set Page Addressing Mode (0x00/0x01/0x02)
self.command(0x02);#
self.command(0xA4);# Disable Entire Display On (0xa4/0xa5)
self.command(0xA6);# Disable Inverse Display On (0xa6/a7)
time.sleep(0.1)
self.command(0xAF);#--turn on oled panel
def reset(self):
"""Reset the display"""
self.RPI.digital_write(self._rst,True)
time.sleep(0.1)
self.RPI.digital_write(self._rst,False)
time.sleep(0.1)
self.RPI.digital_write(self._rst,True)
time.sleep(0.1)
def getbuffer(self, image):
# print "bufsiz = ",(self.width/8) * self.height
buf = [0xFF] * ((self.width//8) * self.height)
image_monocolor = image.convert('1')
imwidth, imheight = image_monocolor.size
pixels = image_monocolor.load()
# print "imwidth = %d, imheight = %d",imwidth,imheight
if(imwidth == self.width and imheight == self.height):
# print ("Vertical")
for y in range(imheight):
for x in range(imwidth):
# Set the bits for the column of pixels at the current position.
if pixels[x, y] == 0:
buf[x + (y // 8) * self.width] &= ~(1 << (y % 8))
# print x,y,x + (y * self.width)/8,buf[(x + y * self.width) / 8]
elif(imwidth == self.height and imheight == self.width):
# print ("Vertical")
for y in range(imheight):
for x in range(imwidth):
newx = y
newy = self.height - x - 1
if pixels[x, y] == 0:
buf[(newx + (newy // 8 )*self.width) ] &= ~(1 << (y % 8))
return buf
# def ShowImage(self,Image):
# self.SetWindows()
# GPIO.output(self._dc, GPIO.HIGH);
# for i in range(0,self.width * self.height/8):
# config.spi_writebyte([~Image[i]])
def ShowImage(self, pBuf):
for page in range(0,8):
# set page address #
self.command(0xB0 + page)
# set low column address #
self.command(0x02);
# set high column address #
self.command(0x10);
# write data #
# time.sleep(0.01)
if(self.Device == Device_SPI):
self.RPI.digital_write(self._dc,True)
for i in range(0,self.width):#for(int i=0;i<self.width; i++)
if(self.Device == Device_SPI):
self.RPI.spi_writebyte([~pBuf[i+self.width*page]]);
else :
self.RPI.i2c_writebyte(0x40, ~pBuf[i+self.width*page])
def clear(self):
"""Clear contents of image buffer"""
_buffer = [0xff]*(self.width * self.height//8)
self.ShowImage(_buffer)
#print "%d",_buffer[i:i+4096]
config.py;
<code># /*****************************************************************************
# * | Author : Waveshare team
# * | Function : Hardware underlying interface,for Raspberry pi
# ******************************************************************************/
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
def __init__(self,spi=spidev.SpiDev(0,0),spi_freq=40000000,rst = 27,dc = 25,bl = 18,bl_freq=1000,i2c=None):
self.GPIO_RST_PIN = self.gpio_mode(RST_PIN,self.OUTPUT)
self.GPIO_DC_PIN = self.gpio_mode(DC_PIN,self.OUTPUT)
self.GPIO_KEY_UP_PIN = self.gpio_mode(KEY_UP_PIN,self.INPUT,True,None)
self.GPIO_KEY_DOWN_PIN = self.gpio_mode(KEY_DOWN_PIN,self.INPUT,True,None)
self.GPIO_KEY_LEFT_PIN = self.gpio_mode(KEY_LEFT_PIN,self.INPUT,True,None)
self.GPIO_KEY_RIGHT_PIN = self.gpio_mode(KEY_RIGHT_PIN,self.INPUT,True,None)
self.GPIO_KEY_PRESS_PIN = self.gpio_mode(KEY_PRESS_PIN,self.INPUT,True,None)
self.GPIO_KEY1_PIN = self.gpio_mode(KEY1_PIN,self.INPUT,True,None)
self.GPIO_KEY2_PIN = self.gpio_mode(KEY2_PIN,self.INPUT,True,None)
self.GPIO_KEY3_PIN = self.gpio_mode(KEY3_PIN,self.INPUT,True,None)
def delay_ms(self,delaytime):
time.sleep(delaytime / 1000.0)
def gpio_mode(self,Pin,Mode,pull_up = None,active_state = True):
return DigitalOutputDevice(Pin,active_high = True,initial_value =False)
return DigitalInputDevice(Pin,pull_up=pull_up,active_state=active_state)
return PWMOutputDevice(Pin,frequency = 10000)
def set_pwm_Duty_cycle(self,Pin,value):
def digital_write(self, Pin, value):
def digital_read(self, Pin):
def spi_writebyte(self,data):
self.spi.writebytes([data[0]])
def i2c_writebyte(self,reg, value):
self.bus.write_byte_data(self.address, reg, value)
self.digital_write(self.GPIO_RST_PIN,False)
if(self.Device == Device_SPI):
self.spi.max_speed_hz = 1000000
self.digital_write(self.GPIO_DC_PIN,False)
if(self.Device == Device_SPI):
self.digital_write(self.GPIO_RST_PIN,False)
self.digital_write(self.GPIO_DC_PIN,False)
<code># /*****************************************************************************
# * | File : config.py
# * | Author : Waveshare team
# * | Function : Hardware underlying interface,for Raspberry pi
# * | Info :
# *----------------
# * | This version: V1.0
# * | Date : 2020-06-17
# * | Info :
# ******************************************************************************/
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
import time
from smbus import SMBus
import spidev
import ctypes
from gpiozero import *
# Pin definition
RST_PIN = 25
DC_PIN = 24
#GPIO define
KEY_UP_PIN = 6
KEY_DOWN_PIN = 19
KEY_LEFT_PIN = 5
KEY_RIGHT_PIN = 26
KEY_PRESS_PIN = 13
KEY1_PIN = 21
KEY2_PIN = 20
KEY3_PIN = 16
Device_SPI = 1
Device_I2C = 0
class RaspberryPi:
def __init__(self,spi=spidev.SpiDev(0,0),spi_freq=40000000,rst = 27,dc = 25,bl = 18,bl_freq=1000,i2c=None):
self.INPUT = False
self.OUTPUT = True
if(Device_SPI == 1):
self.Device = Device_SPI
self.spi = spi
else :
self.Device = Device_I2C
self.address = 0x3c
self.bus = SMBus(1)
self.GPIO_RST_PIN = self.gpio_mode(RST_PIN,self.OUTPUT)
self.GPIO_DC_PIN = self.gpio_mode(DC_PIN,self.OUTPUT)
self.GPIO_KEY_UP_PIN = self.gpio_mode(KEY_UP_PIN,self.INPUT,True,None)
self.GPIO_KEY_DOWN_PIN = self.gpio_mode(KEY_DOWN_PIN,self.INPUT,True,None)
self.GPIO_KEY_LEFT_PIN = self.gpio_mode(KEY_LEFT_PIN,self.INPUT,True,None)
self.GPIO_KEY_RIGHT_PIN = self.gpio_mode(KEY_RIGHT_PIN,self.INPUT,True,None)
self.GPIO_KEY_PRESS_PIN = self.gpio_mode(KEY_PRESS_PIN,self.INPUT,True,None)
self.GPIO_KEY1_PIN = self.gpio_mode(KEY1_PIN,self.INPUT,True,None)
self.GPIO_KEY2_PIN = self.gpio_mode(KEY2_PIN,self.INPUT,True,None)
self.GPIO_KEY3_PIN = self.gpio_mode(KEY3_PIN,self.INPUT,True,None)
#self.Disable_All_PIN
def delay_ms(self,delaytime):
time.sleep(delaytime / 1000.0)
def gpio_mode(self,Pin,Mode,pull_up = None,active_state = True):
if Mode:
return DigitalOutputDevice(Pin,active_high = True,initial_value =False)
else:
return DigitalInputDevice(Pin,pull_up=pull_up,active_state=active_state)
def gpio_pwm(self,Pin):
return PWMOutputDevice(Pin,frequency = 10000)
def set_pwm_Duty_cycle(self,Pin,value):
Pin.value = value
def digital_write(self, Pin, value):
if value:
Pin.on()
else:
Pin.off()
def digital_read(self, Pin):
return Pin.value
def spi_writebyte(self,data):
self.spi.writebytes([data[0]])
def i2c_writebyte(self,reg, value):
self.bus.write_byte_data(self.address, reg, value)
def module_init(self):
self.digital_write(self.GPIO_RST_PIN,False)
if(self.Device == Device_SPI):
self.spi.max_speed_hz = 1000000
self.spi.mode = 0b11
# CS_PIN.off()
self.digital_write(self.GPIO_DC_PIN,False)
return 0
def module_exit(self):
if(self.Device == Device_SPI):
self.spi.close()
else :
self.bus.close()
self.digital_write(self.GPIO_RST_PIN,False)
self.digital_write(self.GPIO_DC_PIN,False)
### END OF FILE ###
</code>
# /*****************************************************************************
# * | File : config.py
# * | Author : Waveshare team
# * | Function : Hardware underlying interface,for Raspberry pi
# * | Info :
# *----------------
# * | This version: V1.0
# * | Date : 2020-06-17
# * | Info :
# ******************************************************************************/
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
import time
from smbus import SMBus
import spidev
import ctypes
from gpiozero import *
# Pin definition
RST_PIN = 25
DC_PIN = 24
#GPIO define
KEY_UP_PIN = 6
KEY_DOWN_PIN = 19
KEY_LEFT_PIN = 5
KEY_RIGHT_PIN = 26
KEY_PRESS_PIN = 13
KEY1_PIN = 21
KEY2_PIN = 20
KEY3_PIN = 16
Device_SPI = 1
Device_I2C = 0
class RaspberryPi:
def __init__(self,spi=spidev.SpiDev(0,0),spi_freq=40000000,rst = 27,dc = 25,bl = 18,bl_freq=1000,i2c=None):
self.INPUT = False
self.OUTPUT = True
if(Device_SPI == 1):
self.Device = Device_SPI
self.spi = spi
else :
self.Device = Device_I2C
self.address = 0x3c
self.bus = SMBus(1)
self.GPIO_RST_PIN = self.gpio_mode(RST_PIN,self.OUTPUT)
self.GPIO_DC_PIN = self.gpio_mode(DC_PIN,self.OUTPUT)
self.GPIO_KEY_UP_PIN = self.gpio_mode(KEY_UP_PIN,self.INPUT,True,None)
self.GPIO_KEY_DOWN_PIN = self.gpio_mode(KEY_DOWN_PIN,self.INPUT,True,None)
self.GPIO_KEY_LEFT_PIN = self.gpio_mode(KEY_LEFT_PIN,self.INPUT,True,None)
self.GPIO_KEY_RIGHT_PIN = self.gpio_mode(KEY_RIGHT_PIN,self.INPUT,True,None)
self.GPIO_KEY_PRESS_PIN = self.gpio_mode(KEY_PRESS_PIN,self.INPUT,True,None)
self.GPIO_KEY1_PIN = self.gpio_mode(KEY1_PIN,self.INPUT,True,None)
self.GPIO_KEY2_PIN = self.gpio_mode(KEY2_PIN,self.INPUT,True,None)
self.GPIO_KEY3_PIN = self.gpio_mode(KEY3_PIN,self.INPUT,True,None)
#self.Disable_All_PIN
def delay_ms(self,delaytime):
time.sleep(delaytime / 1000.0)
def gpio_mode(self,Pin,Mode,pull_up = None,active_state = True):
if Mode:
return DigitalOutputDevice(Pin,active_high = True,initial_value =False)
else:
return DigitalInputDevice(Pin,pull_up=pull_up,active_state=active_state)
def gpio_pwm(self,Pin):
return PWMOutputDevice(Pin,frequency = 10000)
def set_pwm_Duty_cycle(self,Pin,value):
Pin.value = value
def digital_write(self, Pin, value):
if value:
Pin.on()
else:
Pin.off()
def digital_read(self, Pin):
return Pin.value
def spi_writebyte(self,data):
self.spi.writebytes([data[0]])
def i2c_writebyte(self,reg, value):
self.bus.write_byte_data(self.address, reg, value)
def module_init(self):
self.digital_write(self.GPIO_RST_PIN,False)
if(self.Device == Device_SPI):
self.spi.max_speed_hz = 1000000
self.spi.mode = 0b11
# CS_PIN.off()
self.digital_write(self.GPIO_DC_PIN,False)
return 0
def module_exit(self):
if(self.Device == Device_SPI):
self.spi.close()
else :
self.bus.close()
self.digital_write(self.GPIO_RST_PIN,False)
self.digital_write(self.GPIO_DC_PIN,False)
### END OF FILE ###