raspbian-jessie-lite に Python3 をインストールして flask で i2c ( + PWM)
今回は、その準備。
jessie light で環境を作ってみます。
light 版ではない場合は、既にインストールされているライブラリなどがあるので、そこのインストールは飛ばしてください。
8GB SD メモリを挿入。SDFormatter でフォーマットして、わかりやすいように JESSIE と名前をつけておきます。
$ diskutil list
/dev/disk0 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *160.0 GB disk0
1: EFI EFI 209.7 MB disk0s1
2: Apple_HFS MacHD 159.2 GB disk0s2
3: Apple_Boot Recovery HD 650.0 MB disk0s3
/dev/disk1 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *8.0 GB disk1
1: DOS_FAT_32 JESSIE 8.0 GB disk1s1
$
/dev/disk1 が JESSIE の SD メモリ。
書き込み。
$ diskutil unmountDisk /dev/disk1
Unmount of all volumes on disk1 was successful
$ sudo dd bs=1m if=~/Downloads/2016-11-25-raspbian-jessie-lite.img of=/dev/disk1
しばらく放置。
$ diskutil eject /dev/disk1
Raspberry Pi にメモリを挿入して電源投入。
ログインします。
何も入っていない状態では、842Mbyte しか使っていない。
その前に、
pi@raspberrypi:~ $ df -h Filesystem Size Used Avail Use% Mounted on /dev/root 7.3G 842M 6.1G 12% / devtmpfs 214M 0 214M 0% /dev tmpfs 218M 0 218M 0% /dev/shm tmpfs 218M 4.5M 213M 3% /run tmpfs 5.0M 4.0K 5.0M 1% /run/lock tmpfs 218M 0 218M 0% /sys/fs/cgroup /dev/mmcblk0p1 63M 21M 43M 34% /boot pi@raspberrypi:~ $
その前に、
$ sudo raspi-configで ssh を enable にします。sshが不要な方は、disable のままで構いません。
i2c も enable にしておきます。
timezone や画面の周りの黒いところを取ったりなど、お好みで設定。
.ssh/authorized_keys に自分の id_rsa.pub を書き込んでおくと便利。
timezone も Asia/Tokyo にしておきます。
pi@raspberrypi:~ $ sudo raspi-config Current default time zone: 'Asia/Tokyo' Local time is now: Sat Dec 17 11:45:39 JST 2016. Universal Time is now: Sat Dec 17 02:45:39 UTC 2016. pi@raspberrypi:~ $ date Sat 17 Dec 11:45:52 JST 2016 pi@raspberrypi:~ $
それから更新。
$ sudo apt-get update $ sudo apt-get -y upgrade $ uname -a Linux raspberrypi 4.4.34+ #930 Wed Nov 23 15:12:30 GMT 2016 armv6l GNU/Linux $ sudo rpi-update
最近の jessie lite では not found になるので、インストールしてから。
$ sudo apt-get install rpi-update $ sudo rpi-update $ sudo reboot $ uname -a Linux raspberrypi 4.4.38+ #938 Thu Dec 15 15:17:54 GMT 2016 armv6l GNU/Linux
python3も入っていない。
$ python -V Python 2.7.9 $ python3 -V -bash: python3: command not found
python3 と venv をインストール。それと pip も。
$ sudo apt-get -y install python3 $ python3 -V Python 3.4.2 $ sudo apt-get -y install python3.4-venv $ sudo apt-get install python3-pip
ここまでくると 1.1G になってしまう。
pi@raspberrypi:~ $ df -h Filesystem Size Used Avail Use% Mounted on /dev/root 7.3G 1.1G 5.9G 16% / devtmpfs 214M 0 214M 0% /dev tmpfs 218M 0 218M 0% /dev/shm tmpfs 218M 4.5M 213M 3% /run tmpfs 5.0M 4.0K 5.0M 1% /run/lock tmpfs 218M 0 218M 0% /sys/fs/cgroup /dev/mmcblk0p1 63M 21M 43M 34% /boot pi@raspberrypi:~ $
関係のない人は関係がない、wifi の設定をしてしまいます。
線で繋ぐのは面倒なので。
$ sudo sh -c 'wpa_passphrase YourSSID YourPassphrase >> /etc/wpa_supplicant/wpa_supplicant.conf'
wpa_supplicant.conf の中の #psk= の行は削除。
country=GB
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
        ssid="YourSSID"
        #psk="YourPassphrase"
        psk=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
}
固定 ip を設定。dhcpcd.conf の最後のところに追加。
$ sudo nano /etc/dhcpcd.conf # for MySSID interface wlan0 static ip_address=192.168.1.234/24 static routers=192.168.1.1 static domain_name_servers=192.168.1.1
電源を落として、lan ケーブルを抜いてしまう。
$ sudo shutdown -h now
別のパソコンから ssh で接続。
$ ssh pi@192.168.1.234
pip3 でインストールされているライブラリを見てみます。
$ pip3 freeze chardet==2.3.0 colorama==0.3.2 html5lib==0.999 requests==2.4.3 six==1.8.0 urllib3==1.9.1 wheel==0.24.0
jessie lite ではほとんど何も入っていません
jessie では flask とか入っていま。
まず、そのいろいろ入っている Jessie でやってみます。
i2cdetect で接続確認。
上は LCD ユニットだけを接続、下は PWM 素子も接続した状態。
LCD ユニットは、秋月電子で売っている ST7032。
pi@raspberrypi:~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3e -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
pi@raspberrypi:~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3e -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --                         
pi@raspberrypi:~ $ 
Raspberry Pi Type B から I2C で LCD モジュールに出力するプログラム。
i2c_lcd.py
#!/usr/bin/env python
# coding: UTF-8
import smbus
import RPi.GPIO as GPIO
import time
import math
import datetime
# from pypwm.spi_adc import SpiAdc
class st7032i:
    def __init__(self, addr=0x3e, ch=1, contrast=0x20):
        try:
            self.addr = addr
            self.ch = ch
            self.bus = smbus.SMBus(ch)
            self.contrast = contrast
            self.reset()
            self.enable = True
        except:
            self.enable = False
    def reset(self):
        contrast_h = 0x70 | (self.contrast & 0x0f)
        contrast_l = 0x54 | ((self.contrast >> 4) & 0x03)
        self.bus.write_i2c_block_data(
            self.addr, 0, [0x38, 0x39, 0x14, contrast_h, contrast_l, 0x6c])
