Алгоритм брезенхема для регулировки мощности

Алгоритм брезенхема для регулировки мощности

Зарегистрируйтесь и получите два купона по 5$ каждый:https://jlcpcb.com/quote

edds
Встал на лапы

Зарегистрирован: Пт авг 28, 2009 16:08:48
Сообщений: 90
Откуда: г.Вязьма Смоленская обл
Рейтинг сообщения: 0

Twilo
Нашел транзистор. Понюхал.

Зарегистрирован: Вт авг 25, 2009 22:24:39
Сообщений: 193
Откуда: Черкассы
Рейтинг сообщения: 0

В протоколе CAN FD, благодаря ряду изменений, эффективная скорость передачи данных может быть увеличена в несколько раз. Все это делает CAN FD наиболее привлекательной альтернативой для CAN-устройств. Рассмотрим особенности CAN FD, а также пример практической реализации CAN FD на базе микроконтроллеров STM32L5.

maglev

* когда выяснилось, какую мощность хотим передать в нагрузку (пусть будет 20 из интервала [0..99]):
regValue = 20;
regError = 50;
Устанавливаем regError = 99/2, середина интервала. Это нужно делать каждый раз при изменении regValue;

* в начале каждого полного периода сетевого напряжения делаем:

STM32G4 обладают наиболее богатым набором интерфейсов и аналоговой периферии и предназначены для устройств с обработкой смешанных сигналов. Мы собрали самые интересные статьи и видео уроки для работы на микроконтроллерах STM32G4!

edds
Встал на лапы

Зарегистрирован: Пт авг 28, 2009 16:08:48
Сообщений: 90
Откуда: г.Вязьма Смоленская обл
Рейтинг сообщения: 0

Всё, тему можно закрывать

avreal
Опытный кот

Карма: 7
Рейтинг сообщений: 52
Зарегистрирован: Чт дек 31, 2009 19:27:45
Сообщений: 842
Откуда: Бровари, Україна
Рейтинг сообщения: 0

_________________
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.

edds
Встал на лапы

Зарегистрирован: Пт авг 28, 2009 16:08:48
Сообщений: 90
Откуда: г.Вязьма Смоленская обл
Рейтинг сообщения: 0

ПРИСТ расширяет ассортимент

Страница 1 из 1 [ Сообщений: 8 ]

Часовой пояс: UTC + 3 часа

Кто сейчас на форуме

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

Источник

Алгоритм Брезенхэма. Моя реализация.

Хочу представить на обсуждение почтенной публики свою реализацию алгоритма Брезенхэма. Кто не знает, что это за зверь и с чем его едят, могут ознакомиться с предметом обсуждения здесь. Интересующихся прошу под кат.

Для начала небольшой дисклеймер. Род моей деятельности — сраный сисадмин-эникейщик и быдлокодер на Делфи, причем теоретическими познаниями не богат, поскольку институтов не заканчивал :). Эникейщиной зарабатываю на жизнь, Делфями изредка на ништяки. Т.е. типичный провинциальный компьютерщик. МК изучать начал с момента регистрации в сообществе. На С никогда до этого не писал, изучаю по мере необходимости. После Делфи этот процесс конкретно выносит мне мозг, но выбора нет, поскольку разработка на ассемблере объективно сложнее, хоть он мне гораздо ближе и я с ним довольно сносно знаком, а микропаскаль убог. Остается С. И осваивать его приходится с чистого заполненного Делфями листа. На момент написания статьи кнопка «New project» в AVR Studio была нажата четвертый раз в жизни. Поэтому прошу сообщество отнестись к моим потугам с пониманием и органикой в меня не кидать :).

Итак, к делу. Алгоритм Брезенхэма предназначен для построения прямых, заданных координатами (X1,Y1)-(X2,Y2) на растровых устройствах. Если не врут источники, изначально разрабатывался для графопостроителей, но во всех источниках, которые я изучил, описано его применение для вывода графики на экран и только для двух осей. Теория расписана более чем подробно в той же Википедии, цитировать ее тут особого смысла не вижу.

Но мне экран был не нужен, я станочек строить пытаюсь. Поэтому пришлось его адаптировать под свои цели. Сначала он крутился на хост-приложении и был реализован, естественно, на Делфи. Но передавать шаги на контроллер через V-USB — не айс, поскольку медленно и неравномерно, движки работали рывками. Поэтому было решено перенести эти расчеты в контроллер и передавать туда уже координаты. Это было второе нажатие кнопки «New project». Получилось, как графопостроитель мой станок заработал нормально. Концы у окружностей сходились :). Но исходник получился такой, что показать его людям стыдно, да и не только сабж там был, а и V-USB, и управление движками, и все в перемешку. Короче, ужас нечитаемый. Поэтому решил оформить сабж в виде библиотеки и привести код в удобочитаемый вид.

Библиотека поддерживает до 8 осей, на выходе имеем два битовых поля — Step и Direction. Бит Direction, установленный в 0, указывает на уменьшение текущей координаты, установленный в 1 — увеличение. Бит Step указывает на необходимость выполнения шага по данной оси. Короче, стандартный STEP/DIR.

Вот исходник хидера:

Назначение дефайнов:
BresAxisCount — количество обрабатываемых осей, от 2 до 8;
BresUseDirection — если этот дефайн закомментировать, от STEP/DIR останется только STEP. Зачем мне это нужно — объясню ниже;
BresPosHolderSize — разрядность переменных, хранящих координаты. 8, 16 или 32 бита, если работаем без DIR — переменные беззнаковые.

