Мы приступили к тестированию BAM

49 views
Skip to first unread message

Mikhail Sannikov

unread,
Apr 26, 2011, 10:41:38 AM4/26/11
to ligh...@googlegroups.com
Если мы не пишем о подвижках в Лайтпаке это значит что мы заняты им настолько, что просто некогда описывать процесс.)

На сегодняшний день по моим данным есть уже минимум 3 собранных устройства ревизии 5.0. Все они исправно функционируют, но мы хотели бы провести перестраховку о чём я напишу отдельное письмо. Кроме этого мы очень сильно продвинулись с софтом. 

Был переписан алгоритм плавности смены цветов и добавлена гамма-коррекция для вычисления итогового цвета (brunql). Значительно увеличена скорость захвата и добавлена возможность работы с AlienFX (tim.helloworld). Написан интерфейс простого подключения разных типов захвата и почти реализован захват в Aero (karp.mih). Кроме всего этого brunql проделал кучу работы по мерджингу всех изменений, актуализации прошивок под две версии железки и пр. Все эти изменения пойдут в новую версию софта, но мы пока ещё не решили как их передать в GUI и от чего из старых настроек получится избавиться благодаря новым фичам. Так что новой версии "на днях" я вам не обещаю, но она уже на подходе. Если интересно, вы всегда можете слиться из ветки default и собрать приложение при помощи Qt SDK. Не забывайте что для любой железки вам придётся обновить прошивку, которая тоже лежит у нас в репозитории.

Собственно теперь вопрос к знатокам. Как мы давно планировали, после реализации ревизии железа 5.0 мы хотим переехать с PWM на BAM. На сегодняшний день BAM существует в прошивке и обёрнут в условную компиляцию (соответсвующие версии .hex собраны и лежат в репозитории). Если конкретно, то:

1) Реализована 8ми битная модуляция. Никакой постобработки цветов в МК не производится
2) В результате при переполнении разряда возникает мерцание (0b00011111 -> 0b00100000
3) Поворот массива реализован на стороне МК, как мы с вами и обсуждали это ранее.

Нам очень нужны реальные(!) примеры реализации BAM. К сожалению, пока при его включении мы наблюдаем только проблемы. Очевидно нам не хватает опыта реализации таких штук. Если у вас есть опыт работы с этим видом модуляции -- поделитесь с нами.

--
С уважением, Санников Михаил
ata...@gmail.com | www.atarity.ru

Андрей Синюткин

unread,
Apr 26, 2011, 11:02:41 AM4/26/11
to ligh...@googlegroups.com
Чтобы корректно применить BAM, нужно наверное сначала найти ответ на самый главный вопрос - что в уже имеющейся версии firmware, в которой уже реализован PWM, не устраивает? Или, если сформулировать вопрос несколько иначе - чего хотите достичь, применив в железе другой тип модуляции/регулировки яркости светодиодов?

Tue, 26 Apr 2011 18:41:38 +0400 письмо от Mikhail Sannikov <ata...@gmail.com>:

--
Лайтпак: lightpack.googlecode.com
Отправить сообщение в группу: ligh...@googlegroups.com
Отписаться от сообщений группы: lightpack+...@googlegroups.com


С уважением Андрей
sin_...@mail.ru
http://microsin.ru

kv35

unread,
Apr 26, 2011, 11:38:58 AM4/26/11
to Лайтпак: обсуждение проекта и новых идей
>>В результате при переполнении разряда возникает мерцание (0b00011111 ->
0b00100000)

Так только при переполнении разряда данные в драйверах и должны
обновляться.
Все данные для них должны быть готовы до времени отправки.

Сейчас буду смотреть код, но там не должно быть никаких мерцаний даже
в случае каких-то ошибок.
При переходе счетчика прерываний на следущий разряд надо:
-отправить 4 байта (по 2 байта на драйвер) по SPI. Отправка или
неотправка данных никак не влияет на отображаемые цвета: полученные
драйверами данные хранятся в сдвиговых регистрах до получения команды.
-после передачи всех 4 байт передернуть (LOW->HIGH->LOW) LATCH, дабы
перевести данные в сдвиговых регистрах на выходы драйверов.

Неоткуда здесь взяться мерцаниям. После переполнения разряда следущее
обновление должно быть после переполнения следущего разряда: до этого
момента данные на выходе драйверов не меняются.

Все эти 8 смен цветов по кругу при должной частоте должны давать
статичный оттенок света. При ошибке в рассчетах поворота массива -
просто получится другой цвет.

Мерцание может быть только при нестабильном цикле смены цветов.

В общем, попробую понять код, по какому алгоритму работает. С ходу мне
даже непонятно зачем таймер обнулять: он сам должен обнулиться при
прерывании.

P.S.
Мне показалось, или данные на драйвера посылаются по кругу каждое
прерывание, т.е. через равные промежутки времени? Дальше процедуры
BAM() пока не смотрел.

Mike Shatohin