#         // ST7032 Initial Program Code Example For 8051 MPU(8 Bit Interface) の初期化サンプルの通り
#         // Function Set : 8bit bus mode, 2-line mode,normal font,normal instruction mode
#         LCD_write(LCD_RS_CMD, 0b00111000, fd);      // 0x38
#         // Function Set : extension instruction mode
#         LCD_write(LCD_RS_CMD, 0b00111001, fd);      // 0x39
#         // Internal OSC frequency(extension instruction mode)
#         LCD_write(LCD_RS_CMD, 0b00010100, fd);      // 0x14
#         // Contrast set(extension instruction mode) コントラスト値下位4bit設定
#         LCD_write(LCD_RS_CMD, 0b01110000 | (LCD_CONTRAST & 0xF), fd); // 0x78 = 0x70 + 0x8
#         // Power/ICON/Contrast set(extension instruction mode) コントラスト値上位2bit設定
#         LCD_write(LCD_RS_CMD, 0b01011100 | ((LCD_CONTRAST >> 4) & 0x3), fd); // 0x5c + 0
#         // Follower control。internal follower on,
#         LCD_write(LCD_RS_CMD, 0b01101100, fd);      // 0x6c
        time.sleep(0.25)
        self.bus.write_i2c_block_data(self.addr, 0, [0x0c, 0x01, 0x06])
