arduino定时器控制舵机_Arduino如何多任务(上)

本文介绍了如何在Arduino上实现多任务处理,避免使用delay()函数导致的处理器独占问题。通过使用millis()函数进行时间控制,结合状态机和面向对象编程,可以实现多个LED和舵机的同时独立控制,提高程序响应性和可扩展性。
摘要由CSDN通过智能技术生成
76d19b6e8a8797fda610f6e2bc50cf66.gif

本篇为译文,略有删减,原文链接见文末。推荐理由:平时关于Arduino函数功能和各种模块使用的教程很多,却鲜有关于Arduino编程方法和思路的教程。而本篇文章从最基本的示例切入,深入浅出地介绍了Arduino的多任务、状态机、面向对象以及定时器、中断等概念,非常适合提升和开阔初学者Arduino编程的思维方式。

当Arduino初学者掌握了基本的点亮LED,简单的一些传感器和舵机扫动,下一步就要面对的是更大更复杂的项目。这些项目需要初学者学会“东拼西凑”,即把简单的代码片段拼成一个能用的整体。很多初学者最初的苦恼就是,明明很多代码片段自己能跑起来,为什么拼在一起就无法运行了?

Arduino其实是一个没有操作系统(OS)的单核处理器系统,每次只能跑一个程序。不像PC或者树莓派那样,Arduino没有办法同时运行多个程序,但这并不意味着在Arduino上无法处理多任务。我们只需要使用一些特殊的方法。因为Arduino没有操作系统,我们需要手动构建一些框架。

9eff291eff05d4c526dde68ce8de8a9d.png

    避免使用delay()    

使用延时函数delay()可能是很多人第一个学会的Arduino函数。使用delay()控制时间虽然简单粗暴,但它也是你添加更多功能的“拦路虎”。delay()函数的问题是它会霸占整个处理器。

在你使用延时delay()相应的时间段里,Arduino不会对任何输入有反应。你不能处理数据,也不能修改任何输出。延时函数100%地霸占了处理器。所以如果你的代码片段里用了delay(),这段时间里你什么都做不了。比如经典的Blink示例代码:

 /* Blink  Turns on an LED on for one second, then off for one second, repeatedly. This example code is in the public domain. */// Pin 13 has an LED connected on most Arduino boards.// give it a name:int led = 13;// the setup routine runs once when you press reset:void setup() { // initialize the digital pin as an output. pinMode(led, OUTPUT); }// the loop routine runs over and over again forever:void loop() { digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(led, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second}

在舵机扫臂(Sweep)示例中,同样使用了delay()函数来控制Sweep的速度。如果把Blink和Sweep两个示例代码直接接起来,我们可以发现LED的闪动和舵机扫臂并不是同时进行的。

#include  // Pin 13 has an LED connected on most Arduino boards.// give it a name:int led = 13;Servo myservo; // create servo object to control a servo                 // twelve servo objects can be created on most boardsint pos = 0; // variable to store the servo positionvoid setup() { // initialize the digital pin as an output. pinMode(led, OUTPUT); myservo.attach(9); // attaches the servo on pin 9 to the servo object }void loop() { digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(led, LOW); // turn the LED off by making the voltage LOW  delay(1000);               // wait for a second  for(pos = 0; pos <= 180; pos += 1) // goes from 0 degrees to 180 degrees  { // in steps of 1 degree myservo.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } for(pos = 180; pos>=0; pos-=1) // goes from 180 degrees to 0 degrees { myservo.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } }

那么不用delay()延时函数,如何控制程序时间呢?

    使用millis()函数控时    

控制程序执行时间的一个最简单的技巧就是制定时间规划并时刻监控着时间。尽量避免使用delay()函数,需要我们自己时刻检查系统时间,了解执行不同任务的时间点,同时保证其他任务也能被执行。一个很简单的例子就是Arduino IDE自带的BlinkWithoutDelay示例。

代码和连接图如下:

383764f452aa63e0fa553483b5bb425b.png

/* Blink without Delay Turns on and off a light emitting diode(LED) connected to a digital pin, without using the delay() function. This means that other code can run at the same time without being interrupted by the LED code. The circuit: * LED attached from pin 13 to ground. * Note: on most Arduinos, there is already an LED on the board that's attached to pin 13, so no hardware is needed for this example.  created 2005 by David A. Mellis modified 8 Feb 2010 by Paul Stoffregen  This example code is in the public domain. http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay */// constants won't change. Used here to // set pin numbers:const int ledPin =  13;      // the number of the LED pin// Variables will change:int ledState = LOW; // ledState used to set the LEDlong previousMillis = 0;        // will store last time LED was updated// the follow variables is a long because the time, measured in miliseconds,// will quickly become a bigger number than can be stored in an int.long interval = 1000; // interval at which to blink (milliseconds)void setup() { // set the digital pin as output: pinMode(ledPin, OUTPUT); }void loop()</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值