树莓派自动开关机执行延时录像

esp32侧程序,功能有3个,1、是连接Wi-Fi同步网络时间,2、是通过UART口跟树莓派进行通信,检查树莓派是否在预定时间内工作或关机,3、根据时间段控制树莓派开机或关机。该程序在esp32上的文件名为main.py(记得要改名),这样esp32一通电即可工作。程序如下:

上位机(树莓派)与esp32的通信程序check.py,程序如下:

import serial
Port = "/dev/ttyAMA0"
ser = serial.Serial(Port, baudRate, timeout=10)
while True:
   send = '2'
   ser.write(send.encode())
   str = ser.readline().decode()
   if(str !=""):
      print(str)
ser.close()

该程序需要开机自动运行,具体可以将其加入rc.local,具体:

sudo nano /etc/rc.local

在最后一行前加入:python check.py,保存退出重启即可

注意:

树莓派使用串口需要进行以下工作:

1、sudo raspi-config

根据以下步骤进行设置:

选择Interfacing Options

选择serial

再选择 no,禁用串口登录功能,将串口用于通信。
再选择 yes,启动串口硬件。
禁用蓝牙(硬件串口与mini串口默认映射对换

接线:(树莓派(左)——esp32(右))

RXD(GPIO15) <——> TXD(IO12)、TXD(GPIO14) <——> RXD(IO13)、GND <——> GND

sudo nano /boot/config.txt

在打开的文件最后面添加:
(注意:树莓派4b也一样是pi3)

dtoverlay=pi3-disable-bt

修改保存后重启树莓派:

reboot

安装serial,具体如下:

sudo apt-get install python3-serial

烧录esp8266注意事项

很多人第一次用USB转串口模块烧录esp8266失败,这里有几个注意事项:

USB转串口模块与esp8266的接线方式如下:

1、RX->TX,2、TX->RX,3、3V3->3V3,4、GND->GND,以上接线需要确认好。

还有就是要特别注意的一点:烧录时IO0需要接地,烧录成功后需要断开IO0与GND的连接。另外固件选择要对,我的模块很便宜,选择是1M flash的,具体可以到micropython.org上下载对应固件,thonny这个软件就可以直接烧录,而不需要下载esptool工具。

树莓派通过usb摄像头定时拍照

树莓派使用usb摄像头需要安装fswebcam,具体如下:

1、sudo apt-get install fswebcam

2、sudo nano capture.sh

#!/bin/bash
#DATE=$(TZ=UTC-8 date +%Y-%m-%d" "%H:%M:%S)
DATE=$(date +%Y-%m-%H-%M)
fswebcam -d /dev/video0 --no-banner -r 1024X768 -S 60 -D 2 -F 2 /home/pi/$DATE.jpg

3、chmod +x capture.sh

4、crontab -e

* * * * * /home/pi/capture.sh >/dev/null 2>&1

5、记得重启crontab

#重启crontab程序
sudo /etc/init.d/cron restart

fswebcam参数详解
-? –help 显示此帮助页面并退出
-c –config <文件名> 从文件加载配置
-q –quiet 隐藏所有消息(错误除外)
-v –verbose 捕获时显示额外的消息
–version 显示版本并退出
-l –loop <秒> 循环运行
-b –background 在后台运行
-o –output <文件名> 将日志输出到文件
-d –device <摄像头> 设置要使用的摄像头
-i –input 选择要使用的输入
-t –tuner 选择要使用的调谐器
-f –frequency 选择频率使用
-p –palette 选择要使用的调色板格式
-D –delay 设置预捕获延迟时间(秒)
-r –resolution <宽x高> 设置拍摄分辨率
–fps <帧率> 设置捕获帧率
-F –frames 设置要拍摄的帧数
-S –skip 设置要跳过的帧数
–dumpframe 将原始帧转储到文件
-s –set = 设定参数值
–revert 恢复原始捕获的图像
–flip 翻转图像
–crop [,] 裁剪图像的一部分
–scale 缩放图像
–rotate 垂直旋转图像
–deinterlace 减少隔行失真
–invert 反转图像颜色
–greyscale 去除图像的颜色
–swapchannels 交换c1和c2的通道
–no-banner 隐藏横幅
–top-banner 将横幅放在顶部
–bottom-banner 将横幅放在底部(默认)
–banner-colour 设置横幅颜色(#AARRGGBB)
–line-colour 设置横幅线条颜色
–text-colour 设置文字颜色
–font <[name][:size]> 设置字体和和大小
–no-shadow 禁用文字阴影
–shadow 启用文字阴影
–title 设置主标题(左上方)
–no-title 清除主标题
–subtitle 设置字幕 (左下方)
–no-subtitle 清除字幕
–timestamp 设置时间戳格式(右上)
–no-timestamp 清除时间戳记
–gmt 使用GMT代替本地时区
–info 设置信息文本(右下)
–no-info 清除信息文本
–underlay 设置参考图像
–no-underlay 清除底衬
–overlay 设置覆盖图像
–no-overlay 清除覆盖
–jpeg 输出JPEG图像
–png 输出PNG图像(-1, 0 – 10)
–save <文件名> 将图像保存到文件
–exec <命令> 执行命令并等待其完成

pico+tensorflow

Raspberry Pi Pico,上市不足3个月,售价仅有4美元,擅长低时延的 I/O 通信和模拟信号输入,功耗低,可以弥补树莓派在与物理世界互动方面的不足。今天我们项目分享就用Pi Pico+Edge Impulse实现入侵者监测系统。

该项目将热像仪数据给Raspberry Pi Pico,再使用Tensorflow Lite模型分析,达到在黑暗中检测入侵者的目的。这个项目有两大优点:

1)虽然很多家庭会安装摄像头,但有一些是无法在黑暗中工作的。项目中使用的热像仪监测就没有这个问题了。

2)如果一个动物入侵,我们不希望电子设备误报,摄像头肯定是做不到的。这个项目借助Edge Impulse可以准确无误判断当前入侵的是不是人。

注:Tensorflow Lite是针对移动、嵌入式以及IoT设备的工具,能够在终端本地运行机器学习模型的能力,而不必将数据上传到云端服务器进行分析。这样不仅节省网络流量,并且可以用户自己的隐私。

Edge Impulse在线网站自行训练进行分类识别。使用EdgeImpulse在线训练主要分为以下四个步骤:数据集采集、上传、训练以及部署。

01 项目使用到的软硬件

硬件部分:

  • 树莓派PICO开发板
  • MLX90640热成像夜视摄像头
  • Seeed Wio 终端
  • LED灯

开发软件:

  • Raspberry Pi Pico C / C ++ SDK

02 训练数据集

在机器学习项目中,第一步也是最重要的一步是收集训练数据,使训练集能够涵盖给定任务的大多数代表性的案例。

这里使用Seeed Wio终端进行数据采集。Wio终端上的3个按钮用于标记3个类(人,目标和背景)。把收集到的数据保存到Wio终端内置的micro SD卡中。每个热图像数据被捕获为一个单独的文件。该文件不包含标题行,只包含以逗号分隔的768(24×32)个温度读数。示例文件内容如下所示:

采集到的数据的直观表现如下:

03 将数据上传至Edge Impulse