#         // Function Set。normal instruction mode。
#         // LCD_write(LCD_RS_CMD, 0b00111000, fd);   // 0x38
#         // Display On
#         LCD_write(LCD_RS_CMD, 0b00001100, fd);      // 0x0c
#         // Clear Display
#         LCD_write(LCD_RS_CMD, 0b00000001, fd);      // 0x01
#         // Entry Mode Set
#         LCD_write(LCD_RS_CMD, 0b00000110, fd);      // 0x06
        time.sleep(0.05)
    def clear(self):
        if self.enable:
            self.bus.write_i2c_block_data(self.addr, 0, [0x01])
    def mov_to(self, row=0, col=0):
        if self.enable:
            self.bus.write_i2c_block_data(self.addr, 0, [0x80 + 0x40 * row + col])
    def put_str(self, the_str):
        if self.enable:
            self.bus.write_i2c_block_data(self.addr, 0x40, map(ord, the_str))
if __name__ == '__main__':
    try:
        my_lcd = st7032i(0x3e, 1)
        if True and my_lcd.enable:
            while True:
                time_str = datetime.datetime.now().strftime("%H:%m:%S")
                date_str = datetime.datetime.now().strftime("%y/%m/%d")
                my_lcd.clear()
                my_lcd.mov_to(0, 0)
                my_lcd.put_str(date_str)
                my_lcd.mov_to(1, 0)
                my_lcd.put_str(time_str)
                print(date_str + ' ' + time_str)
                time.sleep(1)
        # if False and my_lcd.enable:
        #     light_channel = 0
        #     adc = SpiAdc(light_channel)
        #     if adc is not None and my_lcd.enable:
        #         # Define delay between readings
        #         delay = 1
        #         while True:
        #             # Read the light sensor data
        #             light_level = adc.readChannel()
        #             # light_volts = adc.convertVolts(light_level, 2)
        #             # Print out results
        #             # print("Light: {} ({}V)".format(light_level,light_volts))
        #             # print("%4d %1.2f" % (light_level, light_volts))
        #             the_str = "    " + str(light_level)
        #             my_lcd.mov_to(0, 0)
        #             my_lcd.put_str(the_str[-4:])
        #             # Wait before repeating loop
        #             time.sleep(delay)
    except:
        print("Error accessing default I2C bus")
今度は Jessie Lite でやってみる。
その前に確認。
pi@raspberrypi:~ $ cat /etc/modules # /etc/modules: kernel modules to load at boot time. # # This file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored. i2c-dev pi@raspberrypi:~ $
i2c-dev が入っているので、OK。
入っていない時は、sudo rasps-config か、手で入れる。
必要なライブラリのインストール。
pi@raspberrypi:~ $ sudo apt-get install python-smbus i2c-tools
i2cdetect で確認。
pi@raspberrypi:~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3e -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --                         
pi@raspberrypi:~ $ 
OK。
先ほどのソースを実行してみる。
ファイル名を「i2c_lcd.py」としています。
先ほどのソースを実行してみる。
ファイル名を「i2c_lcd.py」としています。
pi@raspberrypi:~ $ python i2c_lcd.py
16/12/24 14:12:35
16/12/24 14:12:36
16/12/24 14:12:37
16/12/24 14:12:38
16/12/24 14:12:39
16/12/24 14:12:40
16/12/24 14:12:41
LCD に、時刻が表示されている。OK。
今度は、PCA9685 で LED をランダムに明るさを変えてみます。
0x40 が PCA9685 のアドレス。
PCA9685 が3つつながっていても対応できるようにしています。
これだけのファイルを置きます。
pi@raspberrypi:~ $ ls -l *.py
-rw-r--r-- 1 pi pi  500 Dec 24 14:23 const.py
-rw-r--r-- 1 pi pi 4496 Dec 24 14:15 i2c_lcd.py
-rw-r--r-- 1 pi pi 5480 Dec 24 14:41 i2c_pwm_demo.py
-rw-r--r-- 1 pi pi 5065 Dec 24 14:28 i2c_pwm_lib.py
-rw-r--r-- 1 pi pi 3737 Dec 24 14:32 pypwm_db.py
pi@raspberrypi:~ $ 
「i2c_lcd.py」は先ほどの LCD 出力デモのファイル。
「i2c_pwm_demo.py」が main のプログラム。実行するのはこれ。
「pypwm_db.py」は、現在の明るさをデータベースに格納して、次の電源が入った時に、明るさの設定を維持するようにしています。
pi@raspberrypi:~ $ cat const.py
#!/usr/bin/env python
# coding: UTF-8
import os
kRevision = '110'
kPort = '5555'
kFilterPWM = 'pwm'
kMinVal = 0
kMaxVal = 4095
kMinValSliderZero = 0
kMaxValSliderZero = 1023
kDefaultVal = 3600
kChNum = 16
kChMin = 0
kChMax = kChNum
kBlockNum = (kChNum / 2)
kEachCh = 16
kPwmFreq = 200
kDemoDisableFile = '/tmp/demo_disable'
os_name = os.uname()
if os_name[0] == 'Darwin':
    dbname = '/Users/pi/pwm_prefs.db'
