使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

时间:2022-09-24 07:34:09

前言

原创文章,转载引用务必注明链接。水平有限,如有疏漏,欢迎指正。

本文介绍一下UP板的GPIO资源使用,以及一个使用Python演示一个简单的demo。

本文使用Markdown写成,为获得更好的阅读体验和正常的图片、链接,请访问我的博客:

http://www.cnblogs.com/sjqlwy/p/up_1602.html

本文环境:ublinux 3.0;Win7_x64

通过阅读本文你可以学到:

  • UP Board GPIO 接口的介绍以及使用
  • PyCharm 远程调试 UP上的Python代码
  • Lemaker LN IO 拓展板的使用
  • 使用RPi.GPIO这个Python库控制1602液晶屏

UP板载GPIO接口介绍

UP板的GPIO接口兼容树莓派40 Pin。实现起来比较复杂,部分从Intel Atom Z8350引出(需要电平转换),部分由板载CPLD实现。

操作GPIO

官方提供了三种方式:用户空间sysfs (shell)、RPi.GPIO库(Python)和libMRAA(多种编程语言)。

Lemaker LN IO拓展板介绍

之前在云汉社区试用Lemaker Guitar开发板时一并入手的。兼容树莓派引脚。个人非常喜欢乐美客公司的产品,包括BananaPi、BananaPi Pro、Lemaker Guitar、96boards Hikey (Lemaker Version),以及包括LN IO在内的三款拓展板,做工优良,可以在官方微店买到。LN IO 介绍页面电路原理图

使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

【下面是Lemaker Guitar开发板,上面就是LN IO 拓展板】我们下面将会利用板载的4个按键、LED灯以及1602接口。

Python控制LN IO 扩展板按键和LED

最近在学习Python,恰巧ubilinux移植了RPi.GPIO库,让我们可以非常方便地操作GPIO资源。吐槽一下,由于被动散热片的存在,使用转接线等会卡到无法完全贴合。

Blink!——控制发光二极管闪烁

我们以点亮LN IO上的led2为例:

使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

【LED电路原理图】LCD和LED是切换显示的。可以看到LED2连接到GPIO0,那么GPIO0是对应树莓派是哪个引脚呢?

使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

【底板对应引脚】GPIO0对应物理引脚11。

使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

【UP Board 引脚定义图】为了方便起见,我们统一使用BOARD物理引脚编号而非BCM引脚编号。

  • 关于树莓派GPIO的操作可以参考芒果爱吃胡萝卜这个博客,写的非常不错,由浅入深。本文部分以他的博文为基础进行演示。
  • ubilinux移植的RPi.GPIO库仅兼容Python 2.x版本
  • 为方便转换,我们以BOARD编码GPIO引脚顺序(物理顺序)
  • LN IO Board的LED和LCD可以切换显示,连接帽导通不同引脚即可。

下面创建一个文件lcd.py,内容如下,然后运行看看:sudo python lcd.py

#!/usr/bin/env python
# encoding: utf-8 import RPi.GPIO as GPIO
import time # 为保持兼容性,选择GPIO引脚主板编号模式,也就是物理引脚编号
GPIO.setmode(GPIO.BOARD)
LedPin = 11
# 指定11引脚(就是LED长针连接的GPIO针脚)的模式为输出模式
# LN IO 的GPIO0,主板编号是11,对应BCM模式引脚为17
GPIO.setup(LedPin, GPIO.OUT) # 循环10次
for i in range(0, 10):
# 让11引脚输出高电平(LED灯亮)
GPIO.output(LedPin, True)
# 持续一段时间
time.sleep(0.5)
# 让11引脚输出低电平(LED灯灭)
GPIO.output(LedPin, False)
# 持续一段时间
time.sleep(0.5) # 最后清理GPIO口(不做也可以,建议每次程序结束时清理一下,好习惯)
GPIO.cleanup()

效果如图所示:

使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

按键控制LED开关

有了上面的我们再来试试用按键控制LED,很多用过Arduino的应该轻车熟路啦。

#!/usr/bin/env python
# encoding: utf-8 import RPi.GPIO as GPIO
import time # 为保持兼容性,选择GPIO引脚主板编号模式,也就是物理引脚编号
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
LedPin = 11
BtnPin = 13 # 11引脚(LED2)为输出模式,13引脚(Key1)为输入模式
GPIO.setup(LedPin, GPIO.OUT)
GPIO.setup(BtnPin, GPIO.IN) try:
GPIO.output(LedPin, True)
while True:
time.sleep(0.01)
if (GPIO.input(BtnPin)) == False:
GPIO.output(LedPin, False)
else:
GPIO.output(LedPin, True)
except KeyboardInterrupt:
pass # 最后清理GPIO口(不做也可以,建议每次程序结束时清理一下,好习惯)
GPIO.cleanup()

