2.1. CircuitPython内建库

CircuitPython的大部分内建库完全兼容标准的Python3,另外也有一些专门针对嵌入式系统应用的内建库是标准Python3所没有的。 本向导的目的是帮助你快速了解CircuitPython饿内建库。


2.1.1. 流程控制

流程控制是所有计算机编程语言都具备的基础语法,CircuitPython的流程控制包括:

  • if
  • else
  • elif
  • for
  • in
  • while
  • break
  • continue
  • try
  • except
  • return
  • yield

这些基本语法完全兼容标准Python3的流程控制,请查阅Python3的相关参考书掌握他们的用法。

2.1.2. 代码块、行缩进和冒号

所有编程语言都有“代码块”的概念,譬如我们判断“条件A”并根据判断结果执行不同的程序块,即“如果条件A成立则执行程序块1,否则执行程序块2”; 譬如重复执行某个代码块若干次,即“当条件A成立则执行代码块”。Python编程语言采用“行缩进”形式代表程序块:隶属于同一个代码块的全部代码 必须具有相同的行缩进。

示例程序:

1
2
3
4
5
6
7
8
 import time
 from hiibot_bluefi.basedio import LED
 led = LED()
 while True:
     led.white = 1
     time.sleep(0.5)
     led.white = 0
     time.sleep(0.5)

本示例有2个层次的代码块组成,其中第5~8行是一个层次的代码块,这个代码块隶属于第4行“while True:”流程控制语句。前4行是一个层次 的代码块,其中第4行的“:”表示其后有一个代码块。

在使用Python编程语言时,“if、else、elif、for、while、try”等流程控制语句的末尾必须使用“:”表示其后有一个隶属于该流程控制语句的代码块, 其后的代码块的所有程序语句必须具有相同的缩进。值得注意的是,代码块是可以嵌套的。

示例程序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
 import time
 from hiibot_bluefi.basedio import PWMLED
 led = PWMLED()
 b=0
 d=1
 while True:
     led.white = b
     b += 655 if d==1 else -655
     if b>65535:
         b=65535
         d=0
     if b<0:
         b=0
         d=1
     time.sleep(0.01)

本示例有3个层次的4个代码块,除了主程序的代码块之外,“while True:”代码块又包含又两个“if xx:”代码块。

2.1.3. 数据和变量

Python支持的数据和变量类型包括:字符/字符串、数组(array)、元组(turple)、列表(list)、字典(dictionary)等基本类型, 我们可以使用‘单引号’、“双引号”、(小括号)、[中括号]和{大括号}等形式组织基本数据和变量,并使用[index]访问第index个数据项。

Python支持的基本数据包括:整数(int)、浮点数(float)、复数(complex),其中复数由浮点型实部和虚部组成,如a+bj或complex(a,b)的 实部和虚部分别为a和b。

Pthon支持不同数制来表示整数(int),包括二进制、八进制、十进制(默认的)、十六进制等,并又内建库接口实现不同数制之间的转换。

2.1.4. 函数

函数(function)是一种特殊的代码块,允许我们使用函数名调用已定义的函数,调用时可传入若干参数,如果含有有返回值,调用者可以得到 函数的返回值。

示例程序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
  import time
  from hiibot_bluefi.basedio import NeoPixel
  from hiibot_bluefi.soundio import SoundIn
  pixels = NeoPixel()
  pixels.brightness = 0.2
  pixels.clearPixels() # black
  delayCnt = 0
  mic = SoundIn(numSamples=8)

  def delayoff(dt):
      global delayCnt
      time.sleep(dt) # 10ms, x100times=1s
      if delayCnt<=0:
          pixels.clearPixels()
      else:
          delayCnt -= 1

  while True:
      delayoff(0.01)
      if mic.loud_sound(200):
          pixels.fillPixels((255,255,255)) # white
          delayCnt = 1000

本示例程序的第10~16行定义一个名为“delayoff”的函数,有一个输入参数“dt”,无返回值。在第19行语句调用该函数时, 输入参数赋值为0.01,意味着执行该函数时“dt=0.01”。

在Python编程语言中,函数定义必须使用“def”关键词,并使用“:”指定函数的代码块。

2.1.5. 类和对象

类(class)和对象(object)是所有面向对象编程语言都支持的基本功能,允许编程者将同类的数据信息及其操作封装成类,使用者 将类实例化为具体的对象,进而使用类内的数据及其操作方法。

Python的类封装和实例化的对象与其他编程语言相似,但是使用类之前必须使用“import”导入已封装好的类。根据“import”的规则, 我们可以把Python的一个类看作一个模块。

2.1.6. 数学计算

