前回の Flask の Web アプリから入力した文字列を、I2C 接続された LCD に表示させます。
i2c 関係のプログラムを追加します。
i2c_lcd.py です。
前回の「pwm_flask」の下、「pwm_flask.py」と同じ場所に置きます。
ソースはこれで clone できます。
$ git clone git@bitbucket.org:nagasako/pwm_flask.git
ディレクトリの構造はこのようになります。
pwm_flask/
├── i2c_lcd.py
├── pwm_flask.py
├── static
│ └── style.css
└── templates
├── base.html
└── input_text_for_lcd.html
以前は、root でなければ実行できませんでした。
現在は、root でなくても i2c にアクセスできるので、ウェブアプリにしてもそのまま実行できます。
i2c_lcd.py
#!/usr/bin/env python
# coding: UTF-8
'''
$ sudo apt-get install python-smbus i2c-tools
comment out this line in /etc/modprobe.d/raspi-blacklist.conf
blacklist i2c-bcm2708
add the following lines to /etc/modules
i2c-dev
i2c-bcm2708
and then reboot.
search all addr.
$ sudo i2cdetect -y 1
'''
import smbus
import time
import datetime
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, list(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")
pwm_flask.py は一部修正です。
#!/usr/bin/env python
# coding: UTF-8
from flask import Flask, request, redirect
from flask import url_for, render_template, flash
# from flask import session, g, abort
from i2c_lcd import st7032i
import datetime
DEBUG = True
SECRET_KEY = 'something_secret_pwm_flask'
USERNAME = 'admin'
PASSWORD = 'adminpass'
app = Flask(__name__)
app.config.from_object(__name__)
# app.run(host='0.0.0.0', port=5000)
@app.route('/')
def input_text_for_lcd():
return render_template('input_text_for_lcd.html')
@app.route('/send_text', methods=['POST'])
def send_text():
date_str = datetime.datetime.now().strftime("%y/%m/%d")
time_str = datetime.datetime.now().strftime("%H:%m:%S")
msg_text = request.form['msg_text']
print('send_text msg_text=', msg_text)
my_lcd = st7032i(0x3e, 1)
my_lcd.clear()
my_lcd.mov_to(0, 0)
my_lcd.put_str(time_str)
my_lcd.mov_to(1, 0)
if msg_text:
my_lcd.put_str(msg_text)
flash('New entry was successfully posted "' + msg_text + '" at ' + date_str + ' ' + time_str)
return redirect(url_for('input_text_for_lcd'))
if __name__ == '__main__':
app.run()
実行はこう。python3 でも動きます。
$ export FLASK_APP=pwm_flask.py $ python -m flask run --host='0.0.0.0'
プログラム中に「app.run(host='0.0.0.0')」とすれば、他のパソコンからアクセスできるはずなのですが、うまくいかなかったので、export を使う方式にしています。
文字列出力にある「list(map(ord, the_str))」は、python3 の仕様変更のため list が必要になっています。

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