有兴趣的可以做一个防按键抖动(Debounce)版本。

Python控制1602液晶屏显示当前时间

感谢Hugo Zhu的这篇《如何使用Raspberry Pi在1602液晶屏上显示当前时间--电子钟》博文,他的博客非常棒,受益匪浅。以下仍然以BOARD编码为例。

硬件包括LN IO 拓展板;1602液晶屏;USB无线网卡;UPBoard。注意LN IO拓展板将连接帽切换到LCD引脚。

使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

1602液晶屏的引脚定义:

  1. VSS,接地
  2. VDD,接3.3V电源
  3. VO,液晶对比度调节,接电位器中间的引脚(板载R2)
  4. RS,寄存器选择,接PB 03,Pin 29
  5. RW,读写选择,接地,表示写模式
  6. EN,使能信号,接PB 13,Pin 33
  7. D0,数据位0,4位工作模式下不用,不接
  8. D1,数据位1,4位工作模式下不用,不接
  9. D2,数据位2,4位工作模式下不用,不接
  10. D3,数据位3,4位工作模式下不用,不接
  11. D4,数据位4,接GPIO 4,Pin 16
  12. D5,数据位5,接GPIO 5,PIN 18
  13. D6,数据位6,接GPIO 6,PIN 22
  14. D7,数据位7,接GPIO 7,PIN 7
  15. A,液晶屏背光+,接3.3v
  16. K,液晶屏背光-,接地

源代码可以从github页面下载,修改相关引脚序号,如下:

#!/usr/bin/python