elif os_name[0] == 'Linux':
    dbname = '/home/pi/pwm_prefs.db'
pi@raspberrypi:~ $ 
pi@raspberrypi:~ $ cat i2c_pwm_demo.py
#!/usr/bin/python
# coding: UTF-8
from i2c_pwm_lib import PWM
import i2c_lcd
import time
import datetime
import random
import os
import pypwm_db
import const
class TestPWM():
    def __init__(self, addr=0x40, freq=200):
        self.prefs = const.dbname
        self.kChNum = const.kChNum
        self.pwm = PWM(addr, debug=True)
        if self.pwm.i2c is None:
            self.pwm = None
        if self.pwm is not None:
            self.pwm.setPWMFreq(freq)
            self.lcd = None     # i2c_lcd.st7032i(0x3e, 1)
            # if self.lcd.bus is None:
            #    self.lcd = None
            self.debug = False
            self.pwm.debug = True
    def outPWM(self, ch, width):
        if self.pwm is not None:
            self.pwm.setPWM(ch, 0, width)
        if self.debug:
            if self.lcd is not None:
                self.lcd.mov_to(0, 0)
                the_str = 'ch = %2d' % ch
                self.lcd.put_str(the_str)
                self.lcd.mov_to(1, 0)
                the_str = '%4d' % width
                self.lcd.put_str(the_str)
    def read_prefs(self, ch):
        pypwmdb = pypwm_db.pypwm_db(self.prefs)
        width = pypwmdb.get_width_of_ch(ch)
        return width
    def init_all_leds(self):
        pwm_vals = []
        for ch in range(self.kChNum + 1):
            the_val = self.read_prefs(ch)
            pwm_vals.append(the_val)
            if self.debug:
                print('init_all_leds append ch = %d, val = %d' % (ch, the_val))
        for idx in range(self.kChNum):
            pwm_val = pwm_vals[idx + 1]
            self.outPWM(idx, pwm_val)
            if self.debug:
                print('init_all_leds outPWM ch = %d, val = %d' % (idx, pwm_val))
class DemoPWM():
    def __init__(self):
        self.kChNum = const.kChNum
        self.kChMax = self.kChNum - 1
        self.kMaxPWM = const.kMaxVal
        self.kMinPWM = 1
        self.ch_list = range(self.kChNum)
        random.shuffle(self.ch_list)
        self.vals = []
        self.kmms = []
        self.mms = []
        self.demo = [1, 1, 2, 3, 6, 10, 18, 33, 61, 111, 203, 370, 674, 1228, 2239, 4081]
        self.kDemoDisableFile = const.kDemoDisableFile
        for ch in self.ch_list:
            self.vals.append(self.kMinPWM)
            mm = 1.05 + float(ch) / 40.0
            self.kmms.append(mm)
            self.mms.append(mm)
    def demo_01(self, test_pwm):
        for ch in self.ch_list:
            val = self.vals[ch]
            kmm = self.kmms[ch]
            mm = self.mms[ch]
            val *= mm
            if val > self.kMaxPWM:
                val = self.kMaxPWM
                mm = 1.0 / kmm
            elif val < self.kMinPWM:
                val = self.kMinPWM
                mm = kmm
            test_pwm.outPWM(ch, int(val))
            self.vals[ch] = val
            self.mms[ch] = mm
    def demo_02(self, test_pwm, offset, diff):
        for ch in self.ch_list:
            index = ch + offset
            if index > self.kChMax:
                index -= self.kChNum
            elif index < 0:
                index += self.kChNum
            val = self.demo[index]
            test_pwm.outPWM(ch, val)
        offset += diff
        if offset >= self.kChNum:
            offset = self.kChMax
            diff = -1
        elif offset < 0:
            offset = 0
            diff = 1
        return (offset, diff)
    def is_demo_disable(self):
        demo_disable = False
        if os.path.isfile(self.kDemoDisableFile):
            demo_disable = True
        return demo_disable
