0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何学习使用CircuitPython

454398 来源:网络整理 作者:网络整理 2019-11-28 17:27 次阅读

概述

有几种编程微控制器的方法。有些方法比其他方法困难,这通常取决于人们对编程基础的熟悉程度。

本指南主要供Arduino开发人员通过演示程序的使用来学习使用CircuitPython的来龙去脉。两种语言的代码。这可能是对人们熟悉CircuitPython技能的参考。

同样有效的可能是从未使用过Arduino的Python或CircuitPython程序员。显示Arduino用于各种用途的代码可能有助于使自己更适应Arduino环境。

来源:https://www.xkcd.com/303/(CC BY-NC 2.5)

解释与编译

Arduino从大量使用中的工具中获取了很多东西数十年。这包括已编译代码的概念。代码是在没有调试的情况下在文本编辑器类型的环境中编写的。然后,在被命令时,将其馈送到一系列程序,这些程序将获取代码,最后将其从C或C ++编译为微控制器的机器语言。在市场上有各种各样的微控制器,机器代码是该代码和处理器所独有的。

如果需要在Arduino中更改代码,则必须编辑文本代码并通过编译过程将其提交回去。 。在每次发生的编译和加载过程中,进行更改,修复语法错误,“插入”最佳值可能会花费大量时间。

Python通常和CircuitPython特别是解释的。直到必须将代码转换为机器代码。这有很多优点。该代码可以在运行时给出错误消息。随后的任何更改都不需要重新编译。加载代码就像将代码文本文件复制到闪存驱动器一样简单。 CircuitPython程序开发通常只是Arduino程序所需时间的一小部分。该代码对于其他微控制器也具有高度的可移植性。

解释的代码的缺点是速度。将代码转换为机器代码是即时进行的,因此需要时间。解释器还使用微控制器上的RAM和Flash,而不是等效的Arduino用户代码和库。

材料:MS Word 2010剪贴画

Reality

现代微控制器的速度和存储容量不断提高,其价格通常与较旧的微控制器相似或更低(制造商可能希望在某个时候停产)。在现代芯片中,在微控制器上使用Python不会带来速度上的损失。 Python的灵活性以及在学校中教授的灵活性的优势使Python成为人们关注的焦点。

在这个时代,提供帮助将Arduino编码器迁移到CircuitPython的工具似乎特别合适,因为这无疑是行业发展的方向

您可能会很慢,但仍然会赢。而且乌龟的寿命很长。

计算机Python

Linux板呢?

Arduino代码通常不能在Raspberry PiBeagleBone等小型Linux板上运行。为什么?

Linux是一个完整的操作系统,它可以一次运行许多东西。 Arduino代码必须学会共享资源,而不要使用整个处理器,尤其是在无限循环中。也许有一天会添加此功能,但现在不可用。

