前言

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

本文介绍一下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 介绍页面电路原理图

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

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

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

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

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

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

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

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

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

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

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

效果如图所示:

按键控制LED开关

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

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

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

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

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

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

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页面下载,修改相关引脚序号,如下:

  1. #!/usr/bin/python
  2. #
  3. # based on code from lrvick and LiquidCrystal
  4. # lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py
  5. # LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp
  6. #
  7. from time import sleep
  8. from datetime import datetime
  9. from time import sleep
  10. class Adafruit_CharLCD:
  11. # commands
  12. LCD_CLEARDISPLAY = 0x01
  13. LCD_RETURNHOME = 0x02
  14. LCD_ENTRYMODESET = 0x04
  15. LCD_DISPLAYCONTROL = 0x08
  16. LCD_CURSORSHIFT = 0x10
  17. LCD_FUNCTIONSET = 0x20
  18. LCD_SETCGRAMADDR = 0x40
  19. LCD_SETDDRAMADDR = 0x80
  20. # flags for display entry mode
  21. LCD_ENTRYRIGHT = 0x00
  22. LCD_ENTRYLEFT = 0x02
  23. LCD_ENTRYSHIFTINCREMENT = 0x01
  24. LCD_ENTRYSHIFTDECREMENT = 0x00
  25. # flags for display on/off control
  26. LCD_DISPLAYON = 0x04
  27. LCD_DISPLAYOFF = 0x00
  28. LCD_CURSORON = 0x02
  29. LCD_CURSOROFF = 0x00
  30. LCD_BLINKON = 0x01
  31. LCD_BLINKOFF = 0x00
  32. # flags for display/cursor shift
  33. LCD_DISPLAYMOVE = 0x08
  34. LCD_CURSORMOVE = 0x00
  35. # flags for display/cursor shift
  36. LCD_DISPLAYMOVE = 0x08
  37. LCD_CURSORMOVE = 0x00
  38. LCD_MOVERIGHT = 0x04
  39. LCD_MOVELEFT = 0x00
  40. # flags for function set
  41. LCD_8BITMODE = 0x10
  42. LCD_4BITMODE = 0x00
  43. LCD_2LINE = 0x08
  44. LCD_1LINE = 0x00
  45. LCD_5x10DOTS = 0x04
  46. LCD_5x8DOTS = 0x00
  47. # LN IO Board: RS=PB03=29, EN=PB13=33; DB4-7=GPIO4-7=16,18,22,7
  48. def __init__(self, pin_rs=29, pin_e=33, pins_db=[16,18,22,7], GPIO = None):
  49. # Emulate the old behavior of using RPi.GPIO if we haven't been given
  50. # an explicit GPIO interface to use
  51. if not GPIO:
  52. import RPi.GPIO as GPIO
  53. GPIO.setwarnings(False)
  54. self.GPIO = GPIO
  55. self.pin_rs = pin_rs
  56. self.pin_e = pin_e
  57. self.pins_db = pins_db
  58. self.GPIO.setmode(GPIO.BOARD)
  59. self.GPIO.setup(self.pin_e, GPIO.OUT)
  60. self.GPIO.setup(self.pin_rs, GPIO.OUT)
  61. for pin in self.pins_db:
  62. self.GPIO.setup(pin, GPIO.OUT)
  63. self.write4bits(0x33) # initialization
  64. self.write4bits(0x32) # initialization
  65. self.write4bits(0x28) # 2 line 5x7 matrix
  66. self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor
  67. self.write4bits(0x06) # shift cursor right
  68. self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF
  69. self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS
  70. self.displayfunction |= self.LCD_2LINE
  71. """ Initialize to default text direction (for romance languages) """
  72. self.displaymode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
  73. self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) # set the entry mode
  74. self.clear()
  75. def begin(self, cols, lines):
  76. if (lines > 1):
  77. self.numlines = lines
  78. self.displayfunction |= self.LCD_2LINE
  79. self.currline = 0
  80. def home(self):
  81. self.write4bits(self.LCD_RETURNHOME) # set cursor position to zero
  82. self.delayMicroseconds(3000) # this command takes a long time!
  83. def clear(self):
  84. self.write4bits(self.LCD_CLEARDISPLAY) # command to clear display
  85. self.delayMicroseconds(3000) # 3000 microsecond sleep, clearing the display takes a long time
  86. def setCursor(self, col, row):
  87. self.row_offsets = [ 0x00, 0x40, 0x14, 0x54 ]
  88. if ( row > self.numlines ):
  89. row = self.numlines - 1 # we count rows starting w/0
  90. self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row]))
  91. def noDisplay(self):
  92. """ Turn the display off (quickly) """
  93. self.displaycontrol &= ~self.LCD_DISPLAYON
  94. self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
  95. def display(self):
  96. """ Turn the display on (quickly) """
  97. self.displaycontrol |= self.LCD_DISPLAYON
  98. self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
  99. def noCursor(self):
  100. """ Turns the underline cursor on/off """
  101. self.displaycontrol &= ~self.LCD_CURSORON
  102. self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
  103. def cursor(self):
  104. """ Cursor On """
  105. self.displaycontrol |= self.LCD_CURSORON
  106. self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
  107. def noBlink(self):
  108. """ Turn on and off the blinking cursor """
  109. self.displaycontrol &= ~self.LCD_BLINKON
  110. self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
  111. def noBlink(self):
  112. """ Turn on and off the blinking cursor """
  113. self.displaycontrol &= ~self.LCD_BLINKON
  114. self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
  115. def DisplayLeft(self):
  116. """ These commands scroll the display without changing the RAM """
  117. self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT)
  118. def scrollDisplayRight(self):
  119. """ These commands scroll the display without changing the RAM """
  120. self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT);
  121. def leftToRight(self):
  122. """ This is for text that flows Left to Right """
  123. self.displaymode |= self.LCD_ENTRYLEFT
  124. self.write4bits(self.LCD_ENTRYMODESET | self.displaymode);
  125. def rightToLeft(self):
  126. """ This is for text that flows Right to Left """
  127. self.displaymode &= ~self.LCD_ENTRYLEFT
  128. self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
  129. def autoscroll(self):
  130. """ This will 'right justify' text from the cursor """
  131. self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT
  132. self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
  133. def noAutoscroll(self):
  134. """ This will 'left justify' text from the cursor """
  135. self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT
  136. self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
  137. def write4bits(self, bits, char_mode=False):
  138. """ Send command to LCD """
  139. self.delayMicroseconds(1000) # 1000 microsecond sleep
  140. bits=bin(bits)[2:].zfill(8)
  141. self.GPIO.output(self.pin_rs, char_mode)
  142. for pin in self.pins_db:
  143. self.GPIO.output(pin, False)
  144. for i in range(4):
  145. if bits[i] == "1":
  146. self.GPIO.output(self.pins_db[::-1][i], True)
  147. self.pulseEnable()
  148. for pin in self.pins_db:
  149. self.GPIO.output(pin, False)
  150. for i in range(4,8):
  151. if bits[i] == "1":
  152. self.GPIO.output(self.pins_db[::-1][i-4], True)
  153. self.pulseEnable()
  154. def delayMicroseconds(self, microseconds):
  155. seconds = microseconds / float(1000000) # divide microseconds by 1 million for seconds
  156. sleep(seconds)
  157. def pulseEnable(self):
  158. self.GPIO.output(self.pin_e, False)
  159. self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
  160. self.GPIO.output(self.pin_e, True)
  161. self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
  162. self.GPIO.output(self.pin_e, False)
  163. self.delayMicroseconds(1) # commands need > 37us to settle
  164. def message(self, text):
  165. """ Send string to LCD. Newline wraps to second line"""
  166. for char in text:
  167. if char == '\n':
  168. self.write4bits(0xC0) # next line
  169. else:
  170. self.write4bits(ord(char),True)
  171. if __name__ == '__main__':
  172. lcd = Adafruit_CharLCD()
  173. lcd.noBlink()
  174. # lcd.clear()
  175. # lcd.message("Hello, Jessica!\nHow are you? .....abcdefghijg ")
  176. # lcd.scrollDisplayRight()
  177. while True:
  178. sleep(1)
  179. lcd.clear()
  180. lcd.message(datetime.now().strftime(' %I : %M : %S \n%a %b %d %Y'))

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