if __name__ == '__main__':
    while (True):
        if True or not os.path.isfile(const.kDemoDisableFile):
            test_pwm = TestPWM(0x40, const.kPwmFreq)
            if test_pwm.pwm is not None:
                test_pwm.init_all_leds()
            # time.sleep(90)
            if test_pwm.pwm is None:
                test_pwm = None
            test_2_pwm = TestPWM(0x41, const.kPwmFreq)
            if test_2_pwm.pwm is None:
                test_2_pwm = None
            if test_pwm is not None:
                my_lcd = test_pwm.lcd
            prev_time = round(time.time())
            demo_pwm = DemoPWM()
            if demo_pwm.is_demo_disable():
                pass
            else:
                offset = 0
                diff = 1
                for xx in range(1000):
                    if test_pwm.pwm is not None:
                        demo_pwm.demo_01(test_pwm)
                        # (offset, diff) = demo_pwm.demo_02(test_pwm, offset, diff)
                    if test_2_pwm is not None:
                        # demo_pwm.demo_01(test_2_pwm)
                        (offset, diff) = demo_pwm.demo_02(test_2_pwm, offset, diff)
                    time.sleep(0.001)
                    if round(time.time()) > prev_time:
                        prev_time = round(time.time())
                        time_str = datetime.datetime.now().strftime("%H:%m:%S")
                        date_str = datetime.datetime.now().strftime("%y/%m/%d")
                        if my_lcd is not None:
                            my_lcd.clear()
                            my_lcd.mov_to(0, 0)
                            my_lcd.put_str(date_str)
                            my_lcd.mov_to(1, 0)
                            my_lcd.put_str(time_str)
        else:
            time.sleep(1)
pi@raspberrypi:~ $ 
pi@raspberrypi:~ $ cat i2c_pwm_lib.py
#!/usr/bin/env python
# coding: UTF-8
import time
import math
import smbus
# ============================================================================
# PCA9685 16-Channel PWM Servo Driver
# ============================================================================
class i2c_lib():
    @staticmethod
    def getPiRevision():
        "Gets the version number of the Raspberry Pi board"
        try:
            with open('/proc/cpuinfo', 'r') as f:
                for line in f:
                    if line.startswith('Revision'):
                        return 1 if line.rstrip()[-1] in ['1', '2'] else 2
        except:
            return 0
    @staticmethod
    def getPiI2CBusNumber():
        # Gets the I2C bus number /dev/i2c#
        return 1 if i2c_lib.getPiRevision() > 1 else 0
    def __init__(self, address, busnum=-1, debug=False):
        self.address = address
        self.bus = smbus.SMBus(busnum if busnum >= 0 else i2c_lib.getPiI2CBusNumber())
        self.debug = debug
    def errMsg(self, msg):
        print("Error in %s accessing 0x%02X: Check your I2C address" % (msg, self.address))
        return -1
    def write8(self, reg, value):
        "Writes an 8-bit value to the specified register/address"
        try:
            self.bus.write_byte_data(self.address, reg, value)
            if self.debug:
                print("I2C: Wrote 0x%02X to register 0x%02X" % (value, reg))
            return 0
        except IOError:
            return self.errMsg('write8(reg=0x%02x, value=%d)' % (reg, value))
    def readU8(self, reg):
        "Read an unsigned byte from the I2C device"
        try:
            result = self.bus.read_byte_data(self.address, reg)
            if self.debug:
                print(
                    "I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" % (
                        self.address, result & 0xFF, reg))
            return result
        except IOError:
            return self.errMsg('readU8(reg=0x%02x)' % (reg))