Python在Linux板上非常流行。 CircuitPython可以通过Adafruit提供的名为Blinka的帮助程序层在小型Linux板上运行。这提供了CircuitPython在微控制器上可以做什么以及如何在Linux上运行之间所需的映射。它们旨在共同发挥作用(只要您的代码也写得很好。

因此,对于基于Linux的小型单板计算机,CircuitPython是目前的唯一选择。但这是一个不错的选择。

在本指南中,我们将不介绍在Linux上通过CircuitPython使用硬件的详细信息。在此处查看有关Blinka的指南

简单的代码结构

Arduino strong》

上图显示了最简单的Arduino程序,即从菜单中选择文件-》 新建会得到的结果。有两个强制性函数调用:

setup-程序启动时将执行一次的代码

loop-连续的代码一遍又一遍地循环运行

这两个函数都不做任何事情。有些草图仅在setup中执行所有操作,而有些程序根本不使用setup而仅使用loop。但是,即使它们是空的(如上所示),也必须同时定义两者。

CircuitPython

CircuitPython并没有限制像Arduino setup函数这样的开始执行的代码重复的主要代码,例如Arduino loop函数。

也就是说,许多CircuitPython程序的结构与Arduino素描程序的结构非常相似。

一个简单的示例。程序将变量var定义为值5,然后一遍又一遍地打印该值,类似于旧的BASIC Hello World程序。在Arduino中,您可以这样编写:

程序会添加一些代码以打开串行连接并输出输出。

等效的CircuitPython程序为:

任何setup类型语句放在程序顶部附近。

可以在Python中通过loop循环将条件设置为while,因此它永远不会退出True。

串行监视器已“嵌入”到CircuitPython中,用户无需设置任何内容即可使用它,并且将对此进行详细讨论。

没有任何限制,CircuitPython完全必须执行无限循环。一个简单的程序可以读取温度传感器,打印输出并结束。

但是,Arduino和CircuitPython都在微控制器上运行。在课堂上,您可能想要做一次读取和打印温度值之类的操作。如果将这个项目部署到农民的田地中,它可能会一遍又一遍地反复读取温度,可能每分钟或一小时读取一次。在农民的田野里,代码永远都不应停止。

因此执行某些功能的无限循环非常有用,并且在大多数微控制器程序中都使用。这就是Arduino为初学者简化事情的原因,以表明您可能想拥有while和setup。您可以在CircuitPython中执行完全相同的操作,只需构建代码以提供相同的功能即可。

处理数字

照片Nick Hillier在Unsplash上发表的文章

您会认为所有语言中的“数字就是数字”,但事实并非如此。所有数字在内部都以二进制形式在微控制器/计算机内部表示,但是编程语言如何提供数字支持会因语言而异。

数字类型

整数

浮点数

布尔值(true/false)

通常,您需要了解 precision -选择最佳的使用方式,数字的大小可能是多少它在计算机程序中。这使使用数字有些棘手,但学习起来却很容易。

Arduino

在Arduino中,您具有以下类型的变量:

int 表示整数,一个值没有小数点。整数的典型范围是-32,768到零到32,767。例如279、1001、0,-23,-990。

long 是一个大整数,值可以是-2,147,483,648到2,147,483,647。

float (浮点数)(浮点数(带小数点和小数的数字))。例子是3.1415,-22.2、0.0、430000.01。单个字符的数字最大为38 x的3 x 10

char 。例如,读取串行数据可能涉及在接收到数据时提供字符值的接收功能。字符基本上可以是键盘上的任何符号(0到255)。

types.h 库提供了趋于表现的数字的更现代表示形式

函数经常使用无符号短整数 uint8_t ,它的范围也从0到255。

布尔数学通常使用 int 值完成。 0是 false ,而任何非零的值(例如1)都是 true 。

Python/CircuitPython

CircuitPython尝试尽可能接近标准的Python实现(通常称为CPython) 。给定微控制器没有操作系统,某些事情会有所不同,但已记录在案。

以下是CircuitPython中的当前类型:

整数,但不是当前的长整数

浮点数。

字符串

布尔值

布尔值是CircuitPython中的实际类型,可以是值 True 或 False 。

CircuitPython具有专用的 Strings 类型,而不是像Arduino那样使用字符数组(以零/零终止)。请注意,CircuitPython 字符串不是以零/零结尾的,所以使用length属性是您处理字符串长度的方法。

更改数字类型

在Arduino/C中,这称为转换。

下载:文件

复制代码

int a;

float b;

b = (float)a;

a = (int)b; int a;

float b;

b = (float)a;

a = (int)b;

在CircuitPython中,您使用类似于函数的语法:

下载:文件

复制代码

x = 5

y = 3.14

z = float(x)

z = int(y) x = 5

y = 3.14

z = float(x)

z = int(y)

除法,一个斜杠对两个斜杠

两种语言中的单个正斜杠/是浮点除法。

Python中的双斜杠//很特殊。它将除以小数点后的任何值(通常称为下限函数)并进行除法。

示例:

下载:文件

复制代码

# Python code for / and // operators

x = 15

y = 4

# Output: x / y = 3.75

print(‘x / y =’, x/y)

# Output: x // y = 3

print(‘x // y =’, x//y) # Python code for / and // operators

x = 15

y = 4

# Output: x / y = 3.75

print(‘x / y =’, x/y)

# Output: x // y = 3

print(‘x // y =’, x//y)

逻辑运算符

逻辑运算符主要用于if语句和其他块/循环语句中。这些不是用于按位运算符和/或/或仅用于构造逻辑比较的运算符。

AND

OR

不是

Arduino/C

&&

||

!Python/CircuitPython

不是

下载:文件

复制代码

// Arduino / C Logical Operators

a = 5;

b = 7;

if( a 》 2 && b 《 10) {

Serial.println(“Success”);

} // Arduino / C Logical Operators

a = 5;

b = 7;

if( a 》 2 && b 《 10) {

Serial.println(“Success”);

}

下载:文件

复制代码

# CircuitPython Logical Operators

a = 5

b = 7

if a 》 2 and b 《 10:

print(“Success”) # CircuitPython Logical Operators

a = 5

b = 7

if a 》 2 and b 《 10:

print(“Success”)

变量,类型,范围

从Wikipedia中,没有列出创建者

快速参考

变量

Arduino

int a;

int b = 5;

CircuitPython

b = 5

阵列

Arduino

int a[5];

int a = {1, 2, 3, 4, 5};

CircuitPython

a = [1, 2, 3, 4, 5]

讨论

变量

变量就像计算机内存中的小盒子或信箱,可以在其中保留值。

要在C/C ++中创建变量,必须对其进行声明。这就需要给它一个类型,名称和可选的值。

下载:文件

复制代码

int a;

int b = 5; int a;

int b = 5;

在CircuitPython中,您无需声明变量。第一次分配值时便会分配它们。

下载:文件

复制代码

b = 5 b = 5

您只需使用名称即可在两种语言中使用变量的值。

下载:文件

复制代码

int x = a_number; // in C/C++

x = a_number # in CircuitPython int x = a_number; // in C/C++

x = a_number # in CircuitPython

在两种语言中,使用未知变量都是错误的:尚未声明(在C/C ++中)或未初始化(在CircuitPython中)

在C/C ++中,变量使用类型声明,并被静态类型化。它们仅具有该类型的值。

相反,CircuitPython是动态类型的。变量没有关联的类型,并且可以在不同时间具有不同类型的值。每种方法都有优点和缺点,但是在阅读某人的CircuitPython代码时,您应该记住这一点,以防某人重复使用变量并更改其类型。

集合

两种语言都可以创建和操作值的集合。

“终极”-比其他任何集合都要好。只是不要单击它。

(来自维基百科的图像,已获得合理使用许可)

Arduino

Arduino只有一种创建集合作为语言一部分的方法:数组。由于语言是C ++,因此您可以使用大多数C ++库。具有足够的CPU性能和内存,您甚至可以将Arduino版本的标准C ++和Boost库及其集合类一起使用,但是出于讨论的目的,我们假设您使用的是基本语言功能。 p》

数组是简单的固定大小,固定顺序的值序列。 C数组中的所有值都具有相同的类型。实际上,由于C是静态类型的,所以数组项的类型是数组本身类型的一部分。

例如,如果要创建一个可以容纳5个变量int中的值,您可以将其声明为:

下载:文件

复制代码

a int a[5];

如果在编译时已知初始值,则可以初始化数组创建时,并忽略其大小,因为将从初始值的数量中推断出大小。

下载:文件

复制代码

int a[5]; int a[] = {1, 2, 3, 4, 5};

要访问数组中的特定项目,请使用下标符号。可以用来从数组中获取值,或将其设置为新值。

下载:文件

复制代码

int a[] = {1, 2, 3, 4, 5}; int x = a[0];

a[1] = x + 1;

CircuitPython 》

基本的CircuitPython集合是List,其外观和工作方式与C的数组非常相似。但是,它是一个动态得多的结构:您可以自由地删除和插入项目。它的长度是其中当前有多少个项目的函数,而不是它要保留的内容的函数。由于它们是动态的,因此通常不需要提前分配它们。您可以通过将项目放在方括号中来创建列表。

下载:文件

复制代码

int x = a[0];

a[1] = x + 1; 》》》 a = [1, 2, 3, 4, 5]

与C数组一样,您使用下标符号来访问项目。

下载:文件

复制代码

》》》 a = [1, 2, 3, 4, 5] x = a[0]

a[1] = x + 1

CircuitPython的列表提供了比C数组更多的功能,但这超出了本指南的范围。 CircuitPython还具有其他内置集合:元组和字典。请参阅本指南,了解有关Python的基本数据结构,以及该指南的更多内容,重点是列表和流。

Arduino/C和Python都在0处开始元素/数组组。因此对于3元素项,它是x [0],x [1],x [2],这与某些语言(例如FORTRAN)在数组处开始元素1。

范围

来自Elborgo用户的维基百科

变量的作用域是代码中何时何地可用。 C/C ++和CircuitPython都在词法范围内。这意味着变量的范围由代码的结构定义。如果您在函数中创建变量,则该变量在该函数中可用,但不在外部。

下载:文件

复制代码

x = a[0]

a[1] = x + 1 void f() {

int a = 5;

print(a); // 1

}

print(a); // 2

由于void f() {

int a = 5;

print(a); // 1

}

print(a); // 2为范围。即它在函数a中定义,可以使用。但是,第2行会导致编译错误,因为此时名称f尚不清楚。在CircuitPython中,情况类似:

下载:文件

复制代码

a def f():

a = 5

print(a) # 1

print(a) # 2

Local and Global

上面的代码说明了本地状态。即局部于功能。这就是为什么从函数外部引用变量是一个问题。另一个范围是全局范围。在整个代码中都可以使用具有全局范围的内容。

下载:文件

复制代码

def f():

a = 5

print(a) # 1

print(a) # 2 int b = 1;

void f() {

int a = 5;

print(a + b);

}

print(b);

// prints:

// 6

// 1

这是可行的,因为int b = 1;

void f() {

int a = 5;

print(a + b);

}

print(b);

// prints:

// 6

// 1具有全局作用域,因此可以在。在CircuitPython中也是如此。

下载:文件

复制代码

b f

如果我们具有相同名称但在两个作用域中都有变量,该怎么办。现在事情开始不同了。在C/C ++中没有麻烦。

Download:file

Copy代码

b = 1

def f():

a = 5

print(a + b)

print(b)

# prints:

# 6

# 1 b = 1

def f():

a = 5

print(a + b)

print(b)

# prints:

# 6

# 1

但是,CircuitPython中的工作方式却大不相同。

下载:文件

复制代码

int a = 1;

void f() {

int a = 5;

print(a);

}

print(a);

// prints:

// 5

// 1 int a = 1;

void f() {

int a = 5;

print(a);

}

print(a);

// prints:

// 5

// 1

a = 1

def f():

a = 5 # 1

print(a)

print(a)

# prints:

# 5

# 1的分配可能存在问题。这是因为在本地作用域中没有名为“ a”的变量,因此将创建一个变量,因为这是该作用域中对a = 1

def f():

a = 5 # 1

print(a)

print(a)

# prints:

# 5

# 1的第一个赋值。对于该功能的其余部分,将使用此局部变量a,并且将保持不变(且未使用)全局范围内的变量a。

如果这正是您想要的,很好。但是,您的意图可能是将全局a的值更改为5。如果是这种情况,那么您就有问题了。像pylint这样的工具将提醒您以下事实:外部范围(在本例中为全局范围)的名称“ a”正在重新定义。那至少会引起您的注意。如果确实要使用全局a,则可以使用a语句告诉CircuitPython这是您的意图。

下载:文件

复制代码

a global

现在pylint可能会警告您,您正在使用全局语句。这是因为全局变量通常不被接受。但是用一个简单的脚本就可以了(在作者看来)。在更大,结构更强的程序中,它们使用较少,您有办法避免使用它们。

CircuitPython和C/C ++不能共享的一项有趣功能是能够关闭。

数字输入/输出

格雷厄姆·詹金斯(Grahame Jenkins)提供的UnSplash免费许可证

微控制程序的一部分正在使用I/O。 I/O的最基本形式是数字I/O引脚。这些被称为GPIO引脚( G 通用 P 设置 I 输入 O utput)

快速参考 配置输出引脚

Arduino

pinMode(13, OUTPUT);

CircuitPython

import digitalio

import board

led = digitalio.DigitalInOut(board.D13)

led.direction = digitalio.Direction.OUTPUT

为输入引脚配置而不上拉

Arduino

pinMode(13, INPUT);

CircuitPython

import digitalio

import board

button_a = digitalio.DigitalInOut(board.BUTTON_A)

button_a.direction = digitalio.Direction.INPUT

配置带有上拉的输入引脚

Arduino

pinMode(13, INPUT_PULLUP);

CircuitPython

import digitalio

import board

button_a = digitalio.DigitalInOut(board.BUTTON_A)

button_a.direction = digitalio.Direction.INPUT

button_a.pull = digitalio.Pull.UP

从引脚读取

Arduino

int pinValue = digitalRead(inputPin);

CircuitPython

pinValue = button_a.value

写到别针

Arduino

digitalWrite(13, HIGH);

digitalWrite(13, LOW);

CircuitPython

led.value = True

led.value = False

讨论

配置数字I/O引脚

在使用引脚进行输入或输出之前,必须对其进行配置。这涉及将其设置为输入或输出,以及在需要时附加上拉或下拉。

Arduino

Arduino框架提供了pinMode为此。它带有两个参数

正在配置的引脚号。您以后可以使用相同的引脚号来使用I/O线

模式:INPUT,OUTPUT或INPUT_PULLUP。

要将标准的插针13板载LED设置为可用,您将使用:

下载:文件

复制代码

pinMode(13, OUTPUT); pinMode(13, OUTPUT);

CircuitPython

在CircuitPython中,还有很多工作要做。您需要创建一个DigitalInOut实例。为此,您必须首先导入digitalio模块。像在Arduino示例中一样,给它提供要使用的引脚号。

在上面的Arduino示例中,我们如何知道要使用的引脚号?简短的答案是我们刚刚做了。在此示例中,一个约定是板载LED位于引脚13上。对于其他GPIO引脚,您需要检查所使用的板,以查看可用的引脚以及将电路连接到的引脚。

在Arduino中,没有编译时检查您选择的引脚是否有效或存在。 CircuitPython只允许您使用板子知道的管脚,这可以防止您输入错误。

(如果您导入板子模块(稍后再介绍),您可以使用它列出可用的管脚。 )

下载:文件

复制代码

》》》 import digitalio

》》》 import board

》》》 led = digitalio.DigitalInOut(board.D13)

》》》 led.direction = digitalio.Direction.OUTPUT 》》》 import digitalio

》》》 import board

》》》 led = digitalio.DigitalInOut(board.D13)

》》》 led.direction = digitalio.Direction.OUTPUT

如果需要输入,可以使用digitalio.Direction.INPUT,如果需要设置上拉,则可以单独进行。

下载:文件

复制代码

》》》 import digitalio

》》》 import board

》》》 button_a = digitalio.DigitalInOut(board.BUTTON_A)

》》》 button_a.direction = digitalio.Direction.INPUT

》》》 button_a.pull = digitalio.Pull.UP 》》》 import digitalio

》》》 import board

》》》 button_a = digitalio.DigitalInOut(board.BUTTON_A)

》》》 button_a.direction = digitalio.Direction.INPUT

》》》 button_a.pull = digitalio.Pull.UP

CircuitPython运行的SAMD板还支持在输入引脚上设置下拉。为此,您将使用

下载:文件

复制代码

》》》 pin.pull = digitalio.Pull.DOWN 》》》 pin.pull = digitalio.Pull.DOWN

使用数字I/O引脚

现在您已经设置了引脚,如何读取和写入值?

Arduino

该框架提供了digitalRead函数,该函数以引脚号作为参数。

下载:文件

复制代码

int pinValue = digitalRead(inputPin); int pinValue = digitalRead(inputPin);

从digitalRead返回的值是int类型,将是常量HIGH或LOW之一。

digitalWrite功能用于设置引脚值。它的参数是引脚号和将其设置为的值:HIGH或LOW。例如,假设已如上所述将其设置为输出,则打开连接到引脚13的LED,您可以使用:

下载:文件

复制代码

digitalWrite(13, HIGH); digitalWrite(13, HIGH);

并关闭它:

下载:文件

复制代码

digitalWrite(13, LOW); digitalWrite(13, LOW);

此处的示例显示了如何使用数字输出引脚来闪烁内置的LED:微控制器编程的事实上的 Hello World 。

下载:文件

复制代码

void setup()

{

pinMode(13, OUTPUT); // sets the digital pin 13 as output

}

void loop()

{

digitalWrite(13, HIGH); // sets the digital pin 13 on

delay(1000); // waits for a second

digitalWrite(13, LOW); // sets the digital pin 13 off

delay(1000); // waits for a second

}

void setup()

{

pinMode(13, OUTPUT); // sets the digital pin 13 as output

}

void loop()

{

digitalWrite(13, HIGH); // sets the digital pin 13 on

delay(1000); // waits for a second

digitalWrite(13, LOW); // sets the digital pin 13 off

delay(1000); // waits for a second

}

将数字输入和输出放在一起,下面是一个示例,该示例从开关读取并控制LED作为响应。

下载:文件

复制代码

int ledPin = 13; // LED connected to digital pin 13

int inPin = 7; // pushbutton connected to digital pin 7

int val = 0; // variable to store the read value

void setup()

{

pinMode(ledPin, OUTPUT); // sets the digital pin 13 as output

pinMode(inPin, INPUT); // sets the digital pin 7 as input

}

void loop()

{

val = digitalRead(inPin); // read the input pin

digitalWrite(ledPin, val); // sets the LED to the button‘s value

} int ledPin = 13; // LED connected to digital pin 13

int inPin = 7; // pushbutton connected to digital pin 7

int val = 0; // variable to store the read value

void setup()

{

pinMode(ledPin, OUTPUT); // sets the digital pin 13 as output

pinMode(inPin, INPUT); // sets the digital pin 7 as input

}

void loop()

{

val = digitalRead(inPin); // read the input pin

digitalWrite(ledPin, val); // sets the LED to the button’s value

}

CircuitPython

假设led和switch的设置如上所述。

输入引脚可以通过查询其value属性进行读取:

下载:文件

复制代码

》》》 button_a.value 》》》 button_a.value

我们可以通过设置value属性来打开和关闭led = 1》反对一个布尔值:

下载:文件

复制代码

DigitalInOut 》》》 led.value = True

》》》 led.value = False

要在CircuitPython中实现闪烁的演示,我们将做一些类似的事情:

下载:文件

复制代码

》》》 led.value = True

》》》 led.value = False 》》》 import time

》》》 import digitalio

》》》 import board

》》》 led = digitalio.DigitalInOut(board.D13)

》》》 led.direction = digitalio.Direction.OUTPUT

》》》 while True:

。.. led.value = True

。.. time.sleep(0.5)

。.. led.value = False

。.. time.sleep(0.5)

模拟输入

快速参考

配置模拟输入引脚

Arduino

不需要

CircuitPython

import board

import analogio

adc = analogio.AnalogIn(board.A0)

使用模拟输入引脚

Arduino

int val = analogRead(3);

CircuitPython

adc.value

讨论

配置模拟输入引脚

Arduino

配置模拟输入引脚不需要任何特殊操作。需要以与数字输出引脚相同的方式将模拟输出引脚配置为输出。请注意,仅某些引脚可以用作模拟引脚。查看特定电路板的文档以查找哪些电路板。

CircuitPython

在CircuitPython中使用模拟引脚类似于

像以前一样,使用board模块可以按名称访问正确的引脚。另外,analogio模块为您提供模拟I/O类。

要读取模拟输入,您需要创建AnalogIn的实例:

下载:文件

复制代码

》》》 import board

》》》 import analogio

》》》 adc = analogio.AnalogIn(board.A0) 》》》 import board

》》》 import analogio

》》》 adc = analogio.AnalogIn(board.A0)

要设置模拟输出,请创建一个AnalogOut实例。

下载:文件

复制代码

》》》 import board

》》》 import analogio

》》》 led = analogio.AnalogOut(board.A0) 》》》 import board

》》》 import analogio

》》》 led = analogio.AnalogOut(board.A0)

使用模拟输入引脚

Arduino

模拟I/O与数字类似。不同的板可以具有不同数量和位置的模拟引脚。查看您的文档以获取有关主板功能的详细信息。

下载:文件

复制代码

int val = analogRead(3); int val = analogRead(3);

返回的值是一个介于0和1023之间(包括0和1023)的int。该范围假设一个10位模数转换器。通常,模数转换器中的位数决定范围,范围是0到2 bits -1。例如。一个12位转换器将得出0到4095之间的值。请参考您开发板的文档以找到转换器的大小。

CircuitPython

具有上面所示的AnalogIn对象后,只需获取其value属性:

下载:文件

复制代码

adc.value adc.value

在CircuitPython中,模拟如上所示,您输入的输入值将始终在0到65535之间。这并不意味着总会有一个16位转换器。相反,将从转换器读取的值映射到16位范围。这使您不必担心板上的转换器的详细信息。

AnalogIn对象为您提供了一种方便的方法来查询转换器的参考电压,因此如果您需要了解要测量实际电压,只需使用以下代码即可。请记住,其结果将根据引脚上的电压以及参考电压而有所不同。

下载:文件

复制代码

》》》 adc.value / 65535 * adc.reference_voltage

3.2998 》》》 adc.value / 65535 * adc.reference_voltage

3.2998

模拟和PWM输出

快速参考

配置模拟输出引脚

Arduino

大多数开发板没有真正的模拟输出。

CircuitPython

import board

import analogio

dac = analogio.AnalogOut(board.A1)

使用模拟输出引脚

Arduino

大多数板子都没有真正的模拟输出。

CircuitPython

dac.value = 32767

PWM输出引脚

Arduino

不需要

CircuitPython

import board

import pulseio

led = pulseio.PWMOut(board.A1)

使用PWM输出引脚

Arduino

analogWrite(9, 128);

CircuitPython

led.duty_cycle = 32767

讨论 Arduino

直接写入模拟引脚。从技术上讲,这通常不是真正的模拟值,而是PWM信号。即您正在写入的值将设置PWM信号的占空比。范围是0-255(含)。 analogWrite用于此目的,和digitalWrite一样,用于获取引脚和值。

Arduino DUE具有2个实际的模数转换器,可输出实际的模拟电压,而不是输出

下载:文件

复制代码

analogWrite(pin, val);

analogWrite(pin, val);

将它们放在一起,我们可以从模拟引脚读取并写入另一个引脚。区别在于需要容纳值范围,这就是4的除法。

下载:文件

复制代码

int ledPin = 9; // LED connected to digital pin 9

int analogPin = 3; // potentiometer connected to analog pin 3

int val = 0; // variable to store the read value

void setup()

{

pinMode(ledPin, OUTPUT); // sets the pin as output

}

void loop()

{

val = analogRead(analogPin); // read the input pin

analogWrite(ledPin, val / 4); // analogRead values go from 0 to 1023, analogWrite values from 0 to 255

} int ledPin = 9; // LED connected to digital pin 9

int analogPin = 3; // potentiometer connected to analog pin 3

int val = 0; // variable to store the read value

void setup()

{

pinMode(ledPin, OUTPUT); // sets the pin as output

}

void loop()

{

val = analogRead(analogPin); // read the input pin

analogWrite(ledPin, val / 4); // analogRead values go from 0 to 1023, analogWrite values from 0 to 255

}

CircuitPython

》 CircuitPython硬件上有两种类型的模拟输出:真实模拟和PWM(与Arduino一样)。

对于真实模拟输出,AnalogOut对象的value参数设置为a值介于0到65535之间,与AnalogInput的值范围相同:0将输出设置为0v,65535将其设置为参考电压。

下载:文件

复制代码

dac.value = 32767 dac.value = 32767

一个相关的输出功能是PWM(脉冲宽度调制)。它以完全不同的方式完成。代替使用analogio模块,您需要使用pulseio并使用要在其上生成信号的Pin创建一个PWMOut对象。

下载:文件

复制代码

》》》 import board

》》》 import pulseio

》》》 led = pulseio.PWMOut(board.A1) 》》》 import board

》》》 import pulseio

》》》 led = pulseio.PWMOut(board.A1)

一个PWMOut对象,可以将其占空比(输出为高的时间百分比)设置为16位整数(0-65535)。例如:

下载:文件

复制代码

# set the output to 100% (always high)

》》》 led.duty_cycle = 65535

# set the output to 0% (always low)

》》》 led.duty_cycle = 0

# set the output to 50% (high half the time)

》》》 led.duty_cycle = 32767 # set the output to 100% (always high)

》》》 led.duty_cycle = 65535

# set the output to 0% (always low)

》》》 led.duty_cycle = 0

# set the output to 50% (high half the time)

》》》 led.duty_cycle = 32767

时间

苏甘斯摄在Unsplash

快速参考

延迟

Arduino

delay(1500);

CircuitPython

import time

time.sleep(1.5)

系统时间

Arduino

unsigned long now = millis();

CircuitPython

import time

now = time.monotonic()

讨论

能够等待特定的时间时间在许多项目中都很重要。

Arduino和CircuitPython的处理方法非常相似。

延迟 Arduino

该函数用于等待特定时间, delay,已内置在Arduino框架中。不需要#include。单个参数是延迟时间,以毫秒为单位。

一个示例是如下所示的简单闪烁LED代码:

下载:文件

复制代码

int ledPin = 13; // LED connected to digital pin 13

void setup()

{

pinMode(ledPin, OUTPUT); // sets the digital pin as output

}

void loop()

{

digitalWrite(ledPin, HIGH); // sets the LED on

delay(1000); // waits for a second

digitalWrite(ledPin, LOW); // sets the LED off

delay(1000); // waits for a second

} int ledPin = 13; // LED connected to digital pin 13

void setup()

{

pinMode(ledPin, OUTPUT); // sets the digital pin as output

}

void loop()

{

digitalWrite(ledPin, HIGH); // sets the LED on

delay(1000); // waits for a second

digitalWrite(ledPin, LOW); // sets the LED off

delay(1000); // waits for a second

}

每次打开或关闭delay以创建闪烁的灯光时,ledPin函数都会等待一秒钟(1000毫秒)。

CircuitPython

CircuitPython中与delay等效的函数是time.sleep函数。默认情况下不包含time模块,必须将其导入到程序中。

传递给time.sleep的参数是延迟时间(以秒为单位)。 》(不是毫秒)。该值可以是十进制,因此如果要等待一秒钟,请放入1.0,如果要等待50毫秒,则为0.050。

下面的代码重复打印单词Hello。打印件之间的间隔为0.1秒,即100毫秒。

下载:文件

复制代码

import time

while True:

print(“Hello”)

time.sleep(0.1) import time

while True:

print(“Hello”)

time.sleep(0.1)

Djim Loic在Unsplash上拍摄的照片

获取系统时间

通常,微控制器和单板计算机通常缺少实时时钟(RTC)模块来了解时间。每个系统通常具有的功能是对自打开电源以来的时间进行计数。对于完成一段时间的某些工作而言,这仍然很有用。

Arduino

要获取自Arduino开发板以来的时间,常用功能是millis。它没有任何参数,并返回自从上次打开该板电源以来的毫秒数。

以下代码草图显示了每秒从串行端口上电以来的时间(1000毫秒)。

下载:文件

复制代码

unsigned long initial;

void setup(){

Serial.begin(9600);

initial = millis();

}

void loop(){

unsigned long now;

now = millis();

if( now - initial 》 3 ) { // Print done after 3 milliseconds elapses

Serial.print(“done”);

}

else {

initial = now;

}

} unsigned long initial;

void setup(){

Serial.begin(9600);

initial = millis();

}

void loop(){

unsigned long now;

now = millis();

if( now - initial 》 3 ) { // Print done after 3 milliseconds elapses

Serial.print(“done”);

}

else {

initial = now;

}

}

CircuitPython

Python具有许多时间函数。但是许多板卡都遇到了与Arduino发现的相同的问题-没有RTC。

CircuitPython具有与Arduino delay类似的功能,称为time.monotonic。但是它返回的是秒,而不是像delay那样的毫秒。

注意,不建议比较大于一小时的时间,因为该值将开始四舍五入,可能会浪费时间,从而造成准确性。

下载:文件

复制代码

import time

initial = time.monotonic() # Time in seconds since power on

while True:

now = time.monotonic()

if now - initial 》 0.003: # If 3 milliseconds elapses

print(“done”)

else:

initial = now import time

initial = time.monotonic() # Time in seconds since power on

while True:

now = time.monotonic()

if now - initial 》 0.003: # If 3 milliseconds elapses

print(“done”)

else:

initial = now

参考 Arduino

Arduino参考

延迟

millis

CircuitPython

时间-与时间和计时相关的功能

库和模块

长爱尔兰都柏林三一学院室内。来自Wikipedia的用户Diliff,CC BY-SA 4.0

快速参考

Arduino

include

CircuitPython

import time

讨论

Arduino和CircuitPython都提供了一种从正在处理的文件外部提取代码的方法。这可能是您编写的另一个文件,是框架的一部分,或者是传感器支持模块。

Arduino

C和C ++将代码分为代码文件(分别以.c或.cpp结尾)和头文件(以.h结尾)。 Arduino环境为您的草图/程序的主文件收取了少量费用。它以.ino结尾。

头文件通常包含函数和全局变量声明以及宏和类型定义。在C ++中,类定义也位于此处。代码文件包含函数定义。头文件提供了到库的接口,告诉您的代码如何访问/调用库的工具。

要使用头文件(及其包含的库)您包括它:

下载:文件

复制代码

#include #include

现在,您的代码可以使用string.h中定义的函数和类型,该函数和类型是字符串的集合操作功能,例如strcpy()用于复制字符串。

CircuitPython

所有CircuitPython代码文件均具有.py扩展名(结束)。没有定义接口的单独文件。

CircuitPython具有与Arduino/C相似的机制,称为模块。代码创建者为特定目的收集了一组功能并创建了一个模块。

预编译的模块具有.mpy文件扩展名。并非所有模块都必须预先编译,这样只会节省空间。

使用CircuitPython模块,则应将适当的文件(通常是.mpy文件)放置在开发板闪存驱动器上的/lib文件夹中。

“时间”页面上的较早位置, time模块已导入,并提供了两个功能:time.sleep和time.monotonic。

请注意,当您如上所述导入模块时,不能仅引用里面的东西,你必须给它们加上模块名的前缀。即time.monotonic(),而不仅仅是monotonic()。有很多方法可以避免这种情况,但这超出了本指南的范围。

下载:文件

复制代码

import time

while True:

print(“Hello”)

time.sleep(0.1) import time

while True:

print(“Hello”)

time.sleep(0.1)

CircuitPython无法将完整的Python/CPython可用的大型模块导入为微控制器上的内存非常有限。

Adafruit致力于提供大量模块来支持广泛的硬件。这包括传感器,显示器,智能LED(NeoPixel等)等等。正如Adafruit是提供开源Arduino库的领导者一样,Adafruit也在Python世界中努力做到这一点。

Python模块有更多功能,但以上内容基础。有关更多信息,请参见此类Python参考。

有关最新的CircuitPython模块的信息,请参考Adafruit GitHub存储库。

董事会模块

图片作者:Unsplash上的rawpixel

您正在微控制器板上编写嵌入式代码。这几乎总是意味着您正在通过董事会的一些图钉与外界互动。您如何知道哪些代码在做什么,以及在代码中使用哪些代码?

Arduino

在编译之前在Arduino IDE中,选择要使用的板。这基本上告诉了编译器信息,该信息需要专门针对MCU和该特定板的配置进行编译。但是,那无助于知道使用什么引脚。您必须查看电路板的文档并弄清楚。 Arduino硬件平台提供了一些有用的标准。您将始终有一些以“ D”为前缀的引脚。这些用于数字I/O。有些将以“ A”为前缀。这些可以用于模拟信号,但并非全部都支持真实的模拟输出。

将有I2C(SCL和SDA)和SPI(MOSI,MISO和SCK)引脚。在代码中,您将使用适当的管脚编号,尽管某些板具有在Arduino IDE中选择板时可使用的那些管脚的预定义值。

CircuitPython

CircuitPython采用了非常不同的方法来处理各种受支持的电路板。首先,CircuitPython驻留在板上,而Arduino是计算机上的一组工具,该工具会生成一个二进制文件,然后将其保存在板上。

进行此项工作的一部分是制作以下版本的CircuitPython:特定于每个受支持的板。例如,如果您想将CircuitPython与Feather M4 Express一起使用,则可以得到CircuitPython的Feather M4 Express版本,并将其放到Feather M4 Express板上。有关详细信息,请参见本指南。

之所以如此重要,是因为CircuitPython知道其运行在哪个板上,并且知道该板上的功能,以及该板上的引脚是什么。以及他们可以做什么。

要使此功能可用,您可以导入board模块。该模块包含特定板上引脚的常数。 CircuitPython中用于另一块板的board模块将具有特定于该板的不同常量。知道,用户不必告诉CircuitPython它在什么板上运行。

所有这些使使用板模块成为使用板引脚的最安全,最可靠的方法。它使您不必担心板子引脚连接到哪个MCU引脚。对于围绕ARM内核构建的更复杂的MCU(例如SAMD或nRF52系列MCU),这更是一个问题。

例如,可以将I2C信号连接到MCU有多种方式(我们将不介绍),但是使用板卡模块,您可以轻松执行以下操作:

下载:文件

复制代码

import board

import busio

i2c = busio.I2C(board.SCL, board.SDA) import board

import busio

i2c = busio.I2C(board.SCL, board.SDA)

这将在CircuitPython中任何受支持的板上工作。/p》

那么您如何知道板上有哪些引脚可用?他们叫什么?您可以使用CircuitPython的dir函数。这是在Circuit Playground Express上:

下载:文件

复制代码

》》》 import board

》》》 dir(board)

[‘A0’, ‘A1’, ‘A2’, ‘A3’, ‘A4’, ‘A5’, ‘A6’, ‘A7’, ‘A8’, ‘A9’,

ACCELEROMETER_INTERRUPT’, ‘ACCELEROMETER_SCL’,

‘ACCELEROMETER_SDA’, ‘BUTTON_A’, ‘BUTTON_B’, ‘D0’, ‘D1’,

‘D10’, ‘D12’, ‘D13’, ‘D2’, ‘D3’, ‘D4’, ‘D5’, ‘D6’, ‘D7’,

‘D8’, ‘D9’, ‘I2C’, ‘IR_PROXIMITY’, ‘IR_RX’, ‘IR_TX’, ‘LIGHT’,

‘MICROPHONE_CLOCK’, ‘MICROPHONE_DATA’, ‘MISO’, ‘MOSI’,

‘NEOPIXEL’, ‘REMOTEIN’, ‘REMOTEOUT’, ‘RX’, ‘SCK’, ‘SCL’,

‘SDA’, ‘SLIDE_SWITCH’, ‘SPEAKER’, ‘SPEAKER_ENABLE’, ‘SPI’,

‘TEMPERATURE’, ‘TX’, ‘UART’]

》》》 》》》 import board

》》》 dir(board)

[‘A0’, ‘A1’, ‘A2’, ‘A3’, ‘A4’, ‘A5’, ‘A6’, ‘A7’, ‘A8’, ‘A9’,

‘ACCELEROMETER_INTERRUPT’, ‘ACCELEROMETER_SCL’,

‘ACCELEROMETER_SDA’, ‘BUTTON_A’, ‘BUTTON_B’, ‘D0’, ‘D1’,

‘D10’, ‘D12’, ‘D13’, ‘D2’, ‘D3’, ‘D4’, ‘D5’, ‘D6’, ‘D7’,

‘D8’, ‘D9’, ‘I2C’, ‘IR_PROXIMITY’, ‘IR_RX’, ‘IR_TX’, ‘LIGHT’,

‘MICROPHONE_CLOCK’, ‘MICROPHONE_DATA’, ‘MISO’, ‘MOSI’,

‘NEOPIXEL’, ‘REMOTEIN’, ‘REMOTEOUT’, ‘RX’, ‘SCK’, ‘SCL’,

‘SDA’, ‘SLIDE_SWITCH’, ‘SPEAKER’, ‘SPEAKER_ENABLE’, ‘SPI’,

‘TEMPERATURE’, ‘TX’, ‘UART’]

》》》

这是在Gemma M0上:

下载:文件

复制代码

》》》 import board

》》》 dir(board)

[‘A0’, ‘A1’, ‘A2’, ‘APA102_MOSI’, ‘APA102_SCK’, ‘D0’,

‘D1’, ‘D13’, ‘D2’, ‘I2C’, ‘L’, ‘RX’, ‘SCL’, ‘SDA’, ‘SPI’,

‘TX’, ‘UART’]

》》》 import board

》》》 dir(board)

[‘A0’, ‘A1’, ‘A2’, ‘APA102_MOSI’, ‘APA102_SCK’, ‘D0’,

‘D1’, ‘D13’, ‘D2’, ‘I2C’, ‘L’, ‘RX’, ‘SCL’, ‘SDA’, ‘SPI’,

‘TX’, ‘UART’]

您可以看到有一些共同的引脚,但也有特定于主板的引脚。
责任编辑:wv

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编程
    +关注

    关注

    88

    文章

    3440

    浏览量

    92382
  • Arduino
    +关注

    关注

    184

    文章

    6427

    浏览量

    184826
收藏 人收藏

    评论

    相关推荐

    Tech Talks最新蓝牙专题回放,以xG24和CircuitPython加速低功耗蓝牙开发!

    并下载简报档案,提升学习效益。欢迎点击文末的 阅读原文 按钮获通过下方链接前往获取资源。 在本次会议中,芯科科技的无线专家介绍了 CircuitPython (针对微控制器优化的 Python 的开源
    的头像 发表于 11-02 17:40 181次阅读
    Tech Talks最新蓝牙专题回放,以xG24和<b class='flag-5'>CircuitPython</b>加速低功耗蓝牙开发!

    深度学习的由来 深度学习的经典算法有哪些

    深度学习作为机器学习的一个分支,其学习方法可以分为监督学习和无监督学习。两种方法都具有其独特的学习
    发表于 10-09 10:23 355次阅读
    深度<b class='flag-5'>学习</b>的由来 深度<b class='flag-5'>学习</b>的经典算法有哪些

    一文详解机器学习和深度学习的区别

    深度学习这几年特别火,就像5年前的大数据一样,不过深度学习其主要还是属于机器学习的范畴领域内,所以这篇文章里面我们来唠一唠机器学习和深度学习
    发表于 09-06 12:48 1337次阅读
    一文详解机器<b class='flag-5'>学习</b>和深度<b class='flag-5'>学习</b>的区别

    机器学习和深度学习的区别

      机器学习和深度学习是当今最流行的人工智能(AI)技术之一。这两种技术都有助于在不需要人类干预的情况下让计算机自主学习和改进预测模型。本文将探讨机器学习和深度
    发表于 08-28 17:31 1045次阅读

    机器学习有哪些算法?机器学习分类算法有哪些?机器学习预判有哪些算法?

    机器学习有哪些算法?机器学习分类算法有哪些?机器学习预判有哪些算法? 机器学习是一种人工智能技术,通过对数据的分析和学习,为计算机提供智能决
    的头像 发表于 08-17 16:30 1392次阅读

    机器学习是什么意思?机器学习属于什么分支?机器学习有什么用处?

    机器学习是什么意思?机器学习属于什么分支?机器学习是什么有什么用处? 机器学习是指让计算机通过经验来不断优化和改进自身的算法和模型的过程。因此,机器
    的头像 发表于 08-17 16:30 1273次阅读

    机器学习算法入门 机器学习算法介绍 机器学习算法对比

    机器学习算法入门 机器学习算法介绍 机器学习算法对比 机器学习算法入门、介绍和对比 随着机器学习的普及,越来越多的人想要了解和
    的头像 发表于 08-17 16:27 623次阅读

    机器学习算法总结 机器学习算法是什么 机器学习算法优缺点

    机器学习算法总结 机器学习算法是什么?机器学习算法优缺点? 机器学习算法总结 机器学习算法是一种能够从数据中自动
    的头像 发表于 08-17 16:11 1069次阅读

    机器学习和深度学习的区别

    机器学习和深度学习的区别 随着人工智能技术的不断发展,机器学习和深度学习已经成为大家熟知的两个术语。虽然它们都属于人工智能技术的研究领域,但它们之间有很大的差异。本文将详细介绍机器
    的头像 发表于 08-17 16:11 3380次阅读

    深度学习框架和深度学习算法教程

    深度学习框架和深度学习算法教程 深度学习是机器学习领域中的一个重要分支,多年来深度学习一直在各个领域的应用中发挥着极其重要的作用,成为了人工
    的头像 发表于 08-17 16:11 714次阅读

    什么是深度学习算法?深度学习算法的应用

    什么是深度学习算法?深度学习算法的应用 深度学习算法被认为是人工智能的核心,它是一种模仿人类大脑神经元的计算模型。深度学习是机器学习的一种变
    的头像 发表于 08-17 16:03 1472次阅读

    深度学习算法简介 深度学习算法是什么 深度学习算法有哪些

    深度学习算法简介 深度学习算法是什么?深度学习算法有哪些?  作为一种现代化、前沿化的技术,深度学习已经在很多领域得到了广泛的应用,其能够不断地从数据中提取最基本的特征,从而对大量的信
    的头像 发表于 08-17 16:02 6805次阅读

    xG24开发板新增支持CircuitPython,加速物联网原型设计和开发过程

    SiliconLabs (亦称 “ 芯科科技 ” )致力于提升物联网无线连接技术能力,近期进一步为我们的 xG24 无线 SoC 系列开发板引入 CircuitPython 支持
    的头像 发表于 08-02 14:05 334次阅读
    xG24开发板新增支持<b class='flag-5'>CircuitPython</b>,加速物联网原型设计和开发过程

    联合学习在传统机器学习方法中的应用

    联合学习在传统机器学习方法中的应用
    的头像 发表于 07-05 16:30 537次阅读
    联合<b class='flag-5'>学习</b>在传统机器<b class='flag-5'>学习</b>方法中的应用

    亿图AI × 学习,终身学习的效率加速器

    学习型组织之父”彼得·圣吉在《第五项修炼:终身学习者》中提到,我们所有的学习都涉及我们如何与世界交往互动,而学习所带来的实践将影响我们如何创造未来。
    的头像 发表于 06-08 11:28 367次阅读
    亿图AI × <b class='flag-5'>学习</b>,终身<b class='flag-5'>学习</b>的效率加速器