Полетную информацию библиотека хранит в структуре BresDataStruct. Ниже назначение полей.
Массивы для каждой из осей:
StartPos[BresAxisCount] — начальная координата задания;
TargetPos[BresAxisCount] — конечная координата задания;
CurrentPos[BresAxisCount] — текущая координата;
Delta[BresAxisCount] — пробег 🙂
E[BresAxisCount] — накопитель ошибки. Обязательно signed и с большей разрядностью, чем у полей координат.

Общие для всех осей:
MaxDelta — самый большой пробег;
StepCounter — cчетчик шагов задания;
Step — собственно, результат;
Direction — тоже результат;
Status — состояние (спасибо, кэп!).

Нулевой бит полей Step и Direction соответствует оси с индексом 0.

Биты поля Status:
0 BresStateIdle — закончили выполнение задания (или еще не начинали) и ждем следующего;
1 BresStateStepEnable — следующий шаг обсчитан, разрешено выполнение;
2 BresStateStepRequest — шаг выполнен, запрос на вычисление следующего шага;
3 BresStateLock — блокировка работы. Процедуры ничего делать не будут, пока его не сбросишь.

Ну и сами процедуры:
BresInit(BresData *aData) — обнуляет все и вся;

BresSetStartPosition(BresData *aData, BresPosHolderType NewStartPos[BresAxisCount])
— установка начальной позиции. Текущие координаты устанавливаются в те же значения, что и начальные. Координаты передаются в виде массива. Прерывает выполнение задания. Назначение — ноль таскать по рабочему полю. Ну и еще есть применения. 🙂

int BresSetTargetPosition(BresData *aData, BresPosHolderType NewTargetPos[BresAxisCount]) — функция устанавливает конечные координаты задания, производит начальные вычисления и поднимает бит BresStateStepRequest в поле статус. При нормальной отработке (не было заблокировано и т.п.) возвращает 1, иначе 0;

BresProcessStep(BresData *aData); — расчет следующего шага. Срабатывает при поднятом бите BresStateStepRequest в поле статус. Считает следующий шаг для всех осей и поднимает бит BresStateStepEnable в поле статус. Если достроили прямую до конца — поднимает бит BresStateIdle;

BresExecuteStep(BresData *aData, UsersExecuteStep_T UsersExecuteStep) — выполнение рассчитанного шага. Срабатывает при поднятом бите BresStateStepEnable в поле статус. В параметрах получает указатель на пользовательскую процедуру, которую вызывает (да, callback. И не надо меня в Java-головости обвинять — в Java никогда не программировал :)))) и передает ей поля Step и Direction. Можно вызывать по таймеру или прерыванию. По завершении поднимает бит BresStateStepRequest в поле статус.

Вот, собственно, и все описание.
Сишник

и программа, в которой я его отлаживал

Теперь расскажу зачем мне понадобилось отключение Direction. Дело в том, что сабж применим в задачах, где нужно более-менее равномерно распределить некое количество импульсов относительно другого количества импульсов. Например, симмисторный регулятор мощности с пропуском полупериодов. BresExecuteStep вешаем на прерывание, вызываемое детектором перехода синусоиды через ноль. Выбираем две оси, отключаем Direction, размерность выбираем 8 бит. Пишем код

в пользовательской процедуре обработки отправляем соответствующий бит Step на пин, подключенный ко входу симмисторного ключа и вуаля — на выход пройдет 30 равномерно распределенных полупериодов из 100.

Гонял код под дебагером от AVR Studio. Вроде работает.

Исходники во вложении.

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

Источник

Алгоритм Брезенхема для регулирования мощности

Регулирование напряжения микроконтроллером

На каждой итерации ШИМ дает единичный положительный импульс, длительность которого пропорциональна яркости. В результате светодиод начинает быстро мигать, и поскольку импульсы подаются с относительно высокой частотой, а наше зрение инертно, мы воспринимаем это мерцание как непрерывное свечение. Частота мерцания равна частоте ШИМа и в случае малых яркостей и не слишком высоких частот оно может стать заметным для глаза. Чтобы и избавиться от него необходимо увеличивать частоту ШИМ, что не всегда возможно. Например, в случае, когда требуется рулить не единичным светодиодом, а большим светодиодным дисплеем с динамической индикацией, или в случае, когда надо регулировать мощность нагрузки привязываясь к полупериодам сетевого напряжения, как в случае с регулятором мощности паяльника.

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

Алгоритм Брезенхема

Размер сетки:
Наклон прямой:

Осталось разобраться с алгоритмом. Рисование линии реализуется псевдокодом:

Добавляя вычисление разности с предыдущим значением, получаем диаграмму импульсов:

Затем, эту функцию можно еще упростить переписав как:

Наконец, мо жно ещё немного изменить алгоритм и оформить его в виде библиотечного файла:

Тут структура bresenham_struct хранит информацию о настройках и текущем состоянии генератора последовательности Брезенхэма;
Метод bresenham_init(st, size) вызывается в момент инициализации и задаёт количество разбиений оси времени (количество градаций яркости);
Метод bresenham_setValue(st, value) вызывается для задания яркости. Например, если size = 100, то яркость может быть от 0..99;
Метод bresenham_getNext(st) вызывается периодически по прерыванию таймера (или любым другим способом) и возвращает true, если надо подать положительный импульс и false в противном случае.

Результат работы последнего алгоритма можно увидеть ниже:

По ссылкам ниже можно скачать файл с реализацией алгоритма (для AVR GCC) и файл с тестов, проверяющих валидность генерируемых последовательностей.

Источник

Читайте также:  Дэу матиз регулировка передних ступичных подшипников
Оцените статью
( Пока оценок нет )
Поделиться с друзьями
Настройки и регулировки