#
# based on code from lrvick and LiquidCrystal
# lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py
# LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp
# from time import sleep
from datetime import datetime
from time import sleep class Adafruit_CharLCD: # commands
LCD_CLEARDISPLAY = 0x01
LCD_RETURNHOME = 0x02
LCD_ENTRYMODESET = 0x04
LCD_DISPLAYCONTROL = 0x08
LCD_CURSORSHIFT = 0x10
LCD_FUNCTIONSET = 0x20
LCD_SETCGRAMADDR = 0x40
LCD_SETDDRAMADDR = 0x80 # flags for display entry mode
LCD_ENTRYRIGHT = 0x00
LCD_ENTRYLEFT = 0x02
LCD_ENTRYSHIFTINCREMENT = 0x01
LCD_ENTRYSHIFTDECREMENT = 0x00 # flags for display on/off control
LCD_DISPLAYON = 0x04
LCD_DISPLAYOFF = 0x00
LCD_CURSORON = 0x02
LCD_CURSOROFF = 0x00
LCD_BLINKON = 0x01
LCD_BLINKOFF = 0x00 # flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00 # flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00
LCD_MOVERIGHT = 0x04
LCD_MOVELEFT = 0x00 # flags for function set
LCD_8BITMODE = 0x10
LCD_4BITMODE = 0x00
LCD_2LINE = 0x08
LCD_1LINE = 0x00
LCD_5x10DOTS = 0x04
LCD_5x8DOTS = 0x00 # LN IO Board: RS=PB03=29, EN=PB13=33; DB4-7=GPIO4-7=16,18,22,7
def __init__(self, pin_rs=29, pin_e=33, pins_db=[16,18,22,7], GPIO = None):
# Emulate the old behavior of using RPi.GPIO if we haven't been given
# an explicit GPIO interface to use
if not GPIO:
import RPi.GPIO as GPIO
GPIO.setwarnings(False) self.GPIO = GPIO
self.pin_rs = pin_rs
self.pin_e = pin_e
self.pins_db = pins_db self.GPIO.setmode(GPIO.BOARD)
self.GPIO.setup(self.pin_e, GPIO.OUT)
self.GPIO.setup(self.pin_rs, GPIO.OUT) for pin in self.pins_db:
self.GPIO.setup(pin, GPIO.OUT) self.write4bits(0x33) # initialization
self.write4bits(0x32) # initialization
self.write4bits(0x28) # 2 line 5x7 matrix
self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor
self.write4bits(0x06) # shift cursor right self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS
self.displayfunction |= self.LCD_2LINE """ Initialize to default text direction (for romance languages) """
self.displaymode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) # set the entry mode self.clear() def begin(self, cols, lines): if (lines > 1):
self.numlines = lines
self.displayfunction |= self.LCD_2LINE
self.currline = 0 def home(self): self.write4bits(self.LCD_RETURNHOME) # set cursor position to zero
self.delayMicroseconds(3000) # this command takes a long time! def clear(self): self.write4bits(self.LCD_CLEARDISPLAY) # command to clear display
self.delayMicroseconds(3000) # 3000 microsecond sleep, clearing the display takes a long time def setCursor(self, col, row): self.row_offsets = [ 0x00, 0x40, 0x14, 0x54 ] if ( row > self.numlines ):
row = self.numlines - 1 # we count rows starting w/0 self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row])) def noDisplay(self):
""" Turn the display off (quickly) """ self.displaycontrol &= ~self.LCD_DISPLAYON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def display(self):
""" Turn the display on (quickly) """ self.displaycontrol |= self.LCD_DISPLAYON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noCursor(self):
""" Turns the underline cursor on/off """ self.displaycontrol &= ~self.LCD_CURSORON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def cursor(self):
""" Cursor On """ self.displaycontrol |= self.LCD_CURSORON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noBlink(self):
""" Turn on and off the blinking cursor """ self.displaycontrol &= ~self.LCD_BLINKON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noBlink(self):
""" Turn on and off the blinking cursor """ self.displaycontrol &= ~self.LCD_BLINKON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def DisplayLeft(self):
""" These commands scroll the display without changing the RAM """ self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT) def scrollDisplayRight(self):
""" These commands scroll the display without changing the RAM """ self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT); def leftToRight(self):
""" This is for text that flows Left to Right """ self.displaymode |= self.LCD_ENTRYLEFT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode); def rightToLeft(self):
""" This is for text that flows Right to Left """
self.displaymode &= ~self.LCD_ENTRYLEFT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def autoscroll(self):
""" This will 'right justify' text from the cursor """ self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def noAutoscroll(self):
""" This will 'left justify' text from the cursor """ self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def write4bits(self, bits, char_mode=False):
""" Send command to LCD """ self.delayMicroseconds(1000) # 1000 microsecond sleep bits=bin(bits)[2:].zfill(8) self.GPIO.output(self.pin_rs, char_mode) for pin in self.pins_db:
self.GPIO.output(pin, False) for i in range(4):
if bits[i] == "1":
self.GPIO.output(self.pins_db[::-1][i], True) self.pulseEnable() for pin in self.pins_db:
self.GPIO.output(pin, False) for i in range(4,8):
if bits[i] == "1":
self.GPIO.output(self.pins_db[::-1][i-4], True) self.pulseEnable() def delayMicroseconds(self, microseconds):
seconds = microseconds / float(1000000) # divide microseconds by 1 million for seconds
sleep(seconds) def pulseEnable(self):
self.GPIO.output(self.pin_e, False)
self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
self.GPIO.output(self.pin_e, True)
self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
self.GPIO.output(self.pin_e, False)
self.delayMicroseconds(1) # commands need > 37us to settle def message(self, text):
""" Send string to LCD. Newline wraps to second line""" for char in text:
if char == '\n':
self.write4bits(0xC0) # next line
else:
self.write4bits(ord(char),True) if __name__ == '__main__': lcd = Adafruit_CharLCD()
lcd.noBlink()
# lcd.clear()
# lcd.message("Hello, Jessica!\nHow are you? .....abcdefghijg ")
# lcd.scrollDisplayRight() while True:
sleep(1)
lcd.clear()
lcd.message(datetime.now().strftime(' %I : %M : %S \n%a %b %d %Y'))

每秒更新,显示当前时间,效果如图所示:

使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

进阶

分析代码可知,该代码段可作为1602驱动库,支持1602的基本显示控制。后面可以自定义显示自己的信息,例如做一个小闹钟。

PyCharm远程调试UP Board上的Python程序

由于在UP Board上使用终端界面调试Python确实不很方便(其实是PyCharm用起来太爽了),所以使用Windows 上的PyCharm调试UP Board上的程序,可以直接使用UP的GPIO硬件资源,并且可以非常方便地安装各种库,简直停不下来,当然前文提到的cloud9也不错。远程调试功能只有专业版(Professional)可用,免费的社区版(Community)无此功能。通过edu邮箱验证可以免费使用专业版。

参考这篇文章pycharm 远程调试进行设置即可,注意点如下:

  • 因为我们使用ubilinux移植的RPi.GPIO库,所以解释器只能选择python2
  • 需要启用root账户并更改ssh设置允许root登录
  • 可以通过PyCharm更新UP板上的Python库
sudo passwd root #启用root账户
sudo nano /etc/ssh/sshd_config # 添加 PermitRootLogin yes,Ctrl+O保存,Ctrl+X退出
sudo systemctl restart sshd # 重启SSH服务,使更改生效

效果如图所示:

使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)的更多相关文章

  1. Arduino 1602液晶屏实验和程序

    在Arduino IDE中, 项目->加载库->管理库中搜索LiquidCrystal,然后安装即可 1.接线图 2.引脚图 3.最简单程序 #include <LiquidCrys ...

  2. jquery在网页实时显示时间;

    1.定义一个显示时间的位置 <div id="shijian"> </div> 2.jquery代码 function showTime() { var c ...

  3. 使用pycharm远程调试python代码

    使用 pycharm 进行 python 代码远程调试 pycharm 的远程调试是从远程机器连接到本地机器,需要在远程机器的py文件中指定本地机器的IP和端口. 远程机器上,通过easy_insta ...

  4. 在液晶屏里显示浮点数的方法 &lpar;sprintf 的妙用&rpar;

    思路:使用 sprintf 函数将浮点型数据转为指定格式的字符串 #include <stdio.h> #include<string.h> int main() { unsi ...

  5. &lbrack;DM8168&rsqb;Linux下控制GPIO控制12864液晶屏(ST7565控制器)

    首先加载驱动模块,应用程序通过调用API实现GPIO控制功能. 驱动函数: /* * fileName: st7565_driver.c * just for LCD12864 driver * GP ...

  6. 给基于对话框的MFC程序添加状态栏并实时显示时间

    转载自丝雪儿 1.首先在string table 里添加两个字串,ID分别为IDS_INDICATOR_MESSAGE and IDS_INDICATOR_TIME 2.在你的 dlg.h 类里面加个 ...

  7. js页面实时显示时间

    1.通过getMonth()实现获取月份,从0开始计数,需要+1: 2.通过getDay()实现获取星期天数,从0开始,0表示星期日: 3.通过getDate()获取日期. 4.setTimeout( ...

  8. Python测试进阶——(2)配置PyCharm远程调试环境

    新建一个Python项目 配置Deployment,用于本地文件和远程文件的同步,在pycharm的菜单栏依次找到:Tools > Deployment > Configuration 点 ...

  9. 单片机中不带字库LCD液晶屏显示少量汉字

    单片机中不带字库LCD液晶屏如何显示少量汉字,一般显示汉字的方法有1.使用带字库的LCD屏,2.通过SD 卡或者外挂spi flash存中文字库,3.直接将需要的汉字取模存入mcu的flash中. 第 ...

随机推荐

  1. Codeforces Round &num;389 &lpar;Div&period; 2&comma; Rated&comma; Based on Technocup 2017 - Elimination Round 3&rpar; B

    Description Santa Claus decided to disassemble his keyboard to clean it. After he returned all the k ...

  2. JQuery基础核心

    一.代码风格 在jQuery程序中,不管是页面元素的选择.内置的功能函数,都是美元符号“$”来起始的. 而这个“$”就是jQuery当中最重要且独有的对象:jQuery对象,所以我们在页面元素选择或执 ...

  3. php集成开发环境IDE

    ZendStudio EclipsePHP PhpStorm NetBeans

  4. Docker Machine&comma; Compose&comma; and Swarm&colon; How They Work Together

    The three tools are now neatly packaged into what’s called the Docker Toolbox. Docker Machine1/ crea ...

  5. java 生产者消费者问题 并发问题的解决(转)

    引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 生产者消费者图 ...

  6. leetcode&lbrack;159&rsqb; Longest Substring with At Most Two Distinct Characters

    找到最多含有两个不同字符的子串的最长长度.例如:eoeabc,最长的是eoe为3,其他都为2. 思路: 用p1,p2表示两种字符串的最后一个出现的下标位置.初始p1为0. p2为-1.start初始化 ...

  7. 最新版Solr 7&period;2安装配置

    Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引:也可以通过Http Get操 ...

  8. &lbrack;LeetCode&rsqb; Stickers to Spell Word 贴片拼单词

    We are given N different types of stickers. Each sticker has a lowercase English word on it. You wou ...

  9. hdu 5437Alisha’s Party(优先队列)

    题意:邀请k个朋友,每个朋友带有礼物价值不一,m次开门,每次开门让一定人数p(如果门外人数少于p,全都进去)进来,当所有人到时会再开一次,每次都是礼物价值高的人先进. /*小伙伴最开始gg了,结果发现 ...

  10. 再谈javascriptjs原型与原型链及继承相关问题

    什么是原型语言 只有对象,没有类;对象继承对象,而不是类继承类. “原型对象”是核心概念.原型对象是新对象的模板,它将自身的属性共享给新对象.一个对象不但可以享有自己创建时和运行时定义的属性,而且可以 ...