求助检测继电器开合时间
想要实现如下功能:继电器不断的得电失电,然后检测它通断之的时间我写了代码,用外部中断检测,但测得的时间太大了,有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");
}
先用笨办法看看真实的数据。
void onChange()
{
if ( digitalRead(pinInterrupt) ==HIGH )
start=micros();
else
finished=micros();
//把 micros() 的值加到全局数组aTimes[]。
}
想得到时间差,用 aTimes - aTimes 不就出来了。
串口输出数组内容看看,是不是跟你预期的一样,时间差是否还是49900us 49900uS=49.9mS
你在程式中將繼電器 ON 後DELAY 50mS=50000uS
再 OFF,所測得的時間差 < 50000uS 我猜是接點彈跳
讓 start 值被刷新的關係? Stormer 发表于 2017-11-16 13:08
先用笨办法看看真实的数据。
void onChange()
全局数组这里不是很懂,能具体讲解一下吗?我在代码里应该怎么修改
shouzama 发表于 2017-11-16 20:47
49900uS=49.9mS
你在程式中將繼電器 ON 後DELAY 50mS=50000uS
这个问题怎么解决?还望指教
本帖最后由 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();
先試試看,如果時間每次都差很多,有可能就是接點彈跳
的問題了 shouzama 发表于 2017-11-18 07:23
不過我又想到了,RELAY 並不像電子元件有很高的
反應速度,如果不 DELAY ,有可能接點還沒導通線圈
就又斷 ...
感谢,我试试,看怎么样
:lol应该是计时然后触发继电器,等到继电器另一端的接口检测到高电平,再计时,两个时间相减、。、、得到继电器的响应时间。。连续测100次,求最大最小和平均值 shouzama 发表于 2017-11-18 07:23
不過我又想到了,RELAY 並不像電子元件有很高的
反應速度,如果不 DELAY ,有可能接點還沒導通線圈
就又斷 ...
现在测得的时间又很小,是100us左右,还是不对 迷你强 发表于 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");
}
}
}
急速未来 发表于 2017-11-19 15:08
现在测得的时间又很小,是100us左右,还是不对
果然,您測到的應該是接點閉合時,瞬間第一次彈跳的時間差 -_-"
回歸問題本身,是像 8 樓網友說的,是要測繼電器線圈 ON~接點ON 的
時間差(ON作動反應時間)? 還是要試接點 ON 立即斷電使接點 OFF,
測量接點 ON~OFF 的時間差?
好像是前一種會比較有意義,那麼就像 8 樓網友說的做法囉,
您貼的程式碼是另一位網友的耶...(同一位?)
那問題依邏輯來看只差在旗號沒復歸、繼電器沒斷電重來,
所以不會跑第二次,您說修改後也不行...那我就幫不上忙了 :$
页:
[1]