class PWM():
    # Registers/etc.
    __SUBADR1 = 0x02
    __SUBADR2 = 0x03
    __SUBADR3 = 0x04
    __ALLCALLADR = 0x05
    __MODE1 = 0x00
    __MODE2 = 0x01
    __PRESCALE = 0xFE
    __LED0_ON_L = 0x06
    __LED0_ON_H = 0x07
    __LED0_OFF_L = 0x08
    __LED0_OFF_H = 0x09
    __ALLLED_ON_L = 0xFA
    __ALLLED_ON_H = 0xFB
    __ALLLED_OFF_L = 0xFC
    __ALLLED_OFF_H = 0xFD
    def __init__(self, address=0x40, debug=False):
        self.i2c = i2c_lib(address, debug=False)
        self.address = address
        self.debug = debug
        if (self.debug):
            print("Reseting PCA9685 (%02x)" % (address))
        result = self.i2c.write8(self.__MODE1, 0x00)
        if self.debug:
            print("result = %d" % (result))
        if result < 0:
            self.i2c = None
        if (self.debug):
            if self.i2c is not None:
                result = self.i2c.readU8(self.__ALLCALLADR)
                print('__ALLCALLADR = %02x' % (result))
                result = self.i2c.readU8(self.__SUBADR1)
                print('__SUBADR1 = %02x' % (result))
                result = self.i2c.readU8(self.__SUBADR2)
                print('__SUBADR2 = %02x' % (result))
                result = self.i2c.readU8(self.__SUBADR3)
                print('__SUBADR3 = %02x' % (result))
    def setPWMFreq(self, freq):
        "Sets the PWM frequency"
        prescaleval = 25000000.0  # 25MHz
        prescaleval /= 4096.0  # 12-bit
        prescaleval /= float(freq)
        prescaleval = int(round(prescaleval)) - 1
        if (self.debug):
            print("Setting PWM frequency to %d Hz" % (freq))
            print("Estimated pre-scale: %d" % (prescaleval))
        if (self.debug):
            print("Final pre-scale: %d" % (prescaleval))
        oldmode = self.i2c.readU8(self.__MODE1)
        newmode = (oldmode & 0x7F) | 0x10  # sleep
        self.i2c.write8(self.__MODE1, newmode)  # go to sleep
        self.i2c.write8(self.__PRESCALE, prescaleval)
        self.i2c.write8(self.__MODE1, oldmode)
        time.sleep(0.005)
        self.i2c.write8(self.__MODE1, oldmode | 0x80)
        # self.i2c.write8(self.__MODE2, 0x10) # INVRT = 1, OUTDRV = 0
        if (self.debug):
            result = self.i2c.readU8(self.__MODE1)
            print('__MODE1 = %02x' % (result))
            result = self.i2c.readU8(self.__MODE2)
            print('__MODE2 = %02x' % (result))
    def setPWM(self, channel, on, off):
        "Sets a single PWM channel"
        self.i2c.write8(self.__LED0_ON_L + 4 * channel, on & 0xFF)
        self.i2c.write8(self.__LED0_ON_H + 4 * channel, on >> 8)
        self.i2c.write8(self.__LED0_OFF_L + 4 * channel, off & 0xFF)
        self.i2c.write8(self.__LED0_OFF_H + 4 * channel, off >> 8)
        # print('ch = %d, on = %d, off = %d' % (channel, on, off))
    def all_led_on(self):
        self.i2c.write8(self.__ALLLED_ON_L, 0x00)
        self.i2c.write8(self.__ALLLED_ON_H, 0x10)
    def all_led_off(self):
        self.i2c.write8(self.__ALLLED_OFF_L, 0x00)
        self.i2c.write8(self.__ALLLED_OFF_H, 0x10)
