ESP32-S3实战进阶:使用TensorFlow Lite部署模型

AI助手已提取文章相关产品:

ESP32-S3与边缘AI的融合:从模型构建到部署落地

在智能家居、工业物联网和可穿戴设备快速发展的今天,我们越来越不满足于“传感器采集 + 云上分析”的传统模式。用户想要的是——按下语音指令后 立刻响应 ,摄像头看到人影就 即时告警 ,工厂电机出现异常振动时能 提前预警 。这些需求背后,是对低延迟、高隐私和强可靠性的极致追求。

而这一切,正在被一个小小的芯片悄然改变: ESP32-S3

它不是什么超级计算机,却能在掌心大小的设备里运行神经网络;它没有独立GPU,但凭借双核Xtensa LX7架构和专用AI加速指令,足以支撑轻量级推理任务。更关键的是,它把Wi-Fi 4、蓝牙5.0、丰富外设接口和高达240MHz主频整合在一起,成为边缘AI落地的理想载体。

那么问题来了:
👉 如何让一个只有几百KB SRAM的MCU跑通机器学习模型?
👉 怎样把训练好的TensorFlow模型塞进嵌入式固件?
👉 在资源如此紧张的环境下,还能保证实时性和稳定性吗?

答案是:可以,而且已经有人做到了。下面我们就来拆解这条从算法到硬件的完整链路——从模型设计开始,一路走到真实设备上的推理部署,看看如何用ESP32-S3打造真正“聪明”的终端设备 💡。


模型为何必须“瘦身”?TFLite的底层逻辑

当你在Jupyter Notebook里训练完一个CNN模型,准确率98%,激动地准备部署到ESP32-S3时,现实可能会给你泼一盆冷水:

“你的模型有15MB,而整个Flash留给应用的空间才4MB。”
“SRAM只剩不到200KB,但模型中间激活值需要占用600KB。”

这就像试图把一辆SUV塞进共享单车的车筐里——结构对不上,体积也超了。

所以第一步,我们必须学会“减脂增肌”:去掉冗余部分,保留核心能力。这就是 TensorFlow Lite(TFLite) 存在的意义。

TFLite不是一个新框架,而是TensorFlow为边缘端定制的轻量化推理引擎。它的设计理念非常清晰:
- ✅ 去除训练相关操作(梯度、优化器等)
- ✅ 支持算子融合(Conv+ReLU → 单一Op)
- ✅ 提供量化压缩工具链
- ✅ 可编译成纯C/C++代码,在无操作系统环境下运行

换句话说,TFLite做的不是“移植”,而是“重构”。

举个例子,原始Keras模型保存为H5格式可能有56KB,转换成 .tflite 后直接降到4.2KB——光靠格式优化就实现了 92%的压缩率 !而这还只是起点,后续通过量化还能进一步缩小到1.1KB左右。

但这背后有个前提:你得确保模型中的每一层都能被TFLite支持。否则会出现类似这样的报错:

Operator NOT_SUPPORTED_IN_TFLITE is not supported by this version of TensorFlow Lite.

