Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LCD 16x2 simulator #79

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Jumitti
Copy link
Contributor

@Jumitti Jumitti commented Aug 12, 2024

I often code away from home and I don't necessarily have an LCD screen with me... So I created a 16x2 LCD screen simulator using Tkinter, allowing for easy testing and visualization of LCD displays without physical hardware. This simulator helps in developing and debugging LCD-based projects directly from a computer.
Especially if you don't have your Raspberry and LCD with you.

All you have to do is replace Lcd() and CustomCharacters() with LcdSimulator() and CustomCharactersSimulator(). I've recoded all the (hopefully) useful functions for simulation purposes and kept their names.

I've modified __init__.py to also load drivers/simulator.py which contains everything needed for the emulator.

import drivers

display = drivers.LcdSimulator()
cc = drivers.CustomCharactersSimulator(display)

# Then the rest of your finest feats

Demo

@cgomesu cgomesu changed the title LCD 16x2 simulator PR #78 LCD 16x2 simulator Aug 12, 2024
@cgomesu cgomesu self-requested a review August 12, 2024 16:48
Copy link
Collaborator

@cgomesu cgomesu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for your submission, @Jumitti . I think an emulator would be a great addition to this repository. however, I left a few comments here that need to be addressed before merging. the gist of my comments is that the implementation of the emulator needs to work as a standalone, meaning it should not interfere with the i2c device driver interface. any user who want to use the emulator will need to install an additional dependency and then import the package that contains its logic, instead of the package that contains the i2c driver.

on a side note, I think that calling it an emulator is better than simulator. the logic emulates the physical device. the gui it generates is an actual substitute for the physical display. its like this: https://github.com/astro-pi/python-sense-emu.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this modification creates an additional dependency (namely, tkinter) for everyone trying to use the driver interface for the physical (i2c) device. this is not okay. the simulator is a good addition but its use should not interfere with the other use cases.

please undo any modifications made to this file.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this module to its own package (simulators/) and write a __init__.py for it using the drivers/ package as template.

@@ -0,0 +1,234 @@
import tkinter as tk
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this dependency needs to be documented in the README.md as well

# in developing and debugging LCD-based projects directly from a computer.

# Import necessary libraries for communication and display use
import drivers
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this import needs to change, per my other comments

@@ -0,0 +1,57 @@
# Just a 16x2 LCD screen simulator using Tkinter, allowing for easy testing and
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing shebang. make sure the file has +x permission as well.

Comment on lines +119 to +234
"10001",
"10001",
"10001",
"10001",
"11111"]
# Data for custom character #3. Code {0x02}
self.char_3_data = ["11111",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"11111"]
# Data for custom character #4. Code {0x03}
self.char_4_data = ["11111",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"11111"]
# Data for custom character #5. Code {0x04}
self.char_5_data = ["11111",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"11111"]
# Data for custom character #6. Code {0x05}
self.char_6_data = ["11111",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"11111"]
# Data for custom character #7. Code {0x06}
self.char_7_data = ["11111",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"11111"]
# Data for custom character #8. Code {0x07}
self.char_8_data = ["11111",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"11111"]

# load custom character data to CG RAM for later use in extended string. Data for
# characters is hold in file custom_characters.txt in the same folder as i2c_dev.py
# file. These custom characters can be used in printing of extended string with a
# placeholder with desired character codes: 1st - {0x00}, 2nd - {0x01}, 3rd - {0x02},
# 4th - {0x03}, 5th - {0x04}, 6th - {0x05}, 7th - {0x06} and 8th - {0x07}.
def load_custom_characters_data(self):
char_data_list = [
(f"{{0x00}}", self.char_1_data),
(f"{{0x01}}", self.char_2_data),
(f"{{0x02}}", self.char_3_data),
(f"{{0x03}}", self.char_4_data),
(f"{{0x04}}", self.char_5_data),
(f"{{0x05}}", self.char_6_data),
(f"{{0x06}}", self.char_7_data),
(f"{{0x07}}", self.char_8_data)
]

for char_name, bitmap in char_data_list:
if len(bitmap) != 8 or any(len(row) != 5 for row in bitmap):
continue
custom_chars[char_name] = bitmap

def get_custom_char(self, char_name):
return custom_chars.get(char_name, ["00000"] * 8)

# Draw CustomCharacters
def draw_custom_char(self, bitmap, x, y, color):
pixel_size = 15
for row, line in enumerate(bitmap):
for col, bit in enumerate(line):
if bit == '1':
rect_id = self.lcd.canvas.create_rectangle(
x + (col * pixel_size),
y + (row * pixel_size),
x + ((col + 1) * pixel_size),
y + ((row + 1) * pixel_size),
fill=color,
outline=color
)
self.lcd.rectangles.append(rect_id)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i couldn't help but notice that this implementation is re-using logic from the original CustomCharacters class. can't you inherit the original and override where necessary?


All you have to do is replace ``Lcd()`` and ``CustomCharacters()`` with ``LcdSimulator()`` and ``CustomCharactersSimulator()``.
The other functions are similar.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

must doc any additional dependencies as well

The other functions are similar.

```Python
import drivers
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will change per my other comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

LCD 16x2 Simulator #78
2 participants