commit 5510f7792fb4b3c10089855ebd985a0bcb9585d8 Author: BOXTEC AG Date: Wed Apr 17 11:33:19 2019 +0200 initial import 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 0000000..12f937f Binary files /dev/null and b/docs/lcd_character_set.gif differ 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