急速未来 发表于 2017-11-16 10:23:13

求助检测继电器开合时间

想要实现如下功能:继电器不断的得电失电,然后检测它通断之的时间
我写了代码,用外部中断检测,但测得的时间太大了,有49900微秒,
现在想问大神,我怎么才能测得准确的时间

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,16,2);
unsigned long start, finished, elapsed;
long int i=0;
int pinInterrupt = 2; //接中断信号的脚
   
void setup()
{
lcd.init();
lcd.backlight();
lcd.print("Ready Test!!!");
Serial.begin(9600);
pinMode(4, OUTPUT);
pinMode( pinInterrupt, INPUT);//设置管脚为输入
//Enable中断管脚, 中断服务程序为onChange(), 监视引脚变化
attachInterrupt( digitalPinToInterrupt(pinInterrupt), onChange, CHANGE);

}
void onChange()
{
   if ( digitalRead(pinInterrupt) ==HIGH )
       start=micros();   
   else
       finished=micros();   
}
voidrelay_go()
{ int p = digitalRead(pinInterrupt);
    digitalWrite(4, HIGH);
    delay(50);
    digitalWrite(4, LOW);
    delay(50);}

void loop()
{   
       relay_go();
       delay(50);
   elapsed=finished-start;
   Serial.print("Elapsed time= ");
   Serial.print(elapsed);
   Serial.println("us");
lcd.clear();
lcd.print("Elapsed time= ");
lcd.setCursor(0, 1);
lcd.print( elapsed);
lcd.print("us , ");
lcd.print(elapsed/1000);
lcd.print("ms");            
}

Stormer 发表于 2017-11-16 13:08:45

先用笨办法看看真实的数据。

void onChange()
{
   if ( digitalRead(pinInterrupt) ==HIGH )
       start=micros();   
   else
       finished=micros();
//把   micros() 的值加到全局数组aTimes[]。
}

想得到时间差,用 aTimes - aTimes 不就出来了。

串口输出数组内容看看,是不是跟你预期的一样,时间差是否还是49900us

shouzama 发表于 2017-11-16 20:47:57

49900uS=49.9mS

你在程式中將繼電器 ON 後DELAY 50mS=50000uS
再 OFF,所測得的時間差 < 50000uS 我猜是接點彈跳
讓 start 值被刷新的關係?

急速未来 发表于 2017-11-17 09:55:51

Stormer 发表于 2017-11-16 13:08
先用笨办法看看真实的数据。

void onChange()


全局数组这里不是很懂,能具体讲解一下吗?我在代码里应该怎么修改

急速未来 发表于 2017-11-17 09:58:28

shouzama 发表于 2017-11-16 20:47
49900uS=49.9mS

你在程式中將繼電器 ON 後DELAY 50mS=50000uS


这个问题怎么解决?还望指教

shouzama 发表于 2017-11-18 07:23:40

本帖最后由 shouzama 于 2017-11-18 07:44 编辑

急速未来 发表于 2017-11-17 09:58
这个问题怎么解决?还望指教
不過我又想到了,RELAY 並不像電子元件有很高的
反應速度,如果不 DELAY ,有可能接點還沒導通線圈
就又斷電了...

是不是應該把 RELAY 線圈的控制放在中斷程式中,
那麼 RELAY 作動、接點導通觸發中斷控制,記錄 start
時間後,將 PIN4 設為 LOW 切斷 RELAY 電力,接點放開
後再次觸發中斷記錄 finished ,像這樣:

void onChange()
{
   if ( digitalRead(pinInterrupt) ==HIGH )
       start=micros();   
       digitalWrite(4, LOW);    //追加這行切斷 RELAY
   else
       finished=micros();

先試試看,如果時間每次都差很多,有可能就是接點彈跳
的問題了

急速未来 发表于 2017-11-18 11:42:47

shouzama 发表于 2017-11-18 07:23
不過我又想到了,RELAY 並不像電子元件有很高的
反應速度,如果不 DELAY ,有可能接點還沒導通線圈
就又斷 ...

感谢,我试试,看怎么样

迷你强 发表于 2017-11-19 11:48:25

:lol应该是计时然后触发继电器,等到继电器另一端的接口检测到高电平,再计时,两个时间相减、。、、得到继电器的响应时间。。连续测100次,求最大最小和平均值

急速未来 发表于 2017-11-19 15:08:59

shouzama 发表于 2017-11-18 07:23
不過我又想到了,RELAY 並不像電子元件有很高的
反應速度,如果不 DELAY ,有可能接點還沒導通線圈
就又斷 ...

现在测得的时间又很小,是100us左右,还是不对

急速未来 发表于 2017-11-19 15:30:23

迷你强 发表于 2017-11-19 11:48
应该是计时然后触发继电器,等到继电器另一端的接口检测到高电平,再计时,两个时间相减、。、、得到继 ...

之前就是这么测的,但是上电只能测一次,
在这是代码,麻烦你看下怎么改成多次测量

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,16,2);
unsigned long start, finished, elapsed;
boolean D7_flag;
boolean D8_flag;
long int i=0;

void setup()
{
lcd.begin();
lcd.backlight();
lcd.print("Ready Test!!!");
Serial.begin(9600);
pinMode(4, OUTPUT); // Coil action output signal
pinMode(7, INPUT); // start ,Coil input signal
pinMode(8, INPUT); // stop ,Contact input signal
D7_flag = false;
D8_flag = false;

for(i=1;i<=100;i++)
{
digitalWrite(4, HIGH);   // turn the LED on (HIGH is the voltage level)
delay(50);               // wait for a second
digitalWrite(4, LOW);    // turn the LED off by making the voltage LOW
delay(50);
lcd.setCursor(0, 1);
lcd.print("CountDown=");
lcd.print(100-i);
if(i==1||i==90)
{
lcd.clear();
lcd.print("Ready Test!!!");
}
}
}

void loop()
{
digitalWrite(4, HIGH);

{
if ((digitalRead(7) == HIGH) && (!D7_flag))
{
   //start=millis();
start=micros();
D7_flag = true;
//Serial.println("Started...");
}

if ((digitalRead(8) == HIGH) && (!D8_flag))
{
    // finished=millis();
finished=micros();
D8_flag = true;
//Serial.println("Stop...");
Serial.print("Elapsed time= ");
elapsed=finished-start-8;
Serial.print(elapsed);
Serial.println("us");
lcd.clear();
lcd.print("Elapsed time= ");
lcd.setCursor(0, 1);
lcd.print( elapsed);
lcd.print("us , ");
lcd.print(elapsed/1000);
lcd.print("ms");
}
}
}

shouzama 发表于 2017-11-19 16:09:37

急速未来 发表于 2017-11-19 15:08
现在测得的时间又很小,是100us左右,还是不对

果然,您測到的應該是接點閉合時,瞬間第一次彈跳的時間差 -_-"

回歸問題本身,是像 8 樓網友說的,是要測繼電器線圈 ON~接點ON 的
時間差(ON作動反應時間)? 還是要試接點 ON 立即斷電使接點 OFF,
測量接點 ON~OFF 的時間差?

好像是前一種會比較有意義,那麼就像 8 樓網友說的做法囉,
您貼的程式碼是另一位網友的耶...(同一位?)
那問題依邏輯來看只差在旗號沒復歸、繼電器沒斷電重來,
所以不會跑第二次,您說修改後也不行...那我就幫不上忙了 :$
页: [1]
查看完整版本: 求助检测继电器开合时间