Arduino Интерфейс с магнитным пикапом

В настоящее время у меня есть дизельный двигатель с магнитным датчиком. Я хочу использовать Arduino (Uno/Nano) для измерения оборотов двигателя.

Магнитный датчик Описание: Магнитный датчик установлен поверх шестерни (чаще всего маховика внутри раструба транспортного средства), и при повороте механизма датчик создает электрический импульс для каждого зуба на передаче. Эти импульсы затем считываются прибором, который интерпретирует их, чтобы указать правильные обороты или скорость. Сигнал от магнитного датчика скорости, зубцов в секунду (Гц), прямо пропорционален частоте вращения двигателя.

Изображение магнитного датчика: MP - Self Powered

Я попытался выпрямить сигнал, используя диод, затем ограничил ток, используя резистор с конденсатором.1Uf для фильтрации шума, затем подключил его к Optocopler 4N35, и вывод от Opto к выводу прерывания Arduino, просто наблюдая, как пинг прерывания 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 работает со светодиодом в качестве индикатора для импульсов, генерируемых датчиком. (Протестировано с использованием маленького мотора и маленькой шестерни для защиты Arduino).

Также я пытался использовать LM139 Comparator, но показания не имеют смысла (например: 60 об / мин, 1500 об / мин,2150 об / мин, 7150 об / мин).

Схема LM139

Код, используемый с LM139:

// 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 для отображения оборотов в минуту?

1 ответ

Вы используете AnalogRead неправильно. Кроме того, analogRead не приблизит вас к тому, чего вы хотите достичь.

То, что вы хотите от вашего датчика, это чистый цифровой сигнал 0-5В. Вы можете получить это, играя с входным резистором на вашем оптопаре. Я бы сделал некоторые замеры и поместил бы тримбот + резисторы на плате, чтобы фактическое значение можно было настроить после установки системы.

Как только вы получите электрический сигнал настолько чистым, насколько сможете, вы можете использовать контактный прерыватель на 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);
}
Другие вопросы по тегам