From 5510f7792fb4b3c10089855ebd985a0bcb9585d8 Mon Sep 17 00:00:00 2001 From: BOXTEC AG Date: Wed, 17 Apr 2019 11:33:19 +0200 Subject: [PATCH] initial import --- LICENSE | 24 +++++ README.md | 7 ++ docs/hardware_instruction_set.md | 65 +++++++++++++ docs/lcd_character_set.gif | Bin 0 -> 8673 bytes pertelian.py | 153 +++++++++++++++++++++++++++++++ 5 files changed, 249 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 docs/hardware_instruction_set.md create mode 100644 docs/lcd_character_set.gif create mode 100755 pertelian.py diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a842566 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2008 The NetBSD Foundation, Inc. All rights reserved. + +This code is derived from software contributed to The NetBSD Foundation by + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..1a8ef7a --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# pertelian + +Python module to control the Pertelian X2040 LCD Display. + +Based on Pertelians Hardware Instruction Set Docs and damonkohler's pypert module. + + diff --git a/docs/hardware_instruction_set.md b/docs/hardware_instruction_set.md new file mode 100644 index 0000000..06ec434 --- /dev/null +++ b/docs/hardware_instruction_set.md @@ -0,0 +1,65 @@ +Transcript from http://developer.pertelian.com/index.php?option=com_content&view=section&id=3&Itemid=9 +Received via http://web.archive.org/web/20100903020330/http://developer.pertelian.com/index.php?option=com_content&view=section&id=3&Itemid=9 Apr 2019 + + +## Pertelian X2040 Hardware Instruction Set +To issue an instruction, you must first issue a Set Instruction Mode command to set the LCD in instruction mode. The Set Instruction Mode command has byte code 0xFE hex (254 decimal). + +| Instruction | Byte 7 | Byte 6 | Byte 5 | Byte 4 | Byte 3 | Byte 2 | Byte 1 | Byte 0 | Description | Exec. Time | +| ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | +| Set Instruction Mode | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | Sets the LCD to Instruction Mode | 1.64ms | + + +The byte following the Set Instruction Mode command is treated as an instruction. For example, to clear the display write the byte codes 0xFE and 0x01 to the device. + +| Instruction | Byte 7 | Byte 6 | Byte 5 | Byte 4 | Byte 3 | Byte 2 | Byte 1 | Byte 0 | Description | Exec. Time | +| ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | +| Clear display | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Clears display and returns cursor to the home position (address 0) | 1.64ms | +| Backlight Off | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | Turns the backlight off | 1.64ms | +| Backlight On | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | Turns the backlight on | 1.64ms | +| Entry mode set | 0 | 0 | 0 | 0 | 0 | 1 | I/D | S | Sets cursor move direction (I/D), specifies to shift the display (S). These operations are performed during data read/write | 40us | +| Display On/Off control | 0 | 0 | 0 | 0 | 1 | D | C | B | Sets On/Off of all display (D), cursor On/Off (C) and blink of cursor position character (B) | 40us | +| Cursor/display shift | 0 | 0 | 0 | 1 | S/C | R/L | * | * | Sets cursor-move or display-shift (S/C), shift direction (R/L). DDRAM contents remains unchanged | 40uS | +| Function set | 0 | 0 | 1 | DL | N | F | * | * | Sets interface data length (DL), number of display line (N) and character font(F) | 40uS | +| Set CGRAM address 0 1 CGRAM address Sets the CGRAM address. CGRAM data is sent and received after this setting 40uS +| Set Display Data address 1 The offset value: Row 1, Column 1 starts at offset 0x0 hex, Row 2, Column 1 starts at offset 0x40 hex, Row 3, Column 1 starts at offset 0x14 hex, Row 4, Column 1 starts at offset 0x54 hex Set the address where to start displaying characters at using offset to specify row and column 40uS +| Write to CGRAM or DDRAM Data Writes data to CGRAM or DDRAM. For DDRAM see character set below 40uS + + +#### Remarks +- DDRAM = Display Data RAM +- CGRAM = Character Generator RAM +- DDRAM address corresponds to cursor position +- * = Don't care +DL set 1 for 8 bit interface, 0 for 4 bit interface +N set 1 for 2 lines, 0 for 1 line +F set 0 for 5x8 dots +S/C set 1 for Display shift, 0 for Cursor move +R/L set 1 for Shift to the right, 0 for Shift to the left +D set 1 for Display ON, 0 for Display OFF +C set 1 for Cursor ON, 0 for Cursor OFF +B set 1 for Cursor blinking +I/D set 1 for Increment, 0 for Decrement +S set 1 for Automatic display shift + +## LCD Character Set +Use the following character codes to display the following symbols from the table. For example, the character 'A' is 01000001 binary or 65 decimal. + +![charcode0](lcd_character_set.gif?raw=true "LCD character set") + +## Initialization Sequence +Based on the instruction set, the proper Pertelian initialization sequence is as follows: + +0xFE; //Set instruction mode +0x38; //Function set with 8-bit data length, 2 lines, and 5x7 dot size +0xFE; +0x06; //Entry mode set; increment cursor direction; do not automatically shift +0xFE; +0x10; //Cursor/display shift; cursor move +0xFE; +0x0C; //Display On; cursor off; do not blink +0xFE; +0x01; //Clear display + +//Begin normal operations + diff --git a/docs/lcd_character_set.gif b/docs/lcd_character_set.gif new file mode 100644 index 0000000000000000000000000000000000000000..12f937fafee16f81f1fdcd6dd6fc0ba1c65bc071 GIT binary patch literal 8673 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 hYs6_l9R!bGSEPw^wjH*LyLzIdKR*O_+Kt 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 literal 0 HcmV?d00001 diff --git a/pertelian.py b/pertelian.py new file mode 100755 index 0000000..0903be1 --- /dev/null +++ b/pertelian.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# --------------------------------------------------------------------- +# pertelian.py: python module to control Pertelian X2040 USB LCD +# --------------------------------------------------------------------- +# Copyright (c) 2019 BOXTEC AG +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# -------------------------------------------------------------------------- +# + + +""" +__author__ = "boxtec (src@boxtec.ch)" +__appname__ = "pertelian.py" +__version__ = "1.00" +__date__ = "2019-04-07" +__license__ = "BSD" +""" + + +####################### +# IMPORTS +####################### +import serial, time, struct + +####################### +# CONSTANTS +####################### +LCD_WIDTH = 20 +STRING_WIDTH = 20 +SDELAY_DEFAULT = 0.01 +#DEFAULT_INIT = [0x38, 0x06, 0x10, 0x0c, 0x01] +DEFAULT_INIT = [0x38, 0x06, 0x10, 0x0c, 0x01] +FILLER_CHAR = " " + +####################### +# Display class +####################### +class Display(): + + # local methods + def __init__(self, port='/dev/ttyUSB0', baudrate=115200, init_seq=DEFAULT_INIT): + self._sp = serial.Serial(port, baudrate) + self._display_init(init_seq) + + self.backlight(True) + self.enable() + self.lcdprintln("BOXTEC PERTELIAN LIB boxtec pertelian lib") + self.lcdprintln("BOXTEC PERTELIAN LIB") + self.lcdprintln("BOXTEC PERTELIAN LIB") + self.lcdprintln("BOXTEC PERTELIAN LIB") + self.lcdscroll() + + def __del__(self): + self._sp.close() + + + def _display_init(self, init_seq): + for cmd in init_seq: + self._sendcmd(cmd) + + + def _senddata(self, data, datatype="C", delay=SDELAY_DEFAULT): + for c in data: + self._sp.write(chr(c)) + time.sleep(delay) + + + def _sendcmd(self, cmd, delay=SDELAY_DEFAULT): + cmd_data = (0xfe, cmd) + self._senddata(cmd_data, delay) + + + # public methods + def enable(self): + self._sendcmd(0x0c) + + + def disable(self): + self.clear() + self.backlight(False) + self._sendcmd(0x08) + + + def backlight(self, on=True): + if on: + self._sendcmd(0x03) + else: + self._sendcmd(0x02) + + + def clear(self): + self._sendcmd(0x01) + + + def lcdprintln(self, text): + char_list = [] + for c in text: + char_list.append(ord(c)) + if len(char_list) >= 20: break + while len(char_list) < STRING_WIDTH: + char_list.append(ord(FILLER_CHAR)) + self._senddata(char_list) + + + def lcdprint(self, text): + char_list = [] + for c in text: + char_list.append(ord(c)) + self._senddata(char_list) + + + def lcdcursor_set(self, line, position): + #Row1-4 baseaddress: + rowbase = [0x0, 0x40, 0x14, 0x54] + self._sendcmd((rowbase[line-1] + position) | 0x80) + + + def lcdscroll(self, text="", scroll_delay=0.1, iterations=1): + if len(text) > 0: + lcdprintln(text) + for c in range(0, iterations): + for i in range(0, STRING_WIDTH): + self._sendcmd(0x1c) + time.sleep(scroll_delay) + + + + \ No newline at end of file