c# - 在 C# 中创建方波(高低交替)
问题描述
我正在尝试找到一种方法来为 LED 创建 2 Hz 方波(基本上在 2Hz 的高低之间切换) C# 新手,任何帮助将不胜感激!
这是我的一般思考过程:
While(Programruns){
read input
(I feel like there should be a for loop here to keep the square wave going forever until I stop it)
if(button is pressed){
output square wave
}
else {
off}
}
解决方案
您想要一个带有睡眠操作的循环。
你没有告诉我们你是如何打开和关闭那个 LED 的,所以我假设你有一个名为SetLED(val)
. 0 的Aval
关闭 LED,1 将其打开。并且,让我们调用一个在按下按钮时ButtonPressed()
返回的方法。true
要获得 2Hz 方波,您需要val
每 250 毫秒翻转一次。这段代码将为您做到这一点。
var ledState = 1;
while (ButtonPressed()) {
SetLED(ledState);
Thread.Sleep(250); //milliseconds
ledState = 1 - ledState; //flip the value
}
SetLED(0); // turn the LED off when done.
这基本上会奏效。但有一个复杂之处:C# 及其各种底层操作系统都不是硬实时系统。因此Thread.Sleep()
,有时醒来有点晚。这些迟到的唤醒会累积起来,使您的方波有点紧张,累积起来会小于 2Hz。对于抖动,您无能为力。
但是您可以通过查看时间时钟并计算每个循环中的睡眠时间来避免频率下降。
该表达式DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond
以毫秒为单位为您提供当前时间(从很久以前的某个时代开始)。
因此,您可以计算代码中下一次睡眠的毫秒数。这纠正了.Sleep()
睡过头。
var ledState = 1;
long nextTickTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
while (ButtonPressed()) {
SetLED(ledState);
nextTickTime += 250;
long nowTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
int sleepInterval = nextTickTime - nowTime;
if (sleepInterval > 0)
Thread.Sleep(sleepInterval);
ledState = 1 - ledState; //flip the value
}
SetLED(0); // turn the LED off when done.
这是一个相当强大的闪光灯。您还可以在循环运行时提高线程的优先级,但这是另一天的问题和答案。
推荐阅读
- git - 如何为 git pull 合并消息提供评论
- terraform - 用于检索键值的 Terraform 过滤器
- c++11 - 使用 C++11 模板生成算法的多个版本
- python - 无法在 Python 中使用 xpath 定位元素
- macos - Mac 上的 Kafka 在启动控制台使用者时没有对节点 -1 的正在进行的请求
- jquery - 背景位置 css 不使用变量
- struct - 如何将约束添加到结构的字段以进行实例化?
- c++ - Unity 2019.4+ 中的 Apple Mach-O 链接器 (ld) 错误
- spring-boot - Spring boot 2.3.3.RELEASE 类路径未知警告
- kubernetes - Kubernetes Ingress 无法通过路径访问容器