进阶

分析代码可知,该代码段可作为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库
  1. sudo passwd root #启用root账户
  2. sudo nano /etc/ssh/sshd_config # 添加 PermitRootLogin yes,Ctrl+O保存,Ctrl+X退出
  3. sudo systemctl restart sshd # 重启SSH服务,使更改生效

效果如图所示:

使用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. 在液晶屏里显示浮点数的方法 (sprintf 的妙用)

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

  5. [DM8168]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. Day15模块(导入,使用)

    Day15模块 什么是模块: 一系列功能的集合体 一个py文件就是一个模块 aaa.py就是aaa模块 模块四种形式: 内置的模块 py文件 第三方的 包 模块三种来源:内置的,第三方,自定义 为什么 ...

  2. invalid LOC header (bad signature)

    [产生原因] 本地maven仓库相关jar存在问题. [解决方案] 删除本地maven相关jar并重新下载.

  3. PHP-redis命令之 散列(hashes)

    二.散列(hashes) 1.hset:设置散列的值 $redis->hset('myhas','field1','hello'); $redis->hset('myhas','field ...

  4. 自学入门 Python 优质中文资源索引

    所有资源基于 Python3 版本,全部中文内容,适用于 爬虫 / Web / 数据 方向,每个单元根据学习习惯从 书籍 / 文档 / 视频 中选择一类即可,建议任选一本书籍,然后配合文档类进行学习. ...

  5. HDU 4003 Find Metal Mineral

    这个题是POJ1849的加强版. 先说一个很重要的结论,下面两种方法都是从这个结论出发的. 一个人从起点遍历一颗树,如果最终要回到起点,走过的最小权值就是整棵树的权值的2倍. 而且K个人的情况也是如此 ...

  6. 00051_static关键字

    1.static概念 当在定义类的时候,类中都会有相应的属性和方法.而属性和方法都是通过创建本类对象调用的.当在调用对象的某个方法时,这个方法没有访问到对象的特有数据时,方法创建这个对象有些多余.可是 ...

  7. swift写一个简单的列表unable to dequeue a cell with identifier reuseIdentifier - must register a nib or a cla

    报错:unable to dequeue a cell with identifier reuseIdentifier - must register a nib or a class for the ...

  8. wp8.1 sdk preview 预览版

    http://pan.baidu.com/s/1hqyusja?qq-pf-to=pcqq.c2c#dir/path=%2FWPSDK%208.1%20DevPreview%20Installerwp ...

  9. Wordpress无法上传图片

    当在自己新搭建的个人网站添加文章的时候,我遇到了wordpress最普遍的第一个问题——无法上传图片.     每次图片上传完成之后跳出如上图无法建立目录的警告,根据提示首先确定是否有修改文件的权限通 ...

  10. redis主从原理介绍(三)

    博客参考:散尽浮华的Redis主从复制下的工作原理梳理 此作者写的非常好,此处只做挪用,方便自己查看. Redis主从复制的配置十分简单,它可以使从服务器是主服务器的完全拷贝.需要清除Redis主从复 ...