超低成本数据采集+迷你实时看板-基于ESP32

如果想了解一样东西,最好的方法也许是直接亲手从头开始构建它。
时间有限,只记录看板的部分,数据采集后面有空再写。

1. 目的

  • 了解单片机、IoT、传感器、Arduino、MicroPython
  • 基于以上做一个小应用

2. 事前准备

  • 硬件
    • NodeMCU-32S开发板 —23元
    • 1.14 135×240 IPS彩色液晶显示屏 —17元
    • PCB万用板 —2元
    • 导线 —几毛
    • 传感器若干(温湿度传感器、人体感应、摄像头、薄膜压力传感器等)
  • 软件

后来发现有一款直接带同款显示屏的开发板,只要40元,TTGO T-Display,比上面这些加起来还便宜,而且还能省掉焊接、接线等繁琐的过程。
以上硬件其实还可以做非常多的东西,有网就有海量数据、有屏幕就可做可视化。

3. 相关内容

3.1 ESP32

什么是ESP32?
ESP8266 Wi-Fi模块是过去几年中最受欢迎和最实用的模块之一。市场上有这种模块的各种版本。ESP32模块是ESP8266的升级版本。除了Wi-Fi模块,该模块还包含蓝牙4.0模块。双核CPU工作频率为80至240 MHz,包含两个Wi-Fi和蓝牙模块以及各种输入和输出引脚, ESP32是物联网项目的理想选择。

ESP32-S2 芯片 32-bit MCU & 2.4 GHz Wi-Fi 单核 CPU 时钟频率高达 240 MHz
支持多种低功耗工作状态:精细时钟门控、动态电压时钟频率调节 安全机制:eFuse 存储、安全启动、Flash 加密、数字签名,支持AES、SHA 和 RSA 算法 外设包括 43 个 GPIO 口,1 个全速 USB OTG接口,SPI,I2S,UART,I2C,LED PWM,LCD 接口,Camera 接口,ADC,DAC,触摸传感器可对接丰富的网络云平台、拥有通用的产品特性,极大缩短产品构建与上市时间

3.2 IoT

百度百科 - IoT

物联网(Internet of Things,简称IOT)是指通过 各种信息传感器、射频识别技术、全球定位系统、红外感应器、激光扫描器等各种装置与技术,实时采集任何需要监控、 连接、互动的物体或过程,采集其声、光、热、电、力学、化 学、生物、位置等各种需要的信息,通过各类可能的网络接入,实现物与物、物与人的泛在连接,实现对物品和过程的智能化感知、识别和管理。物联网是一个基于互联网、传统电信网等的信息承载体,它让所有能够被独立寻址的普通物理对象形成互联互通的网络 [1] 。

3.2 Arduino

百度百科 - Arduino

Arduino是一款便捷灵活、方便上手的开源电子原型平台。包含硬件(各种型号的Arduino板)和软件(ArduinoIDE)。由一个欧洲开发团队于2005年冬季开发。其成员包括Massimo Banzi、David Cuartielles、Tom Igoe、Gianluca Martino、David Mellis和Nicholas Zambetti等。
它构建于开放原始码simple I/O介面版,并且具有使用类似Java、C语言的Processing/Wiring开发环境。主要包含两个的部分:硬件部分是可以用来做电路连接的Arduino电路板;另外一个则是Arduino IDE,你的计算机中的程序开发环境。你只要在IDE中编写程序代码,将程序上传到Arduino电路板后,程序便会告诉Arduino电路板要做些什么了。
Arduino能通过各种各样的传感器来感知环境,通过控制灯光、马达和其他的装置来反馈、影响环境。板子上的微控制器可以通过Arduino的编程语言来编写程序,编译成二进制文件,烧录进微控制器。对Arduino的编程是通过 Arduino编程语言 (基于 Wiring)和Arduino开发环境(基于 Processing)来实现的。基于Arduino的项目,可以只包含Arduino,也可以包含Arduino和其他一些在PC上运行的软件,它们之间进行通信 (比如 Flash, Processing, MaxMSP)来实现。

3.3 MicroPython

MicroPython官网

MicroPython是Python3编程语言的一个完整软件实现,用C语言编写,被优化于运行在微控制器之上。MicroPython是运行在微控制器硬件之上的完全的Python编译器和运行时系统。提供给用户一个交互式提示符(REPL)来立即执行所支持的命令。除了包括选定的核心Python库,MicroPython还包括了给予编程者访问低层硬件的模块。MicroPython努力与普通的Python(称为CPython)尽可能兼容,这样如果你了解Python就已经知道了MicroPython。另一方面,您对MicroPython的了解越多,您在Python中的表现就越好。
MicroPython is a lean and efficient implementation of the Python 3 programming language that includes a small subset of the Python standard library and is optimised to run on microcontrollers and in constrained environments.
The MicroPython pyboard is a compact electronic circuit board that runs MicroPython on the bare metal, giving you a low-level Python operating system that can be used to control all kinds of electronic projects.
MicroPython is packed full of advanced features such as an interactive prompt, arbitrary precision integers, closures, list comprehension, generators, exception handling and more. Yet it is compact enough to fit and run within just 256k of code space and 16k of RAM.
MicroPython aims to be as compatible with normal Python as possible to allow you to transfer code with ease from the desktop to a microcontroller or embedded system.

