jenya7 0 22 ноября, 2018 Опубликовано 22 ноября, 2018 · Жалоба У меня 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(); } Вроде получается правильно. Или тут есть какие то подводные камни? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 22 ноября, 2018 Опубликовано 22 ноября, 2018 · Жалоба 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; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 22 ноября, 2018 Опубликовано 22 ноября, 2018 · Жалоба 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; понял. спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 22 ноября, 2018 Опубликовано 22 ноября, 2018 · Жалоба Да, конечно: typedef signed short s16; копипаст клятый..... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 22 ноября, 2018 Опубликовано 22 ноября, 2018 · Жалоба Прогнал уже в эмбедед 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; } Получаю правильный результат. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться