Часы из часов на дисплее из дисплеев

Arduino & Pi

1.4K постов20.6K подписчика

Добавить пост

Правила сообщества

В нашем сообществе запрещается:

• Добавлять посты не относящиеся к тематике сообщества, либо не несущие какой-либо полезной нагрузки (флуд)

• Задавать очевидные вопросы в виде постов, не воспользовавшись перед этим поиском

• Выкладывать код прямо в посте - используйте для этого сервисы ideone.com, gist.github.com или схожие ресурсы (pastebin запрещен)

• Рассуждать на темы политики

• Нарушать установленные правила Пикабу

279
DELETED
Автор поста оценил этот комментарий

Воу воу, мир настолько очистился, что гайвер вернулся на пикабу)

раскрыть ветку (1)
116
Автор поста оценил этот комментарий

даааа, в запасе есть десяток роликов которые забыл опубликовать)

показать ответы
20
Автор поста оценил этот комментарий

Есть претензии к оптимизации математики, но результат выше всяких похвал

раскрыть ветку (1)
56
Автор поста оценил этот комментарий

благодаря комментарию выше оптимизировал операции с шестёркой. Теперь текст летит на ардуино нано как водяной понос =)

82
DELETED
Автор поста оценил этот комментарий

это хорошо) Можешь кстати по два раза выкладывать, в последнее время тут любят баяны часовой давности выкладывать)

раскрыть ветку (1)
49
Автор поста оценил этот комментарий

ну я раз в день буду, не чаще. Если не забуду)

показать ответы
20
Автор поста оценил этот комментарий

Есть претензии к оптимизации математики, но результат выше всяких похвал

раскрыть ветку (1)
36
Автор поста оценил этот комментарий

ну так я готов их выслушать! Только спешу напомнить, что умножение и остаток от деления на числа "из степени двойки" компилятор оптимизирует самостоятельно, а деление у меня в коде заменено на сдвиг. Если есть что-то ещё - пишите!

показать ответы
14
Автор поста оценил этот комментарий

я был больше всего удивлен что ардуинка не вытягивает вычисления в динамике

раскрыть ветку (1)
25
Автор поста оценил этот комментарий

дело в том, что размер блока виртуальных пикселей был сделан 4х6, а операции деления и остатка от деления с числами не из степеней двойки (2 4 8 16 32) выполняются в 20 раз медленнее, потому что у ардуинки нет аппаратного деления. Все остальные вычисления оптимизированы до степеней двойки, поэтому только лишь вот эта шестёрка добавляет около 150 миллисекунд!!!! к расчётам позиций пикселей при отрисовке часов

показать ответы
32
Автор поста оценил этот комментарий

Возможно вам стоило бы подкинуть в программу функцию ускоренного деления на 6 через умножение на заранее посчитанную целочисленную константу.
Ну и вызывать свою функцию вместо оператора деления.

Вот тут немного тема раскрыта:
https://habr.com/ru/post/147096/

раскрыть ветку (1)
19
Автор поста оценил этот комментарий

о, супер, спасибо! Я как раз сейчас сидел гуглил про быстрое деление на 6, но ничего вменяемого не нашёл)

показать ответы
11
Автор поста оценил этот комментарий

Для ардуино с 16-битными регистрами деление на 6 будет примерно так (я не проверял, только прикинул):


final int cpuRegisterSize = 16;

final int b = 3;

final int L = 2; // 2**L >= b

final int N = (cpuRegisterSize – L) / 2; // ==7

final int B = ((1 << (N + L)) / b) + 1;

final int shiftSize = N + L + 1; // additional '+1' to move from div3 to div6


private static int divideBy6(int a) {

    return (a * B) >> shiftSize;

}

private static int modBy6(int a) {

    return a - divideBy6(a) * 6;

}

раскрыть ветку (1)
14
Автор поста оценил этот комментарий

я не очень вник в статью, загуглил - нашёл более короткое объяснение. В моём случае до чисел 150 деление на 6 можно записать так:

x = (i * 342) >> 11;

выполняется в ячейке 2 байта. Точно там же можно найти остаток

val - x * 6

код ускорен в два раза, спасибо за наводку)

11
Автор поста оценил этот комментарий

Для ардуино с 16-битными регистрами деление на 6 будет примерно так (я не проверял, только прикинул):


final int cpuRegisterSize = 16;

final int b = 3;

final int L = 2; // 2**L >= b

final int N = (cpuRegisterSize – L) / 2; // ==7

final int B = ((1 << (N + L)) / b) + 1;

final int shiftSize = N + L + 1; // additional '+1' to move from div3 to div6


private static int divideBy6(int a) {

    return (a * B) >> shiftSize;

}

private static int modBy6(int a) {

    return a - divideBy6(a) * 6;

}

раскрыть ветку (1)
11
Автор поста оценил этот комментарий

вот такой инструмент получился, выдаёт результат деления и остаток

Иллюстрация к комментарию
показать ответы
3
Автор поста оценил этот комментарий

А если quot * 6 заменить на quot << 2 + quot << 1

раскрыть ветку (1)
6
Автор поста оценил этот комментарий

Экономия на крохах буквально ;) возможно компилятор уже оптимизирует это сам, я проверю

показать ответы
Автор поста оценил этот комментарий

А остаток прямо всегда нужен?
Можно при желании сделать его вычисляемым опционально.
способы разные есть красиво оформить

раскрыть ветку (1)
5
Автор поста оценил этот комментарий

Прямо всегда, для расчетов установки одного пикселя нужно и деление и остаток

показать ответы
21
Автор поста оценил этот комментарий

С очки зрения оптимизации ваш вариант куда удачнее.

раскрыть ветку (1)
22
Автор поста оценил этот комментарий

С точки зрения оптимизации чего? Если захочется вывести другую графику, текст или анимацию - это сидеть опять руками всё переделывать и хранить кадры в памяти? Это не похоже как минимум на оптимизацию памяти и на оптимизацию ручной работы ;)

показать ответы
14
Автор поста оценил этот комментарий

С точки зрения решения конкретой задачи - вывода часов.

раскрыть ветку (1)
16
Автор поста оценил этот комментарий

Не соглашусь. В эту задачу входят подзадачи "нарисуй шрифт" и "расположи его на экране", а делать это на матрице, которая не является ровной сеткой - эксплуатация дизайнера, который будет рисовать и перерисовывать шрифты, в том числе если захочется подвинуть цифру на один сегмент в сторону ;)

показать ответы
3
Автор поста оценил этот комментарий

А если quot * 6 заменить на quot << 2 + quot << 1

раскрыть ветку (1)
Автор поста оценил этот комментарий

не, это уже получается медленнее ~ на 30%, потому что вместо одной аппаратной операции умножения у нас три операции - два сдвига и одно сложение