Utilities for drawing on 4 Adafruit 8x8 LED Backpack displays as one
at master 119 lines 3.8 kB view raw
1#!/usr/bin/env ruby 2# 3# Copyright (c) 2012, Sungjin Han <meinside@gmail.com> (Matrix8x8) 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 9# * Redistributions of source code must retain the above copyright notice, 10# this list of conditions and the following disclaimer. 11# * Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# * Neither the name of meinside nor the names of its contributors may be 15# used to endorse or promote products derived from this software without 16# specific prior written permission. 17# 18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28# POSSIBILITY OF SUCH DAMAGE. 29# 30 31require "i2c/i2c" 32require "i2c/backends/i2c-dev" 33 34class Matrix8x8 35 # Registers 36 HT16K33_REGISTER_DISPLAY_SETUP = 0x80 37 HT16K33_REGISTER_SYSTEM_SETUP = 0x20 38 HT16K33_REGISTER_DIMMING = 0xE0 39 40 # Blink rate 41 HT16K33_BLINKRATE_OFF = 0x00 42 HT16K33_BLINKRATE_2HZ = 0x01 43 HT16K33_BLINKRATE_1HZ = 0x02 44 HT16K33_BLINKRATE_HALFHZ = 0x03 45 46 MAX_COL = 8 47 MAX_ROW = 8 48 49 attr_accessor :device, :address 50 51 def self.board_revision 52 File.open("/proc/cpuinfo", "r"){|file| 53 return ["2", "3"].include?(file.each_line.find{|x| x =~ /^Revision/ } 54 .strip[-1]) ? 1 : 2 55 } 56 end 57 58 def self.i2c_device_path 59 case self.board_revision 60 when 1 61 return "/dev/i2c-0" 62 when 2 63 return "/dev/i2c-1" 64 end 65 end 66 67 def initialize(device = self.i2c_device_path, address = 0x70, 68 options = {blink_rate: HT16K33_BLINKRATE_OFF, brightness: 15}) 69 if device.kind_of? String 70 @device = ::I2C.create(device) 71 else 72 [ :read, :write ].each do |m| 73 raise IncompatibleDeviceException, 74 "Missing #{m} method in device object." unless device.respond_to?(m) 75 end 76 @device = device 77 end 78 @address = address 79 80 # turn on oscillator 81 @device.write(@address, HT16K33_REGISTER_SYSTEM_SETUP | 0x01, 0x00, 0x00) 82 83 # set blink rate and brightness 84 set_blink_rate(options[:blink_rate]) 85 set_brightness(options[:brightness]) 86 87 if block_given? 88 yield self 89 end 90 end 91 92 def set_blink_rate(rate) 93 rate = HT16K33_BLINKRATE_OFF if rate > HT16K33_BLINKRATE_HALFHZ 94 @device.write(@address, HT16K33_REGISTER_DISPLAY_SETUP | 0x01 | (rate << 1), 95 0x00, 0x00) 96 end 97 98 def set_brightness(brightness) 99 brightness = 15 if brightness > 15 100 @device.write(@address, HT16K33_REGISTER_DIMMING | brightness, 0x00, 0x00) 101 end 102 103 def clear 104 (0...MAX_ROW).each{|n| write(n, 0x00, 0x00) } 105 end 106 107 def fill 108 (0...MAX_ROW).each{|n| write(n, 0xFF, 0xFF) } 109 end 110 111 def write(row, value, value2) 112 @device.write(@address, row * 2, value) 113 @device.write(@address, row * 2 + 1, value2) 114 end 115 116 def read(row) 117 @device.read(@address, 2, row * 2).unpack("C*") 118 end 119end