XanderEVG

XanderEVG

Пикабушник
Дата рождения: 25 февраля 1989
поставил 15217 плюсов и 4447 минусов
отредактировал 10 постов
проголосовал за 36 редактирований
Награды:
10 лет на Пикабу
48К рейтинг 40 подписчиков 279 подписок 15 постов 1 в горячем

Зацените новый классный жанр - подборка падений

Ответ на пост «Скажите честно»

Сейчас листал "Новое издание" в телеге.


Новость 1: цель России паника и жертвы.

Новость 2-4: местные остановили колонны военной техники в разных городах и ничего им за это не было.

Новость 5: рф не дала гуманитарный коридор.


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

Ответ на пост «Скажите честно» Политика, Россия и Украина, Ответ на пост, Длиннопост
Ответ на пост «Скажите честно» Политика, Россия и Украина, Ответ на пост, Длиннопост
Ответ на пост «Скажите честно» Политика, Россия и Украина, Ответ на пост, Длиннопост
Ответ на пост «Скажите честно» Политика, Россия и Украина, Ответ на пост, Длиннопост
Ответ на пост «Скажите честно» Политика, Россия и Украина, Ответ на пост, Длиннопост
Ответ на пост «Скажите честно» Политика, Россия и Украина, Ответ на пост, Длиннопост
Ответ на пост «Скажите честно» Политика, Россия и Украина, Ответ на пост, Длиннопост

Ну и последний скрин с другого канала:

Ответ на пост «Скажите честно» Политика, Россия и Украина, Ответ на пост, Длиннопост
Показать полностью 8

Хард турист

Народный контроль исполнения пдд, любой ценой

В очередной раз о прохождении поворотов

Привет всем, читаю байкпост, там чел оценил качество видоса-обучалки как неудовлетворительное из за того, что автор посоветовал проходить повороты на ровном газу.


Я в курсе, что кейт код говорил о том, что идеальное распределение веса на байке 40/60, поэтому нужно ехать на легком газу, особенно на выходе. Но так ли плохо ехать на ровном газу, чем это опасно, кто что думает?


И основное, что я не понял, этот комментатор обосновал необходимость ехать на газу тем, что в повороте длинна окружности колеса уменьшается(из за наклона и профиля резины), но как обычно в интернете бывает, он выставил это как факт, но не обьяснил почему. Почему уменьшение длинны окружности ухудшает управляемость, почему открытие газа это компенсирует? Кто нить сталкивался с подобным?

В очередной раз о прохождении поворотов Мото, Вопрос, Нуб, Длиннопост
Показать полностью 1

Думал ли он, что отсутствие шлема может привести к таким последствиям на таком пустяковом падении?

Как думаете, сотрудники действовали корректно? хочу сравнить реакцию мотосообщества пикабу с реакцией чуваков из вк) Думаю срача тут быть не должно, но кто знает)


За одно еще раз напомним себе, что выезжая за хлебом нужно надевать экип


Смотреть с 16 секунды, основное действо на 1:30

Новогоднее обращение к мотоциклистам России

Таймерная служба и диспетчер для ардуино от DiHalt

Пост по мотивам  дверного звонка.

Можно сказать логическое его продолжение. Совместим приятное с полезным и заодно рассмотрим таймерную службу и диспетчер задач от DiHalt. Мне показалось эта система довольно удобна для организации кода, особенно если кода много и он чуть сложнее чем мигание светодиодом.


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


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

SetTask(BlinkON); 

Функция добавления выполняется не долго (конкретно сколько - хз, можно посчитать, это вам в качестве домашки). Понятно что моргнуть светодиодом можно и в самом прерывании, это быстрее. Но к примеру:

SetTask(SendToSerial_длинный_текст); 

уже выгода ощущается заметно.


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

Например в прерывании мы спалили что нажата кнопка:

if(кнопка нажата){

отключаем прерывание у этой кнопки;

SetTask(btnPress); 

}


В btnPres() мы выполняем нужные действия и добавляем SetTimerTask(btnRelease, 100);

Таким образом через 100мс после нажатия кнопки сработает btnRelease, где мы обратно включим прерывания с кнопки. Этим самым мы добиваемся того, что в главном цикле меньше говнокода, портянки проверок и запусков всего, упрощаем масштабирование кода(пример в конце) и заодно, конкретно в этом примере мы избавляемся от головняка отслеживания дребезга.


Теперь кусок псевдокода моего проекта, задача:

1) по нажатию кнопки включать проигрывание мелодии

2) ночью снижать громкость, время синхронизировать с RTC микрухой

3) ограничивать звук вручную с переменного резистора

4) синхронизироваться с телефоном(выбор мелодии, установка времени тихого режима, синхронизация времени телефон->ардуино->RTC и тд)


Главный цикл:

void setup() {

поднимаем_serial();

настраиваем_пины();

инициализируем_переменные();

настраиваем_mp3();

настраиваем_прерывание_с_кнопки(PCIN2);

настраиваем_таймер_для_отсчета_времени();


InitRTOS(); // Инициализируем ядро таймерной службы

RunRTOS(); //Запускаем таймерную службу и диспетчер задач


// Запуск фоновых задач

SetTimerTask(read_max_volume, 1000);  //читаем данные с переменного резистора каждые 1 сек

SetTimerTask(check_time, 1000);  //проверяем время, не поздно ли. если поздно - включим тихий режим

SetTimerTask(read_rtc, 65000);  //синхронизируемся с RTC

SetTimerTask(check_sync, SYNC_PERIOD); //читаем bluetooth модуль, проверяем пришли ли данные

SetTimerTask(BlinkON,500); //моргаем светодиодом

sei();

}


void loop() {

TaskManager(); 

}


И все, ничего лишнего. check_sync проверяет есть ли данные в буфере от bluetooth модуля.

Если данные есть - мы их считываем и запускаем задачу их распарсить. Как только доходит очередь до функции парсинга, мы понимаем какой пакет данных пришел:

- если это запрос текущих настроек - отправляем ответ

- если это данные с новыми настройками - принимаем и сохраняем их

- если это запрос "воспроизведи текущую мелодию" запускаем задачу воспроизведения


Каждую задачу нужно писать так что бы она выполнялась как можно быстрее, никаких delay внутри быть не должно(кроме совсем уж мелких, как у 1-wire), вместо этого отдаем управление другой задаче, предварительно добавив нужный флаг состояния этой задачи и добавив себя же в очередь(таймерную)

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


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


UPD:  Забыл про пример расширяемости кода. Допустим мы захотели к дверному звонку добавить пару функций:  датчик дыма, угарного газа, с оповещением или датчик движения, с оповещением, etc.

Для этого нужно добавить в конец setup() пару строк:

SetTimerTask(check_gas, 1000);

SetTimerTask(check_motion_sensor, 500); 

Останется написать сами эти функции. т к опросы датчиков происходят очень редко, по меркам МК, это нисколько не нагрузит ни очередь, ни сам микропроцессор. Функция проигрывания уже написана, нам нужно только записать нужные мелодии на флешку и запомнить их id


Вопросы, пожелания и критика приветствуется)

Показать полностью
Отличная работа, все прочитано!