Код Arduino RPM с квадратурным энкодером 600ppr

Я пытаюсь настроить свой arduino uno таким образом, чтобы он предоставлял мне данные об оборотах, измеряемых на моем энкодере. До сих пор мне удавалось выяснить, как точно измерить RPM для первого значения, однако я изо всех сил пытаюсь сбросить значение в конце цикла, поэтому вместо того, чтобы давать мне фактические обороты, он просто увеличивается с предыдущими данными. . Вот мой код для лучшего понимания того, что я имею в виду...

// Red - 5V
// Black - GND

const int encoder_a = 2; // Green - pin 2 - Digital
const int encoder_b = 3; // White - pin 3 - Digital
long encoder = 0;
long encoderO=0;


void setup() {
    Serial.begin(9600);
    pinMode(encoder_a, INPUT_PULLUP);
    pinMode(encoder_b, INPUT_PULLUP);

    attachInterrupt(0, encoderPinChangeA, CHANGE);
    attachInterrupt(1, encoderPinChangeB, CHANGE);
}

void loop() {
    Serial.println(encoder/2400.00*60);
    delay(1000);
}

void encoderPinChangeA() {
    encoder += digitalRead(encoder_a) == digitalRead(encoder_b) ? -1 : 1;
}

void encoderPinChangeB() {
    encoder += digitalRead(encoder_a) != digitalRead(encoder_b) ? -1 : 1;
}

person Allan Bonet    schedule 12.07.2018    source источник


Ответы (3)


Я бы попробовал немного реструктурировать код. Это в основном для разделения скорости и направления, так как они не зависят друг от друга. Например:

long encoder_pulse_counter = 0;
long direction = 1


void setup() {
    Serial.begin(9600);
    pinMode(encoder_a, INPUT_PULLUP);
    pinMode(encoder_b, INPUT_PULLUP);

    attachInterrupt(0, encoderPinChangeA, CHANGE);
    attachInterrupt(1, encoderPinChangeB, CHANGE);
}

void loop(){
    long speed = encoder_pulse_counter/2400.00*60; // Not sure, encoder not specified
    Serial.println(direction*speed);
    encoder_pulse_counter = 0; // Clear variable just before counting again 
    delay(1000);
}


void encoderPinChangeA(){
    encoder_pulse_counter += 1;
    direction = digitalRead(encoder_a) == digitalRead(encoder_b) ? -1 : 1;
}

void encoderPinChangeB(){
    encoder_pulse_counter += 1;
    direction = digitalRead(encoder_a) != digitalRead(encoder_b) ? -1 : 1;
}

Я не тестировал этот код, поэтому могут быть небольшие ошибки. Но я думаю, что разделить расчеты будет намного проще. Надеюсь это поможет!

person Hein Wessels    schedule 12.07.2018

Хороший ответ Весселса. Некоторые небольшие ошибки в предоставленном коде, полный рабочий и протестированный код:

const int encoder_a = 3; // Pin 3
const int encoder_b = 5; // Pin 5
long encoder_pulse_counter = 0;
long direction = 1;

void encoderPinChangeA()
{
    encoder_pulse_counter += 1;
    direction = digitalRead(encoder_a) == digitalRead(encoder_b) ? -1 : 1;
}

void encoderPinChangeB()
{
    encoder_pulse_counter += 1;
    direction = digitalRead(encoder_a) != digitalRead(encoder_b) ? -1 : 1;
}

void setup() 
{
    Serial.begin(9600);
    pinMode(encoder_a, INPUT_PULLUP);
    pinMode(encoder_b, INPUT_PULLUP);
    attachInterrupt(0, encoderPinChangeA, CHANGE);
    attachInterrupt(1, encoderPinChangeB, CHANGE);
}

void loop()
{
    long speed = encoder_pulse_counter/1024.00*60; // For encoder plate with 1024 Pulses per Revolution
    Serial.print("RPM: ");
    Serial.println(direction*speed);
    encoder_pulse_counter = 0; // Clear variable just before counting again 
    delay(1000);
}
person Håkon Haram    schedule 12.10.2018

volatile long encoder_pulse_counter = 0;
volatile long direction = 1


void setup() {
    Serial.begin(9600);
    pinMode(encoder_a, INPUT_PULLUP);
    pinMode(encoder_b, INPUT_PULLUP);

    attachInterrupt(0, encoderPinChangeA, CHANGE);
    attachInterrupt(1, encoderPinChangeB, CHANGE);
}

void loop(){
    long speed = encoder_pulse_counter/2400.00*60; // Not sure, encoder not specified
    Serial.println(direction*speed);
    encoder_pulse_counter = 0; // Clear variable just before counting again 
    delay(1000);
}


void encoderPinChangeA(){
    encoder_pulse_counter += 1;
    direction = digitalRead(encoder_a) == digitalRead(encoder_b) ? -1 : 1;
}

void encoderPinChangeB(){
    encoder_pulse_counter += 1;
    direction = digitalRead(encoder_a) != digitalRead(encoder_b) ? -1 : 1;
}

согласитесь, это выглядит хорошо, просто добавьте volatile к любой переменной, используемой в ISR.

person TechMasterJoe    schedule 03.03.2019