关于loop( ) 阻塞和非阻塞探究

一、SIR的补充

在上几篇博客中,有朋友私信问我,在ticker函数程序和中断服务程序(ISR)中写 物联网请求报错。怎么回事,在此解释。控制台如下

1.1解释

在使用 Ticker 函数和中断服务程序(ISR)时,如果在 ISR 中进行物联网请求可能会导致一些问题,因为 ISR 中需要尽量保持简洁和快速执行,而物联网请求可能涉及到网络通信,执行时间较长,容易引起不可预期的问题,比如中断嵌套、堆栈溢出等。

通常来说,在 ISR 中不应该执行耗时的操作,包括网络通信、文件操作等。如果需要在 ISR 中进行某些操作,可以考虑通过设置标志位的方式,在主循环中检查该标志位并执行相应的操作。

1.2说明

因此在实现网络请求时,请将请求程序写入loop()主循环内,简单的硬件信号输入输出程序则可以放入 多任务处理 ticker和中断执行ISR中。如下

#include <Ticker.h>Ticker ticker;
Ticker ticker1;void setup() {attachInterrupt(digitalPinToInterrupt(keyPin), handleInterrupt, FALLING);  // 设置外部中断ticker.attach_ms(10, controlLED);  // 10微秒执行一次// ------// 设置定时器,在1秒后发送设备信息ticker1.once(1, startedInstruction);
}// 1.外部中断处理函数
ICACHE_RAM_ATTR void handleInterrupt() {flag = !flag;  // 切换 LED 状态//不能在 ticker 和中断中写网络请求
}// 2.控制 LED 状态
void controlLED() {digitalWrite(ledPin, flag ? HIGH : LOW);  // 根据标志控制 LED 亮灭
}//3.ticker检测启动说明
void startedInstruction() {Serial.println("启动说明");String tag = String("/LoveMomServer/jb82IWj8q")+ "?dIdmail=" + String(DEVICE_ID) + "&netWork="+ netWork + "&deviceName=" + deviceName + "&localIp="+ localIp + "&deviceMac=" + deviceMac;Serial.println(tag);
}

二、loop也有阻塞的时候

2.1案例

网络请求写在loop中,有的请求是10秒请求一次,有的请求是20秒、甚至是5秒、1秒。这么多网络请求都写在loop函数内,请求和休眠时间各不一样。

尤其是对硬件监听digitalRead(keyPin) == LOW是毫秒级的不间歇的。强行加delay(1000),会导致程序阻塞的。

2.2阻塞情况