unread,
Apr 26, 2011, 12:37:51 PM4/26/11
to ligh...@googlegroups.com
Логика работы сейчас следующая:
- Срабатывает прерывание таймера
1) Увеличивается номер текущего обрабатываемого бита
2) Обновляются значения в драйверах, соответственно обрабатываемому биту
3) Пересчитывается задержка до обработки следующего бита
4) Сбрасывается счетчик таймера (он не сбрасывается автоматически при входе в прерывание, да и в процессе работы прерывания продолжает тикать)
- Ожидание следующего прерывания

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

Проблема в следующем: при установке вручную значений 0b00111110, 0b00111101, 0b00111100, 0b00111011 -  в момент переключения никакого мерцания нет.
При смене значения с 0b00111111 на 0b01000000 яркость светодиодов становится немного ниже и светодиоды в процессе смены цвета мерцают (плавное изменение цветов выключено).

Если в прошивке просто попробовать с некоторой задержкой менять цвет с 0x00 до 0xFF, то будет заметно что яркость, то возрастает, то немного снижается и снова возрастает. C PWM таких проблем нет.

Теперь про то зачем нам BAM, на данный момент при использовании 10 светодиодов в принципе не нужен, но чтобы подключить больше светодиодов придется уменьшать время нахождения контроллера в процессе формирования и передачи данных. Сейчас контроллер только и делает, что сидит в прерывании таймера и передает данные по SPI на драйверы, изредка прерываясь на обновление цветов, прилетевших с эвм. В BAM контроллер будет больше времени сидеть без дела, что позволит пересчитывать в это время текущий цвет (для плавного изменения цветов), а также чем меньше времени контроллер проводит в прерывании тем меньше вероятность потери USB-пакетов (хотя этим занимается другая подсистема контроллера и, как мне кажется, она достаточно асинхронна, чтобы не париться по этому поводу).

PS: Что-то мне все больше кажется, что BAM пока нам не нужен.


26 апреля 2011 г. 19:38 пользователь kv35 <kv0...@gmail.com> написал:

Андрей Синюткин

unread,
Apr 26, 2011, 1:26:38 PM4/26/11
to ligh...@googlegroups.com
Как мне кажется, при использовании аппаратного SPI проц только и должен делать, что отдыхать, вся фоновая вычислительная работа должна вестись вне прерываний.

Схема работы должна быть примерно такая:

1. Делается кольцевой буфер BUFSPI достаточной длины - для данных, передаваемых на SPI. Самый удобный буфер - на 256 байт, так как 8-мибитный индекс указателя на буфер при его инкременте кольцуется автоматически, без наложения маски. На буфер делаются два указателя - idxIN и idxOUT. Буфер нужен для того, чтобы два процесса (один критичный по времени realtime, а другой критичный к ресурсам процессора) - процесс модуляции яркости и процесс вычисления данных для него могли выполняться независимо друг от друга, в подходящие для этого интервалы времени.

2. Фоновая работа в цикле main заботится от том, чтобы в кольцевой буфер все время подкачивались новые данные для SPI. Алгоритм заполнения буфера прост до безобразия - если буфер опустошился, скажем, уже наполовину (разница между idxIN и idxOUT превысила 128), то в буфер можно закачать еще порцию из 128 байт. Данные вычисляются и кладутся в буфер по адресу BUFSPI[idxIN++], и так 128 раз кладутся в буфер 128 байт. Само собой, сырые данные для BUFSPI вычисляются на основе данных из другого буфера - данные яркости RGB[n], которые обновляются иногда по USB, а также из других текущих настроек (если они есть), и от режима работы (применяемой модуляции PWM или BAM).

3. Данные BUFSPI опустошаются обработчиком таймера. По срабатыванию таймера очередной байт BUFSPI[idxOUT++] из буфера должен перекладываться в регистр данных SPI. Это единственное, что должен делать обработчик прерывания таймера.

Если применить такую схему, то резерв для повышения скорости очень большой. Код обработчика таймера при необходимости легко перекладывается на ассемблер (там весь алгоритм укладывается примерно в 4 команды на ассемблере - взять данные по адресу, положить эти данные в регистр SPI, инкрементировать адрес, сделать возврат), и при переходе на ассемблер можно устранить лишние сохранения статуса на входе и выходе (PUSH, POP статуса и временных регистров - эти сохранения неизбежны, если применять обработчик прерывания, написанный на C).

Tue, 26 Apr 2011 20:37:51 +0400 письмо от Mike Shatohin <bru...@gmail.com>:

Логика работы сейчас следующая:
- Срабатывает прерывание таймера
1) Увеличивается номер текущего обрабатываемого бита
2) Обновляются значения в драйверах, соответственно обрабатываемому биту
3) Пересчитывается задержка до обработки следующего бита
4) Сбрасывается счетчик таймера (он не сбрасывается автоматически при входе в прерывание, да и в процессе работы прерывания продолжает тикать)
- Ожидание следующего прерывания

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

Проблема в следующем: при установке вручную значений 0b00111110, 0b00111101, 0b00111100, 0b00111011 -  в момент переключения никакого мерцания нет.
При смене значения с 0b00111111 на 0b01000000 яркость светодиодов становится немного ниже и светодиоды в процессе смены цвета мерцают (плавное изменение цветов выключено).