当前,Edge Impulse不支持非时间序列数据类型(图像除外)。为了使用Edge Impulse,数据被假定为时间序列的实例。下面的代码是将原始数据转换为Edge Impluse的数据采集JSON格式。(全部代码可以在“达尔闻说”回复:入侵检测。)

  • import json
  • import time
  • import hmac
  • import hashlib
  • import os
  • HMAC_KEY = “<insert your edge impulse hmac key>”
  • labels = { 
  • ‘1’: ‘Person’,
  • ‘2’: ‘Object’,
  • ‘3’: ‘Background’
  • }
  • dir = ‘raw_data’
  • for filename in os.listdir(dir):
  • if filename.endswith(‘.csv’):
  • prefix, ext = os.path.splitext(filename)
  • label = labels[prefix[-1]] 
  • outfilename = os.path.join(‘formatted_data’, ‘{}.{}.json’.format(label, prefix)) 
  • with open(os.path.join(dir, filename)) as fp: 
  • values = [[float(i)] for i in fp.read().split(‘,’)] 
  • emptySignature = ”.join([‘0’] * 64)
  • data = { “
  • protected”: {
  • “ver”: “v1”, 
  • “alg”: “HS256”,
  • “iat”: time.time()
  • }, 
  • “signature”: emptySignature, 
  • “payload”: { 
  • “device_name”: “A0:C0:D3:00:43:11”,
  • “device_type”: “Raspberry_Pi_Pico”, 
  • “interval_ms”: 1, 
  • “sensors”: [
  • { “name”: “temperature”, “units”: “Cel” },
  • ],
  • “values”: values
  • }
  • # encode in JSON
  • encoded = json.dumps(data)
  • # sign message signature = hmac.new(bytes(HMAC_KEY, ‘utf-8’), msg = encoded.encode(‘utf-8’), digestmod = hashlib.sha256).hexdigest() # 
  • set the signature again in the message, and encode again data[‘signature’] = signature encoded = json.dumps(data, indent=4)
  • with open(outfilename, ‘w’) as fout: 
  • fout.write(encoded)

数据使用Edge Impulse CLI上传,需要先在Edge Impulse注册一个账户,并创建一个新项目来上传数据。下面的命令用于上传所有JSON文件,这些文件会自动分成训练和测试数据集。$ edge-impulse-uploader –category split *.json

上传的数据可以在Edge Impulse Studio查看。

训练数据是以1 ms为间隔的时间序列,但通过设置窗口大小768 ms(等于32×24=768热读数),它被用作单个数据实例。由于这不是一个时间序列数据,我们将使用原始数据块(无需预处理),直接反馈到神经网络块。下面是训练输出。因为没有很多的实例样本数据作为支撑,所以准确率只能达到80%,但是之后通过大量的实例训练数据集可以进一步提高。

04 硬件设置

Pi Pico通过I2C协议与MLX90640热像仪连接,通过SPI协议连接TFT显示器。TFT显示屏用于演示。红色LED灯连接到树莓派Pico的GPIO引脚3上。

Raspberry Pi Pico —– MLX90640热感相机

GP8 —————— SDA

GP9 —————— SCL

3V3(OUT) —————– 5V/3V3

GND. —————— GND

Raspberry Pi Pico —— TFT Display

GP14 —————— MISO

GP13 —————— CS

GP6 —————— SCK

GP7 —————– MOSI

3V3(OUT) —————– 5V

GND. —————— GND

GP15 —————– DC

GP14 —————– RST

05 Edge Impluse移植

只要根据其他平台可用的移植代码,创建一个移植代码文件,就可以在Edge Impulse SDK中加入对Raspberry Pico硬件的支持。以下是代码片段。(在写这篇文章的时候,Edge Impulse还没有正式支持Raspberry Pi Pico,但是相信在不久的将来会支持它的。)#include “ei_classifier_porting.h”
#include “pico/stdlib.h”
#define EI_WEAK_FN __attribute__((weak))
EI_WEAK_FN EI_IMPULSE_ERROR ei_run_impulse_check_canceled() {   
return EI_IMPULSE_OK;
}
EI_WEAK_FN EI_IMPULSE_ERROR ei_sleep(int32_t time_ms) {   
sleep_ms(time_ms);   
return EI_IMPULSE_OK;
}
uint64_t ei_read_timer_ms() {   
return to_ms_since_boot(get_absolute_time());}
uint64_t ei_read_timer_us() {   
return to_us_since_boot(get_absolute_time());} 

06 在Pi Pico上进行模型分类

复制下面代码:$ git clone  https://github.com/metanav/pico_person_detection_thermal.git$ cd pico_person_detection_thermal$ mkdir build$ cd build$ cmake ..$ make -j4

可以通过下面的步骤将生成的pico_person_detection_thermal.uf2二进制文件烧录到Raspberry Pi Pico上。1. 按住BOOTSEL按钮,将Raspberry Pi Pico插入电脑的USB接口,就会显示一个名为RPI-RP2的大容量存储设备。2. 将pico_person_detection_thermal.uf2二进制文件拖放到RPI-RP2上。烧录二进制文件后,Raspberry Pi Pico将重新启动,开始执行检测。

最终如上面演示视频所示,就可以看到,当有一个人出现时,摄像头检测到数据,随后树莓派Pico分析出是人,LED灯亮起。

用Edge Impulse实现MCU机器学习

将AI应用带到边缘终端设备(智能手机、可穿戴、汽车和物联网设备等)可以降低功耗,并减少数据中心资源的负载,其中在MCU上实现机器学习是这种愿景中最为活跃的领域之一,tinyML是一个致力于该领域的新的研究方向。本文讲述了使用Edge Impulse训练验证模型、模型转换、生成代码并部署的过程。Edge Impulse是一个在边缘设备上进行机器学习的在线开发平台,正在获得嵌入式系统产业界的广泛支持。

业界对机器学习 的兴趣近来大增,已经有许多云应用帮助我们进行机器学习的开发。但是,如果应用缺乏互联网连接,需要处理敏感数据,或者要求低延迟,在小型微控制器上运行机器学习会更为合理。本文通过一个样例项目演示使用Edge Impulse在小型、低功耗、低成本微控制器上进行机器学习的开发。

在应用端运行机器学习(ML)算法被称为边缘计算, 比如在工业园区的一个厂房内。在工业4.0和物联网中通过边缘计算使用ML意味着数据不会离开现场,基于ML的决策也可以被快速采用。模型的训练需要大量的计算,但是我们可以在小型、高性价比的微控制器上运行这些计算。基于非对称的ML的大量研究是tinyML基金会的成立的前奏。在嵌入式设备上运行机器学习模型的主要原因有三个:

•本地处理:避免传输传感器收集的数据。不需要互联网连接的话,设备部署的限制就会更少。

•低能耗:微控制器的能耗非常低。一个电池驱动的微控制器可以持续运行图像辨识算法一年。

•成本和部署:微控制器普适而且低成本,方便ML模型的部署。通过简单的软件升级,它们可以很快部署新的或者升级后的模型,而不需要替换硬件。

tinyML依然是一个比较新的研究方向,但是其应用非常广泛,包括农业、医疗和预测性维护等。

Edge Impluse

创建账户并登录之后,你就可以创建你的第一个tinyML项目了,如图1所示,SDK的界面简洁、直观。

图1 Edge Impulse SDK仪表盘

登录之后,仪表盘(Dashboard)显示项目的概况,以及如何启动你的第一个项目,或者继续一个现有项目的指南。界面左侧,在仪表盘下方是其他的主菜单选项,它们的顺序反映了开发的不同阶段,比如设备(Devices)页显示已连接的设备列表,数据获取(Data acquisition)则显示已经收集好的测试和训练数据。Impulse设计(Impulse design)创建一个Impulse,Impulse是一个接收原始数据、运用信号处理提取特性和通过学习块对新数据进行分类的过程。

连接设备时,需要参照仪表盘画面中间的指示,也可以前往设备栏点击连接新设备(Connect a new device)。开发环境支持下列设备:

•ST IoT Discovery Kit:即B-L745E-IOT01A,开发板上搭载使用Cortex-M4处理器的微控制器、MEMS动作传感器、麦克风和WiFi。

•Arduino Nano 33 BLE Sense:一个小尺寸的开发板,上面搭载基于Cortex-M4的微控制器、动作传感器、麦克风和BLE。

•AI ECM3532 Eta Compute Sensor:一个小尺寸的开发板,上面的TENSAI ECM3532 SoC搭载基于Cortex-M3的微控制器和一个单独的CoolFlux DSP用于机器学习的加速。开发板上有两个麦克风,一个6轴加速度计/陀螺仪和一个气压/温度传感器。ECM3532 SoC支持连续电压频率缩放,这允许系统在运行时通过缩放时钟频率和电压调整到最佳的电源效率,从而支持超低功耗机器学习。

•智能手机:Edge Impulse支持能够运行现代浏览器的任何智能手机,过程和方法和其他设备一样。最终,任何数据/模型都可以部署到嵌入式设备上。

图2 设备页显示已连接的设备

收集数据

首先,需要收集用于训练机器学习模型的音频数据。为了检测到水从水龙头流出的声音,我们需要收集一些流水的声音,以及典型的背景噪声(没有流水)的声音样本,这样模型就能够学习两者间的区别。这两类样本代表着我们模型中的两个类型:背景噪声和水龙头开启。在SDK的数据获取(Data acquisition)页可以收集设备传感器数据,这里是存储原始数据的地方。如果设备已经连接到远程管理API,就可以从数据获取页开始新的数据采样。

现在让我们先收录一段水龙头没有打开时的背景噪声,在收录新数据(Record new data)部分选择数据,设置标签(Label)为噪声,定义样本长度(Sample length)为1000,传感器(Sensor)选择内建麦克风。这意味着我们将收录一秒的声音,并将其标记为噪声,标签之后还可以再修改。点击开始采样(Start sampling),设备会录音一秒,并将数据传输到Edge Impulse。数据载入之后,已收集的数据(Collected data)下会出现新的一行记录,可以在界面上分析信号波形或者重播音频(见图3)。

图3 数据收集页收录和回放音频数据的部分

构建数据集

接下来,开始创建一个数据集。对于一个比较简单的音频分类模型,我们应该收集大约10分钟的数据。两个类型的样本应该基本均衡,所以我们需要收集:五分钟的背景噪声,标记为“噪声”;五分钟水龙头开启时的声音,标记为“水龙头”。

在真实世界中,我们感兴趣的声音往往会和其他声音混杂在一起,比如水龙头的流水声往往会伴随着洗碗的声音或者厨房的交谈声,背景噪声还可能有电视、小孩玩耍或者车辆从附近经过的声音。训练用的数据必须包含这些实际环境的声音,如果模型没有接触到它们,准确度会降低。在本文中将收录下面的样本:

•背景噪声:

o没有其他声音:两分钟

o同时有电视/音乐的声音:一分钟

o同时有偶尔的讲话/谈话:一分钟

o同时有做家务的声音:一分钟

•水龙头开启的声音:

o水龙头开启流水的声音:一分钟

o另一个不同的水龙头开启流水的声音:一分钟

o同时有电视/音乐的声音:一分钟

o同时有偶尔的聊天/对话:一分钟

o同时有做家务的声音:一分钟

即使无法取得全部的样本,也不必担心。我们的目标是每个分类都有五分钟的真实世界数据,在具有代表性的数据集上训练出的模型会更加准确有效。无法保证模型能准确分辨数据集以外的声音,所以我们必须尽可能地贴近真实世界,在数据集中包括多种声音。另一个选项是从Edge Impulse下载现成的十分钟样本 ,解压到本地后,在数据获取页点击上传数据(Upload data)图标(见图4),然后上传下载的文件,并添加标签。

图4 数据获取页,用于上传预先准备好的数据集

一次性可以收录的音频长度取决于特定硬件的存储大小,ST B-L745E-IOT01A板的存储容量允许一次性录音60秒,Arduino Nano 33 BLE Sense则只能录音16秒。录音60秒意味着需要将样本长度设置为60 000。从开发板上传输数据往往很慢,在Edge Impulse中采集60秒的样本大约需要7分钟。取得需要的10分钟数据后,就可以开始设计Impulse了。

设计Impulse

Impulse读取原始数据,将其分割为多个更小的窗口,然后通过信号处理块提取特征,通过学习块分类新的数据。信号处理块的作用是简化原始数据的处理,针对同样的输入同一个信号处理块总会返回一致的数值,因此学习块可从之前的经验中学习。在本文使用MFCC信号处理块,MFCC指梅尔频率倒谱系数[ ],这听上去很复杂,实际上就是从声音数据中移除大量的冗余信息。接下来,我们会将简化后的音频数据送到一个神经网络块(学习块)中,学习块将会学习如何区分两个音频类别(水龙头开启和噪声)。现在,打开创建Impulse(Create impulse)页面,你会看到原始数据(Raw data)部分。

同之前提过的一样,Edge Impulse在训练时将样本分割为小的窗口,然后将数据发送到机器学习模型中。窗口大小(Window size)参数控制每个数据段的长度(单位毫秒),一秒长的音频样本足够确定水龙头是否开启,所以设置为1000毫秒。每一个原始样本被分为多个窗口,窗口间距(Window increase)的大小决定下一个窗口和上一个窗口的间距,1000毫秒的窗口间距意味着每个窗口在上一个窗口开始的一秒后开始。

如果窗口间距的数值小于窗口大小,则可创建互相重叠的窗口。虽然窗口间会包括一部分相似的数据,每一个样本依然是独特的。互相重叠的窗口帮助我们高效地利用训练数据,比如1000毫秒的窗口大小和100毫秒的窗口间距意味着可以从两秒的数据中提取十个独特的窗口。本文中设置窗口大小为1000毫秒,窗口间距为300毫秒。点击添加处理块(Add a processing block),选择MFCC块,然后点击添加学习块(Add a learning block),选择Keras神经网络块(Neural Network – Keras),最后点击保存。创建Impulse的页面如图5所示。

图5 创建Impulse

MFCC块配置

目前已经凑齐了Impulse所需要的基本组成模块,现在可以单独配置每个部分了。在左侧的导航菜单中点击MFCC标签进入块配置页,界面上可以预览数据将如何被转换。在右侧可以看到一个频谱图上显示了MFCC处理音频输入后的输出结果。MFCC块将一个音频样本转换为一个数据表格,每一行是一个频率范围,每一列是本时间区段内频率范围内声音的强度。频谱图用颜色填充每个单元格,颜色的深浅表示振幅的高低。图6中对比了噪声和水龙头声音的频谱图。

图6 噪声(上)和水龙头声音(下)的频谱图

我们的双眼很难分辨出两张图的区别,但对于一个神经网络而言,它们间的差别足够用来学习两个类别的不同。在参数(Parameter)框中可以配置MFCC块,Edge Impulse的默认数值适用于多数情形,这里不做修改。MFCC块产生的频谱图会被发送到神经网络中,神经网络的特性意味着它特别适合学习此类列表数据背后的模式。

在训练神经网络之前,需要从采集的所有音频窗口中产生MFCC特征。点击页面上方的产生特征(Generate feature),然后点击绿色的同名按钮,分析十分钟的样本需要几分钟的时间,这一过程结束后,特征浏览器(Features explorer)会以可视化的形式显示数据集,你可以检查不同类型间的区别是否明显,并查找错误的数据标签。为了能在三维空间内显示所有的特性,这里用到了降维手段。

神经网络配置

神经网络借鉴人脑的工作方式,能够学习辨识训练数据中的模式。我们训练的神经网络从MFCC中取得数据,然后决定输入数据属于噪声类别还是水龙头类别。点击左侧菜单的神经网络分类器(NN Classifier)进入块配置窗口。一个神经网络由多层虚拟的神经元组成,在页面的左侧可以看到当前的状态。输入数据(来自MFCC的频谱图)首先进入第一层神经元,这些神经元有着各自独特的内部状态,会对输入进行过滤和转换。第一层神经元的输出会被送到第二层神经元,以此类推,神经网络会一点点转变原始输入,最终变成完全不同的输出。在本例中,频谱图经过4个中间层后变成两个数字,分别是输入数据代表噪声和水龙头开启的可能性。

在训练中,为了让神经网络能够正确地转换输入并输出我们想要的结果,每个神经元的内部状态都会逐渐转变。当输入一个样本时,根据网络输出结果和正确的响应(标签)间的距离,神经元的内部状态会被调整,这样下次网络给出正确响应的可能性就会更大。重复这一过程几千次,就会得到经过训练的网络。

对于神经网络而言,神经元层的安排被称为“结构”,不同的结构适用于不同的任务。虽然Edge Impulse中默认的神经网络结构很适合当前的项目,但也可以定义你自己的结构。在开始训练模型前,需要更改配置中的一些数值。首先将训练周期数(Number of training cycles)设为300,这意味着整个数据集在训练中会被处理300次。如果周期数太少,网络无法从训练数据中充分学习,但是如果周期数太多,网络可能会过度切合训练数据,无法正确处理新数据,这一问题被称为“过拟合”。

接下来,将最低置信度(Minimum confidence rating)设为0.7,这意味着当神经网络作出预测时,除非声音是水龙头流水声的概率为0.7以上(比如0.8),Edge Impulse将会忽略这一预测。现在我们可以点击开始训练(Start training),训练将会花上几分钟时间,结束后会在页面下方看到上次训练表现面板(见图7)。

图7 训练后网络的表现

虽然完成了Edge Impulse中神经网络的训练,但是结果中这些数字都意味着什么?在训练开始前,20%的数据被预设为验证数据,它们被用来验证模型的性能,而不是用做训练数据。上次训练表现(Last training performance)面板上显示验证的结果,从而提供关于模型性能的信息,你看到的数字可能会和这里的不同。准确度(Accuracy)指被正确分类的音频样本的百分比,数字越高越好,不过一般不太可能接近100%,极高的准确度往往也意味着过拟合。就许多应用而言,高于80%的准确度已经很好了。面板中央的混淆矩阵 显示正确和错误分类的数目。

分类新的数据

虽然上一步中的性能数据说明模型在训练数据上的表现很好,但在部署前用新数据测试它依然是非常重要的,这能帮助我们确认模型没有过拟合。Edge Impulse内建了一些测试工具,帮助从设备上实时抓取数据并立即进行分类。点击左侧菜单上的实时分类(Live classification)按钮,你的设备应该出现在分类新数据(Classify new data)面板上,点击开始采样(Start sampling)将会收集5秒的背景噪声数据。

测试模型

通过实时分类(Live classification)标签页可以快速测试你的模型,了解模型的行为。不过,如果想要确保你的模型的正确性,需要更加严格地测试你的模型。模型测试(Model testing)标签页正是为此而存在的。理想状况下,你的测试数据集大小应该至少是训练数据集的25%,假设训练数据是10分钟,测试数据至少需要2分30秒。此外,还需要确保测试数据能够反映大量的真实情形,这样能够以不同的输入测试模型的性能。

比如说,收集若干不同水龙头的声音是一个很好的主意,可以从数据获取(Data acquisition)标签页管理你的测试数据。打开标签页,点击上方的测试数据(Test data),使用上传(Upload)功能导入数据,过程同之前上传训练数据一样。确保数据的标签是正确的,结束后返回模型测试(Model testing)标签页,选择全部样本,然后点击分类选中的数据(Classify selected)。

图8是分类的结果,面板显示模型的准确率是73.42%。针对每个样本,面板上会显示其准确率,比如其中一个样本的分类准确度为67%。有很多误分类的样本非常宝贵,这样的样本中有许多模型目前不拟合的音频类型,通常需要将此类样本加入到训练数据中。

图8 测试数据分类的结果

在硬件设备上部署模型

设计、训练并验证了我们的impulse之后,就可以在硬件设备上部署了,这意味着模型可以在没有互联网的情况下以最小的延迟和最低的功耗运行。Edge Impulse可以将整个impulse包装为一个C++代码库以供编程使用,包括MFCC算法、神经网络和分类代码。点击菜单中的部署(Deployment)开始模型的导出过程,接下来在构建固件(Build firmware)下选择正确的开发选项,然后点击构建(Build),就会针对特定的开发板将impulse输出为二进制可执行文件。构建过程完成后程序会提供二进制文件下载,将文件保存到本地。点击构建(Build)按钮时,程序会弹出窗口、提供关于部署的说明,指导你在构建后进行测试。可以在命令行上运行如下命令以打开连接硬件固件的串行接口:$ edge-impulse-run-impulse

这一命令会打开麦克风收录声音,在数据上运行MFCC代码,并对产生的频谱图进行分类。

结 语

在微控制器上运行机器学习是一个比较新的领域,对于不熟悉人工智能的开发者而言很难上手。Edge Impulse简化了数据的收集和分析、神经网络的训练和构建,以及在微控制器上部署的过程。这类模型有着诸多应用,从监控工业机械到辨识语音命令都可以适用。Edge Impulse易于使用,界面直观,而且免费,这意味着可以立即开始探索在嵌入式设备上运行tinyML。(本文首先在Elettronica Open Source 上以意大利文发表。)

相关参考链接:

https://www.expert.ai/blog/machine-learning-definition/.

https://www.tinyml.org/.

https://www.tinyml.org/.

https://cdn.edgeimpulse.com/datasets/faucet.zip.

https://www.tinyml.org/.

https://www.dataschool.io/simple-guide-to-confusion-matrix-terminology/.

https://it.emcelettronica.com/.

树莓派GPIO使用指南

 RPi.GPIO是 Python的一个module( 模块 ), 树莓派官方系统默认已经安装, 仍在不断更新中, 截至20180521, 最新版0.6.3, 适配了树莓派3B+, 可以访问  python主页下载源码 .      本文根据树莓派RPI.GPIO模块的官方文档翻译,当时的模块版本为0.6.3。官方的帮助文档的链接: https://sourceforge.net/p/raspberry-gpio-python/wiki/BasicUsage/

1、导入模块

要导入RPi.GPIO模块,请执行以下操作:

import RPi.GPIO  as GPIO 

通过这样做,您可以通过脚本的其余部分将其称为GPIO。

导入模块并检查它是否成功:

tryimport RPi.GPIO  as GPIO 
except RuntimeError print
"Error importing RPi.GPIO!  This is probably because you need superuser privileges.  You can achieve this by using 'sudo' to run your script"

2、引脚编号

     在RPi.GPIO中,有两种方法可以对Raspberry Pi上的IO引脚进行编号。第一种是使用BOARD编号系统。这是指Raspberry Pi板上P1接头上的引脚号。使用这种编号系统的优点是,无论树莓派的电路板版本如何,您的硬件都能正常工作。你不需要重新连接你的连接器或更改你的代码。

     第二个编号系统是BCM号码。这是一种较低级别的工作方式 – 它指的是Broadcom SOC上的通道号码。您必须始终使用那个通道编号所对应的树莓派板上哪个引脚的图表。您的脚本程序可能会在Raspberry Pi板的硬件修订后而不能使用。

        树莓派引脚有BOARD和BCM两种编号方式( 使用python时? 似乎使用C还有一种wringPi编号方式 ), BOARD具有很好的适用性( 不用看接口图,数引脚1~40就可以接线 ), 不论树莓派1 2 3, 都不用修改代码, 吼啊! BCM编号方式换个版本再接线时数引脚是不行的, 需要看下下面的接口图…不难看出推荐用BOARD编号方式. 但很多程序中使用BCM方式. 
下面给出一张树莓派2B的硬件接口图( 来源找不到了,侵删 ): 

图中的GPIOxx的方框即是BCM编码方式, 直接写数字的深灰框是BOARD编码方式, 如BCM编码方式的 GPIO02 对应BOARD编码方式的 3.

只需要使用BCM编号方式时, 用下面这两张: 


要指定您使用引脚编号方式:

GPIO.setmode(GPIO.BOARD)
  # or
GPIO.setmode(GPIO.BCM)

要检测哪个引脚编号系统已被设置模式(例如,由另一个Python模块配置过模式):

mode = GPIO.getmode()

模式将是GPIO.BOARD,GPIO.BCM或None

3、警告

您可能在Raspberry Pi的GPIO上有多个脚本/电路。因此,如果RPi.GPIO检测到引脚已被配置为默认(输入)以外的其他引脚,则在尝试配置脚本时会收到警告。要禁用这些警告:

GPIO.setwarnings(False)

4、设置一个通道

您需要设置您用作输入或输出的每个通道。将通道配置为输入:

GPIO.setup(channel, GPIO.IN)

(其中通道是基于您指定的编号系统(BOARD或BCM)的通道编号)。

有关设置输入通道的更多高级信息可以在这里找到。

要将通道设置为输出:

GPIO.setup(channel, GPIO.OUT)

(其中通道是基于您指定的编号系统(BOARD或BCM)的通道编号)。

您还可以为您的输出通道指定一个初始值:

GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)