pi@raspberrypi:~ $ 
pi@raspberrypi:~ $ cat pypwm_db.py
#!/usr/bin/env python
# coding: UTF-8
import sqlite3
import const
class pypwm_db():
    def __init__(self, fname):
        self.con = None
        self.fname = fname
        if fname is not None:
            self.con = sqlite3.connect(fname)   # , isolation_level=None
            no_db = True
            try:
                cur = self.con.cursor()
                cur.execute('SELECT width FROM pwmvals WHERE ch=1')
                no_db = False
            except Exception as ex:
                print(ex)
            self.con.close()
            if no_db:
                # Create table
                self.con = sqlite3.connect(fname)
                cur = self.con.cursor()
                cur.execute('''CREATE TABLE pwmvals (ch INTEGER, width INTEGER,
                                block INTEGER, which INTEGER,
                                row INTEGER, col INTEGER,
                                enable INTEGER)''')
                for ch in range(200):
                    if 1 <= ch <= const.kChNum:
                        width = const.kDefaultVal
                        block = (ch - 1) % 16
                        which = 0
                        row = 0
                        col = 0
                        enable = 1
                        tp = (ch, width, block, which, row, col, enable,)
                        cur.execute(''' INSERT INTO pwmvals VALUES (?, ?, ?, ?, ?, ?, ?)''', tp)
                    else:
                        width = 0
                        block = 0
                        which = 0
                        row = 0
                        col = 0
                        enable = 0
                        tp = (ch, width, block, which, row, col, enable,)
                        cur.execute(''' INSERT INTO pwmvals VALUES (?, ?, ?, ?, ?, ?, ?)''', tp)
                self.con.commit()
                cur.close()
    def connect(self):
        if self.fname is not None:
            self.con = sqlite3.connect(self.fname)
        else:
            self.con = None
        return self.con
    def get_width_of_ch(self, ch):
        width = None
        self.connect()
        if self.con is not None:
            try:
                cur = self.con.cursor()
                tp = (ch,)
                cur.execute('SELECT width FROM pwmvals WHERE ch=?', tp)
                for row in cur:
                    width = row[0]
                cur.close()
            except Exception as ex:
                print(ex)
                width = None
        return width
    def put_width_of_ch(self, ch, width):
        sql = 'UPDATE pwmvals SET width=? WHERE ch=?;'
        self.connect()
        if self.con is not None:
            try:
                cur = self.con.cursor()
                tp = (width, ch,)
                cur.execute(sql, tp)
                self.con.commit()
                cur.close()
            except Exception as ex:
                print(ex)
if __name__ == '__main__':
    dbname = const.dbname
    pypwmdb = pypwm_db(dbname)
    widths = []
    ch_max = const.kChNum + 1
    """
    # save prev width
    for ch in range(ch_max):
        width = pypwmdb.get_width_of_ch(ch)
        widths.append(width)
    # init table
    for ch in range(ch_max):
        width = ch * 2
        pypwmdb.put_width_of_ch(ch, width)
    # read table
    for ch in range(ch_max):
        width = pypwmdb.get_width_of_ch(ch)
        print("ch = %3d, width = %4d" % (ch, width))
    # restore table
    for ch in range(ch_max):
        width = widths[ch]
        pypwmdb.put_width_of_ch(ch, width)
    """
    # read table
    for ch in range(ch_max):
        width = pypwmdb.get_width_of_ch(ch)
        print("ch = %3d, width = %4d" % (ch, width))
pi@raspberrypi:~ $ 
PCA9685 に接続された16個の LED がランダムっぽく明滅します
次回以降で、flask でこれらのデバイスを制御してみます。
- Raspberry Pi B + python3 + flask + i2c + PWM 準備
- Raspberry Pi B + python3 + flask + i2c + PWM まず LCD
- Raspberry Pi B + python3 + flask + i2c + PWM まず LCD その2
- Raspberry Pi B + python3 + flask + i2c + PWM Slider
- Raspberry Pi B + python3 + flask + i2c + PWM 完了


 
0 件のコメント:
コメントを投稿