MicroPython——有点东西,但是不多

news2024/11/20 18:48:18

在这里插入图片描述

引言

之前做过一个树莓派驱动墨水屏的项目,本来想整理出来与大家分享的,但是由于树莓派已经成了理财产品,所以为了让这个项目更加具有实践意义,最近我打算把这个项目移植到ESP32上。在树莓派上我使用的是Python编写的代码,所以出于简便考虑(后来发现其实也不是很简便) 我决定用ESP32的MicroPython框架来编写代码。
正如标题所言,在我最近的MicroPython学习和实践过程中,我发现MicroPython框架有那么点意思,但同时也有很多的问题和缺点,这篇文章我将分享最近在MicroPython学习和实践过程中的一些看法和见解。

MicroPython简介

在MicroPython出现之前,C/C++几乎是给单片机写程序的唯一的高级语言。2013年,澳大利亚程序员和物理学家Damien George通过众筹活动发布了MicroPython框架和第一个支持该框架的pyboard开发板1,让开发者能够使用Python语言来开发单片机。
时至今日,MicroPython框架已经支持包含ESP32在内的多种架构的单片机,但是MicroPython框架一直处于一种不温不火的状态,下面我将会从一个计算机专业的学生、一个开源硬件爱好者、半个STEM教育从业者的角度去探讨MicroPython。

从计算机专业学生角度看MicroPython

对于一个计算机专业的大学生来说,对于MicroPython的认识肯定不能只停留在“别的单片机只能拿C语言开发,装了MicroPython框架以后就能运行Python代码”这么简单,我们还是要大致了解一下它的原理的。

解释型语言与单片机

众所周知,C语言是编译型语言,而Python是解释型语言。当我们在个人电脑上运行这两种语言编写的程序的时候并不能感受到很大的区别,无非前者是将代码整体编译成机器码再执行,后者是将代码逐句解释成机器码执行。
在这里插入图片描述
但是当我们将目光转向单片机的时候,情况就有所不同了:我们需要考虑编译(解释)源代码这个操作到底在哪里完成?对于C语言来说,将C源代码编译成单片机能够执行的机器码的工作是在我们的PC机上完成的,我们只需要将编译好的机器码烧录到单片机上,单片机就能够执行我们的程序;而对于MicroPython来说,单片机可以实时执行我们发送的Python代码,这就意味着解释Python源码的工作是在单片机上完成的,而运行在单片机上的这套Python解释器就是我们所说的MicroPython框架。
在这里插入图片描述

解释型语言在单片机上的缺点

对比编译型语言,解释型语言的一大缺点就是运行速度慢,这个问题不论是在PC上还是在单片机上都是存在的。而解释型语言在运行时是直接解释源码这一特性,在PC机上看似并没有什么问题,但到了单片机上就成为了一个新的缺点。
目前的PC机的硬盘容量少说也是GB级别起步的,几KB哪怕是几MB的源代码根完全可以忽略不计,而对于MicroPython而言,我们需要把源代码存储在单片机的FLASH上,以ESP32系列单片机为例,其FLASH容量只有2-4MB,这个时候源代码的大小就是一个无法忽略的事情了。
我们不得不在有限的空间里面尽量想办法减小源代码的大小,比如说删除所有的注释,变量名和函数名起的尽量简短一些,这些都可以有效地减小源代码的大小。但作为一种高级语言,为了程序的可读性,我们却又是是希望在代码中添加注释、给各类标识符(变量名、函数名、类名等)起一个有意义的名字,这两者之间便产生了不可调和的矛盾
如果说注释和变量名在源码中并不能占据太多的空间的话,在MicroPython中存储位图则是更大的一笔开销:例如一张40x40像素的黑白位图需要40*40 = 1600bit = 200Byte的空间,在MicroPython中可以这样表示:

myimg = bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe7\xff\xff\xff\xff\xe7\xff\xff\xff\xff\xe7\xff\xff\xff\xff\xe7\xff\xff\xff\xff\xe7\xff\xff\xff\x3f\xe7\xfc\xff\xff\x1f\xe7\xf8\xff\xff\x8f\xff\xf1\xff\xff\xc7\xff\xe3\xff\xff\xe7\x81\xe7\xff\xff\xfe\x00\x7f\xff\xff\xfc\x00\x3f\xff\xff\xf8\x00\x1f\xff\xff\xf8\x00\x1f\xff\xff\xf0\x00\x0f\xff\xff\xf0\x00\x0f\xff\xe0\x30\x00\x0c\x07\xe0\x30\x00\x0c\x07\xff\xf0\x00\x0f\xff\xff\xf0\x00\x0f\xff\xff\xf8\x00\x1f\xff\xff\xf8\x00\x1f\xff\xff\xfc\x00\x3f\xff\xff\xfe\x00\x7f\xff\xff\xe7\x81\xe7\xff\xff\xc7\xff\xe3\xff\xff\x8f\xff\xf1\xff\xff\x1f\xe7\xf8\xff\xff\x3f\xe7\xfc\xff\xff\xff\xe7\xff\xff\xff\xff\xe7\xff\xff\xff\xff\xe7\xff\xff\xff\xff\xe7\xff\xff\xff\xff\xe7\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff')

在上面的例子中,一个\xff表示1Byte,但是\xff本身是4个字符,占用了4Byte的空间。所以说用想在MicroPython中硬编码一个图片,至少需要花费图片本身大小4倍的空间,这无疑是对本不富裕的FLASH空间雪上加霜。但是如果我们在C语言中硬编码一个图片,却不会导致空间的浪费,这是因为编译的过程将“源代码中用字符表示的字节”转换成了“真正的字节”再烧进单片机里的。
当然,MicroPython提供了基础的文件系统,如果不用硬编码的方式把图片存储在代码里面,而是单独作为一个文件存放,就可以避免这个问题,不过这也会引来新的问题,我后续的博客中会详细分享我的解决方案。所以从存储图片这个角度来说,MicroPython并不比用C语言开发方便。
总之,从一个计算机专业学生角度来看,我无时无刻不在怀念C编译器给我们带来的便利,让我们能够随心所欲加注释、起变量名、定义常量、将字节数组硬编码进程序,无需担心源代码的大小,只要把源代码交给编译器,最后烧录进单片机的是编译后的机器码。

从开源硬件爱好者角度看MicroPython

对于开源硬件爱好者(创客)来说,最关心的问题是能否方便快捷地实现我们的创意。如果想实现一个功能不太复杂的小玩意的话,我猜大多数人都会选择使用Arduino,这是因为Arduino的生态十分完善,网上不仅有各种教程、例程的分享,还有各种传感器、硬件模块的第三方库可以供我们直接使用,用Arduino编程与其说是在“写”代码,不如说是在“拼”代码
而对于MicroPython,它处在一个十分尴尬的境地:它自己的生态没有发展起来,真Python的代码也不能直接照搬。

MicroPython自己的生态

MicroPython自己的生态目前的生态并不完善,主要体现在:缺少相应的模块库可以直接“拼”代码,那么想用MicroPython的人就少,相应的用MicroPython做的项目也少,能够参考的项目代码也少。

扩展库

Arduino官网上收录了上千个扩展库(如下图2),如果想用Arduino驱动一个硬件模块,通常我们只需要找到对应型号的库,然后参考例程就可以开始愉快地“拼代码”了。
在这里插入图片描述
而MicroPython只提供了标准库的文档(并且MicroPython的标准库只是Python标准库的子集),同时官方也没有对扩展库作出统一的收录,如果我们想用MicroPython驱动一个硬件模块,只能尝试使用搜索引擎手动搜集别人写好的库,更大概率的情况下我们只能从轮子造起,翻芯片的数据手册,然后先写驱动再实现上层的功能(显然有这个闲工夫我肯定去用隔壁的Arduino了)。

项目