void loop() {if (sendDeviceInfoRequestCount < 3) {sendDeviceInfo();sendDeviceInfoRequestCount++;} else {Serial.println("------");}if (digitalRead(keyPin) == LOW) {sendChangeLEDRequest();while (!digitalRead(keyPin));  //按键释放时候退出while循环,防止按键按下多次触发}delay(10000);httpRequest();delay(10000);
}

在 loop() 函数中,当执行 delay(10000); 的时候,代码会暂停执行10秒钟。如果在这10秒钟内按下了按钮,digitalRead(keyPin) == LOW 将会成立,从而触发 sendChangeLEDRequest()。然而,由于 delay(10000); 正在执行,代码会一直停留在这个延迟函数中,直到时间到了才会继续执行后面的代码。因此,在延迟期间按下按钮是不会触发 sendChangeLEDRequest() 的。

2.3非阻塞逐个定时

void loop() {unsigned long currentMillis = millis();if (sendDeviceInfoRequestCount < 1) {sendDeviceInfo();sendDeviceInfoRequestCount++;} else {//Serial.println("eeeeee");}if (digitalRead(keyPin) == LOW) {sendChangeLEDRequest();while (!digitalRead(keyPin));  //等待按键释放}if (currentMillis - previousMillis >= interval) {httpRequest();previousMillis = currentMillis;  // 重置计时器}
}

millis() 函数是 Arduino 编程中常用的一个函数,用于获取从 Arduino 开始运行以来经过的毫秒数。它返回一个 unsigned long 类型的值,表示自 Arduino 开始运行以来经过的毫秒数。

在 Arduino 程序中,通常需要进行时间相关的操作,比如控制执行某些任务的时间间隔、实现定时功能等。millis() 函数可以帮助你实现这些功能,而不必使用阻塞延迟函数 delay(),从而使得 Arduino 在等待某些事件发生的同时可以执行其他任务。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++面向对象程序设计 - 访问对象中成员的3种方法

在C程序中访问对象的成员变量和成员函数&#xff0c;有三种方法&#xff1a; 通过对象名和成员运算符访问对象中的成员&#xff1b;通过指向对象的指针访问对象中的成员&#xff1b;通过对象的引用变量访问对象中的成员 在了解访问对象中成员的3种方法前&#xff0c;先了解下C…

蓝桥杯真题:单词分析

import java.util.Scanner; //1:无需package //2: 类名必须Main, 不可修改 public class Main{public static void main(String[]args) {Scanner sannernew Scanner(System.in);String strsanner.nextLine();int []anew int [26];for(int i0;i<str.length();i) {a[str.charA…

4.2 c++

#include <iostream>using namespace std; int Max10; class Stack { public:int* base;//栈底&#xff1b;int* top;//栈顶&#xff1b;void creat(Stack& s);//初始化顺序栈void in(Stack& s);//入栈void out(Stack& s);//出栈void empty(Stack& s);//…

Ps:颜色查找

颜色查找 Color Lookup命令通过应用预设的 LUT 来改变图像的色彩和调性&#xff0c;从而为摄影师和设计师提供了一种快速实现复杂色彩调整的方法&#xff0c;广泛应用于颜色分级、视觉风格的统一和创意色彩效果的制作。 Ps菜单&#xff1a;图像/调整/颜色查找 Adjustments/Colo…

栈溢出攻击的软硬件缓解技术

为了防范栈溢出攻击&#xff0c;现代处理器架构&#xff08;如Arm架构&#xff09;具有执行权限。在Armv8-A中&#xff0c;主要的控制是在MMU地址转换表&#xff08;translation tables&#xff09;中的执行权限位。 UXN User (EL0) Execute-never …

什么是AIGC,AIGC的应用领域有哪些,以及对AIGC的未来展望有什么值得关注的方向

AIGC:人工智能生成内容的深度解析 在数字技术的浪潮中,AIGC(ArtificialIntelligenceGeneratedContent,人工智能生成内容)逐渐崭露头角,成为继专业生产内容(PGC)和用户生产内容(UGC)之后的新型内容创作方式。它不仅改变了内容生产的传统模式,更在多个行业中展现出…

Hive on Spark 配置

目录 1 Hive 引擎简介2 Hive on Spark 配置2.1 在 Hive 所在节点部署 Spark2.2 在hive中创建spark配置文件2.3 向 HDFS上传Spark纯净版 jar 包2.4 修改hive-site.xml文件2.5 Hive on Spark测试2.6 报错 1 Hive 引擎简介 Hive引擎包括&#xff1a;MR&#xff08;默认&#xff09…

js使用canvas实现画roi功能,并实现交集并集差集操作,附源码

效果概览 支持圆形,矩形,旋转矩形绘制,鼠标像素拾取,图片缩放,图片拖拽,像素测量,roi交集并集补集输出 TODO:实现自由路径绘制,与后台交互数据 实现原理 交集并集差集使用像素做运算,使用0代表没有像素,1代表有像素,然后再做运算 // 计算交集calculateIntersec…

腾讯电商再度回归!视频号小店成为今年最强黑马?

大家好&#xff0c;我是电商小布。 现在在电商的这个圈子里&#xff0c;视频号这个项目&#xff0c;也是常常被大家提起。 特别是在新型电商玩法的发展下&#xff0c;传统电商已经不足以满足客户的需求&#xff0c;搞流量才是重点。 而在这其中&#xff0c;抖音、视频号这两…

Flume学习笔记

视频地址:https://www.bilibili.com/video/BV1wf4y1G7EQ/ 定义 Flume是一个高可用的、高可靠的、分布式的海量日志采集、聚合和传输的系统。 Flume高最要的作用就是实时读取服务器本地磁盘的数据,将数据写入HDFS。 官网:https://flume.apache.org/releases/content/1.9.0/…

TikTok账号被封是为什么?如何解决?

多人在使用TikTok的过程中都会遇到一些问题&#xff0c;比如为什么TikTok没有浏览量&#xff1f;事实上&#xff0c;这很可能是因为你的账号已被禁止。但为什么它会被封呢&#xff1f;你怎样才能解决它&#xff1f; 一、TikTok账号为什么被封&#xff1f; 1、什么是 TikTok 影…

鸿蒙原生应用开发-网络管理Socket连接(一)

一、简介 Socket连接主要是通过Socket进行数据传输&#xff0c;支持TCP/UDP/TLS协议。 二、基本概念 Socket&#xff1a;套接字&#xff0c;就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。 TCP&#xff1a;传输控制协议(Transmission Control Protocol)。是一…