Commits

Ben Bass committed ab921c0

add examples, update setup script

Comments (0)

Files changed (6)

+LICENSE
+README
+examples/lcd.py
+examples/led_flash.py
+setup.py
+pylibftdi/__init__.py
 batteries included approach, there are various interesting devices
 supported out-of-the-box.
 
+Plans
+-----
+ * Add more examples: SPI devices, knight-rider effects, input devices...
+ * Further support for serial usage (as opposed to BitBang)
 
 Changes
 -------
-
+0.3
+ * added some examples
+ * new Bus class in pylibftdi (though it probably belongs somewhere else)
+ * first release on PyPI
 0.2
  * fixed various bugs
  * added ftdi_fn and set_baudrate functions in Driver class
+"""
+Write a string (argv[1] if run from command line) to a HD44780
+LCD module connected via a FTDI UM232R/245R module using pylibftdi
+
+example usage:
+
+# while true;
+>   do python lcd.py $( awk '{print $1}' /proc/loadavg);
+>   sleep 5;
+> done
+
+Copyright (c) 2010 Ben Bass <benbass@codedstructure.net>
+All rights reserved.
+"""
+
+from pylibftdi import BitBangDriver, Bus
+
+
+class LCD(object):
+    """
+    The UM232R/245R is wired to the LCD as follows:
+       DB0..3 to LCD D4..D7 (pin 11..pin 14)
+       DB6 to LCD 'RS' (pin 4)
+       DB7 to LCD 'E' (pin 6)
+    """
+    data = Bus(0, 4)
+    rs = Bus(6)
+    e = Bus(7)
+
+    def __init__(self, driver):
+        # The Bus descriptor assumes we have a 'driver'
+        # attribute which provides a port
+        self.driver = driver
+
+    def init_four_bit(self):
+        """
+        set the LCD's 4 bit mode, since we only have
+        8 data lines and need at least 2 to strobe
+        data into the module and select between data
+        and commands.
+        """
+        self.rs = 0
+        self.data = 3
+        self.e = 1; self.e = 0
+        self.e = 1; self.e = 0
+        self.e = 1; self.e = 0
+        self.data = 2
+        self.e = 1; self.e = 0
+
+    def _write_raw(self, rs, x):
+        # rs determines whether this is a command
+        # or a data byte. Write the data as two
+        # nibbles. Ahhh... nibbles. QBasic anyone?
+        self.rs = rs
+        self.data = x >> 4
+        self.e = 1; self.e = 0
+        self.data = x & 0x0F
+        self.e = 1; self.e = 0
+
+    def write_cmd(self, x):
+        self._write_raw(0, x)
+
+    def write_data(self, x):
+        self._write_raw(1, x)
+
+def display(string):
+    "Display the given string on an attached LCD"
+    with BitBangDriver() as bb:
+    
+        # These LCDs are quite slow - and the actual baudrate
+        # is 16x this in bitbang mode...
+        bb.baudrate = 60
+
+        lcd = LCD(bb)
+        lcd.init_four_bit()
+    
+        # 001xxxxx - function set
+        lcd.write_cmd(0x20)
+        # 00000001 - clear display
+        lcd.write_cmd(0x01)
+        # 000001xx - entry mode set
+        # bit 1: inc(1)/dec(0)
+        # bit 0: shift display
+        lcd.write_cmd(0x06)
+        # 00001xxx - display config
+        # bit 2: display on
+        # bit 1: display cursor
+        # bit 0: blinking cursor
+        lcd.write_cmd(0x0C)
+    
+        for i in string:
+            lcd.write_data(ord(i))
+
+
+if __name__ == '__main__':
+    import sys
+    if len(sys.argv) == 2:
+        display(sys.argv[1])
+    else:
+        print "Usage: %s 'display string'"

examples/led_flash.py

+"""
+Flash an LED connected via a FTDI UM232R/245R module using pylibftdi
+
+Copyright (c) 2010 Ben Bass <benbass@codedstructure.net>
+All rights reserved.
+"""
+
+from pylibftdi import BitBangDriver
+
+import time
+
+def flash_forever(rate):
+    "toggle bit zero at rate Hz"
+    # put an LED with 1Kohm or similar series resistor
+    # on D0 pin
+    with BitBangDriver() as bb:
+        while True:
+            time.sleep(1.0/(2*rate))
+            bb.port ^= 1
+
+if __name__ == '__main__':
+    flash_forever(1)

pylibftdi/__init__.py

 rather than a problem with the libftdi library.
 """
 
-__VERSION__ = "0.2"
+__VERSION__ = "0.3"
 __AUTHOR__ = "Ben Bass"
 
 
-
-__ALL__ = ['Driver', 'BitBangDriver', 'ALL_OUTPUTS', 'ALL_INPUTS']
+__ALL__ = ['Driver', 'BitBangDriver', 'Bus', 'ALL_OUTPUTS', 'ALL_INPUTS']
 
 import functools
 from ctypes import *
     @port.setter
     def port(self, value):
         self._latch = value
-        return super(BitBangDriver, self).write(chr(value))
+        return super(BitBangDriver, self).write(chr(value))
+
+
+class Bus(object):
+    """
+    This class is a descriptor for a bus of a given width starting
+    at a given offset (0 = LSB).  Thet driver which does the actual
+    reading and writing is assumed to be a BitBangDriver instance
+    in the 'driver' attribute of the object to which this is attached.
+    """
+    def __init__(self, offset, width=1):
+        self.offset = offset
+        self.width = width
+        self._mask = ((1<<width)-1)
+
+    def __get__(self, obj, type):
+        val = obj.driver.port
+        return (val >> offset) & self._mask
+
+    def __set__(self, obj, value):
+        value = value & self._mask
+        # in a multi-threaded environment, would
+        # want to ensure following was locked, eg
+        # by acquiring a driver lock
+        val = obj.driver.port
+        val &= ~(self._mask << self.offset)
+        val |= value << self.offset
+        obj.driver.port = val
 
 setup(
     name="pylibftdi",
-    version="0.2",
+    version="0.3",
     description="Pythonic interface to FTDI devices using libftdi",
     author="Ben Bass",
     author_email="benbass@codedstructure.net",
     url="http://bitbucket.org/codedstructure/pylibftdi",
     packages=["pylibftdi"],
     classifiers=[
-        "Development Status :: 3 - Alpha",
+        "Development Status :: 4 - Beta",
         "Environment :: Console",
         "Intended Audience :: Developers",
         "License :: OSI Approved :: MIT License",