CircuitPython的内建数学计算库——math兼容标准的Python3。使用USB数据线将BlueFi与计算机连接好,你的电脑上将出现 一个名叫“CIRCUITPY”的可卸载磁盘,打开MU编辑器并点击“串口”按钮打开MU控制台,在控制台区域按“ctrl+c”键强制终止BlueFi当前 正在执行的py程序并进入REPL模式,在“>>>”提示符后面输入以下命令:

1
2
3
4
5
6
7
 >>> import math
 >>> dir(math)
 ['__class__', '__name__', 'acos', 'asin', 'atan', 'atan2', 'ceil',
 'copysign', 'cos', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod',
 'frexp', 'isfinite', 'isinf', 'isnan', 'ldexp', 'log', 'modf', 'pi',
 'pow', 'radians', 'sin', 'sqrt', 'tan', 'trunc']
 >>>

使用“import math”首先导入CircuitPython内建的“math”库;使用“dir(math)”可以查看内建的math库所支持的全部数学计算方法。

对于其他内建库,我们可以使用同样的方法获得帮助。

2.1.7. 其他内建库

CircuitPython到底支持多少种内建库?让BlueFi进入REPL模式,并在“>>>”提示符后输入“help(“modules”)”即可查看CircuitPython 支持的全部内建库。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 >>> help("modules")
 __main__          binascii          io                storage
 _bleio            bitbangio         json              struct
 _os               board             math              supervisor
 _pixelbuf         builtins          microcontroller   sys
 _time             busio             micropython       terminalio
 aesio             collections       neopixel_write    time
 analogio          digitalio         os                touchio
 array             displayio         pulseio           ulab
 audiobusio        errno             random            usb_hid
 audiocore         fontio            re                usb_midi
 audiomixer        framebufferio     rgbmatrix         vectorio
 audiomp3          gamepad           rotaryio          watchdog
 audiopwmio        gc                rtc
 Plus any modules on the filesystem
 >>>

对于某一种内建库,可以使用“import xxx”和“dir(xxx)”分别导入并查看接口方法。

如,想要了解“analogio”——模拟输入和输出库,可以使用以下语句:

1
2
3
4
5
6
7
8
9
 >>> import analogio
 >>> dir(analogio)
 ['__class__', '__name__', 'AnalogIn', 'AnalogOut']
 >>> help(analogio)
 object <module 'analogio'> is of type module
   __name__ -- analogio
   AnalogIn -- <class 'AnalogIn'>
   AnalogOut -- <class 'AnalogOut'>
 >>>

可以看到,“analogio”包含2个子类:“AnalogIn”和“AnalogOut”。根据子类的访问方法,进一步地操作:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
 >>> help(analogio.AnalogIn)
 object <class 'AnalogIn'> is of type type
   deinit -- <function>
   __enter__ -- <function>
   __exit__ -- <function>
   value -- <property>
   reference_voltage -- <property>
 >>> help(analogio.AnalogOut)
 object <class 'AnalogOut'> is of type type
   deinit -- <function>
   __enter__ -- <function>
   __exit__ -- <function>
   value -- <property>
 >>>

子类“AnalogIn”包含有两种属性类方法:value和reference_voltage;子类“AnalogOut”仅包含一个属性“value”。 如何使用呢?请在提示符“>>>”后输入以下命令:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
 >>> import analogio
 >>> import board
 >>> a0 = analogio.AnalogIn(board.P0)
 >>> a0.value
 720
 >>> a0.reference_voltage
 3.3
 >>> a0.value
 37760
 >>> a0.value
 0
 >>>

本示例中,前两个语句分别导入内建库“analogio”和“board”,第3行语句将BlueFi的P0端口定义为模拟输入通道,然后 我们就可以使用“AnalogIn”的“value”和“reference_voltage”属性获取P0端口的值以及参考电压。试着用手指放在P0 触摸盘上并读取这个模拟输入通道的值,观察“value”属性值。被触摸或不被触摸时,这个模拟输入通道的属性值是不同的, 这是为什么?

2.1.8. lambda函数

使用lambda定义一些函数非常便捷,譬如

1
2
3
4
5
6
 >>> f = lambda x, y: x**y
 >>> f(2, 3)
 8
 >>> f(8, 3)
 512
 >>>

定义一个名为“f”的lambda函数计算变量x的y次方。

2.1.9. 随机数

CircuitPython内建的随机数发生器库,用法如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 >>> import random
 >>> random.random()
 0.429787
 >>> random.random()
 0.815612
 >>> random.randint(10, 20)
 11
 >>> random.randint(10, 20)
 20
 >>>

第1行导入内建库“random”,使用“random.random()”函数随机地生成一个0.0~1.0之间的浮点数;使用“random.randint(10, 20)”函数 随机地生成一个10~20之间的整数,其中20包含其中,整数随机数发生器函数原型为“random.randint(min, max)”。