关于本教程:
ESP32 基础篇
1.ESP32简介
2.ESP32 Arduino 集成开发环境
3.VS 代码和 PlatformIO
4.ESP32 引脚
5.ESP32 输入输出
6.ESP32 脉宽调制
7.ESP32 模拟输入
8.ESP32 中断定时器 ☑
9.ESP32 深度睡眠
ESP32 协议篇
ESP32 网络服务器
ESP32 LoRa
ESP32 BLE
ESP32 BLE 客户端-服务器
ESP32 蓝牙
ESP32 MQTT
ESP32 ESP-NOW
ESP32 Wi-Fi
ESP32 WebSocket
ESP32 ESP-MESH
ESP32 邮箱
ESP32 短信
ESP32 HTTP 获取 POST
HTTP GET Web APIs
HTTP POST Web APIs
ESP32 服务器篇
持续更新,关注博主不迷路!!!
ESP32 传感器模块篇
持续更新,关注博主不迷路!!!
ESP32 终极实战篇
百余项ESP32实战项目,敬请关注!!!
本教程介绍如何使用 PIR 运动传感器通过 ESP32 检测运动。在此示例中,当检测到运动(触发中断)时,ESP32 启动定时器并打开 LED 并持续预定义的秒数。当定时器完成倒计时时,LED 自动关闭。

通过这个例子,我们还将探索两个重要的概念:中断和定时器。
在继续本教程之前,您应该在 Arduino IDE 中安装 ESP32 插件。
要学习本教程,您需要以下部分
ESP32 DOIT DEVKIT V1 板
迷你 PIR 运动传感器 (AM312) 或 PIR 运动传感器 (HC-SR501)
5mm LED
330欧姆电阻
跳线
面包板
要使用 PIR 运动传感器触发事件,您可以使用中断。中断对于使微控制器程序中的事情自动发生很有用,并且可以帮助解决时序问题。
使用中断,您不需要经常检查引脚的当前值。对于中断,当检测到变化时,会触发一个事件(调用一个函数)。
要在 Arduino IDE 中设置中断,您可以使用attachInterrupt()函数,它接受以下参数:GPIO 引脚、要执行的函数的名称和模式:
attachInterrupt(digitalPinToInterrupt(GPIO), function, mode);
GPIO 中断
第一个参数是 GPIO 编号。通常,你应该使用数字引脚中断(GPIO)将实际的 GPIO 设置为中断引脚。例如,如果你想使用GPIO 27作为中断,使用:
digitalPinToInterrupt(27)
对于 ESP32 开发板,下图中所有用红色矩形突出显示的管脚都可以配置为中断管脚。在这个例子中我们将使用GPIO 27作为连接到 PIR 运动传感器的中断。

要触发的函数
的第二个参数attachInterrupt()中function 是每次触发中断时将调用的函数的名称。
模式
第三个参数是模式。有5种不同的模式:
对于此示例,将使用 RISING 模式,因为当 PIR 运动传感器检测到运动时,它所连接的 GPIO 从低电平变为高电平。
在这个例子中,我们还将介绍定时器。我们希望 LED 在检测到运动后保持预定的秒数。而不是使用delay()阻止您的代码并且不允许您在确定的秒数内执行任何其他操作的功能,我们应该使用计时器。