常见“黑名单”包括:
- LayerNormalization
- 自定义Lambda层(如 tf.sin(x)
- 高级激活函数(LeakyReLU、Swish)
- 动态Resize操作(除非指定method)

遇到这些问题怎么办?两个字: 替换

比如LeakyReLU可以用分段线性近似代替:

tf.maximum(x, 0.1 * x)  # 替代 tf.nn.leaky_relu(x)

BatchNorm可以在训练后合并到卷积核中,变成“融合卷积”:

# 训练后处理
gamma, beta, moving_mean, moving_var = bn_layer.get_weights()
std = np.sqrt(moving_var + epsilon)
new_kernel = old_kernel * gamma / std
new_bias = (old_bias - moving_mean) * gamma / std + beta

这样既去掉了BN层,又不损失精度,还能提升推理速度 👍。


把模型“压扁”还不够,还得让它“变小跑快”

如果说模型转换是第一步瘦身,那 量化(Quantization) 就是第二轮深度塑形。

我们知道,标准神经网络权重通常使用FP32(32位浮点),每个参数占4字节。但对于嵌入式设备来说,这种精度完全是浪费——毕竟没人要求洗衣机识别手势时达到医学影像级别的准确度。

于是我们问自己:能不能用更低精度表示这些数值?

答案是可以。最常见的方案就是将FP32转为INT8(8位整数),存储空间直接从4字节降到1字节,压缩率达75%!

更重要的是,INT8运算可以用SIMD指令并行处理,速度远超浮点计算。ESP32-S3虽然没有FPU,但其向量扩展单元能高效执行定点运算,这让量化模型的实际推理时间大幅缩短。

目前主流量化方式有三种:

方法 权重类型 激活类型 是否需要校准数据 推理速度 典型场景
动态范围量化 INT8 FP32 中等 快速原型验证
全整数量化 INT8 INT8 ⚡️极快 生产环境首选
量化感知训练(QAT) INT8 INT8 精度敏感任务

🔹 全整数量化的实战实现

以下是一个完整的全整数量化流程示例:

def representative_dataset():
    for i in range(100):
        yield [np.random.rand(1, 28, 28, 1).astype(np.float32)]  # 模拟输入

converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_dataset
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8

tflite_quant_model = converter.convert()
with open('model_quant.tflite', 'wb') as f:
    f.write(tflite_quant_model)

注意几个关键点:
- representative_dataset 提供少量样本用于统计动态范围(min/max)
- 显式声明输入输出也为INT8,避免运行时类型转换开销
- 使用 TFLITE_BUILTINS_INT8 限制只使用整数内建算子

实测数据显示,在ESP32-S3上运行同一模型:
- FP32版本:耗时86ms,模型大小4.2KB
- 全整数量化版:耗时仅37ms,模型大小1.1KB,精度下降<1.5%

⚡️性能翻倍,空间节省75%,这是典型的“低成本高回报”优化策略。

❗ QAT:当量化导致精度暴跌时的选择

有时候普通量化会让模型准确率“跳水”超过3%,这时候就得祭出杀手锏—— 量化感知训练(Quantization-Aware Training, QAT)

原理很简单:在训练阶段就模拟量化噪声,让模型学会在这种“失真”环境下依然保持稳定。

实现也很简单,借助 tensorflow_model_optimization 库即可:

import tensorflow_model_optimization as tfmot

quantize_model = tfmot.quantization.keras.quantize_model
q_aware_model = quantize_model(model)

q_aware_model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
q_aware_model.fit(x_train[:1000], y_train[:1000], epochs=5)

# 转换时仍需设置校准数据
converter = tf.lite.TFLiteConverter.from_keras_model(q_aware_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_dataset
qat_tflite_model = converter.convert()

结果呢?在相同INT8配置下,QAT模型通常比后训练量化(PTQ)高出1~2个百分点精度,尤其在小样本或类别不平衡任务中优势明显 ✅。


开发环境怎么搭?别让工具链绊住手脚 🛠️

有了模型,接下来要解决的问题是: 怎么把它烧录到ESP32-S3上运行?

很多人卡在这一步,不是因为技术难,而是环境配得太痛苦。Python版本不对、交叉编译器缺失、CMake报错……各种依赖问题让人抓狂。

别担心,这里有一套经过验证的标准化流程,适用于Linux/macOS/WSL2环境。

🧰 第一步:安装ESP-IDF

ESP-IDF是乐鑫官方推出的IoT开发框架,相当于ESP32系列的“操作系统底座”。

推荐使用v5.1.x版本(生产级稳定):

mkdir ~/esp && cd ~/esp
git clone -b v5.1 --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
./install.sh esp32s3
. ./export.sh

完成后运行:

idf.py --version

如果输出类似 ESP-IDF v5.1.2 ,说明安装成功 ✅。

⚠️ Windows用户强烈建议使用WSL2,原生CMD容易因路径分隔符问题失败。

📦 第二步:集成TFLite Micro

TFLite Micro(TFLM)是专为微控制器设计的C++库,不依赖malloc/new,采用静态内存池管理张量,非常适合资源受限设备。

将其作为组件引入项目:

cd components
git clone https://github.com/tensorflow/tflite-micro tflite_micro

然后在项目根目录的 CMakeLists.txt 中注册路径:

set(EXTRA_COMPONENT_DIRS "${PROJECT_DIR}/components")

并在 main/CMakeLists.txt 中添加依赖:

set(COMPONENT_REQUIRES tflite_micro)

别忘了开启C++支持!修改 sdkconfig.defaults 文件:

CONFIG_CPP_EXCEPTIONS=y
CONFIG_CPP_RTTI=y

最后通过 idf.py menuconfig 确认已启用:
- Component config → C/C++ Support → Enable C++ support
- Exceptions 和 RTTI 选项打开

搞定之后,就可以在 main.cpp 中包含头文件了:

#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/schema/schema_generated.h"

能编译过去,就意味着你已经打通了“PC ↔ MCU”的桥梁 🌉。


模型怎么放进固件?三种策略大比拼

现在有个关键问题摆在面前:ESP32-S3不能像手机那样动态加载模型文件,那 .tflite 模型该怎么放进去?

主要有三种方式:

方式 优点 缺点 适用场景
Header化(编译进Flash) 加载快,安全性高 固件体积大,无法热更新 小模型(<500KB)、固定功能
存储于SPIFFS/FATFS 支持OTA替换模型 需文件系统,启动慢 多模型切换、远程更新
OTA下载至PSRAM 最灵活,支持A/B更新 依赖网络,需签名验证 商业产品、持续迭代

对于大多数初学者和中小项目, Header化 是最优选择。

做法也很简单:把 .tflite 文件转成C数组。

Python脚本一键生成:

def tflite_to_header(input_path, output_path, array_name):
    with open(input_path, 'rb') as f:
        data = f.read()
    with open(output_path, 'w') as h:
        h.write(f'#ifndef {array_name.upper()}_H_\n')
        h.write(f'#define {array_name.upper()}_H_\n\n')
        h.write(f'const unsigned char {array_name}[] = {{\n')
        hex_data = [f'0x{b:02x}' for b in data]
        for i in range(0, len(hex_data), 12):
            h.write('  ' + ', '.join(hex_data[i:i+12]) + ',\n')
        h.write('};\n')
        h.write(f'const int {array_name}_len = {len(data)};\n')
        h.write('#endif\n')

tflite_to_header('mnist_cnn.tflite', 'main/model_data.h', 'g_model')

生成的 model_data.h 可以直接在 model_data.cc 中引用,并参与编译。

优点显而易见:模型随固件一起烧录,无需额外存储介质,加载速度快到毫秒级 ⚡️。

缺点也很明确:一旦模型变了,就必须重新编译整个固件,不适合频繁迭代的产品。

如果你做的是智能音箱唤醒词检测、手势识别这类功能固定的设备,Header化完全够用;但如果是工业网关需要定期更新故障检测模型,那就得考虑SPIFFS或OTA方案了。


解释器怎么玩?MicroInterpreter生命周期详解

终于到了最激动人心的部分: 让模型真正跑起来!

TFLM的核心是 MicroInterpreter 类,它负责解析FlatBuffer格式的模型、分配张量内存、调度算子执行。

但由于ESP32-S3运行FreeRTOS,我们必须格外小心对象的生命周期和线程安全。

以下是典型初始化代码:

#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/micro/micro_mutable_op_resolver.h"

constexpr int tensor_arena_size = 10 * 1024;
uint8_t tensor_arena[tensor_arena_size];

tflite::MicroMutableOpResolver<5> resolver;
resolver.AddConv2D();
resolver.AddDepthwiseConv2D();
resolver.AddFullyConnected();
resolver.AddSoftmax();
resolver.AddReshape();

const tflite::Model* model = tflite::GetModel(g_model);
if (model->version() != TFLITE_SCHEMA_VERSION) {
    TF_LITE_REPORT_ERROR(error_reporter, "Schema mismatch");
    return kTfLiteError;
}

static tflite::MicroInterpreter static_interpreter(
    model, resolver, tensor_arena, tensor_arena_size, error_reporter);

TfLiteStatus status = static_interpreter.AllocateTensors();
if (status != kTfLiteOk) {
    TF_LITE_REPORT_ERROR(error_reporter, "AllocateTensors() failed");
    return status;
}

这里面有几个关键细节需要注意👇:

🧱 1. tensor_arena :静态内存池的艺术

TFLM默认禁用动态内存分配,所有中间张量共享一块连续内存区域,称为 tensor_arena

好处非常明显:
- 避免堆碎片
- 提升Cache命中率
- 实现确定性内存行为(适合实时系统)

但代价是你必须估算好大小。太小会OOM,太大浪费RAM。

建议做法是先用Benchmark Tool测出峰值内存占用,再留出20%余量。

例如某模型实测需96KB,则设置:

alignas(16) uint8_t tensor_arena[120 * 1024]; // 对齐+预留

🔤 2. Op Resolver:你要哪个算子?

TFLM不会自动注册所有算子,必须手动列出你需要的那些。

上面代码中用了 MicroMutableOpResolver<5> ,模板参数5表示最多注册5个算子。

如果你漏写了某个层(比如忘了加 AddMaxPool2D() ),就会在运行时报错:

Could not resolve operator MaxPool2D

所以务必根据模型结构精确填写!

也可以偷懒用 AllOpsResolver ,但它会链接所有算子代码,显著增大二进制体积 ❌ 不推荐用于生产环境。

🔄 3. AllocateTensors():一次调用,终身有效

这个函数触发图解析和内存规划,必须在 Invoke() 之前调用。

但它只需要执行一次!后续每次推理都复用相同的内存布局。

这也是为什么我们把它放在setup阶段而不是loop里。


输入输出怎么对接?数据格式匹配至关重要

模型跑起来了,下一步是喂数据、取结果。

但这里有个坑: 数据类型必须严格匹配!

假设你的模型输入是INT8,范围[-128, 127],但你传了个float数组进去,结果只会是乱码 😵‍💫。

所以一定要搞清楚这几个属性:

属性 获取方式 示例
维度数量 input->dims->size 4
各维大小 input->dims->data[i] [1,96,96,3]
数据类型 input->type kTfLiteInt8
总字节数 input->bytes 27648
数据指针 input->data.int8 指向首地址

以一个量化版MobileNetV1为例,输入尺寸为 (1, 96, 96, 3) ,类型为 int8 ,则写入方式如下:

TfLiteTensor* input = interpreter.input(0);
for (int i = 0; i < input->bytes; ++i) {
    input->data.int8[i] = preprocessed_image[i] - 128; // 零中心化
}

推理完成后读取输出:

TfLiteStatus invoke_status = interpreter.Invoke();
if (invoke_status != kTfLiteOk) {
    TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed");
}

TfLiteTensor* output = interpreter.output(0);
int max_index = 0;
int8_t max_value = output->data.int8[0];
for (int i = 1; i < output->dims->data[1]; ++i) {
    if (output->data.int8[i] > max_value) {
        max_value = output->data.int8[i];
        max_index = i;
    }
}

记住一句话: 预处理的归一化方式必须和训练时一致!

比如训练时用了 (x / 255.0 - 0.5) / 0.5 映射到[-1,1],那你部署时也要做同样的变换,否则模型表现会严重偏离预期。


双核怎么调度?CPU绑定与优先级控制技巧

ESP32-S3支持双核(Pro CPU & App CPU),我们可以利用这一点实现任务隔离。

推荐做法:
- AI推理 → 绑定到Pro CPU(CPU 0),设置高优先级
- UI刷新、日志上传 → 迁移到App CPU(CPU 1),低优先级

这样既能保证推理不被打断,又能维持系统整体流畅性。

创建任务时使用 xTaskCreatePinnedToCore

xTaskCreatePinnedToCore(
    inference_task,          // 函数指针
    "inference",             // 任务名
    4096,                    // 栈大小
    NULL,
    configMAX_PRIORITIES - 2, // 高优先级
    NULL,
    0                        // 绑定到CPU 0
);

FreeRTOS优先级范围通常是0~24(取决于配置),数值越大优先级越高。

AI任务应高于Wi-Fi事件处理(通常为 configMAX_PRIORITIES - 3 ),但低于ISR中断服务程序。

同时,低优先级任务也应迁移到另一核:

xTaskCreatePinnedToCore(ui_task, "ui", 2048, NULL, 1, NULL, 1);

这样一来,两颗CPU各司其职,互不干扰,系统稳定性大大增强 ✅。


外设冲突怎么办?DMA与NN计算的时序博弈

当你用OV2640摄像头通过I2S DMA采集图像时,大量数据流会占用系统总线,影响CPU从Flash读取模型权重的速度,导致推理卡顿。

实测数据显示,在全速I2S传输期间启动推理,平均延迟增加约38%!

怎么办?这里有几种缓解策略:

🕐 1. 分时调度:错峰执行

不在DMA传输高峰期做推理,比如每帧结束后等待几毫秒再启动模型。

void on_frame_complete() {
    vTaskDelay(pdMS_TO_TICKS(5));  // 等待DMA释放总线
    start_inference();             // 再进行推理
}

💾 2. PSRAM缓存模型:减少Flash访问

将频繁使用的模型权重加载至PSRAM,利用其更快的随机访问速度。

// 链接脚本中将tensor_arena映射到PSRAM
extern uint8_t __psram_start;
uint8_t* tensor_arena = &__psram_start;

前提是开启了PSRAM支持且模型不大于可用空间。

📉 3. 降低DMA速率:牺牲带宽换稳定

适当减小I2S采样频率,降低总线压力。

例如从10MHz降到6MHz,虽牺牲帧率,但换来推理稳定性,值得权衡。

🔒 4. 临界区保护:短暂屏蔽中断

对关键计算段使用临界区保护:

portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&mux);
// 执行关键NN层计算
portEXIT_CRITICAL(&mux);

但时间不宜过长,否则会影响其他中断响应。


实战案例:三个典型应用场景深度剖析

理论讲完了,让我们来看三个真实世界的应用案例,看看如何把上述技术组合起来解决问题。

📷 场景一:智能摄像头中的图像分类

目标:在本地完成人体/物体识别,无需上传云端。

硬件配置:
- ESP32-S3-WROOM-1
- OV2640摄像头(QVGA分辨率)
- 外扩8MB PSRAM

流程如下:
1. 摄像头采集RGB565图像(320×240)
2. 中心裁剪 + 双线性插值缩放至224×224
3. 归一化至[-1,1],填入模型输入张量
4. 全整数量化MobileNetV1推理(耗时约380ms)
5. WebSocket推送结果至Web前端

其中最关键的瓶颈是图像缩放。由于ESP32-S3无GPU,全部由CPU完成,耗时可达180ms。

优化建议:
- 使用Neon SIMD指令加速像素转换
- 利用LVGL图形库内置缩放函数
- 或干脆训练一个适配QVGA输入的轻量模型,省去缩放步骤

最终实现“感知→推理→展示”闭环,端到端延迟<1.2秒,适用于家庭安防、自动标签等场景。


🎤 场景二:低功耗语音唤醒系统

目标:实现“Hi Lemon”关键词检测,电池供电可持续工作数周。

挑战:既要灵敏又要省电。

解决方案:“两级唤醒机制”:

  1. 第一级(粗粒度) :每20ms采集一次音频块,计算RMS能量
    c float rms = sqrtf(sum / N); if (rms < NOISE_THRESHOLD) { esp_light_sleep_start(); // 进入浅睡 } else { start_full_pipeline(); // 启动MFCC+DS-CNN }

  2. 第二级(细粒度) :提取MFCC特征,送入DS-CNN模型判断是否为唤醒词

MFCC提取流程:
- Hamming窗加权
- FFT频域变换
- Mel滤波器组加权
- 取对数能量
- DCT降维 → 得到10维特征向量

模型选用深度可分离卷积网络(DS-CNN),参数少、计算快,推理耗时约140ms。

实测平均功耗从85mA降至18mA,唤醒响应时间<250ms,完美平衡能效与体验。


🛠️ 场景三:设备振动异常检测

目标:通过MPU6050采集电机三轴加速度,提前发现机械故障。

采样率:1kHz(每1ms采集一次)

输入窗口:128步 × 6通道(ax/ay/az/gx/gy/gz)

对比测试多种模型:
| 模型 | 推理延迟 | 内存占用 | 准确率 |
|------|----------|----------|--------|
| 1D-CNN | <50ms | ~90KB | 94.3% |
| LSTM | ~120ms | ~210KB | 95.1% |
| 统计阈值法 | <5ms | <5KB | 78.2% |

综合来看,1D-CNN在速度、内存和精度之间达到了最佳平衡。

部署后通过MQTT上报异常事件至云平台:

String payload = "{\"device\":\"motor_01\",\"status\":\"abnormal\",\"ts\":" + String(millis()) + "}";
client.publish("sensor/alert", payload.c_str());

结合OTA机制,还可远程更新模型以适应新故障模式,真正实现“越用越聪明”。


性能还能再榨一榨?高级优化技巧揭秘

你以为这就完了?不,还有更多潜力可挖!

⚙️ 1. CPU频率与Cache调优

默认情况下,ESP32-S3可能运行在80MHz或160MHz,但我们完全可以锁到240MHz:

esp_pm_config_t pm_config = {
    .max_freq_mhz = 240,
    .min_freq_mhz = 80,
    .light_sleep_enable = false
};
esp_pm_configure(&pm_config);

配合增大I-Cache和D-Cache至32KB:

配置 推理耗时(ms) Cache命中率
默认(16KB) 134 73%
32KB Cache 96 91%
关闭Cache 210 42%

差距惊人!强烈建议在 menuconfig 中启用更大缓存。


🚀 2. 算子级优化:用SIMD加速卷积

虽然ESP32-S3没有NPU,但其向量扩展指令支持部分ARM Neon-like操作。

我们可以手动重写卷积内核,利用 vmull.s8 vpaddl.s16 等指令实现并行乘加:

vld1.8 {d0}, [r0]!    @ 加载输入
vld1.8 {d1}, [r1]!    @ 加载权重
vmull.s8 q2, d0, d1   @ 8-bit乘转16-bit
vpaddl.s16 q2, q2     @ 水平累加

实际开发中可借助ESP-DL库提供的优化内核替代默认算子:

op_data->evaluation_proc = esp_dl_conv_eval;

测试表明,优化后卷积层性能提升达2.3倍!


🔄 3. 多模型OTA动态加载

为支持功能切换(如白天人脸识别 + 夜间运动检测),可实现多模型热更新。

方法是预留一个 model_storage 分区用于OTA写入:

# partitions.csv
name,   type, subtype, offset,  size
model_storage, 0x40, 0x00, 0x100000, 1M

通过HTTP下载新模型并写入Flash:

esp_partition_write(partition, 0, buffer, len);

重启后由Bootloader校验签名并加载最新模型,实现安全远程升级。


未来已来:TinyML生态正在爆发 🌱

随着Edge Impulse、TensorFlow Lite Micro、Arduino Nano BLE等平台成熟,TinyML开发门槛正迅速降低。

未来几年,我们将看到更多创新方向:
- 混合精度推理 :FP16激活 + INT8权重,兼顾精度与效率
- 自动算子融合 :类似TensorRT的Pass机制,自动合并Conv+BN+ReLU
- NAS搜索专属轻量网络 :针对ESP32-S3特性定制最优结构
- 自监督学习上设备 :在端侧完成增量训练,适应环境变化

甚至可能出现“微型视觉伺服”、“手势控制家电”、“自适应环境感知节点”等全新交互形态。

而这一切的起点,或许就是你现在手里这块不起眼的ESP32-S3开发板 🔥。

所以别犹豫了——
插上电源,打开IDE,把你第一个 .tflite 模型烧进去吧!

当LED灯随着推理结果闪烁那一刻,你会明白:
真正的智能,从来都不在云端,而在你触手可及的地方。

您可能感兴趣的与本文相关内容

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

2022 / 01/ 30: 新版esptool 刷micropython固件指令不是 esptool.py cmd... 而是 esptool cmd... 即可;另外rshell 在 >= python 3.10 的时候出错解决方法可以查看:  已于2022年发布的: 第二章:修复rshell在python3.10出错 免费内容: https://edu.csdn.net/course/detail/29666 2025/07/07: 由于该视频在2019年制作,当时py3.7;现在py3.13 由于pyreadline冲突rshell已不能用;如果仍要使用rshell请安装py3.12并用我修改的rshell: https://github.com/gamefunc/rshell/releases micropython语法和python3一样,编写起来非常方便。如果你快速入门单片机玩物联网而且像轻松实现各种功能,那绝力推荐使用micropython。方便易懂易学。 同时如果你懂C语音,也可以用C写好函数并编译进micropython固件里然后进入micropython调用(非必须)。 能通过WIFI联网(2.1章),也能通过sim卡使用2G/3G/4G/5G联网(4.5章)。 为实现语音控制,本教程会教大家使用tensorflow利用神经网络训练自己的语音模型并应用。为实现通过网页控制,本教程会教大家linux(debian10 nginx->uwsgi->python3->postgresql)网站前后台入门。为记录单片机传输过来的数据, 本教程会教大家入门数据库。  本教程会通过通俗易懂的比喻来讲解各种原理与思路,并手把手编写程序来实现各项功能。 本教程micropython版本是 2019年6月发布的1.11; 更多内容请看视频列表。  学习这门课程之前你需要至少掌握: 1: python3基础(变量, 循环, 函数, 常用库, 常用方法)。 本视频使用到的零件与淘宝上大致价格:     1: 超声波传感器(3)     2: MAX9814麦克风放大模块(8)     3: DHT22(15)     4: LED(0.1)     5: 8路5V低电平触发继电器(12)     6: HX1838红外接收模块(2)     7:红外发射管(0.1),HX1838红外接收板(1)     other: 电表, 排线, 面包板(2)*2,ESP32(28)  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值