roboforum.ru

Технический форум по робототехнике.


24 битный счетчик

Обсуждаем рождающиеся мысли и результаты экспериментов.

24 битный счетчик

Сообщение CiSi » 23 янв 2012, 16:55

Есть 24 битный беззнаковый счетчик, считает он импульсы энкодера. проблемма в том что если значение счетчика 0 то при реверсе он считает не в отрицательную сторону, а вычитает из своего максимального значения. Собственно требуется получить на выходе знаковое значение.
сейчас у меня реализовано следующим образом:
Код: Выделить всёРазвернуть
 procedure ReadMoving(K: double; var Moving: double);
begin
      if directionTop = 1 then    //прибавляем
       begin
          Moving:=Moving+((Encoder-bufer)/K);
          Bufer:= Encoder;
         end;

         if directionBottom = 1 then // вычитаем
           begin
              Moving:=Moving+((Bufer-(16777215-Encoder))/K);
               Bufer:= 16777215-Encoder;
               
           end;
end;

После каждой смены направления движения счетчик обнуляется (переменная Encoder).

Добавлено спустя 1 минуту 28 секунд:
K это коэффициент для перевода импульсов в мм.
Аватара пользователя
CiSi
 
Сообщения: 1027
Зарегистрирован: 04 окт 2007, 16:11
Откуда: иваново
Skype: cybsys1
прог. языки: Delphi
ФИО: Павел

Re: 24 битный счетчик

Сообщение boez » 23 янв 2012, 18:40

Да вроде вот так можно:
Код: Выделить всёРазвернуть
procedure ReadMoving(K: double; var Moving: double);
begin
   if directionTop = 1 then    //прибавляем
     begin
       Moving:=Moving+((Encoder-bufer)/K);
       Bufer:= Encoder;
     end;

   if directionBottom = 1 then // вычитаем
     begin
       Moving:=Moving-((Encoder-Buffer)/K);
       Bufer:= Encoder;
     end;
end;


Кстати, в этом варианте вроде даже не надо обнулять Encoder и Buffer при реверсе. Еще возможно надо добавить обрезку до 24 бит, если реальные encoder и buffer 32-битные:
Код: Выделить всёРазвернуть
Moving:=Moving+(((Encoder-bufer)&0xffffff)/K)
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++

Re: 24 битный счетчик

Сообщение CiSi » 23 янв 2012, 19:10

Так не получилось :(

Добавлено спустя 5 минут 22 секунды:
так как у меня сейчас реализованно конечно работает, но мне почемуто не нравится, считаю что какойто кривой код.
Аватара пользователя
CiSi
 
Сообщения: 1027
Зарегистрирован: 04 окт 2007, 16:11
Откуда: иваново
Skype: cybsys1
прог. языки: Delphi
ФИО: Павел

Re: 24 битный счетчик

Сообщение boez » 23 янв 2012, 19:11

Странно, а почему? Вроде должно. Вообще, сами переменные Encoder и bufer какого типа и разрядности?
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++

Re: 24 битный счетчик

Сообщение CiSi » 23 янв 2012, 19:30

Encoder и bufer типа double

Добавлено спустя 2 минуты 54 секунды:
поменял на тип real с меньшей разрядностью, работает так же.
Аватара пользователя
CiSi
 
Сообщения: 1027
Зарегистрирован: 04 окт 2007, 16:11
Откуда: иваново
Skype: cybsys1
прог. языки: Delphi
ФИО: Павел

Re: 24 битный счетчик

Сообщение boez » 23 янв 2012, 19:57

Стоп, я кажись немного неправильно телепатировал что такое переменная Encoder :) Это в твоей проге счетчик (тогда почему он именно 24-битный, сделай целым 32-битным и забудь про переполнения, они сами отрабатывать будут) или откуда-то число приходит, по каналу связи или еще как? Что делается с самой переменной encoder при вращении назад - она увеличивается или уменьшается?

Добавлено спустя 11 минут 13 секунд:
Все, я присмотрелся внимательнее к твоей первой проге, похоже что encoder считает таки сразу с направлением (поправь, если не так). Тогда, если уж тебе надо чтоб он был именно 24-битным, то делай так:
Код: Выделить всёРазвернуть
procedure ReadMoving(K: double; var Moving: double);
begin
       Moving:=Moving+(((Encoder-Bufer)shl 8)shr 8)/K);
       Bufer:= Encoder;
end;


Encoder и Bufer типа integer (машина 32-битная, я полагаю?), за синтаксические ошибки не пинать, я на паскале писал давно и неправду :)
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++

Re: 24 битный счетчик

Сообщение CiSi » 23 янв 2012, 21:54

счетчик этот аппаратный он 24 битный, опрашивается при помощи процедуры и передает своё значение в переменную encoder. при реверсе значение уменьшается, но при переходе через ноль оно становится не отрицательным, а уменьшается от максимального значения (16777215)
Аватара пользователя
CiSi
 
Сообщения: 1027
Зарегистрирован: 04 окт 2007, 16:11
Откуда: иваново
Skype: cybsys1
прог. языки: Delphi
ФИО: Павел

Re: 24 битный счетчик

Сообщение dccharacter » 23 янв 2012, 23:22

Так что такое "отрицательное значение" по-твоему? Чем отличается, допустим, signed char и unsigned char? Каждый из них принимает значение от 0b00000000 до 0b11111111. Но чем они отличаются?
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: 24 битный счетчик

Сообщение CiSi » 23 янв 2012, 23:57

