前回の 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 件のコメント:
コメントを投稿