极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 24683|回复: 14

光电计数问题(抖动?)

[复制链接]
发表于 2015-5-30 10:16:10 | 显示全部楼层 |阅读模式
我在用1个马达计数的光电开关记录遮挡次数,每次用纸片遮挡再拿开,我的程序上的计数值增加2,3,4(不是1),请大神指教这个是什么原因?
int x;                                                                //用于记录遮挡光电开关的次数
void setup() {
  Serial.begin(9600);
  pinMode(2,INPUT);                                             //用2号口 接受中断
   x=0;
  attachInterrupt(0,z,CHANGE);                              //每当2号口变化时,触发中断函数 Z
   
}

void loop() {
   
  Serial.print(x);                                                 //串口输出遮挡次数
  delay(1000);
  Serial.println();
}
  void z()                                                          //中断函数
{
  
  if (digitalRead(2)==LOW)                                  //每当2号口输出变为0时,x值加1
  {
   x++;
   delay(20);
  
  }
}

这个光电开关是平时输出高电平,遮挡输出低电平的,是对射的那种。不知道问题出在哪里啦,电路连接应该没问题,我接下拉电阻和上拉电阻都试过啦,计数值每次还是加2~4,感觉像程序问题或硬件问题,请问怎么解决?
回复

使用道具 举报

发表于 2015-5-30 12:58:35 | 显示全部楼层
你用的是中断程序,但是在loop中用了1S的延迟,谁知道在1S中发生过几次中断呢?建议loop中的延迟不加或少加。
回复 支持 反对

使用道具 举报

发表于 2015-5-30 16:42:52 | 显示全部楼层
林定祥 发表于 2015-5-30 12:58
你用的是中断程序,但是在loop中用了1S的延迟,谁知道在1S中发生过几次中断呢?建议loop中的延迟不加或少加 ...

+1

loop中什么都不要
println放在中断里

btw:中断程序开始的地方要不要关中断?
回复 支持 反对

使用道具 举报

发表于 2015-5-30 17:10:26 | 显示全部楼层
1. void z();中的delay(20);去掉。
2. 示波器看看 输入波形。波形最好是方波
回复 支持 反对

使用道具 举报

发表于 2015-5-30 20:19:58 | 显示全部楼层
上升沿计数,而不是低电平计数
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-30 20:24:59 | 显示全部楼层
catnull 发表于 2015-5-30 20:19
上升沿计数,而不是低电平计数

RISING和CHANGE都试过啦,还是每次遮挡 计数增加2或者3
回复 支持 反对

使用道具 举报

发表于 2015-5-30 20:47:04 | 显示全部楼层
看看传感器波形,必要的化加运放进行滤波
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-30 21:03:42 | 显示全部楼层
catnull 发表于 2015-5-30 20:47
看看传感器波形,必要的化加运放进行滤波

多谢,可能就是传感器的问题,毕竟某宝上 只有5块钱,呵呵
回复 支持 反对

使用道具 举报

发表于 2015-5-30 21:03:43 | 显示全部楼层
hustwhzl 发表于 2015-5-30 20:24
RISING和CHANGE都试过啦,还是每次遮挡 计数增加2或者3

你估计一秒中里不会来一个脉冲吗?
回复 支持 反对

使用道具 举报

发表于 2015-5-30 21:08:15 | 显示全部楼层
hustwhzl 发表于 2015-5-30 21:03
多谢,可能就是传感器的问题,毕竟某宝上 只有5块钱,呵呵

和5块钱没关系,需要判断你信号性质,首先是否能够“真”的“高”或“低”,第二估计下脉冲的可能的频率范围,是前一种就可能是质量问题,第二种可以用不同的算法来克服。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-30 21:20:08 | 显示全部楼层
林定祥 发表于 2015-5-30 21:08
和5块钱没关系,需要判断你信号性质,首先是否能够“真”的“高”或“低”,第二估计下脉冲的可能的频率范 ...

谢谢啦,真的能够高或低,但是每次遮挡并放开,中断信号动作2~4次不等,我就是不会算法克服,假如我每次用纸片遮挡并放开用时1秒,我20秒周期遮挡并放开一次,大神帮忙给个程序吧
回复 支持 反对

使用道具 举报

发表于 2015-6-1 09:58:15 | 显示全部楼层
hustwhzl 发表于 2015-5-30 21:20
谢谢啦,真的能够高或低,但是每次遮挡并放开,中断信号动作2~4次不等,我就是不会算法克服,假如我每次用 ...

这么慢的速度可以用轮询方法,即在在干其他事的轮回中到端口读一次,读到一次延迟再读一次,几次读到再确认基数,以此避免“干扰”。其他是做得多了,插入延迟可以少些,避免影响速度。
回复 支持 反对

使用道具 举报

发表于 2015-6-1 10:01:36 | 显示全部楼层
林定祥 发表于 2015-6-1 09:58
这么慢的速度可以用轮询方法,即在在干其他事的轮回中到端口读一次,读到一次延迟再读一次,几次读到再确 ...

中断方式也可以,只是在中断中需要有确认有脉冲和不该有脉冲的抗”干扰“措施,确认没有干扰,再计数。
回复 支持 反对

使用道具 举报

发表于 2015-8-5 22:11:05 | 显示全部楼层
类似按钮  你需要消抖 delay(10);外加if在判断一次
回复 支持 反对

使用道具 举报

发表于 2015-8-6 08:22:31 | 显示全部楼层
int x=0;                                                               
void setup()
{
  Serial.begin(9600);
  pinMode(2,INPUT);                                            
  //attachInterrupt(0,z,RISING);                              
}

void loop()
{
  if(digitalRead(2)== LOW)  
  {
    delay(10); //然后延时一段时间,
    if(digitalRead(2)==LOW)
    {
      x+=1;
      Serial.println(x);
      while(digitalRead(2)==LOW)
      {
        delay(1);
      }
    }
  }                                         

}


回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-7 19:29 , Processed in 0.037992 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表