2017-08-13 136 views
0

目前我有一個附有磁性拾音器的柴油發動機。我想用Arduino(Uno/Nano)來測量發動機轉速。Arduino與磁性拾音器接口

磁性拾音器說明:磁性拾音器安裝在齒輪上(通常是車輛鐘形外殼內的飛輪),當齒輪轉動時,拾音器將爲齒輪上的每個齒形成電脈衝。然後由儀器讀取這些脈衝,將其解釋爲指示正確的RPM或速度。來自磁性速度傳感器的信號,即每秒齒數(HZ),與發動機速度成正比。

電磁傳感器圖片: MP - Self Powered

我試圖使用二極管來糾正信號然後使用具有.1Uf電容器的電阻器來過濾噪聲限制電流,然後將它連接到Optocopler 4N35,並從輸出通過觀察Arduino中斷ping,Opto to Arduino中斷引腳受環境影響很大。

此外,我試圖直接將磁性拾音器連接到「A0」引腳,並使用模擬讀取並將引腳連接到引腳13,以監視來自MP的脈衝。

int sensorPin = A0;  
int ledPin = 13;  
int sensorValue = 0; 

void setup() { 
    pinMode(ledPin, OUTPUT); 
    Serial.begin(9600); 
} 

void loop() { 
    // read the value from the sensor: 
    sensorValue = analogRead(sensorPin); 
    digitalWrite(ledPin, HIGH); 
    delay(sensorValue); 
    digitalWrite(ledPin, LOW); 
    Serial.println(sensorValue); 
    Serial.println(" "); 
} 

使用analogueRead作品與LED作爲通過拾取產生的脈衝指示器。 (使用小型電機和小型裝置進行測試以保護Arduino)。

此外,我試圖使用LM139比較器,但讀數沒有意義 (例如:60 RPM,1500 RPM,2150 RPM,7150 RPM)。與LM139採用

LM139 Circuit

代碼:

// read RPM 
volatile int rpmcount = 0; 
//see http://arduino.cc/en/Reference/Volatile 
int rpm = 0; 
unsigned long lastmillis = 0; 

void setup() { 
    Serial.begin(9600); 
    attachInterrupt(0, rpm_fan, RISING); 
    //interrupt cero (0) is on pin two(2). 
} 

void loop() { 
    if (millis() - lastmillis == 500) { 
    /*Update every one second, this will be equal to reading frequency (Hz).*/ 
    detachInterrupt(0); //Disable interrupt when calculating 
    rpm = rpmcount * 60; 
    /* Convert frequency to RPM, note: this works for one interruption per full rotation. For two interrupts per full rotation use rpmcount * 30.*/ 
    Serial.print(rpm); // print the rpm value. 
    Serial.println(" "); 
    rpmcount = 0; // Restart the RPM counter 
    lastmillis = millis(); // Update lastmillis 
    attachInterrupt(0, rpm_fan, RISING); //enable interrupt 
    } 
} 

void rpm_fan() { 
    /* this code will be executed every time the interrupt 0 (pin2) gets low.*/ 
    rpmcount++; 
} 
// Elimelec Lopez - April 25th 2013 

什麼是接口與Arduino的一個磁感應器到顯示RPM的最佳方式或方法?

回答

0

您使用analogRead是錯誤的。此外,analogRead不會讓你靠近你想要達到的目標。

你想從你的皮卡是一個清晰的0-5V數字信號。您可以通過使用光耦合器上的輸入電阻來獲得該功能。我會做一些測量,並且在電路板上放置一個trimpot +電阻,在安裝系統後可以調整實際值。

一旦您獲得的電信號儘可能乾淨,您可以使用Arduino上的中斷引腳來保持脈衝數的計數。

#define SENSOR_PIN (2) // using define instead of variable for constants save memory. 
#define LED_PIN  (13) 

#define READ_DELAY (100) // in milliseconds. 

// we'll get a reading every 100ms, so 8 bits are enough to keep 
// track of time. You'd have to widen to unsigned int if you want 
// READ_DELAY to exceed 255 ms. 
// 
typedef delay_type unsigned char; 

typedef unsigned int counter_type; // You may want to use 
            // unsigned long, if you 
            // experience overflows. 

volatile counter_type pulseCount = 0; // volatile is important here 

counter_type lastCount = 0; 
delay_type lastTime = 0; 

// pulse interrupt callback, keep short. 
void onSensorPulse() 
{ 
    ++pulseCount; 

    // the following may already be too long. Use for debugging only 
    // digitalWrite() and digitalRead() are notoriously slow. 
    // 
    // 
    // digitalWrite(LED_PIN, !digitalRead(LED_PIN)); 
    // 
    // using fastest direct port access instead. (for ATMega) 
    // 
    if (pulseCount & 1) 
     PORTB |= (1 << PB5); 
    else 
     PORTB &= ~(1 << PB5); 
} 

void setup() 
{ 
    pinMode(SENSOR_PIN, INPUT); 
    attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), onSensorPulse, RISING); 

    pinMode(ledPin, OUTPUT); 
    Serial.begin(9600); 
} 

void loop() 
{ 
    // control frequency of readings 
    // 
    delay_type now = (delay_type)millis(); 
    if (now - lastTime < READ_DELAY) 
    { 
     return; 
    } 
    lastTime = now; 

    // get a reading. must disable interrupts while doing so. 
    // because pulseCount is multi-bytes. 
    // 
    noInterrupts(); 
    counter_type curCount = pulseCount; 
    interrupts(); 

    // get the number of pulses since last reading. 
    // 
    counter_type delta = curCount - lastCount; 
    lastCount = curCount; 

    // to convert to RPMs, you will need to use this formula: 
    // note the use of long (UL) to avoid overflows in the 
    // computation. 60000 = miliseconds per minute. 
    // 
    // RPM = delta * 60000UL/(READ_DELAY * TEETH_COUNT); 

    // send delta to client for now. 
    // 
    Serial.println(delta); 
} 
+0

[鏈接](https://www.youtube.com/watch?v=tDxK7IWfHEc) 這是從MP傳感器出來的信號的視頻,我應該怎麼做才能得到那個0- 5 V –

+0

您提供的LM319原理圖應該會給您帶來不錯的脈衝,但電子噪音可能會給您帶來不必要的短暫尖峯。您需要添加一個低通濾波器來消除與信號無關的尖峯信號。我認爲你得到的讀數可能是由於溢出。您的問題中提供的代碼沒有考慮到齒輪上的齒數,所以您獲得的RPM可能會過度乘數。使用ADC時,使用analogRead()速度太慢,無法提供可靠的計數。 –