Перейти к содержанию
    

Алгоритм вычисления позиции.

У меня 16-битный энкодер. По нему я знаю позицию мотора.

Проблема когда счетчик энкодера делает rollover.

Допустим  энкодер считает вверх - первое чтение энкодера 65530, второе 10 – то есть произошел rollover и тогда позиция = 65535 + 10.

Энкодер считает вниз - первое чтение энкодера 10, второе 65530 - и тогда позиция = (65535-65530) + 10.

 

Симулирую в шарпе.

 UInt16 encoder_counter;
        UInt16 prev_encoder_counter;
        Int32 position;
        Int32 rounds;
        UInt32 direction;

        private void buttonEncUp_Click(object sender, EventArgs e)
        {
            direction = 1;

            encoder_counter += (UInt16)numericUpDownEncoderStep.Value;
            numericUpDowneEncoder.Value = encoder_counter;

            GetEncoder();
       }

        private void buttonEncDown_Click(object sender, EventArgs e)
        {
            direction = 2;

            encoder_counter -= (UInt16)numericUpDownEncoderStep.Value;
            numericUpDowneEncoder.Value = encoder_counter;

            GetEncoder();
        }

        void GetEncoder()
        {
            if (Math.Abs(encoder_counter- prev_encoder_counter)>40000) //rollover
            {
                if (encoder_counter < prev_encoder_counter)
                    rounds++;
                else
                    rounds--;    
            }
            position = (Int32)((rounds * 65535) + encoder_counter);

            prev_encoder_counter = encoder_counter;

            textBoxPosition.Text = position.ToString();
        }

Вроде получается правильно. Или тут есть какие то подводные камни?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

57 минут назад, jenya7 сказал:

Проблема когда счетчик энкодера делает rollover.

И что? В чём проблема? не знаете что такое операция "вычитание"?

typedef signed long s32;

s32 offset = (s32)(encoder_counter - prev_encoder_counter << 16) >> 16;

position += offset;

всё.

 

или ещё короче:

typedef signed long s32;

typedef signed short s16;

s32 offset = (s32)(s16)(encoder_counter - prev_encoder_counter);

position += offset;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

45 minutes ago, jcxz said:

И что? В чём проблема? не знаете что такое операция "вычитание"?

typedef signed long s32;

s32 offset = (s32)(encoder_counter - prev_encoder_counter << 16) >> 16;

position += offset;

всё.

 

или ещё короче:

typedef signed long s32;

typedef signed long s16;

s32 offset = (s32)(s16)(encoder_counter - prev_encoder_counter);

position += offset;

понял. спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прогнал уже в эмбедед

uint16_t prev_enc_counter;
int32_t position;

int32_t GetPosition(uint16_t enc_counter)
{
    int32_t offset;

    offset = (int16_t)(enc_counter - prev_enc_counter);
    
    position += offset;
    
    prev_enc_counter = enc_counter;
    
    return position;
}

int main()
{
        g_position = GetPosition(enc);
        printf ("%d\n", g_position);   
        enc -= 10;
        g_position = GetPosition(enc);
        printf ("%d\n", g_position);
        enc -= 10;
        g_position = GetPosition(enc);
        printf ("%d\n", g_position);
        enc += 10;
        g_position = GetPosition(enc);
        printf ("%d\n", g_position);
        enc += 100;
        g_position = GetPosition(enc);
        printf ("%d\n", g_position);
            
    
  return 0;
}

Получаю правильный результат.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...