4、设置多个频道

您可以一次设置多个通道(从0.5.8开始)。例如:

chan_list  =  [ 11 ,12 ]     #加你想尽可能多的渠道!
                       #你可以用元组代替,即:
                       #chan_list =(11,12)
GPIO.setup(chan_list, GPIO.OUT)

5、输入

读取GPIO引脚的值:

GPIO.input(channel)

     ( 其中通道是基于您指定的编号系统(BOARD或BCM)的通道编号)。这将返回0 / GPIO.LOW / False或1 / GPIO.HIGH / True。

     有几种方法可以将GPIO输入到您的程序中。第一种也是最简单的方法是在某个时间点检查输入值。这就是所谓的“轮询”,如果你的程序在错误的时间读取了值,可能会错过输入。轮询在循环中执行,并可能是处理器密集型的。响应GPIO输入的另一种方式是使用’中断’(边沿检测)。边沿是从高电平到低电平(下降沿)或从低电平到高电平(上升沿)的意思。

5.1 上拉/下拉电阻

     如果你没有连接到任何输入引脚,它将’浮空’。换句话说,读入的值是未定义的,因为它只有在按下按钮或开关时才会连接到任何东西。由于引脚会接收到干扰,可能读取到变化的值。

      为了解决这个问题,我们使用上拉或下拉电阻。这样,可以设置输入的默认值。可以在硬件上使用上拉/下拉电阻并使用软件。在硬件中,通常使用输入通道和3.3V(上拉)或0V(下拉)之间的10K电阻。RPi.GPIO模块允许您配置Broadcom SOC以在软件中执行此操作:

GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
  # or
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

(其中通道是基于您指定的编号系统的通道编号 – BOARD或BCM)。

5.2 测试输入(轮询)

您可以立即读取IO引脚的输入值:

if GPIO.input(channel):
    print('Input was HIGH')
else:
    print('Input was LOW')

要通过轮询轮询等待按钮按下:

while GPIO.input(channel) == GPIO.LOW:
    time.sleep(0.01)  # wait 10 ms to give CPU chance to do other things

(这里假设按下按钮将输入从LOW改变为HIGH)

5.3 中断和边缘检测

    边沿是电信号从低电平变为高电平(上升沿)或从高电平变为低电平(下降沿)的状态变化。很多时候,我们更关心输入状态的变化而非价值。这种状态变化是一个事件。

     为了避免在程序忙于做其他事情时按下按钮,有两种方法可以解决这个问题:

  • wait_for_edge()函数
  • event_detected()函数
  • 在检测到边缘时运行线程的回调函数

wait_for_edge()函数

wait_for_edge()函数设计用于阻止程序的执行,直到检测到边缘。换句话说,上面等待按钮按下的示例可以被重写为:

GPIO.wait_for_edge(channel, GPIO.RISING)

    请注意,您可以检测GPIO.RISING,GPIO.FALLING或GPIO.BOTH类型的边沿。这样做的好处是它使用的CPU时间可以忽略不计,因此CPU还有很多工作要做。