搜索关键词“Arduino 项目”和“MicroPython 项目”,前者的搜索结果数就是后者的10倍,并且可以看到Arduino有很多系统的适合初学者的入门教程,但是MicroPython只有一些爱好者的相对来说比较复杂的项目分享,这也为新手入门MicroPython设置了一个较高的门槛。
在这里插入图片描述

用户活跃度

上述的各种问题最终导致的结果就是MicroPython的用户很少,在著名IT问答网站Stack Overflow上搜索包含Arduino标签和MicroPython标签的问题,两者的数量差异也达两倍之多(Arduino还有专门的Stack Exchange板块3,而MicroPython没有)。提问的人越少,也就意味着帮你踩坑的前人越少,碰到问题没有现成的解决方案,通常只能自己想办法;同时也是因为活跃的用户少,即使提出一个问题,能够得到及时的回答的可能性也越少。
在这里插入图片描述

借用Python生态的难度

Python之所以好用不仅是因为它简洁的语法和列表、字典等好用的数据结构,更是因为它有很多强大的第三方扩展库。写一个Python项目几乎不可能只用标准库而不使用第三方的扩展库。
以我做的Python驱动墨水屏的项目为例,我用到了pillow库来绘制墨水屏上需要显示的图像,用了datetime库将时间戳格式化为日期字符串。当我尝试将Python程序移植到MicroPython中时,我发现MicroPython没有这些库,将这些库移植到MicroPython上几乎是不可能的,唯一的办法就是使用MicroPython仅有的东西去重新实现一遍所需要的功能
在Python中使用datetime库将“时间戳格式化为日期字符串”只需:

import datetime
timestamp = 1668521610
dt = datetime.datetime.fromtimestamp(timestamp)
print(dt.strftime('%m月%d日 %H:%M'))

而在MicroPython中并不能使用datetime库,只能使用内置的time.mktime()函数将时间戳转换为一个(年,月,日,时,分,秒,星期,一年中的第几天)的元组。所以要实现"时间戳格式化为日期字符串"则需要自己实现:

import utime as time
class MyDateTime:
    def __init__(s, timestamp, tz=8):
        timestamp = int(timestamp)
        timestamp += tz * 3600
        tt = time.gmtime(timestamp)
        s.m, s.d, s.H, s.M, s.s= tt[1:6]
    def strftime(s, str_):
        return str_.replace('%m', str(s.m)).replace('%d', str(s.d)).replace('%H', str(s.H).zfill(2)).replace('%M', str(s.M).zfill(2))
        
timestamp = 1668521610
dt = MyDateTime(timestamp)
print(dt.strftime('%m月%d日 %H:%M'))

这只是最简单的一个移植的例子,在MicroPython中要实现绘图功能需要使用自带的framebuf模块而这个模块相比pillow库的提供的功能少得多,移植起来更加麻烦。
也就是说,想要让一个Python程序成功在MicroPython上运行,也是需要进行大量的移植和适配工作,MicroPython并不能直接吃到Python生态所带来的红利。

从STEM教育角度看MicroPython

虽然说了那么多MicroPython的问题和缺点,但在我看来MicroPython依然有其存在的价值,就目前而言我认为MicroPython在STEM教育领域的意义是更大的。

MicroPython对于STEM教育的意义

不论是在STEM教育机构、国际学校、高中信息技术课,Python在已经逐渐成为孩子们接触编程时的第一种语言了,而MicroPython提供了一个从虚拟世界的Python走向物理世界的硬件的一个桥梁。
目前也有一些STEM教育领域的公司开发了使用MicroPython作为编程语言的套件,如由英国广播电视公司(BBC)推出的micro:bit开发板4、国内公司Makeblock推出的光环板等开发板5,都可以使用MicroPython进行编程。这类开发板通常板载常用的传感器和一组LED矩阵,这方便教学时不用拼接额外的模块就能够实现基本的项目。
在这里插入图片描述
在此之前,如果想要给孩子们启蒙硬件,只能使用类似于arduinoblocks的图形化编程或者重写学习C语言,对于刚入门编程的孩子们来说,这不仅会增加学习成本,而且会降低他们的学习动机。而MicroPython为硬件提供了统一的语言,让孩子们可以把学会的Python技能在单片机上得到实践,让孩子们明白编程不仅可以在电脑屏幕上算个数字、画个图,还可以操控硬件、点亮LED、驱动小车。我认为尤其是在STEM教育领域,对于兴趣的培养要远比能力的培养重要得多


  1. https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers ↩︎

  2. https://www.arduino.cc/reference/en/libraries/ ↩︎

  3. https://arduino.stackexchange.com/ ↩︎

  4. https://microbit.org/code/ ↩︎

  5. https://www.makeblock.com/cn/steam-kits/halocode ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/10705.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++简单工厂模式详解

C简单工厂模式详解1.问题引入2.编写代码思路的迭代2.1 main函数主体内编写全部代码2.2 修改上述问题后的main函数代码2.3 引入面向对象后的代码2.4 加上继承和多态后的代码3.C简单工厂代码4.总结4.1 简单工厂模式适用场景4.2收获1.问题引入 编写一个计算器程序代码&#xff0c…

论文笔记:Region Representation Learning via Mobility Flow

2017 CIKM 1 摘要和介绍 使用出租车出行数据学习区域向量表征 同时考虑时间动态和多跳位置转换——>通过flow graph和spatial graph学习表征出租车交通流可以作为区域相似度的一种 A区域和B区域之间流量大 ——>A和B的特征更相关——>用一个/很相似的vector来表征他…

如何实现基于场景的接口自动化测试用例?来看看大佬的方案

自动化本身是为了提高工作效率,不论选择何种框架,何种开发语言,我们最终想实现的效果,就是让大家用最少的代码,最小的投入,完成自动化测试的工作。 基于这个想法,我们的接口自动化测试思路如下…

R语言七天入门教程七:项目实战

R语言七天入门教程七:项目实战 在完成之前R语言基础知识的学习后,今天的内容是项目实战,通过完成一些小项目来巩固知识。 一、矩阵运算计算器(变量与运算符练习) 1、问题描述 给定矩阵A和B,计算矩阵相加…

MySql常用内置函数详解

目录日期函数--了解***字符串函数--重要数学函数--了解其他函数--了解MySql为我们提供了一些内主函数,方便我们对特定数据进行相关操作! 注意:都是配合select使用哦,个人理解SQL的select相当于C中的printf; 日期函数–了解 一般用于insert in…

C++ 主函数几种语法

Cmain函数的两种写法 1&#xff0c;返回值为int&#xff0c;且main不带参数 #include<iostream> using namespace std; int main() { cout << "Hello C \n" << endl; system("pause"); return 1;//函数返回值取值范围0到255&#xf…

深入了解 JavaScript 语法错误以及如何防止它们

最近&#xff0c;在 Leader 的建议下&#xff0c;去看了看 emotion 和 storybook 的相关文档。学习过后&#xff0c;小有收获。因此&#xff0c;这次将以我自己的视角带你们体验一下 storybook&#xff0c;也算是对我自己学习过程中的一个 review。 何为 storybook 什么是 st…

第2关:伪分布式体验及分布式安装配置

服务器leader选举 为进一步了解ZooKeeper的leader选举过程&#xff0c;本节实训利用服务器的关闭启动&#xff0c;观察服务器的leader产生过程。利用以下命令查看当前服务器节点的状态(/xxx为安装目录)&#xff1a; ./xxx/bin/zkServer.sh status 当仅启动1个服务器节点&…

进博会期间,多地政府领导密集考察深兰科技

从11月初开始&#xff0c;借第五届中国国际进口博览会在上海举办的契机&#xff0c;来自全国各地的地级、县级市的各级领导纷纷来到上海&#xff0c;深入到各个行业领域的国企、央企、民企和跨国企业中走访调研&#xff0c;寻求技术合作&#xff0c;洽谈招商引资。 期间仅1日至…

流体力学基础——简介