Если в прошивке просто попробовать с некоторой задержкой менять цвет с 0x00 до 0xFF, то будет заметно что яркость, то возрастает, то немного снижается и снова возрастает. C PWM таких проблем нет.

Теперь про то зачем нам BAM, на данный момент при использовании 10 светодиодов в принципе не нужен, но чтобы подключить больше светодиодов придется уменьшать время нахождения контроллера в процессе формирования и передачи данных. Сейчас контроллер только и делает, что сидит в прерывании таймера и передает данные по SPI на драйверы, изредка прерываясь на обновление цветов, прилетевших с эвм. В BAM контроллер будет больше времени сидеть без дела, что позволит пересчитывать в это время текущий цвет (для плавного изменения цветов), а также чем меньше времени контроллер проводит в прерывании тем меньше вероятность потери USB-пакетов (хотя этим занимается другая подсистема контроллера и, как мне кажется, она достаточно асинхронна, чтобы не париться по этому поводу).

PS: Что-то мне все больше кажется, что BAM пока нам не нужен.


26 апреля 2011 г. 19:38 пользователь kv35 <kv0...@gmail.com> написал:
>>В результате при переполнении разряда возникает мерцание (0b00011111 ->
0b00100000)

--
Лайтпак: lightpack.googlecode.com
Отправить сообщение в группу: ligh...@googlegroups.com
Отписаться от сообщений группы: lightpack+...@googlegroups.com

--
Лайтпак: lightpack.googlecode.com
Отправить сообщение в группу: ligh...@googlegroups.com
Отписаться от сообщений группы: lightpack+...@googlegroups.com

kv35

unread,
Apr 26, 2011, 2:00:06 PM4/26/11
to Лайтпак: обсуждение проекта и новых идей
On 26 апр, 20:37, Mike Shatohin <bru...@gmail.com> wrote:
> Логика работы сейчас следующая:
> - Срабатывает прерывание таймера
> 1) Увеличивается номер текущего обрабатываемого бита
> 2) Обновляются значения в драйверах, соответственно обрабатываемому биту
> 3) Пересчитывается задержка до обработки следующего бита
> 4) Сбрасывается счетчик таймера (он не сбрасывается автоматически при входе
> в прерывание, да и в процессе работы прерывания продолжает тикать)
> - Ожидание следующего прерывания
>

Пересчет задержки во время работы таймера?

Я делал немного иначе.
У меня таймер постоянно генерирует прерывания с равными промежутками.
Что для PWM, что для BAM.
Для этого достаточно настроить прерывание по совпадению и активировать
сброс при совпадении (Clear Timer on Compare).
Таймер постоянно будет считать от 0 и до заданного значения, при
достижении которого будет генерировать прерывание и автоматом
сбрасываться.

Никаких дополнительных вмешательств в работу таймера не требуется.

Далее..
для PWM: проверка совпадения счетчика прерывания со значением каждого
канала, при необходимости - обновление данных на драйверах
для BAM: проверка совпадения счетчика прерываний с 2^n (n:0-7), при
совпадении - отправка новых данных

Тут BAM выигрывает по двум параметрам: максимальное время работы
процедуры (можно увеличить частоту на пару порядков) и затрачиваемое
процессорное время в целом.

>Проблема в следующем: при установке вручную значений 0b00111110,
>0b00111101, 0b00111100, 0b00111011 - в момент переключения никакого
>мерцания нет.
>При смене значения с 0b00111111 на 0b01000000 яркость светодиодов становится
>немного ниже и светодиоды в процессе смены цвета мерцают (плавное изменение
>цветов выключено).

Не совсем понимаю какое значение вы меняете. Это значение яркости
канала?
Как долго происходит смена цвета, что они успевают померцать?
Для глаза изменение значение на единицу вообще должно быть мало
различимо.
Подозреваю, что проблема в рассчете поворота массива.

>Если в прошивке просто попробовать с некоторой задержкой менять цвет с 0x00
>до 0xFF, то будет заметно что яркость, то возрастает, то немного снижается и
>снова возрастает. C PWM таких проблем нет.

Да, было у меня подобное.. Некорретно поворачивал массив.
Посмотрю, как это у вас происходит.

>PS: Что-то мне все больше кажется, что BAM пока нам не нужен.

На данный момент это неприоритетная задача. PWM вполне справляется с
работой, так что с BAM можно не торопиться.
Но кто знает, когда и где понадобятся дополнительные ресурсы. Лучше
изучать более оптимальные решения просто для того, что бы была
возможность использовать их когда они будут востребованы.

kv35

unread,
Apr 26, 2011, 2:43:35 PM4/26/11
to Лайтпак: обсуждение проекта и новых идей
В упор не помню, в чем конкретно была проблема.
Посмотрел код - вроде все верно.
Вариантов тут не много: можно либо опрашивать биты в другу сторону (7-
>0 вместо 0->7), либо поменять порядок измеряемых отрезков времени
(128..1 вместо 1..128).
Итого 4 варианта комбинаций. Один из них - рабочий, другой -
инверсный.

А два других какраз работают волнообразно, и волнообразно инверсно.
Если, конечно, правильно вспоминаю.

Reply all
Reply to author
Forward
0 new messages