如果您只想等待一段时间,则可以使用timeout参数:

#上升沿等待最多5秒(超时以毫秒为单位)
channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000)
if channel is None:
    print('Timeout occurred')
else:
    print('Edge detected on channel', channel)

event_detected()函数

event_detected()函数设计用于与其他工作一起循环使用,但与轮询不同,在CPU忙于处理其他事情时,不会错过输入状态的变化。当使用类似Pygame或PyQt的东西时,这可能很有用,因为主循环会及时监听和响应GUI事件。

GPIO.add_event_detect(channel, GPIO.RISING)  # add rising edge detection on a channel
do_something()
if GPIO.event_detected(channel):
    print('Button pressed')

请注意,您可以检测GPIO.RISING,GPIO.FALLING或GPIO.BOTH的事件。

Threaded回调

RPi.GPIO为回调函数运行第二个线程。这意味着回调函数可以与主程序同时运行,并立即响应边缘事件。例如:

def my_callback(channel):
    print('This is a edge event callback function!')
    print('Edge detected on channel %s'%channel)
    print('This is run in a different thread to your main program')
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback)  # add rising edge detection on a channel
...the rest of your program...

如果你想要多个回调函数:

ef my_callback_one(channel):
    print('Callback one')
def my_callback_two(channel):
    print('Callback two')
GPIO.add_event_detect(channel, GPIO.RISING)
GPIO.add_event_callback(channel, my_callback_one)
GPIO.add_event_callback(channel, my_callback_two)

请注意,在这种情况下,回调函数按顺序运行,而不是同时运行。这是因为只有一个线程用于回调,每个回调都按照定义的顺序运行。

5.4开关抖动

您可能会注意到,每次按下按钮都会多次调用回调。这是所谓的“开关抖动”的结果。处理抖动有两种方法:

  • 在开关输入脚上添加一个0.1uF的电容。
  • 软件去除抖动
  • 以上两种方法的结合

要使用软件去抖动,请将bouncetime =参数添加到指定回调函数的函数中。抖动时间应以毫秒为单位指定。例如:

#在通道上添加上升沿检测,忽略处理
   GPIO的开关抖动操作的进一步边缘200ms 
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback, bouncetime=200)

要么

GPIO.add_event_callback(channel, my_callback, bouncetime=200)

5.5 删除事件检测

如果由于某种原因,您的程序不再希望检测边缘事件,则可以删除它们:

GPIO.remove_event_detect(channel)

6、输出

要设置GPIO引脚的输出状态,请执行以下操作:

GPIO.output(channel, state)

(其中通道是基于您指定的编号系统(BOARD或BCM)的通道编号)。

状态可以是0 / GPIO.LOW / False或1 / GPIO.HIGH / True。

A.设置输出高电平:

GPIO.output(12, GPIO.HIGH)
 # or
GPIO.output(12, 1)
 # or
GPIO.output(12, True)

B.设置输出低电平:

GPIO.output(12, GPIO.LOW)
 # or
GPIO.output(12, 0)
 # or
GPIO.output(12, False)

7、输出到几个通道

您可以一次设置输出多个频道(从0.5.8开始)。例如:

chan_list = [11,12]                             # also works with tuples
GPIO.output(chan_list, GPIO.LOW)                # sets all to GPIO.LOW
GPIO.output(chan_list, (GPIO.HIGH, GPIO.LOW))   # sets first HIGH and second LOW

8.在RPi.GPIO中使用PWM

要创建一个PWM实例:

p = GPIO.PWM(channel, frequency)

要启动PWM:

p.start(dc)   # where dc is the duty cycle (0.0 <= dc <= 100.0)

要更改频率:

p 。ChangeFrequency (freq )   #其中freq是以Hz为单位的新频率

要改变占空比:

p.ChangeDutyCycle(dc)  # where 0.0 <= dc <= 100.0

要停止PWM:

p.stop()

请注意,如果实例变量’p’超出范围,PWM也会停止。

每两秒闪烁一次LED的示例:

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
p = GPIO.PWM(12, 0.5)
p.start(1)
input('Press return to stop:')   # use raw_input for Python 2
p.stop()
GPIO.cleanup()

增亮/调暗LED的示例:

import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
p = GPIO.PWM(12, 50)  # channel=12 frequency=50Hz
p.start(0)
try:
    while 1:
        for dc in range(0, 101, 5):
            p.ChangeDutyCycle(dc)
            time.sleep(0.1)
        for dc in range(100, -1, -5):
            p.ChangeDutyCycle(dc)
            time.sleep(0.1)
except KeyboardInterrupt:
    pass
p.stop()
GPIO.cleanup()

9、GPIO恢复默认

    在程序的末尾,清理您可能使用的任何资源是一种很好的做法。这与RPi.GPIO没有什么不同。通过将您用过的所使用的通道返回到到无上拉/下拉输入的状态,这样可以避免短接GPIO引脚来导致意外损坏您的树莓派。请注意,这样只会清除你写的脚本中使用的GPIO通道。请注意,GPIO.cleanup()也会清除正在使用的引脚编号系统。

       在你的脚本程序的末尾写上:

GPIO.cleanup()

当您的程序退出时,可能不希望清理每个通道,而留下一些设置。您可以清理个别通道,使用通道的元组或列表做为参数输入:

GPIO.cleanup(channel)
GPIO.cleanup( (channel1, channel2) )
GPIO.cleanup( [channel1, channel2] )

10、RPi板信息和RPi.GPIO版本

发现有关您的RPi的信息:

GPIO.RPI_INFO

发现Raspberry Pi电路板版本:

GPIO.RPI_INFO [ 'P1_REVISION']
GPIO.RPI_REVISION(不建议使用)

要发现RPi.GPIO的版本:

GPIO.VERSION

11、编写一个测试程序blinkled.py

      这个测试程序控制树莓派上一GPIO 25每2秒变化一个电平,如果接一个LED灯到这个IO上面,就会看到这个灯亮2秒灭2秒。

#!/usr/bin/python#*coding:utf-8*#GPIO控制LED灯程序import RPi.GPIO as GPIOimport timepin = 25GPIO.setmode(GPIO.BCM)GPIO.setup(pin, GPIO.OUT) while True:    GPIO.output(pin, GPIO.HIGH)    time.sleep(2)    GPIO.output(pin, GPIO.LOW)    time.sleep(2) 

     在这个blinkled.py的目录中,在命令行中执行sudo python blinkled.py就可以运行此程序,LED就会一闪一闪的了

无需任何电脑,从网络安装树莓派操作系统

大部分时候,我们都是用另一台计算机(比如运行 Raspberry Pi Imager写入镜像)来给树莓派装系统的。

但是,如果你一开始没有PC,如何将操作系统安装到 SD 卡上呢?

这是经典的先有鸡还是先有蛋的问题,我们刚刚解决了它。

新的网络安装程序正在运行

现在有一个实现网络安装的 Raspberry Pi 引导加载程序(beta版),希望你能帮助我们进行测试。

下载地址:

https://www.raspberrypi.com/software/

新的网络安装功能可直接在Raspberry Pi 4或Raspberry Pi 400上启动Raspberry Pi Imager应用程序。

注:要用以太网电缆从 Internet 下载。


Raspberry Pi Imager 应用程序将在你的 Raspberry Pi 内存中运行,然后把操作系统写入空白 SD 卡或 USB 磁盘,就像平常一样。


如何使用网络安装程序

如果你想试用这个网络安装程序,首先必须安装bootloader的测试版。

对于当前已经上市的电路板,需要更新bootloader。

不过一旦测试期结束,我们最终将在树莓派出厂时直接安装新的网络引导加载程序,不再需要此步骤。

安装新的 beta 引导加载程序

在 Raspberry Pi 4 或 400 上更新bootloader最简单方法是在 Raspberry Pi 或另一台计算机上运行Raspberry Pi Imager,将所需的软件复制到 SD 卡上。


你需要一张备用的空白 SD 卡,如果你使用的是 Raspberry Pi 或另一台没有 SD 卡插槽的计算机,则需要一个 USB to SD转接头。

你应该知道,用于更新 Raspberry Pi 引导加载程序的 SD 卡将被擦除所有现有数据,因此不要将有重要数据的 SD 卡装在当前Raspberry Pi上 。

在Imager应用程序中,单击“选择操作系统”按钮并在弹出窗口中向下滚动“操作系统”列表。选择“Misc utility images”,然后选择“Beta Test Bootloader”。

选择新的 Beta 测试引导加载程序

接下来,你需要选择引导顺序。

所有选项看上去差不多,但启动顺序不同。除非有其它理由,否则应该选择“SD Card Boot”。

选择引导顺序

然后按照正常说明将更新的引导加载程序写入SD卡。

当SD卡完成写入后,你应该关闭 Raspberry Pi 并移除现有的SD卡并将其放在安全的地方。

将 Imager 应用程序写过的卡插入 Raspberry Pi 并重新打开电源。板子 LED 会闪烁,屏幕会变绿,新的引导加载程序成功启动。

如果你想将引导加载程序恢复到“Release”版本,可以再次执行这些步骤,选择顶部的“引导加载程序”选项而不是“Beta 测试引导加载程序”选项。


现在移除你的引导加载程序更新 SD 卡并重启树莓派。

尝试网络启动

现在你已经更新了引导加载程序,一切应该和以前一样工作。

当 Raspberry Pi 启动时,引导加载程序会搜索要加载的软件。它首先查找 SD 卡,然后查找 USB 记忆棒,依此类推。

它会一直循环下去,直到找到要使用的软件。几秒钟后,你会在屏幕上看到一个诊断信息,告知它正在做什么。

如果你想插入原来的 SD 卡(你在这一切开始之前使用的那个),你的 Raspberry Pi 应该会像往常一样无缝地引导回操作系统。

如果你在插槽中没有 SD 卡或使用空白 SD 卡的情况下启动 Raspberry Pi,并且连接了键盘,那么你现在会看到一些不同的东西。

如果你连接了键盘(Raspberry Pi 400 总是如此),但 Raspberry Pi 无法找到操作系统,它将显示新的网络安装界面。

新的网络安装界面

在后台,你的 Raspberry Pi 仍在寻找可运行的操作系统。但是此时,你可以通过按住该Shift键三秒钟来启动网络安装过程。在出现提示时按确认你要继续按Space,它应该会要求你插入以太网电缆。

你需要通过以太网电缆将 Raspberry Pi 物理连接到路由器,而不是将其连接到无线网络。你需要一根两端都有公头 RJ45 连接器的以太网电缆。

大多数家用路由器的背面都有网口,可让你插入以太网电缆,因此将电缆的一端插入路由器,另一端插入树莓派。

记得插网线

当它检测到已插入电缆时,它会自动下载 Raspberry Pi Imager。如果下载失败,你可以重复该过程。

安装 Raspberry Pi Imager

最终,Raspberry Pi Imager 应用程序在树莓派上启动,允许你将完整的操作系统安装到新的空白 SD 卡或 USB 记忆棒上。

如果你还没有这样做,此时应该将另一张空白 SD 卡插入 Raspberry Pi 卡槽。Raspberry Pi Imager 允许你直接从 Internet 烧录系统。

系统装好后不会在启动时看到网络安装界面。

如果还想运行它,只需要删除所有可启动磁盘,等 Raspberry Pi Imager 运行再重新插入它们。但注意不要覆盖任何有重要工作内容的磁盘!

工业和信息化领域数据安全管理办法(试行)

(公开征求意见稿)

第一章 总则 

第一条【目的依据】为规范工业和信息化领域数据处理活动,加强数据安全管理,保障数据安全,促进数据开发利用,保护个人、组织的合法权益,维护国家安全和发展利益,根据《中华人民共和国数据安全法》《中华人民共和国网络安全法》《中华人民共和国个人信息保护法》《中华人民共和国国家安全法》《中华人民共和国民法典》等法律法规,制定本办法。 

第二条【适用范围】在中华人民共和国境内开展的工业和信息化领域数据处理活动及其安全监管,应当遵守相关法律、行政法规和本办法的要求。 

第三条【数据定义】工业和信息化领域数据包括工业数据、电信数据和无线电数据。工业数据是指工业各行业各领域在研发设计、生产制造、经营管理、运行维护、平台运营等过程中产生和收集的数据。 

电信数据是指在电信业务经营活动中产生和收集的数据。 

无线电数据是指在开展无线电业务活动中产生和收集的无线电频率、台(站)等电波参数数据。 

工业和信息化领域数据处理者是指对工业和信息化领域数据进行收集、存储、使用、加工、传输、提供、公开等数据处理活动的工业企业、软件和信息技术服务企业、取得电信业务经营许可证的电信业务经营者和无线电频率、台(站)使用单位等工业和信息化领域各类主体。 

第四条【监管机构】在国家数据安全工作协调机制统筹协调下,工业和信息化部负责督促指导各省、自治区、直辖市及计划单列市、新疆生产建设兵团工业和信息化主管部门(以下统称地方工业和信息化主管部门),各省、自治区、直辖市通信管理局(以下统称地方通信管理局)和各省、自治区、直辖市无线电管理机构(以下统称地方无线电管理机 

构)开展数据安全监管,对工业和信息化领域数据处理者的数据处理活动和安全保护进行监督管理。 

地方工业和信息化主管部门负责对本地区工业数据处理者的数据处理活动和安全保护进行监督管理。地方通信管理局负责对本地区电信数据处理者的数据处理活动和安全保护进行监督管理。地方无线电管理机构负责对本地区无线电数据处理者的数据处理活动和安全保护进行监督管理。 

工业和信息化部及地方工业和信息化主管部门、通信管理局、无线电管理机构统称为行业(领域)监管部门。 

