S.Bus System
Прошу разъяснить следующий момент: каким образом прочитать значение передаваемой длительности импульса в кадре S.Bus после старта?
Для примера возьмём самый простой вариант - первый канал. Итак, передача в S.Bus осуществляется методом MSb first (передаётся сначала самый старший бит). На передачу значения длительности первого канала отводится 8 бит(0-7) из первого переданного байта и 3 бита(0-2) из второго. Вопрос состоит в следующем: где среди этих 11 бит находится MSb? Я предполагаю, что он находится во 2-ом бите второго байта, т.е. 11-битное значение надо читать начиная со 2-го бита 2-го байта справа налево. Так ли это?
Второй момент, который я бы хотел понять: как рассовать биты из значения канала c типом unsigned int в два байта передаваемые через стандартный UART(в котором передача начинается с LSb), чтобы переданные байты образовывали число в формате протокола S.Bus?
-да, так
-ИМХО сдвигом и преобразованием типа, наподобии следующего
unsigned int iPulse ;
unsigned char iPulseL ;
unsigned char iPulseH ;
…
iPulseH = (char)(iPulse >>8);
iPulseL = (char)iPulse;
О, Юрий, рад Вас снова видеть “в деле”.
Ваша идея понятна, только тогда каким образом дозаполнить оставшиеся пять бит в iPulseH ? Да и дальнейшая процедура заполнения байт S.Busa по Вашей схеме не ясна.
Я сейчас использую способ перераспределения бит посредством последовательного считывания из int iPulse начиная с младшего и потом установка считанного значения бита в очередном байте S.Busa тоже от младшего к старшему. Затем сдвиг iPulse и байта S.Bus. Заканчивается очередной байт, продолжаем в следующем.
Если интересно, могу процедуру сортировки выложить.
Фишка для меня была, в основном, в первом вопросе. Я перекопал много разных источников, но для себя 100% -го ответа не нашёл. Вот тут mbed.org/…/futaba-s-bus-controlled-by-mbed/ мужик проделал немалую работу, но мне это ясности всё равно не добавило.
Я где то встречал процедуру считывания красивую, но ссылку никак не найду 😦 Комп слетал и где теперь та ссылка… Ну да ладно…
Следующий кусок просто получаете из следующего значения канала тем же сдвигом в требуемом направлении, ну куда надо биты передвинуть и преобразованием типа с последующим сложением уже имеющегося куска, например
iPulseL = TCNT1L;
iPulseH = TCNT1H;
iPulse = (((unsigned int)iPulseH)<<8) + iPulseL;
Вот еще полезная вещь, попалась тут на www.multirotorforums.com/showthread.php?9661-R7008…, чтоб не региться там файлик прилагаю
Перестановка битов в байте тут нарыл в инете:
char bit_reverse (char bits)
{
bits = ((bits & 0x0F) << 4) | ((bits & 0xF0) >> 4);
bits = ((bits & 0x33) << 2) | ((bits & 0xcc) >> 2);
bits = ((bits & 0x55) << 1) | ((bits & 0xaa) >> 1);
return bits;
}
Юрий, Вы всё ещё тут?! Приятно удивлён!
Файлик зипованый я посмотрел - он тот же, на который я давал ссылку.
Прцедуру я не вкурил. Зачем биты реверсировать? Это мне больше напоминает процедуру определения бита чётности. Короче, вот моя процедурка:
////************************************
////Конвертация. Длительность порядка 1760 мкСек(3538 инстр.циклов)
////************************************
void convertation()
{
int mask = 0x01; //Маска для проверки битов в Channel_Pulse[]
unsigned char buffer = 0; //Буфер для промежуточного хранения байта высчитанного из Channel_Pulse[]
char mask_buffer = 0b10000000; //Маска усановки битов в байтах buffer
char k = 0; //счетчик бит в байтах buffer
char n = 0; //счетчик байт в массиве DATA[n]
for(char p=0; p<8; p++) //Для каждого из 8-ми значений Channel_Pulse[]
{
for(char i=0; i<=10; i++) //Для 11 младших бит Channel_Pulse[p]
{
if(Channel_Pulse[p] & mask) //Если в i-ом разряде Channel_Pulse[p] единица
{buffer = buffer | mask_buffer;} //Пишем 1 в соответствующий разряд переменной buffer
else {buffer = buffer | 0x00;} //Иначе пишем 0
mask_buffer = mask_buffer >> 1; //сдвигаем 1 на разряд вправо в маске усановки битов в buffer
mask = mask << 1; //сдвигаем 1 на разряд влево в маске для проверки битов в Channel_Pulse[p]
k++; //добавляем +1 в счётчик бит в байтах buffer
if(k>=8) //Если счётчик бит в байтах buffer досчитал до 8
{
DATA[n] = buffer; //Пишем содержимое буфера в DATA[n]
mask_buffer = 0b10000000; //Устанавливаем 1 в 0-й разряд маски усановки битов в байтах buffer
k = 0; //Сбрасываем счётчик бит в байтах buffer
buffer = 0; //и очищаем буфер
n+=1; //добавляем +1 в счётчик байт в массиве DATA[n]
}
if(i>=10) //Если счётчик бит в байтах Channel_Pulse[p] досчитал до 10, то
{mask = 0x01;} //Устанавливаем 1 в 0-й разряд маски для проверки битов в Channel_Pulse[]
}
}
}
Она может и не очень красива(я программер тот ещё), но работает быстро и можно колбасить биты по всем направлениям меняя маску и направление сдвига. На выходе массив из байт для ЭсБуса.
Файлик зипованый я посмотрел - он тот же, на который я давал ссылку
В файлике ссылка, что начало с той страницы, но кой чего добавлено, может я его просмотрел на той странице, новый IE такие фокусы местами выкидывает, что уж подумываю на другой браузер переползти 😦
Прцедуру я не вкурил. Зачем биты реверсировать?
Биты не реверсируются, просто меняется порядок битов в байте из MSB в LSB или наоборот, в вопросе упоминалось про порядок следования, вот и кинул на всяк случай.
Нормальная у Вас процедурка, главное работает и быстродействие устраивает.
Провёл сейчас такой эксперимент: записал в 1-й канал значение 1024, во 2-й 1536 и в третий 2047. Таким образом, при подключении в 1-й канал, серва должна устанавливаться в “минимальное” положение; при подключении ко 2-му каналу - в “среднее” положение и при подключении к 3-му каналу в “максимальное” положение.
При подключении к FuBar, получилось следующее: серва в 1-м какале - положение “чуть меньше середины”; серва во 2-м канале - “середина”; серва в 3-м канале - “максимум”.
Выходит передаётся всё правильно, а интерпретирует FuBar как то странно. Или я неправильный вывод делаю?
Не совсем понял, вроде минимальное-0, среднее-1023 и максимум 2047 ?
Для РРМ-сигнала 1024 - это 0%, 1536 - 50% и 2047 - 100%. Или в S.Bus 0 - это 0%, 1024 - это 50%, а 2047 - 100%? Или, иными словами, конвертировать надо так: (((Длительность_РРМ_импульса) - 1023) / 1023)*100% Так что ли?
Блин, если это так, то я чудак на букву “М”! Мне ж еще 7.03.2014 RW9UAO говорил о том же:
среднее положение столбика в фубаре - 1023, минимум - 0, максимум 2047. возможно вы неправильно конвертируете входящие данные.
А я прощёлкал клювом…
Зачем так сурово к себе относиться. Правильнее говорить о диапозоне укладывающемся в S.BUS, потому как 0 и 2047 это не плюс/минус 100%, а максимум отклонений, который возможен даже не в футабе, а в той аппаратуре с которой Вы перегоняете сигнал в S.BUS, если конечно есть желание продолжать работать с аппаратурой в показываемых ей цифирях, а не пересчитывать все с калькулятором.
Усё! Допилил, наконец я конвертер! Вчера вечером уже подлётывал на 250-ке дома. Спасибо, мужики, большое за участие и помощь!
Молодца 😃