Trouble displaying data to NHD-C12832A1Z-FSW-FBW-3V3

Comments

4 comments

  • Engineering Support
    Community moderator

    Hi Jacob,

    I can't say with certainty why the periphery.GPIO implementation is not working, but I will try to offer guidance.  Because RPi.GPIO is slower than periphery.GPIO, you may need to introduce delays in your code.  Please try adding a 100ms delay after GPIO.output(LCD_RST, False) and GPIO.output(LCD_RST, True) to ensure a proper reset.  It may also help to add a 100us delay after asserting the CS pin.  Let me know if this helps.

    0
  • Jacob Shade

    I have tried adding the delays with no luck.

    - I have tried with the spidev library having that handle all spi operations with periphery.GPIO accessing the Reset and A0 pins.
    - I have tried using the same implementation as above by only accessing the pins via periphery.GPIO

    here is code that does all gpio access with the periphery library

    from periphery import GPIO
    from ascii_values import ASCII168
    import icon_manager
    import time

    # Mapping based on BCM (Broadcom) pinout from https://pinout.xyz/
    LCD_CS = 8
    LCD_RST = 22
    LCD_A0 = 23
    LCD_CLK = 11
    LCD_SI = 10

    class LcdGpio:

    def __init__(self):
    self.RST = GPIO("/dev/gpiochip0", LCD_RST, "out")
    self.A0 = GPIO("/dev/gpiochip0", LCD_A0, "out")
    self.CS = GPIO("/dev/gpiochip0", LCD_CS, "out")
    self.CLK = GPIO("/dev/gpiochip0", LCD_CLK, "out")
    self.SI = GPIO("/dev/gpiochip0", LCD_SI, "out")

    self._lcd_init()

    def lcd_byte(self, bits):
    tmp = bits
    for i in range(0, 8):
    self.CLK.write(False)
    if (tmp & 0x80):
    self.SI.write(True)
    else:
    self.SI.write(False)
    tmp = (tmp << 1)
    self.CLK.write(True)

    def cleanup(self):
    self.RST.close()
    self.A0.close()
    self.CS.close()
    self.CLK.close()
    self.SI.close()

    #######################################################################################################
    # SEND INSTRUCTIONS
    #######################################################################################################

    def _send_instruction(self, instruction):
    self.CS.write(False)
    self.CLK.write(True)
    self.A0.write(False)
    self.lcd_byte(instruction)
    self.CS.write(True)

    def _send_instructions_bulk(self, data):
    self.CS.write(False)
    self.CLK.write(True)

    for d in data:
    self.A0.write(False)
    self.lcd_byte(d)

    self.CS.write(True)

    def _lcd_init(self):
    self.CS.write(True)
    self.RST.write(False)
    self.RST.write(True)
    init_instructions = [0xE2, 0xA2, 0xA0, 0xC8, 0xA4, 0xA6, 0x2F, 0x40, 0x20, 0x81, 0x30, 0b10101111]
    self._send_instructions_bulk(init_instructions)
    self.lcd_clear()

    def lcd_set_page(self, page, column):
    lsb = column & 0x0f
    msb = column & 0xf0
    msb >>= 4
    msb |= 0x10
    page |= 0xb0
    self._send_instruction(page)
    self._send_instruction(msb)
    self._send_instruction(lsb)

    #######################################################################################################
    # SEND DATA
    #######################################################################################################

    def _send_data(self, data):
    self.CS.write(False)
    self.CLK.write(True)
    self.A0.write(True)
    self.lcd_byte(data)
    self.CS.write(True)

    def _send_data_bulk(self, instructions):
    self.CS.write(False)
    self.CLK.write(True)

    for instr in instructions:
    self.A0.write(True)
    self.lcd_byte(instr)

    self.CS.write(True)

    def display_icon(self, x_pos, y_pos, icon, negative=False):
    icon_matrix = icon_manager.format_icon(icon, negative)

    if not isinstance(icon_matrix, list) or not all(isinstance(i, int) for i in icon_matrix):
    raise TypeError("icon_matrix must be a list of integers")

    quadrant_offsets = [
    (0, 0, 0, 8), # Quadrant 1: Top-left
    (1, 0, 8, 16), # Quadrant 2: Bottom-left
    (0, 8, 16, 24), # Quadrant 3: Top-right
    (1, 8, 24, 32), # Quadrant 4: Bottom-right
    ]

    for y_offset, x_offset, start_idx, end_idx in quadrant_offsets:
    self.lcd_set_page(y_pos + y_offset, x_pos + x_offset)
    # Transfer the entire quadrant data at once
    data = icon_matrix[start_idx:end_idx]
    self._send_data_bulk(data)

    def lcd_ascii168_string(self, x_pos, y_pos, string):
    string_len = len(string)
    for i in range(0, string_len):
    self.lcd_ascii168(x_pos + i * 8, y_pos, ord(string[i]) - 32)

    def lcd_ascii168(self, x_pos, y_pos, char):
    self.lcd_set_page(y_pos, x_pos)

    for i in range(0, 8):
    self._send_data(ASCII168[char][i])

    self.lcd_set_page(y_pos + 1, x_pos)
    for i in range(8, 16):
    self._send_data(ASCII168[char][i])

    def lcd_clear(self):
    empty_row = [0x00] * 128

    self.CS.write(False)
    for i in range(0, 8):
    self.lcd_set_page(i, 0)
    self._send_data_bulk(empty_row)
    self.CS.write(True)

    def main():
    print("Initializing LCD for testing...")

    lcd = LcdGpio()

    try:
    # Display some text
    print("trying to display text")
    lcd.lcd_ascii168_string(0, 0, "Hello!")
    time.sleep(2)
    except Exception as e:
    print(f"Error displaying text: {e}")
    finally:
    lcd.lcd_clear()
    lcd.cleanup()

    print("was it successful?")

    if __name__ == "__main__":
    main()
    0
  • Jacob Shade

    Update: I was able to finally get it working on the target board Up Squared 7100. Using the spidev library combined with periphery.GPIO to set the RST and A0 worked. Seems to have been a timing issue when sending the data serially via just GPIO

    0
  • Engineering Support
    Community moderator

    Thank you for the update and I am glad you got the display working.  Please let us know if you need further assistance.

    0

Please sign in to leave a comment.