行业(领域)监管部门依照有关法律、行政法规的规定,依法配合有关部门开展的数据安全监管相关工作。 

第五条【产业发展】行业(领域)监管部门鼓励数据开发利用和数据安全技术研究,支持推广数据安全产品和服务,培育数据安全企业、研究和服务机构,发展数据安全产业,提升数据安全保障能力,促进数据的创新应用。 

工业和信息化领域数据处理者研究、开发、使用数据新技术、新产品、新服务,应当有利于促进经济社会和行业发展,符合社会公德和伦理。 

第六条【标准制定】行业(领域)监管部门推进工业和信息化领域数据开发利用和数据安全标准体系建设,组织开展行业相关标准制修订工作。鼓励支持企业、研究机构、高等院校、行业组织等不同主体,合作开展国际标准、国家标准、行业标准、团体标准、企业标准制定。引导工业和信息化领域数据处理者开展数据管理、数据安全贯标达标工作。 

第二章 数据分类分级管理 

第七条【分类分级工作要求】工业和信息化部组织制定工业和信息化领域数据分类分级、重要数据和核心数据识别认定、数据分级防护等标准规范,指导开展数据分类分级管理工作,制定行业重要数据和核心数据具体目录并实施动态管理。 

地方工业和信息化主管部门、通信管理局、无线电管理机构组织开展本地区工业和信息化领域数据分类分级管理及重要数据和核心数据识别工作,确定本地区行业(领域)重要数据和核心数据具体目录并上报工业和信息化部,目录发生变化的,应当及时上报更新。 

工业和信息化领域数据处理者应当定期梳理数据,按照相关标准规范识别重要数据和核心数据并形成目录。 

第八条【分类分级方法】根据行业要求、特点、业务需求、数据来源和用途等因素,工业和信息化领域数据分类类别包括但不限于研发数据、生产运行数据、管理数据、运维数据、业务服务数据等。 

根据数据遭到篡改、破坏、泄露或者非法获取、非法利用,对国家安全、公共利益或者个人、组织合法权益等造成的危害程度,工业和信息化领域数据分为一般数据、重要数据和核心数据三级。 

工业和信息化领域数据处理者可在此基础上细分数据的类别和级别。 

第九条【一般数据】危害程度符合下列条件之一的数据为一般数据: 

(一)对公共利益或者个人、组织合法权益造成较小影响,社会负面影响小; 

(二)受影响的用户和企业数量较少、生产生活区域范围较小、持续时间较短,对企业经营、行业发展、技术进步和产业生态等影响较小; 

(三)其他未纳入重要数据、核心数据目录的数据。 

第十条【重要数据】危害程度符合下列条件之一的数据为重要数据: 

(一)对政治、国土、军事、经济、文化、社会、科技、电磁、网络、生态、资源、核安全等构成威胁,影响海外利益、生物、太空、极地、深海、人工智能等与国家安全相关的重点领域;

(二)对工业和信息化领域发展、生产、运行和经济利益等造成严重影响; 

(三)造成重大数据安全事件或生产安全事故,对公共利益或者个人、组织合法权益造成严重影响,社会负面影响大; 

(四)引发的级联效应明显,影响范围涉及多个行业、区域或者行业内多个企业,或者影响持续时间长,对行业发展、技术进步和产业生态等造成严重影响; 

(五)经工业和信息化部评估确定的其他重要数据。 

第十一条【核心数据】危害程度符合下列条件之一的数据为核心数据: 

(一)对政治、国土、军事、经济、文化、社会、科技、电磁、网络、生态、资源、核安全等构成严重威胁,严重影响海外利益、生物、太空、极地、深海、人工智能等与国家安全相关的重点领域; 

(二)对工业和信息化领域及其重要骨干企业、关键信息基础设施、重要资源等造成重大影响; 

(三)对工业生产运营、电信网络(含互联网)运行和服务、无线电业务开展等造成重大损害,导致大范围停工停产、大面积无线电业务中断、大规模网络与服务瘫痪、大量业务处理能力丧失等; 

(四)经工业和信息化部评估确定的其他核心数据。 

第十二条【重要数据和核心数据目录备案】工业和信息化领域数据处理者应当将本单位重要数据和核心数据目录向地方工业和信息化主管部门(工业领域)或通信管理局(电信领域)或无线电管理机构(无线电领域)备案。备案内容包括但不限于数据类别、级别、规模、处理目的和方式、使用范围、责任主体、对外共享、跨境传输、安全保护措施等 

基本情况,不包括数据内容本身。 

地方工业和信息化主管部门(工业领域)或通信管理局(电信领域)或无线电管理机构(无线电领域)应当在工业和信息化领域数据处理者提交备案申请的二十个工作日内完成审核工作,备案内容符合要求的,予以备案并发放备案凭证,同时将备案情况报工业和信息化部;不予备案的应当及时反馈备案申请人并说明理由。 

重要数据和核心数据的类别或规模变化 30%以上的,或者其它备案内容发生重大变化的,工业和信息化领域数据处 

理者应当在发生变化的三个月内履行备案变更手续。 

第三章 数据全生命周期安全管理 

第十三条【主体责任】工业和信息化领域数据处理者应当对数据处理活动负安全主体责任,对各类数据实行分级防护,不同级别数据同时被处理且难以分别采取保护措施的,应当按照其中级别最高的要求实施保护,确保数据持续处于有效保护和合法利用的状态。 

(一)建立数据全生命周期安全管理制度,针对不同级别数据,制定数据收集、存储、使用、加工、传输、提供、公开等环节的具体分级防护要求和操作规程; 

(二)根据需要配备数据安全管理人员,统筹负责数据处理活动的安全监督管理,协助行业(领域)监管部门开展工作; 

(三)合理确定数据处理活动的操作权限,严格实施人员权限管理; 

(四)根据应对数据安全事件的需要,制定应急预案,并定期进行演练; 

(五)定期对从业人员开展数据安全教育和培训; 

(六)法律、行政法规等规定的其他措施。 

工业和信息化领域重要数据和核心数据处理者,还应当: 

(一)建立覆盖本单位相关部门的数据安全工作体系,明确数据安全负责人和管理机构,建立常态化沟通与协作机制。本单位法定代表人或者主要负责人是数据安全第一责任人,领导团队中分管数据安全的成员是直接责任人; 

(二)明确数据处理关键岗位和岗位职责,并要求关键岗位人员签署数据安全责任书; 

(三)建立内部登记、审批机制,对重要数据和核心数据的处理活动进行严格管理并留存记录。 

第十四条【数据收集】工业和信息化领域数据处理者收集数据应当遵循合法、正当的原则,不得窃取或者以其他非法方式收集数据。 

数据收集过程中,应当根据数据安全级别采取相应的安全措施,加强重要数据和核心数据收集人员、设备的管理,并对收集时间、类型、数量、频度、流向等进行记录。 

通过间接途径获取重要数据和核心数据的,工业和信息化领域数据处理者应当与数据提供方通过签署相关协议、承诺书等方式,明确双方法律责任。 

第十五条【数据存储】工业和信息化领域数据处理者应当依据法律规定或者与用户约定的方式和期限存储数据。存储重要数据和核心数据的,应当采用校验技术、密码技术等措施进行安全存储,不得直接提供存储系统的公共信息网络访问,并实施数据容灾备份和存储介质安全管理,定期开展数据恢复测试。存储核心数据的,还应当实施异地容灾备份。 

第十六条【数据使用加工】工业和信息化领域数据处理者利用数据进行自动化决策分析的,应当保证决策分析的透明度和结果公平合理。使用、加工重要数据和核心数据的,还应当加强访问控制。工业和信息化领域数据处理者提供数据处理服务,涉及经营电信业务的,应当按照相关法律、行政法规规定取得电信业务经营许可。 

第十七条【数据传输】工业和信息化领域数据处理者应当根据传输的数据类型、级别和应用场景,制定安全策略并采取保护措施。传输重要数据和核心数据的,应当采取校验技术、密码技术、安全传输通道或者安全传输协议等措施。 

第十八条【数据提供】工业和信息化领域数据处理者提供数据,应当明确提供的范围、类别、条件、程序等,并与数据获取方签订数据安全协议。提供重要数据和核心数据的,应当对数据获取方数据安全保护能力进行评估或核实,采取必要的安全保护措施。 

