问题描述
从我读过,解决我的问题是使用中断,但如果我正确地理解他们,我不能在得到由中断称为常规使用的延迟。我有一个大的按钮开关。我希望它有心跳,而闲置,但一旦它的推出,保持绿色和执行code。
我可以打破心跳()
如果我按下按钮足够的时间(我假设得到在恰当的时间状态的变化,因为它完成的一个循环心率
),但我卡在如何使它的第一个点击工作。是否有其他的方式做什么,我试图?
无效循环(){心跳(); //使LED节拍。
buttonVal = digitalRead(buttonPin); //检查按钮。
如果(buttonVal!= buttonState){//如果按钮状态改变。
如果(buttonVal == HIGH){//检查按钮pressed。
analogWrite(greenPin,255); //按钮常亮绿灯一次推动。
泛函//中有一些延误。
functionB //有一些其他的延误。
}
}
}无效的心跳(){
对于(i = 0; I< PMW;我++){
analogWrite(greenPin,I);
延时(((60000 /速度)* 1)/ PMW);
} 为(ⅰ= PMW;我大于0; I - ){
analogWrite(greenPin,I);
延时(((60000 /速度)* 2)/ PMW);
} 对于(i = 0; I< PMW;我++){
analogWrite(greenPin,I);
延时(((60000 /速度)* 1)/ PMW);
} 为(ⅰ= PMW;我大于0; I - ){
analogWrite(greenPin,I);
延时(((60000 /率)* 6)/ PMW);
}
}
您在大多数你的假设是正确的。处理这种情况的正确方法是使用中断,这是不是在你的中断服务程序(ISR)延迟一个好主意。所以,你想要做的是设置一个标志在你的ISR和检查标志主循环的东西。
//下垂需要挥发,如果在使用ISR
挥发性INT buttonFlag = 0;无效循环()
{
如果(buttonFlag == 0)
{
心跳(); //使领导节拍
}
其他
{
analogWrite(greenPin,255); //按钮保持绿色一次推
泛函//中有一些延误
functionB //有一些其他方面的延迟
buttonFlag = 0;执行code后//清除标志
}}//中断服务程序连接到INT0矢量
ISR(EXT_INT0_vect)
{
buttonFlag = digitalRead(buttonPin); //设置标志按钮的价值
}
由于中断将只在按钮的状态变化触发,你并不需要检查这一点。
请确保您的标志变量是全球性的声明在ISR使用。并确保你使用了正确的中断向量与您正在使用的针使用。
下面是一个good在Arduino的教程中断。这里有另外一个你要什么好榜样做的。
您可能还需要寻找到debouncing交换机取决于你使用什么类型的交换机presses。如果不是失踪的第一个preSS,你得到了太多presses,你将需要实现某种类型的反跳的。
From what I've read, the solution to my problem is to use an interrupt, but if I understand them correctly, I can't use a delay in the routine that gets called by the interrupt. I've got a large pushbutton LED switch. I want it to have a heartbeat while sitting idle, but once it's pushed, stay green and execute code.
I can break the heartbeat()
if I push the button enough times (I assume getting the state change at just the right time as it finishes a loop of the heartbeat
), but I'm stuck on how to make it work on the first click. Is there an alternative way to do what I'm attempting?
void loop(){
heartbeat(); //Make LED beat.
buttonVal = digitalRead(buttonPin); //Check the button.
if (buttonVal != buttonState) { //If the button state changed.
if (buttonVal == HIGH){ //Check if the button is pressed.
analogWrite(greenPin, 255); //Button stays green once pushed.
functionA //Has some delays in it.
functionB //Has some other delays.
}
}
}
void heartbeat(){
for(i = 0; i < pmw; i++) {
analogWrite(greenPin,i);
delay(((60000/rate)*.1)/pmw);
}
for (i = pmw; i > 0; i--){
analogWrite(greenPin,i);
delay(((60000/rate)*.2)/pmw);
}
for(i = 0; i < pmw; i++) {
analogWrite(greenPin,i);
delay(((60000/rate)*.1)/pmw);
}
for (i = pmw; i > 0; i--){
analogWrite(greenPin,i);
delay(((60000/rate)*.6)/pmw);
}
}
You are correct in most of your assumptions. The proper way to handle this is using an interrupt and it is not a good idea to have delays in your interrupt service routines (ISR). So what you want to do is set a flag in your ISR and check that flag in your main loop.
// Flag needs to be volatile if used in an ISR
volatile int buttonFlag = 0;
void loop()
{
if (buttonFlag == 0)
{
heartbeat(); //make led beat
}
else
{
analogWrite(greenPin, 255); //button stays green once pushed
functionA //has some delays in it
functionB //has some other delays
buttonFlag = 0; //clear flag after executing code
}
}
// Interrupt Service Routine attached to INT0 vector
ISR(EXT_INT0_vect)
{
buttonFlag = digitalRead(buttonPin); //set flag to value of button
}
Since the interrupt will only trigger on a change in the state of the button, you don't need to check for that.
Make sure that your flag variable is global and is declared volatile
for use in the ISR. And make sure you are using the correct interrupt vector for use with the pin you are using.
Here is a good tutorial on Arduino interrupts. And here is another good example of what you're trying to do.
You may also want to look into debouncing your switch presses depending on what type of switch you're using. If instead of missing the first press, you're getting too many presses, you will need to implement some type of debouncing.
这篇关于Arduino的中断替代品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!