流体定义&#xff1a;无规则的运动&#xff0c;流体&#xff1b;流体在静止时内部不能产生剪切力&#xff0c;流动产生的剪切力叫做粘力流体特点&#xff1a; 1、力与变形的关系不同&#xff1b;固体&#xff0c;应力正比于应变&#xff0c;静力学为主&#xff1b;流体&#xf…

DeepLearn关于数组和数的操作

本篇文章纯属作为自己的笔记&#xff0c;因为每次写程序都忘记下面的内容&#xff0c;找起来又很浪费时间&#xff0c;所有就索性一次性都整理下来&#xff0c;后续又不新的不会的内弄也会及时更新到文章当中&#xff0c;方便以后查阅。 DeepLearn关于数组和数的操作Python标准…

【详解】BIO、AIO、NIO Netty 知识点和工作原理

Netty框架 基础 三大网络编程 BIO 同步阻塞:服务器实现模式一个连接一个线程,既客户端有连接请求时,服务器就需要启动一个线程进行处理,如果这个连接不任何事情会造成不必要的线程线程开销 适用场景&#xff1a; 连接数目比较小且固定的架构&#xff0c;这种方式对服务器资源…

Android企业微信分享到小程序

1.官方文档Android应用 - 接口文档 - 企业微信开发者中心https://developer.work.weixin.qq.com/document/path/91196 2.创建应用 登录企业微信管理后台&#xff0c;选择企业应用&#xff0c;选择“企业微信授权登录”&#xff0c;在设置界面填写Android的 App的签名&包名…

[附源码]java毕业设计基于技术的新电商助农平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

HTTP 消息头

title: HTTP 消息头 date: 2022-11-16 14:36 tags: [HTTP,X-Real-IP,Host,X-Forwarded-For,Nginx] 文章目录〇、问题一、前言二、什么是消息头&#xff1f;三、Host四、X-Real-IP五、X-Forwarded-For参考更新〇、问题 什么是HTTP Headers&#xff1f;作用是什么&#xff1f; …

qemu-system-aarch64使用记录

qemu-system-aarch64 使用记录下载安装qemu查看是否支持KVM运行qemu-M内核启动问题内核编译下载安装qemu #!/bin/bashsudo apt update > /dev/null sudo apt upgrade > /dev/null sudo apt-get install -y make gcc g git > /dev/nullcd sudo apt-get install -y r…

一起来庆祝属于GISer的节日GIS DAY

概述 作为一名GISer的你&#xff0c;有没有想过其实我们GISer也有自己的节日&#xff1f;这个节日便是GIS DAY&#xff0c;今年的GIS DAY恰在今天&#xff08;2022年11月16日&#xff09;。究竟什么是GIS DAY&#xff1f;这里为大家介绍一下这个节日。 什么是GIS DAY GIS DA…

Python学习----异常、模块、安装第三方包

异常 异常的含义就不用解释了 打开一个不存在的文件&#xff1a; 异常的捕获 语法&#xff1a; 捕获所有异常 try:可能发生错误的代码 except:发生错误之后执行的代码try:可能发生错误的代码 except Exception as e:发生错误之后执行的代码两种写法都行 捕获指定异常&…

【maptplotlib大全图】一段代码洞查matplotlib图片真谛

此文通过给大家设计一个全面的代码&#xff0c;帮助大家了解matplotlib库画图的全貌 代码解读&#xff0c;略。 图示解读&#xff1a; 对照上图序号和下面序号看代码解释&#xff1a; 1.应用风格使用代码&#xff1a;plt.style.use(sty) 2.文本注释 plt.annotate(‘maximum…

QSS(Qt样式表)概念

Qt样式表是一个可以自定义部件外观的十分强大的机制&#xff0c;除了QStyle更改的样式&#xff0c;其他的都可以由QSS修改。由于受到Html的CSS启发&#xff0c;所以叫QSS。 代码添加样式表ui界面上添加样式表代码添加样式表&#xff1a; setStyleSheet&#xff08;&#xff09…