第十九条【数据公开】工业和信息化领域数据处理者应当在数据公开前分析研判可能对公共利益、国家安全产生的影响,存在重大影响的不得公开。 

第二十条【数据销毁】工业和信息化领域数据处理者应当建立数据销毁制度,明确销毁对象、规则、流程和技术等要求,对销毁活动进行记录和留存。个人、组织依据法律规定、合同约定等请求销毁的,工业和信息化领域数据处理者应当销毁相应数据。 

销毁重要数据和核心数据的,应当及时向地方工业和信息化主管部门(工业领域)或通信管理局(电信领域)或无线电管理机构(无线电领域)更新备案,不得以任何理由、任何方式对销毁数据进行恢复。 

第二十一条【数据出境】工业和信息化领域数据处理者在中华人民共和国境内收集和产生的重要数据和核心数据,法律、行政法规有境内存储要求的,应当在境内存储,确需向境外提供的,应当依法依规进行数据出境安全评估。工业和信息化部根据有关法律和中华人民共和国缔结或者参加的国际条约、协定,或者按照平等互惠原则,处理外国工业、电信、无线电执法机构关于提供工业和信息化领域数据的请求。非经工业和信息化部批准,工业和信息化领域数据处理者不得向外国工业、电信、无线电执法机构提供存储于中华人民共和国境内的工业和信息化领域数据。 

第二十二条【数据转移】工业和信息化领域数据处理者因兼并、重组、破产等原因需要转移数据的,应当明确数据转移方案,并通过电话、短信、邮件、公告等方式通知受影响用户。涉及重要数据和核心数据的,应当及时向地方工业和信息化主管部门(工业领域)或通信管理局(电信领域)或无线电管理机构(无线电领域)更新备案。 

第二十三条【委托处理】工业和信息化领域数据处理者委托他人开展数据处理活动的,应当通过签订合同协议等方式,明确委托方与被委托方的数据安全责任和义务。委托处理重要数据和核心数据的,应当对被委托方的数据安全保护能力、资质进行评估或核实。 

除法律、行政法规等另有规定外,未经委托方同意,被委托方不得将数据提供给第三方。 

第二十四条【核心数据跨主体处理】跨主体提供、转移、委托处理核心数据的,应当评估安全风险,采取必要的安全保护措施,并经由地方工业和信息化主管部门(工业领域)或通信管理局(电信领域)或无线电管理机构(无线电领域)报工业和信息化部。工业和信息化部按照有关规定进行审查。 

第二十五条【日志留存】工业和信息化领域数据处理者应当在数据全生命周期处理过程中,记录数据处理、权限管理、人员操作等日志。日志留存时间不少于六个月。 

第四章 数据安全监测预警与应急管理 

第二十六条【监测预警机制】工业和信息化部建立数据安全风险监测机制,组织制定数据安全监测预警接口和标准,统筹建设数据安全监测预警技术手段,形成监测、溯源、预警、处置等能力,与相关部门加强信息共享。 

地方工业和信息化主管部门、通信管理局和无线电管理机构建设本地区数据安全监测预警机制,组织开展本地区工业、电信行业和无线电数据安全风险监测,按照有关规定及时发布预警信息,通知本地区工业和信息化领域数据处理者及时采取应对措施。 

工业和信息化领域数据处理者应当开展数据安全风险监测,及时排查安全隐患,采取必要的措施防范数据安全风险。 

第二十七条【信息上报和共享】工业和信息化部建立数据安全风险信息上报和共享机制,统一汇集、分析、研判、通报数据安全风险信息,鼓励安全服务机构、行业组织、科研机构等开展数据安全风险信息上报和共享。 

地方工业和信息化主管部门、通信管理局和无线电管理机构汇总分析本地区工业、电信行业和无线电数据安全风险,及时将可能造成重大及以上安全事件的风险上报工业和信息化部。 

工业和信息化领域数据处理者应当及时将可能造成较大及以上安全事件的风险向地方工业和信息化主管部门(工业领域)或通信管理局(电信领域)或无线电管理机构(无线电领域)报告。 

第二十八条【应急处置】工业和信息化部制定工业和信息化领域数据安全事件应急预案,组织协调重要数据和核心数据安全事件应急处置工作。 

地方工业和信息化主管部门、通信管理局和无线电管理机构组织开展本地区工业、电信行业和无线电数据安全事件应急处置工作。涉及重要数据和核心数据的安全事件,应当立即上报工业和信息化部,并及时报告事件发展和处置情况。 

工业和信息化领域数据处理者在数据安全事件发生后,应当按照应急预案,及时开展应急处置,涉及重要数据和核心数据的安全事件,应当第一时间向地方工业和信息化主管部门(工业领域)或通信管理局(电信领域)或无线电管理机构(无线电领域)报告。事件处置完成后应当在规定期限内形成总结报告,每年向地方工业和信息化主管部门(工业领域)或通信管理局(电信领域)或无线电管理机构(无线电领域)报告数据安全事件处置情况。 

工业和信息化领域数据处理者对可能损害用户合法权益的数据安全事件,应当及时告知用户,并提供减轻危害措施。 

第二十九条【举报投诉处理】工业和信息化部委托相关行业组织建立工业和信息化领域数据安全违法行为投诉举报渠道,地方工业和信息化主管部门、通信管理局、无线电管理机构建立本地区工业、电信行业和无线电数据安全违法行为投诉举报机制或渠道,依法接收、处理投诉举报,根据工作需要开展执法调查。鼓励工业和信息化领域数据处理者 

建立用户投诉处理机制。 

第五章 数据安全检测、认证、评估管理 

第三十条【安全检测与认证】工业和信息化部鼓励、引导具备相应资质的机构,依据相关标准开展行业数据安全检测、认证工作。 

第三十一条【安全评估】工业和信息化部制定行业数据安全评估机构管理制度,开展评估机构管理工作。制定行业数据安全评估规范,指导评估机构开展数据安全风险评估、合规评估、能力评估、出境评估等工作。 

地方工业和信息化主管部门、通信管理局和无线电管理机构负责组织开展本地区工业、电信行业和无线电数据安全评估工作。 

工业和信息化领域重要数据和核心数据处理者应当自行或委托第三方评估机构,每年至少开展一次安全评估,及时整改风险问题,并向地方工业和信息化主管部门(工业领域)或通信管理局(电信领域)或无线电管理机构(无线电领域)报送评估报告。 

第六章 监督检查 

第三十二条【监督检查和协助义务】行业(领域)监管部门对工业和信息化领域数据处理者落实本办法要求的情况进行监督检查。 

工业和信息化领域数据处理者应当对行业(领域)监管部门监督检查予以配合。 

第三十三条【数据安全审查】工业和信息化部在国家数据安全工作协调机制指导下,开展数据安全审查相关工作。 

第三十四条【保密要求】行业(领域)监管部门及其委托的数据安全评估机构工作人员对在履行职责中知悉的个人信息和商业秘密等,应当严格保密,不得泄露或者非法向他人提供。 

第七章 法律责任 

第三十五条【约谈整改】行业(领域)监管部门在履行数据安全监督管理职责中,发现数据处理活动存在较大安全风险的,可以按照规定权限和程序对工业和信息化领域数据处理者进行约谈,并要求采取措施进行整改,消除隐患。 

第三十六条【法律责任】有违反本办法规定行为的,由行业(领域)监管部门依照相关法律法规,根据情节严重程度给予没收违法所得、罚款、暂停业务、停业整顿、吊销业务许可证等行政处罚;构成犯罪的,依法追究刑事责任。 

第八章 附则 

第三十七条【个人信息保护】开展涉及个人信息的数据处理活动,还应当遵守有关法律、行政法规的规定。 

第三十八条【其他规定参照】涉及军事、国家秘密信息、密码使用等数据处理活动,按照国家有关规定执行。 

第三十九条【政务数据排除】工业和信息化领域政务数据处理活动的具体办法,由工业和信息化部另行规定。 

第四十条【国防科工、烟草领域】国防科技工业、烟草领域数据安全管理由国防科工局、国家烟草专卖局负责,具体制度参照本办法另行制定。 

第四十一条【施行日期】本办法自 2022 年 月 日起施行。