您应该熟悉delay()功能,因为它被广泛使用。这个函数使用起来非常简单。它接受一个 int 数字作为参数。这个数字表示程序必须等待直到移动到下一行代码的时间(以毫秒为单位)。
delay(time in milliseconds)
当你做delay(1000)您的程序在该行停止 1 秒钟。
delay()是阻塞函数。阻塞函数阻止程序在特定任务完成之前执行任何其他操作。如果您需要同时执行多个任务,则不能使用delay().对于大多数项目,您应该避免使用延迟,而是使用计时器。
使用一个名为毫秒()您可以返回自程序首次启动以来经过的毫秒数。
millis()
为什么这个功能有用?因为通过使用一些数学,您可以轻松地验证已经过去了多少时间而不会阻塞您的代码。
下面的代码片段展示了如何使用millis()创建闪烁 LED 项目的函数。它打开 LED 1000 毫秒,然后将其关闭。
// constants won't change. Used here to set a pin number :
const int ledPin = 26; // the number of the LED pin
// Variables will change :
int ledState = LOW; // ledState used to set the LED
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change :
const long interval = 1000; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop() {
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
代码如何工作
让我们仔细看看这个无需delay()功能(它使用millis()代替功能)。
基本上,这段代码减去之前记录的时间(previousMillis) 从当前时间 (currentMillis). 如果余数大于间隔(在本例中为 1000 毫秒),程序将更新previousMillis变量为当前时间,然后打开或关闭 LED。
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
(...)
因为这个片段是非阻塞的,任何位于第一个之外的代码如果声明应该可以正常工作。
您现在应该能够理解您可以将其他任务添加到您的loop()功能,您的代码仍然会每隔一秒闪烁一次 LED。
你可以将这段代码上传到你的ESP32中,组装成如下原理图进行测试,修改毫秒数,看看效果如何。

理解了这几个概念:中断和定时器,我们继续做项目。
我们将构建的电路易于组装,我们将使用带电阻器的 LED。LED连接到GPIO 26. 我们将使用工作电压为 3.3V 的Mini AM312 PIR 运动传感器。它将连接到GPIO 27. 只需按照下一个示意图进行操作即可。

重要提示: 本项目中使用的Mini AM312 PIR 运动传感器在3.3V 下运行。但是,如果您使用的是另一个 PIR 运动传感器,如 HC-SR501,它的工作电压为 5V。您可以 将其修改为在 3.3V 下运行 ,或者简单地使用 Vin 引脚为其供电。
下图显示了 AM312 PIR 运动传感器引脚排列。

按照示意图所示连接电路后,将提供的代码复制到您的 Arduino IDE。
您可以按原样上传代码,也可以修改检测到运动后 LED 点亮的秒数。只需更改时间秒变量与你想要的秒数。
#define timeSeconds 10
// Set GPIOs for LED and PIR Motion Sensor
const int led = 26;
const int motionSensor = 27;
// Timer: Auxiliary variables
unsigned long now = millis();
unsigned long lastTrigger = 0;
boolean startTimer = false;
// Checks if motion was detected, sets LED HIGH and starts a timer
void IRAM_ATTR detectsMovement() {
Serial.println("MOTION DETECTED!!!");
digitalWrite(led, HIGH);
startTimer = true;
lastTrigger = millis();
}
void setup() {
// Serial port for debugging purposes
Serial.begin(115200);
// PIR Motion Sensor mode INPUT_PULLUP
pinMode(motionSensor, INPUT_PULLUP);
// Set motionSensor pin as interrupt, assign interrupt function and set RISING mode
attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);
// Set LED to LOW
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
}
void loop() {
// Current time
now = millis();
// Turn off the LED after the number of seconds defined in the timeSeconds variable
if(startTimer && (now - lastTrigger > (timeSeconds*1000))) {
Serial.println("Motion stopped...");
digitalWrite(led, LOW);
startTimer = false;
}
}
让我们看一下代码。首先将两个 GPIO 引脚分配给LED和运动传感器变量。
// Set GPIOs for LED and PIR Motion Sensor
const int led = 26;
const int motionSensor = 27;
然后,创建允许您设置定时器以在检测到运动后关闭 LED 的变量。
// Timer: Auxiliar variables
long now = millis();
long lastTrigger = 0;
boolean startTimer = false;
这now变量保存当前时间。这lastTrigger变量保存 PIR 传感器检测到运动的时间。这startTimer是一个布尔变量,它在检测到运动时启动计时器。
在里面setup(), 首先以 115200 波特率初始化串口。
Serial.begin(115200);
将 PIR 运动传感器设置为输入上拉。
pinMode(motionSensor, INPUT_PULLUP);
要将 PIR 传感器引脚设置为中断,请使用attachInterrupt()功能如前所述。
attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);
将检测运动的引脚是GPIO 27它会调用函数检测运动()在上升模式。LED 是一个 OUTPUT,其状态从 LOW 开始。
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
这loop()功能不断地一遍又一遍地运行。在每个循环中,now变量用当前时间更新。
now = millis();
没有做任何其他事情loop().
但是,当检测到运动时,detctsMovement()函数被调用是因为我们之前已经在setup().
这detctsMovement()函数在串行监视器中打印一条消息,打开 LED,设置startTimer布尔变量到真的并更新lastTrigger随当前时间变化。
void IRAM_ATTR detectsMovement() {
Serial.println("MOTION DETECTED!!!");
digitalWrite(led, HIGH);
startTimer = true;
lastTrigger = millis();
}
笔记: IRAM_ATTR用于在 RAM 中运行中断代码,否则代码存储在闪存中并且速度较慢。
在这一步之后,代码返回到loop().
这一次,startTimer变量为真。因此,当以秒为单位定义的时间过去后(自检测到运动以来),以下if声明将是真实的。
if(startTimer && (now - lastTrigger > (timeSeconds*1000))) {
Serial.println("Motion stopped...");
digitalWrite(led, LOW);
startTimer = false;
}
“Motion stopped...”消息将打印在串行监视器中,LED 熄灭,startTimer 变量设置为 false。
将代码上传到您的 ESP32 开发板。确保选择了正确的板和 COM 端口。
以 115200 的波特率打开串行监视器。

将您的手移到 PIR 传感器前面。LED 应该亮起,串行监视器中会打印一条消息,提示“检测到运动!!!”。10 秒后 LED 应该熄灭。

总而言之,中断用于检测 GPIO 状态的变化,而无需不断读取当前 GPIO 值。对于中断,当检测到变化时,将触发一个函数。您还学习了如何设置一个简单的计时器,它允许您检查是否已经过了预定义的秒数,而不必阻塞您的代码。
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear
在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
require'mechanize'agent=Mechanize.newlogin=agent.get('http://www.schoolnet.ch/DE/HomeDE.htm')agent.clicklogin.link_withtext:/Login/然后我得到Mechanize::UnsupportedSchemeError。 最佳答案 Mechanize不支持javascript但您可以将搜索字段添加到表单并为其分配搜索词并使用mechanize提交表单form=page.forms.firstform.add_fie