4. 功能描述

  • 通过板载Wifi连接热点
  • 通过板载ADC - 数模转换器 - 传感器采集数据信号
  • 通过MQTT协议发布、订阅数据
  • 驱动屏幕显示内容、画图可视化呈现

4.0 板子接线

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
根据以上引脚图,接线如下:

ESP32屏幕
GNDGND
5VVCC
VSPI-SCK GPIO18SCL
VSPI-MOSI GPIO23SDA
GPIO26RES
GPIO27DC
VSPI-SS GPIO5CS

下面开始软件部分

4.1 通过板载Wifi连接热点

MicroPython方法

import network
ssid = 'wifi名称'
password = 'wifi密码'
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect(ssid, password)
while station.isconnected() == False:
    pass
print('Connection successful')
ip = station.ifconfig()[0]

4.2 通过板载ADC - 数模转换器 - 传感器采集数据信号

如果还要接一些传感器的话,这个板子带了n个ADC,可以用MCP3008这种数模转换器来转换模拟量采集数据,这个有空后面再讲,先附上MCP3008资料:
在这里插入图片描述
在这里插入图片描述

import machine

adc = machine.ADC(pin)   # create an ADC object acting on a pin
val = adc.read_u16()     # read a raw analog value in the range 0-65535

4.3 通过MQTT协议发布、订阅数据

如果固件里没带的话这个库可以从Github上下载
最好用thread单独开个线程
订阅数据:

from umqtt.simple import MQTTClient

def sub_cb(topic, msg):
	print(msg)

def mqtt():
    while True:
        if True:
            # Blocking wait for message
            c.wait_msg()
        else:
            # Non-blocking wait for message
            c.check_msg()
            # Then need to sleep to avoid 100% CPU usage (in a real
            # app other useful actions would be performed instead)
            time.sleep(1)
        time.sleep(2)

c = MQTTClient("umqtt_client", server='ip', port=1883,user="username",password="password")
c.set_callback(sub_cb)
c.connect()
c.subscribe(b"topic")

发布数据的话可以在自己的服务器上搭一个
如可以在树莓派上搭Mosqitto server
然后就可以通过esp32联网,把采集到的数据传上去了

4.4 驱动屏幕显示内容、画图可视化呈现

这块屏幕的驱动芯片是st7789v,如果是Arduino的话可以用TFT库很容易的驱动
但是Micropython我找了好多,如果用py的话反应非常的慢,这里推荐两种:

  1. https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo/wiki/firmwares
    MicroPython_LoBo_esp32_all
  2. https://github.com/russhughes/st7789_mpy
    我用了第一个里的固件,虽然有点旧,但是至少能直接拿来用
    链接里有各种函数方法的说明
import display

tft = display.TFT()
tft.init(tft.ST7789,rot=tft.LANDSCAPE,rst_pin=26, miso=35, mosi=23, clk=18, cs=5, dc=27)
tft.setwin(40,52,320,240)
tft.set_bg(0xFFFFFF)
tft.clear()
tft.font(tft.FONT_Comic)
tft.text(20,1,"IoT",0xFFFFFF-0x708090)
tft.roundrect(10,30,230,130,8,0xFFFFFF-0x00465B,0xFFFFFF-0x00465B)
tft.arc(65,90,45,25,-120,120,0xFFFFFF-0x708090,0xFFFFFF-0x708090)

通过以上的软硬件配合,简单做了个实时显示数据的看板
因为MQTT暂时没那么多数据,所以都注释掉了
以下是全套代码

import time
# 本来还有请求数据的内容,暂时不放了
# import urequests
import json
import _thread
import display
import network
# 我直接把simple.py拷贝出来了
from simple import MQTTClient
import random


def sub_cb(topic, msg):
	print(msg)


def mqtt():
    while True:
        if True:
            # Blocking wait for message
            c.wait_msg()
        else:
            # Non-blocking wait for message
            c.check_msg()
            # Then need to sleep to avoid 100% CPU usage (in a real
            # app other useful actions would be performed instead)
            time.sleep(1)
        time.sleep(2)

def ran():
    while True:
        mu = random.random()*100
        a = random.random()
        if a > 0.7:
            bd = 0
        else:
            bd = int(random.random()*30)

        print(mu)
        mu_text = str(mu)[:4]+"%"
        tft.set_bg(0xFFFFFF - 0x00465B)
        tft.font(tft.FONT_Ubuntu)
        tft.text(190, 37, str(int(random.random()*10000)), 0xFFFFFF - 0xDCDCDC)
        tft.text(190, 52, str(int(random.random()*10000)), 0xFFFFFF - 0xDCDCDC)
        tft.text(190, 67, str(int(random.random()*10000)), 0xFFFFFF - 0xDCDCDC)
        tft.text(190, 82, str(int(random.random()*10000)), 0xFFFFFF - 0xDCDCDC)

        tft.font(tft.FONT_DejaVu18)

        tft.arc(65, 90, 45, 25, -120, 120, 0xFFFFFF - 0x708090, 0xFFFFFF - 0x00465B)
        if mu >= 50:
            du = int(mu/100*240-120)
        else:
            du = int(240 + mu/100*240)
        if mu >= 76:
            # tft.lineByAngle(65, 90, 0,45,du,0xFFFFFF-0xBFD732)
            tft.text(36, 115, mu_text, 0xFFFFFF - 0xBFD732)
            tft.arc(65, 90, 45, 25, -120, du, 0xFFFFFF - 0xBFD732, 0xFFFFFF - 0xBFD732)
            tft.font(tft.FONT_Ubuntu)
            tft.text(53, 97, "AA", 0xFFFFFF - 0xBFD732)
        else:
            # tft.lineByAngle(65, 90, 0, 45, du, 0xFFFFFF - 0xDC143C)
            tft.text(36, 115, mu_text, 0xFFFFFF - 0xDC143C)
            tft.arc(65, 90, 45, 25, -120, du, 0xFFFFFF - 0xDC143C, 0xFFFFFF - 0xDC143C)
            tft.font(tft.FONT_Ubuntu)
            tft.text(53, 97, "AA", 0xFFFFFF - 0xDC143C)

        if 0 < bd < 999:
            tft.font(tft.FONT_Ubuntu)
            tft.roundrect(130,105,100,25,8,0xFFFFFF - 0xDC143C,0xFFFFFF - 0xDC143C)
            tft.set_bg(0xFFFFFF - 0xDC143C)
            tft.text(140, 110, "FF: ", 0xFFFFFF - 0xF5F5F5)
            tft.text(170, 110, str(bd)+'ggg', 0xFFFFFF - 0xF5F5F5)
        else:
            tft.roundrect(130, 105,100,25,8, 0xFFFFFF - 0xBFD732, 0xFFFFFF - 0xBFD732)
            tft.set_bg(0xFFFFFF - 0xBFD732)
            tft.text(147, 110, "Running", 0xFFFFFF - 0xF5F5F5)
        time.sleep(0.5)

mu = 0
tft = display.TFT()
tft.init(tft.ST7789,rot=tft.LANDSCAPE,rst_pin=26, miso=35, mosi=23, clk=18, cs=5, dc=27)
tft.setwin(40,52,320,240)
tft.set_bg(0xFFFFFF)
tft.clear()
tft.font(tft.FONT_Comic)
tft.text(20,1,"IoT",0xFFFFFF-0x708090)
tft.roundrect(10,30,230,130,8,0xFFFFFF-0x00465B,0xFFFFFF-0x00465B)
tft.arc(65,90,45,25,-120,120,0xFFFFFF-0x708090,0xFFFFFF-0x708090)


print('Ready to connect to wifi')
time.sleep(2)
ssid = 'wifi name'
password = 'wifi password'
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect(ssid, password)
while station.isconnected() == False:
    pass
print('Connection successful')
ip = station.ifconfig()[0]
tft.font(tft.FONT_DefaultSmall)
tft.text(75,13,"Running on",0xFFFFFF-0x708090)
tft.text(145,13,ip,0xFFFFFF-0x708090)
tft.set_bg(0xFFFFFF-0x00465B)
tft.font(tft.FONT_Ubuntu)
tft.text(53,97,"AA",0xFFFFFF-0xDCDCDC)
tft.text(140,37,"BB",0xFFFFFF-0xDCDCDC)
tft.text(140,52,"CC",0xFFFFFF-0xDCDCDC)
tft.text(140,67,"DD",0xFFFFFF-0xDCDCDC)
tft.text(140,82,"EE",0xFFFFFF-0xDCDCDC)



'''
c = MQTTClient("umqtt_client", server='ip', port=1883,user="user",password="password")
c.set_callback(sub_cb)
c.connect()
c.subscribe(b"topic")
'''
# _thread.start_new_thread("mqtt",mqtt,())
_thread.start_new_thread("ran",ran,())

5. 最终效果

数据是random出来的
左边的仪表图设置了大于76%为绿色,小于为红色
右下角FF值>=0显示数据,=0则为绿色
在这里插入图片描述

6. 一些坑

  1. micro usb线也有好坏,差的线可能会供电不足
  2. 屏幕分8bit、9bit,坑死人
  3. 有的传感器极易受干扰,有的甚至你用东西靠近点就没数据了,磁场?
  4. 上次用C还是大学的时候,太久了,回忆起来真痛苦,还是Python简单

7. 总结

通过实践,摸到了物联网应用的门在哪里,了解了涉及到的软硬件等等各个方面,如单片机、传感器、模电/数电、PCB、物联网通信协议NB-IoT、C、MicroPython等等。
由于时间有限,本文只展示了的MicroPython的代码,并且数据采集、数据转化、后期分析方法等内容都没来得及举例。
另外MicroPython虽然易于理解,上手比较快,但是运行效率不高、库不丰富,实际工业应用还是得用C。
完。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值