Тип char может быть знаковым и беззнаковым. Обозначается, соответственно, как "signed char" (знаковый тип) и "unsigned char" (беззнаковый тип). Знаковый тип может хранить значения в диапазоне от -128 до +127. Беззнаковый - от 0 до 255.
Аватара пользователя
CiSi
 
Сообщения: 1027
Зарегистрирован: 04 окт 2007, 16:11
Откуда: иваново
Skype: cybsys1
прог. языки: Delphi
ФИО: Павел

Re: 24 битный счетчик

Сообщение dccharacter » 24 янв 2012, 00:11

Супер, а теперь сделай следующий шаг - переведи все числа, которые ты написал, в бинарный вид.
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: 24 битный счетчик

Сообщение Michael_K » 24 янв 2012, 00:53

dccharacter, проблема в том, что в си в паскале :) нету натурального типа для 24-битных значений.

CiSi, вам можно попробовать расширять знак.
Если старший (23-й) бит счетчика равен единице, то нужно старший ("лишний") байт (с 24-го по 31-й бит) поставить во "все единицы". Тогда результат будет меняться от 8млн до -8млн (точно лень считать).
Паскаль не знаю.

Добавлено спустя 3 минуты 35 секунд:
А boez хорошо написал - он вообще честно расширил счетчик. До полных значащих 32-х бит.
Аватара пользователя
Michael_K
 
Сообщения: 6028
Зарегистрирован: 07 окт 2009, 00:29
Откуда: СПб

Re: 24 битный счетчик

Сообщение dccharacter » 24 янв 2012, 01:52

нету - так можно отдельную переменную для знака ввести :-)
В каком-то аппноуте от микрочипа (кажися про ПИД и маятник) используется то ли ниббл, то ли байт для обозначения знака.

Ну или я не догоняю в чем проблема.
А еще я бы не переводил все постоянно в миллиметры, а считал в попугаях.

Добавлено спустя 21 минуту 31 секунду:
Вместо вот этого: "После каждой смены направления движения счетчик обнуляется (переменная Encoder)."
сделай вот это: "при прохождении нуля знак меняется на противоположный"

Добавлено спустя 8 минут 21 секунду:
Или еще проще. Не обнуляй счетчик, а присваивай ему значение 0x100000. Соответственно твое знаковое будет (Encoder - 0x100000). Т.е. ноль у тебя - и не ноль вовсе :-)
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: 24 битный счетчик

Сообщение boez » 24 янв 2012, 02:20

dccharacter писал(а):Или еще проще. Не обнуляй счетчик, а присваивай ему значение 0x100000. Соответственно твое знаковое будет (Encoder - 0x100000). Т.е. ноль у тебя - и не ноль вовсе :-)

Так прикол счетчика CiSi в том, что он не может ему ничего присвоить. Он его только читает - затем и введена переменная Bufer.

Короче, так как я написал должно работать, я вначале неправильно написал, потому что исходил из гипотезы, что энкодер считает всегда в плюс (не квадратурный, а одноканальный), а знак ему надо добавить вручную, исходя из неких флагов направления вращения. А раз энкодер честный - нужно именно сделать знаковое расширение разности (enc-buf) с 24 до 32 бит. 32 бита со знаком в обычном паскале для 32-разрядного x86 представлен типом integer. Это можно делать ручками через байты, как написал Michael_K, и паскаль даже позволяет такие манипуляции при помощи наложения памяти (absolute), но ИМХО сдвигами проще. Результат 100% идентичен - младшие 24 бита сохраняются полностью, а старшие (24-31) делаются все равны 23-му биту. В формате знакового целого это соответствует -0x00800000...0x007fffff, что и требовалось.

Добавлено спустя 3 минуты 20 секунд:
А, стоп, вроде правда пишет что может обнулять. Но все равно вписывать 0x100000 не поможет - а если направление вращения не сменится? Через 0x100001 тиков вращения назад все равно перескочит с нуля на 0xffffff. Надо именно получить 24-битную разность со знаком - и тогда все будет ОК само, без никаких проверок.
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++

Re: 24 битный счетчик

Сообщение CiSi » 24 янв 2012, 10:21

Наврал - переменная Encoder типа cardinal (беззнаковый). Прошу прошения.
Так как я получаю значение с аппаратного счетчика, то задать ему какоето значение нельзя, переменной конечно можно но не увидел в этом смысла. Счетчик можно только обнулить. Четкое отслеживание нуля то же не увенчалось успехом, после чего осталось значение счетчика привязать к направлению вращения энкодера. И при каждой смене направления (движение в ту или иную сторону) сначало обнуляю счетчик и он считает от нуля.

Michael_K, если я вас правильно понял, то в таком случае нулевое значение счетчика будет соответствовать -8388607 знаковой 24 битной пременной.
Аватара пользователя
CiSi
 
Сообщения: 1027
Зарегистрирован: 04 окт 2007, 16:11
Откуда: иваново
Skype: cybsys1
прог. языки: Delphi
ФИО: Павел

Re: 24 битный счетчик

Сообщение Romikgy » 24 янв 2012, 11:21

Код: Выделить всёРазвернуть
if Bufer>$7fffff then 
begin
   Bufer:=-(Bufer-$7fffff);
end;

а так не проще?
die Wahrheit ist irgendwo da draußen
Аватара пользователя
Romikgy
 
Сообщения: 750
Зарегистрирован: 15 ноя 2009, 13:37
Откуда: Porto Franco "Odessa"

След.

Вернуться в Идеи

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 23