ESP32:异步向后计数

如何解决ESP32:异步向后计数

我写了一个小程序,它从 5 倒数到 0,然后执行 println。我已经稍微包装了一下,但请让我展示我的代码:

Main.ino

#include "MyObject.h"
#include <string>
using namespace std;

MyObjekt *myObject;

void setup() {
  Serial.begin(115200);

  string trigger = "triggering";
  myObject = new MyObject(trigger);
}
void loop(){}

MyObject.h

#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <string>
using namespace std;

class MyObject{
  public: 
    string field;

    MyObject(string trigger);
    
    string GetField(){ return field; }
    void SetField(string trigger);
};

#endif

MyObject.cpp

#include "MyObject.h"
#include <string>
using namespace std;
#include "Timer.h"

MyObject::MyObject(string trigger){
    SetField(trigger);
}
void MyObject::SetField(string trigger){

    field = trigger;

    auto f = []() {std::cout << "---------------- I waited to print! ----------------\n"; };
    Timer t1{10000,f};
}

定时器.h

#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>

class Timer {
public:
    Timer(size_t time,const std::function<void(void)>& f) : time{std::chrono::milliseconds{time}},f{f} {}
    ~Timer() {wait_thread.join();}

private:
    void wait_then_call()
    {
        std::unique_lock<std::mutex> lck{mtx};
        for(int i{5}; i > 0; --i) {
            //std::cout << "Thread " << wait_thread.get_id() << " countdown at: " << '\t' << i << '\n';
            cv.wait_for(lck,time / 10);
        }
        f();
    }
    std::mutex mtx;
    std::condition_variable cv{};
    std::chrono::milliseconds time;
    std::function <void(void)> f;
    std::thread wait_thread{[this]() {wait_then_call();}};
};

不幸的是,这会阻塞主线程,因此在此期间不会执行任何其他操作(例如另一个 println)。是否有可能在后台进行这个倒计时,并且只在前台执行 println (f )(换句话说:在做工作时监听,如果检测到/发送到监听器,执行,然后再听一遍并继续工作)?

对每个答案和帮助努力都会感到非常高兴。对不起,如果我表达自己的问题,我希望它变得清楚我想要实现的目标^^

最好的问候

解决方法

您好像在使用 Arduino。使用 arduino-timer 库,代码看起来应该类似:

#include <arduino-timer.h>

const size_t TIMER_INTERVAL_MS = 1000;
volatile int counter = 5;
auto timer = timer_create_default();

void setup() {
    timer.every(TIMER_INTERVAL_MS,[](void*) -> bool { counter--; return true; });
}

void loop() {
    timer.tick();
    if (counter <= 0) {
        Serial.println("Counter is 0");
        counter = 5; // Reset counter
}

抱歉,无法验证或运行代码,因为我没有准备好 Arduino 设置。但你应该明白这一点。

您还可以执行更复杂的解决方案,例如向定时器外设请求中断;或在 RTOS 中设置计时器服务(假设您已升级到一个)。基本原理是一样的。

,

首先,如果您从不调用 new,请不要使用关键字 delete,因为它会导致内存泄漏。可以通过两种方式实现您想要的:

1.使用计数器

这仍然是在loopTask上运行,但它是让其他代码运行。

long lastMillis = 0;
long interval = 1000;
long counter = 5;

void setup() {
  Serial.begin(115200);
}

void loop() {
  if (millis() - lastMillis > interval && counter >= 0) {
    lastMillis = millis();
    Serial.println(counter--);
  }

  //Other code would still run
}

2.创建另一个任务

这将是完全异步的,即使您在另一个任务上调用 delay(),loopTask 上的代码仍会运行。

int counter = 5;
int interval = 1000;

void vTask(void *param) {
  while (counter >= 0) {
    delay(1000);
    Serial.println(counter--);
  }
  vTaskDelete(NULL);
}

void setup() {
  Serial.begin(115200);
  xTaskCreate(vTask,"vTask",4096,NULL,1,NULL);
}

void loop() {}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?